'version'], ['value' => '0.0.0']); Setting::updateOrCreate(['key' => 'build'], ['value' => '0']); $composer = json_decode((string) file_get_contents(base_path('composer.json')), true); $expectedVersion = (string) ($composer['version'] ?? ''); $expectedBuild = (string) ($composer['build'] ?? ''); $exitCode = Artisan::call('version:fetch'); expect($exitCode)->toBe(0); expect(Setting::where('key', 'version')->value('value'))->toBe($expectedVersion); expect(Setting::where('key', 'build')->value('value'))->toBe($expectedBuild); }); }); it('fails when composer.json cannot be decoded', function (): void { withComposerBackupForFetch(function (string $path): void { file_put_contents($path, 'not-json'); $exitCode = Artisan::call('version:fetch'); expect($exitCode)->toBe(1); }); }); it('fails when composer.json is missing build', function (): void { withComposerBackupForFetch(function (string $path): void { $data = json_decode((string) file_get_contents($path), true); unset($data['build']); file_put_contents($path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . PHP_EOL); $exitCode = Artisan::call('version:fetch'); expect($exitCode)->toBe(1); }); }); it('fails when file_get_contents returns false', function (): void { withComposerBackupForFetch(function (): void { $GLOBALS['version_fetch_file_get_contents_false'] = true; $exitCode = Artisan::call('version:fetch'); expect($exitCode)->toBe(1); }); }); }