createMachine('Machine A'); $client = $this->createViewerClient(); $client->request('POST', '/api/comments', [ 'json' => [ 'content' => 'Test comment', 'entityType' => 'machine', 'entityId' => $machine->getId(), 'entityName' => 'Machine A', ], ]); $this->assertResponseStatusCodeSame(201); $this->assertJsonContains([ 'content' => 'Test comment', 'entityType' => 'machine', 'status' => 'open', ]); } public function testCreateCommentUnauthenticated(): void { $client = $this->createUnauthenticatedClient(); $client->request('POST', '/api/comments', [ 'json' => [ 'content' => 'No auth', 'entityType' => 'machine', 'entityId' => 'fake-id', ], ]); $this->assertResponseStatusCodeSame(401); } public function testCreateCommentEmptyContent(): void { $client = $this->createViewerClient(); $client->request('POST', '/api/comments', [ 'json' => [ 'content' => '', 'entityType' => 'machine', 'entityId' => 'some-id', ], ]); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['message' => 'Le contenu est requis.']); } public function testCreateCommentInvalidEntityType(): void { $client = $this->createViewerClient(); $client->request('POST', '/api/comments', [ 'json' => [ 'content' => 'Invalid type', 'entityType' => 'invalid', 'entityId' => 'some-id', ], ]); $this->assertResponseStatusCodeSame(400); $this->assertJsonContains(['message' => "Type d'entité invalide."]); } public function testCreateCommentMissingEntityId(): void { $client = $this->createViewerClient(); $client->request('POST', '/api/comments', [ 'json' => [ 'content' => 'Missing ID', 'entityType' => 'machine', 'entityId' => '', ], ]); $this->assertResponseStatusCodeSame(400); } public function testResolveComment(): void { $machine = $this->createMachine('Machine A'); $viewerClient = $this->createViewerClient(); $response = $viewerClient->request('POST', '/api/comments', [ 'json' => [ 'content' => 'To resolve', 'entityType' => 'machine', 'entityId' => $machine->getId(), ], ]); $data = $response->toArray(); $commentId = $data['id']; $gestionnaireClient = $this->createGestionnaireClient(); $gestionnaireClient->request('PATCH', sprintf('/api/comments/%s/resolve', $commentId)); $this->assertResponseIsSuccessful(); $this->assertJsonContains(['status' => 'resolved']); } public function testResolveCommentNotFound(): void { $client = $this->createGestionnaireClient(); $client->request('PATCH', '/api/comments/nonexistent-id/resolve'); $this->assertResponseStatusCodeSame(404); } public function testUnresolvedCount(): void { $machine = $this->createMachine('Machine A'); $client = $this->createViewerClient(); $client->request('POST', '/api/comments', [ 'json' => [ 'content' => 'Open 1', 'entityType' => 'machine', 'entityId' => $machine->getId(), ], ]); $client->request('POST', '/api/comments', [ 'json' => [ 'content' => 'Open 2', 'entityType' => 'machine', 'entityId' => $machine->getId(), ], ]); $client->request('GET', '/api/comments/stats/unresolved-count'); $this->assertResponseIsSuccessful(); $this->assertJsonContains(['count' => 2]); } public function testCreateCommentJsonReturnsDocumentsArray(): void { $machine = $this->createMachine('Machine A'); $client = $this->createViewerClient(); $response = $client->request('POST', '/api/comments', [ 'json' => [ 'content' => 'No files', 'entityType' => 'machine', 'entityId' => $machine->getId(), ], ]); $this->assertResponseStatusCodeSame(201); $data = $response->toArray(); $this->assertSame([], $data['documents']); } public function testCreateCommentWithFile(): void { $machine = $this->createMachine('Machine A'); $client = $this->createViewerClient(); $tmpFile = tempnam(sys_get_temp_dir(), 'test_'); file_put_contents($tmpFile, 'test file content'); $uploadedFile = new UploadedFile( $tmpFile, 'test-doc.pdf', 'application/pdf', null, true, ); $client->request('POST', '/api/comments', [ 'extra' => [ 'parameters' => [ 'content' => 'Comment with file', 'entityType' => 'machine', 'entityId' => $machine->getId(), 'entityName' => 'Machine A', ], 'files' => [ 'files' => [$uploadedFile], ], ], ]); $this->assertResponseStatusCodeSame(201); $data = json_decode($client->getResponse()->getContent(), true); $this->assertSame('Comment with file', $data['content']); $this->assertCount(1, $data['documents']); $this->assertSame('test-doc.pdf', $data['documents'][0]['filename']); $this->assertArrayHasKey('fileUrl', $data['documents'][0]); $this->assertArrayHasKey('downloadUrl', $data['documents'][0]); @unlink($tmpFile); } public function testCreateCommentWithMultipleFiles(): void { $machine = $this->createMachine('Machine A'); $client = $this->createViewerClient(); $tmpFile1 = tempnam(sys_get_temp_dir(), 'test_'); file_put_contents($tmpFile1, 'content 1'); $tmpFile2 = tempnam(sys_get_temp_dir(), 'test_'); file_put_contents($tmpFile2, 'content 2'); $file1 = new UploadedFile($tmpFile1, 'doc1.pdf', 'application/pdf', null, true); $file2 = new UploadedFile($tmpFile2, 'doc2.png', 'image/png', null, true); $client->request('POST', '/api/comments', [ 'extra' => [ 'parameters' => [ 'content' => 'Multiple files', 'entityType' => 'machine', 'entityId' => $machine->getId(), ], 'files' => [ 'files' => [$file1, $file2], ], ], ]); $this->assertResponseStatusCodeSame(201); $data = json_decode($client->getResponse()->getContent(), true); $this->assertCount(2, $data['documents']); @unlink($tmpFile1); @unlink($tmpFile2); } }