0]); config(['constants.ssh.mux_enabled' => false]); Log::spy(); $team = Team::factory()->create(); $server = Server::factory()->create(['team_id' => $team->id, 'private_key_id' => PrivateKey::factory()->create(['team_id' => $team->id])->id]); $destination = StandaloneDocker::query()->where('server_id', $server->id)->firstOrFail(); $this->application = Application::factory()->create([ 'build_pack' => 'dockercompose', 'git_repository' => 'https://github.com/coollabsio/private-repo', 'git_branch' => 'main', 'base_directory' => '/', 'docker_compose_location' => '/docker-compose.yml', 'destination_id' => $destination->id, 'destination_type' => $destination->getMorphClass(), ]); $this->gitError = "Cloning into 'checkout'...\nfatal: unable to access 'https://x-access-token:ghs_SECRET123@github.com/coollabsio/private-repo.git/': The requested URL returned error: 403 denied"; }); function fakeComposeLoadServer(?string $failingStep, string $errorOutput): void { Process::fake(function ($process) use ($failingStep, $errorOutput) { $command = is_array($process->command) ? implode(' ', $process->command) : $process->command; if ($failingStep !== null && str_contains($command, $failingStep)) { return Process::result(errorOutput: $errorOutput, exitCode: 128); } return Process::result(output: str_contains($command, 'git --version') ? 'git version 2.43.0' : ''); }); } it('shows and logs why the Compose file could not be read, without credentials', function () { fakeComposeLoadServer('sparse-checkout', $this->gitError); expect(fn () => $this->application->loadComposeFile()) ->toThrow(function (RuntimeException $exception) { expect($exception->getMessage()) ->toContain('Failed to read the Docker Compose file from the repository.') ->toContain('The requested URL returned error: 403 <b>denied</b>') ->toContain('https://***@github.com/') ->not->toContain('ghs_SECRET123') ->not->toContain(''); }); Log::shouldHaveReceived('warning')->withArgs(fn (string $message, array $context) => $message === 'Failed to read the Docker Compose file from the repository.' && $context['application_uuid'] === $this->application->uuid && str_contains($context['error'], 'The requested URL returned error: 403') && ! str_contains(json_encode($context), 'ghs_SECRET123')); }); it('shows and logs why the Git source could not be read, without credentials', function () { fakeComposeLoadServer('ls-remote', $this->gitError); expect(fn () => $this->application->loadComposeFile()) ->toThrow(function (RuntimeException $exception) { expect($exception->getMessage()) ->toContain('Failed to read Git source. Please verify repository access and try again.') ->toContain('The requested URL returned error: 403') ->not->toContain('ghs_SECRET123'); }); Log::shouldHaveReceived('warning')->withArgs(fn (string $message, array $context) => $message === 'Failed to read Git source.' && ! str_contains(json_encode($context), 'ghs_SECRET123')); });