httpClient = $this->createMock(HttpClientInterface::class); $this->kernel = $this->createMock(KernelInterface::class); $this->gitClient = $this->createMock(GitClient::class); $this->geminiClient = $this->createMock(GeminiClient::class); $this->tempDir = sys_get_temp_dir() . '/git_log_test_' . uniqid(); mkdir($this->tempDir . '/var', 0777, true); } protected function tearDown(): void { $this->removeDirectory($this->tempDir); } public function testExecuteNewCommit() { // 1. Setup Mocks $this->kernel->method('getProjectDir')->willReturn($this->tempDir); $this->gitClient->expects($this->once()) ->method('getLastCommitInfo') ->willReturn([ 'message' => 'feat: add awesome feature', 'date' => '2026-01-30 10:00:00', 'hash' => 'hash123' ]); $this->geminiClient->expects($this->once()) ->method('generateFriendlyMessage') ->with('feat: add awesome feature') ->willReturn('Super nouvelle fonctionnalité ajoutée !'); $this->httpClient->expects($this->once()) ->method('request') ->with('POST', $this->stringContains('discord.com'), $this->arrayHasKey('json')); // 2. Execute $command = new GitSyncLogCommand( $this->httpClient, $this->kernel, $this->gitClient, $this->geminiClient ); $application = new Application(); $application->addCommand($command); $commandTester = new CommandTester($application->find('app:git-log-update')); $commandTester->execute([]); // 3. Assert Output $output = $commandTester->getDisplay(); $this->assertStringContainsString('Journal client mis à jour avec succès', $output); // 4. Assert File Content $filePath = $this->tempDir . '/var/update.json'; $this->assertFileExists($filePath); $data = json_decode(file_get_contents($filePath), true); $this->assertCount(1, $data); $this->assertEquals('feature', $data[0]['type']); $this->assertEquals('Super nouvelle fonctionnalité ajoutée !', $data[0]['message']); $this->assertEquals('hash123', $data[0]['hash']); } public function testExecuteAlreadyUpToDate() { // 1. Setup File $filePath = $this->tempDir . '/var/update.json'; file_put_contents($filePath, json_encode([ ['hash' => 'hash123'] ])); // 2. Setup Mocks $this->kernel->method('getProjectDir')->willReturn($this->tempDir); $this->gitClient->expects($this->once()) ->method('getLastCommitInfo') ->willReturn([ 'message' => 'fix: bug', 'date' => '2026-01-30 12:00:00', 'hash' => 'hash123' // Same hash ]); // Gemini & Discord should NOT be called $this->geminiClient->expects($this->never())->method('generateFriendlyMessage'); $this->httpClient->expects($this->never())->method('request'); // 3. Execute $command = new GitSyncLogCommand( $this->httpClient, $this->kernel, $this->gitClient, $this->geminiClient ); $application = new Application(); $application->addCommand($command); $commandTester = new CommandTester($application->find('app:git-log-update')); $commandTester->execute([]); // 4. Assert Output $output = $commandTester->getDisplay(); $this->assertStringContainsString('déjà à jour', $output); } private function removeDirectory($dir) { if (!is_dir($dir)) return; $files = array_diff(scandir($dir), array('.','..')); foreach ($files as $file) { (is_dir("$dir/$file")) ? $this->removeDirectory("$dir/$file") : unlink("$dir/$file"); } rmdir($dir); } }