diff --git a/src/Controller/BulkInfoProviderImportController.php b/src/Controller/BulkInfoProviderImportController.php index 905df42d..8ee8444b 100644 --- a/src/Controller/BulkInfoProviderImportController.php +++ b/src/Controller/BulkInfoProviderImportController.php @@ -467,11 +467,9 @@ class BulkInfoProviderImportController extends AbstractController try { // Use the job's field mappings to perform the search - $fieldMappings = $job->getFieldMappings(); + $fieldMappingDtos = $job->getFieldMappings(); $prefetchDetails = $job->isPrefetchDetails(); - $fieldMappingDtos = $this->convertFieldMappingsToDto($fieldMappings); - try { $searchResultsDto = $this->bulkService->performBulkSearch([$part], $fieldMappingDtos, $prefetchDetails); } catch (\Exception $searchException) { @@ -542,8 +540,7 @@ class BulkInfoProviderImportController extends AbstractController } try { - $fieldMappings = $job->getFieldMappings(); - $fieldMappingDtos = $this->convertFieldMappingsToDto($fieldMappings); + $fieldMappingDtos = $job->getFieldMappings(); $prefetchDetails = $job->isPrefetchDetails(); // Process in batches to reduce memory usage for large operations diff --git a/src/Entity/BulkInfoProviderImportJob.php b/src/Entity/BulkInfoProviderImportJob.php index 936438fd..e1355e77 100644 --- a/src/Entity/BulkInfoProviderImportJob.php +++ b/src/Entity/BulkInfoProviderImportJob.php @@ -218,6 +218,11 @@ class BulkInfoProviderImportJob extends AbstractDBElement return $this->searchResultsDTO; } + public function hasSearchResults(): bool + { + return !empty($this->searchResults); + } + public function getStatus(): BulkImportJobStatus { return $this->status; diff --git a/tests/Controller/BulkInfoProviderImportControllerTest.php b/tests/Controller/BulkInfoProviderImportControllerTest.php index 02cdacda..3a04ea5b 100644 --- a/tests/Controller/BulkInfoProviderImportControllerTest.php +++ b/tests/Controller/BulkInfoProviderImportControllerTest.php @@ -27,6 +27,10 @@ use App\Entity\Parts\Part; use App\Entity\BulkInfoProviderImportJob; use App\Entity\BulkImportJobStatus; use App\Entity\UserSystem\User; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultsDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; +use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpFoundation\Response; @@ -43,7 +47,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client->request('GET', '/tools/bulk-info-provider-import/step1'); - $this->assertResponseRedirects(); + self::assertResponseRedirects(); } public function testStep1WithInvalidIds(): void @@ -53,7 +57,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client->request('GET', '/tools/bulk-info-provider-import/step1?ids=999999,888888'); - $this->assertResponseRedirects(); + self::assertResponseRedirects(); } public function testManagePage(): void @@ -68,7 +72,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client->followRedirect(); } - $this->assertResponseStatusCodeSame(Response::HTTP_OK); + self::assertResponseStatusCodeSame(Response::HTTP_OK); } public function testAccessControlForStep1(): void @@ -76,7 +80,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client = static::createClient(); $client->request('GET', '/tools/bulk-info-provider-import/step1?ids=1'); - $this->assertResponseRedirects(); + self::assertResponseRedirects(); $this->loginAsUser($client, 'noread'); $client->request('GET', '/tools/bulk-info-provider-import/step1?ids=1'); @@ -98,7 +102,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client = static::createClient(); $client->request('GET', '/tools/bulk-info-provider-import/manage'); - $this->assertResponseRedirects(); + self::assertResponseRedirects(); $this->loginAsUser($client, 'noread'); $client->request('GET', '/tools/bulk-info-provider-import/manage'); @@ -120,7 +124,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client = static::createClient(); $this->loginAsUser($client, 'admin'); - $entityManager = $client->getContainer()->get('doctrine')->getManager(); + $entityManager = static::getContainer()->get('doctrine')->getManager(); // Use an existing part from test fixtures (ID 1 should exist) $partRepository = $entityManager->getRepository(Part::class); @@ -143,30 +147,20 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->setCreatedBy($user); $job->addPart($part); $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([ - [ - 'part_id' => $part->getId(), - 'search_results' => [ - [ - 'dto' => [ - 'provider_key' => 'test_provider', - 'provider_id' => 'TEST123', - 'name' => 'Test Component', - 'description' => 'Test component description', - 'manufacturer' => 'Test Manufacturer', - 'mpn' => 'TEST-MPN-123', - 'provider_url' => 'https://example.com/test', - 'preview_image_url' => null, - '_source_field' => 'test_field', - '_source_keyword' => 'test_keyword' - ], - 'localPart' => null - ] - ], - 'errors' => [] - ] + + $searchResults = new BulkSearchResponseDTO(partResults: [ + new BulkSearchPartResultsDTO(part: $part, + searchResults: [new BulkSearchPartResultDTO( + searchResult: new SearchResultDTO(provider_key: 'test_provider', provider_id: 'TEST123', name: 'Test Component', description: 'Test component description', manufacturer: 'Test Manufacturer', mpn: 'TEST-MPN-123', provider_url: 'https://example.com/test', preview_image_url: null,), + sourceField: 'test_field', + sourceKeyword: 'test_keyword', + localPart: null, + )] + ) ]); + $job->setSearchResults($searchResults); + $entityManager->persist($job); $entityManager->flush(); @@ -178,7 +172,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client->followRedirect(); } - $this->assertResponseStatusCodeSame(Response::HTTP_OK); + self::assertResponseStatusCodeSame(Response::HTTP_OK); // Verify the template rendered the source_field and source_keyword correctly $content = $client->getResponse()->getContent(); @@ -223,7 +217,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client = static::createClient(); $this->loginAsUser($client, 'admin'); - $entityManager = $client->getContainer()->get('doctrine')->getManager(); + $entityManager = self::getContainer()->get('doctrine')->getManager(); $userRepository = $entityManager->getRepository(User::class); $user = $userRepository->findOneBy(['name' => 'admin']); @@ -244,7 +238,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->setCreatedBy($user); $job->addPart($part); $job->setStatus(BulkImportJobStatus::COMPLETED); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -273,7 +267,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client = static::createClient(); $this->loginAsUser($client, 'admin'); - $entityManager = $client->getContainer()->get('doctrine')->getManager(); + $entityManager = self::getContainer()->get('doctrine')->getManager(); $userRepository = $entityManager->getRepository(User::class); $user = $userRepository->findOneBy(['name' => 'admin']); @@ -291,7 +285,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -312,7 +306,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client = static::createClient(); $this->loginAsUser($client, 'admin'); - $entityManager = $client->getContainer()->get('doctrine')->getManager(); + $entityManager = self::getContainer()->get('doctrine')->getManager(); $userRepository = $entityManager->getRepository(User::class); $user = $userRepository->findOneBy(['name' => 'admin']); @@ -330,7 +324,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -380,7 +374,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -420,7 +414,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -461,7 +455,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -511,7 +505,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -551,7 +545,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::COMPLETED); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -672,59 +666,6 @@ class BulkInfoProviderImportControllerTest extends WebTestCase } } - public function testBulkInfoProviderImportJobSerialization(): void - { - $client = static::createClient(); - $this->loginAsUser($client, 'admin'); - - $entityManager = $client->getContainer()->get('doctrine')->getManager(); - $partRepository = $entityManager->getRepository(Part::class); - $part = $partRepository->find(1); - - if (!$part) { - $this->markTestSkipped('Test part with ID 1 not found in fixtures'); - } - - // Test the entity's serialization methods directly - $job = new BulkInfoProviderImportJob(); - $job->addPart($part); - - $searchResults = [ - [ - 'part' => $part, - 'search_results' => [ - [ - 'dto' => new \App\Services\InfoProviderSystem\DTOs\SearchResultDTO( - provider_key: 'test', - provider_id: 'TEST123', - name: 'Test Component', - description: 'Test description', - manufacturer: 'Test Manufacturer', - mpn: 'TEST-MPN', - provider_url: 'https://example.com', - preview_image_url: null - ), - 'localPart' => null, - 'source_field' => 'mpn', - 'source_keyword' => 'TEST123' - ] - ], - 'errors' => [] - ] - ]; - - // Test serialization - $serialized = $job->serializeSearchResults($searchResults); - $this->assertIsArray($serialized); - $this->assertArrayHasKey(0, $serialized); - $this->assertArrayHasKey('part_id', $serialized[0]); - - // Test deserialization - $deserialized = $job->deserializeSearchResults($entityManager); - $this->assertIsArray($deserialized); - $this->assertCount(0, $deserialized); // Empty because job has no search results set - } - public function testManagePageWithJobCleanup(): void { $client = static::createClient(); @@ -749,7 +690,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->setCreatedBy($user); $job->addPart($part); $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -760,7 +701,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $client->followRedirect(); } - $this->assertResponseStatusCodeSame(Response::HTTP_OK); + self::assertResponseStatusCodeSame(Response::HTTP_OK); // Find job from database to avoid detached entity errors $jobId = $job->getId(); @@ -850,13 +791,9 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $bulkService = $client->getContainer()->get(\App\Services\InfoProviderSystem\BulkInfoProviderService::class); // Create empty search results to test prefetch method - $searchResults = [ - [ - 'part' => $part, - 'search_results' => [], - 'errors' => [] - ] - ]; + $searchResults = new BulkSearchResponseDTO([ + new BulkSearchPartResultsDTO(part: $part, searchResults: [], errors: []) + ]); // The prefetch method should not throw any errors $bulkService->prefetchDetailsForResults($searchResults); @@ -887,7 +824,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -937,7 +874,7 @@ class BulkInfoProviderImportControllerTest extends WebTestCase $job->addPart($part); } $job->setStatus(BulkImportJobStatus::COMPLETED); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); diff --git a/tests/Controller/PartControllerTest.php b/tests/Controller/PartControllerTest.php index b6a1ec19..b523520b 100644 --- a/tests/Controller/PartControllerTest.php +++ b/tests/Controller/PartControllerTest.php @@ -32,6 +32,7 @@ use App\Entity\Parts\Supplier; use App\Entity\UserSystem\User; use App\Entity\BulkInfoProviderImportJob; use App\Entity\BulkImportJobStatus; +use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\HttpFoundation\Response; @@ -119,7 +120,7 @@ class PartControllerTest extends WebTestCase $job->setCreatedBy($user); $job->setPartIds([$part->getId()]); $job->setStatus(BulkImportJobStatus::IN_PROGRESS); - $job->setSearchResults([]); + $job->setSearchResults(new BulkSearchResponseDTO([])); $entityManager->persist($job); $entityManager->flush(); @@ -331,4 +332,4 @@ class PartControllerTest extends WebTestCase $client->loginUser($user); } -} \ No newline at end of file +} diff --git a/tests/Entity/BulkInfoProviderImportJobTest.php b/tests/Entity/BulkInfoProviderImportJobTest.php index 48678bf7..7053b613 100644 --- a/tests/Entity/BulkInfoProviderImportJobTest.php +++ b/tests/Entity/BulkInfoProviderImportJobTest.php @@ -25,6 +25,11 @@ namespace App\Tests\Entity; use App\Entity\BulkInfoProviderImportJob; use App\Entity\BulkImportJobStatus; use App\Entity\UserSystem\User; +use App\Services\InfoProviderSystem\DTOs\BulkSearchFieldMappingDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultDTO; +use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; +use App\Services\InfoProviderSystem\DTOs\SearchResultDTO; +use Doctrine\ORM\Mapping\FieldMapping; use PHPUnit\Framework\TestCase; class BulkInfoProviderImportJobTest extends TestCase @@ -57,7 +62,7 @@ class BulkInfoProviderImportJobTest extends TestCase $this->assertEquals(BulkImportJobStatus::PENDING, $job->getStatus()); $this->assertEmpty($job->getPartIds()); $this->assertEmpty($job->getFieldMappings()); - $this->assertEmpty($job->getSearchResults()); + $this->assertEmpty($job->getSearchResultsRaw()); $this->assertEmpty($job->getProgress()); $this->assertNull($job->getCompletedAt()); $this->assertFalse($job->isPrefetchDetails()); @@ -75,17 +80,10 @@ class BulkInfoProviderImportJobTest extends TestCase } $this->assertEquals([1, 2, 3], $this->job->getPartIds()); - $fieldMappings = ['field1' => 'provider1', 'field2' => 'provider2']; + $fieldMappings = [new BulkSearchFieldMappingDTO(field: 'field1', providers: ['provider1', 'provider2'])]; $this->job->setFieldMappings($fieldMappings); $this->assertEquals($fieldMappings, $this->job->getFieldMappings()); - $searchResults = [ - 1 => ['search_results' => [['name' => 'Part 1']]], - 2 => ['search_results' => [['name' => 'Part 2'], ['name' => 'Part 2 Alt']]] - ]; - $this->job->setSearchResults($searchResults); - $this->assertEquals($searchResults, $this->job->getSearchResults()); - $this->job->setPrefetchDetails(true); $this->assertTrue($this->job->isPrefetchDetails()); @@ -162,11 +160,22 @@ class BulkInfoProviderImportJobTest extends TestCase { $this->assertEquals(0, $this->job->getResultCount()); - $searchResults = [ - 1 => ['search_results' => [['name' => 'Part 1']]], - 2 => ['search_results' => [['name' => 'Part 2'], ['name' => 'Part 2 Alt']]], - 3 => ['search_results' => []] - ]; + $searchResults = new BulkSearchResponseDTO([ + new \App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultsDTO( + part: $this->createMockPart(1), + searchResults: [new BulkSearchPartResultDTO(searchResult: new SearchResultDTO(provider_key: 'dummy', provider_id: '1234', name: 'Part 1', description: 'A part'))] + ), + new \App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultsDTO( + part: $this->createMockPart(2), + searchResults: [new BulkSearchPartResultDTO(searchResult: new SearchResultDTO(provider_key: 'dummy', provider_id: '1234', name: 'Part 2', description: 'A part')), + new BulkSearchPartResultDTO(searchResult: new SearchResultDTO(provider_key: 'dummy', provider_id: '5678', name: 'Part 2 Alt', description: 'Another part'))] + ), + new \App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultsDTO( + part: $this->createMockPart(3), + searchResults: [] + ) + ]); + $this->job->setSearchResults($searchResults); $this->assertEquals(3, $this->job->getResultCount()); } @@ -357,4 +366,4 @@ class BulkInfoProviderImportJobTest extends TestCase $this->job->setCompletedAt($customTime); $this->assertEquals($customTime, $this->job->getCompletedAt()); } -} \ No newline at end of file +} diff --git a/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php b/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php index b1951e09..a76c9748 100644 --- a/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php +++ b/tests/Services/InfoProviderSystem/DTOs/BulkSearchResponseDTOTest.php @@ -20,7 +20,6 @@ namespace App\Tests\Services\InfoProviderSystem\DTOs; -use App\Doctrine\Types\BulkSearchResponseDTOType; use App\Entity\Parts\Part; use App\Services\InfoProviderSystem\DTOs\BulkSearchResponseDTO; use App\Services\InfoProviderSystem\DTOs\BulkSearchPartResultDTO; @@ -86,10 +85,127 @@ class BulkSearchResponseDTOTest extends KernelTestCase public function testToSerializableRepresentation(): void { + $serialized = $this->dummy->toSerializableRepresentation(); + $expected = array ( + 0 => + array ( + 'part_id' => 1, + 'search_results' => + array ( + 0 => + array ( + 'dto' => + array ( + 'provider_key' => 'dummy', + 'provider_id' => '1234', + 'name' => 'Test Part', + 'description' => 'A part for testing', + 'category' => NULL, + 'manufacturer' => NULL, + 'mpn' => NULL, + 'preview_image_url' => NULL, + 'manufacturing_status' => NULL, + 'provider_url' => NULL, + 'footprint' => NULL, + ), + 'source_field' => 'mpn', + 'source_keyword' => '1234', + 'localPart' => NULL, + 'priority' => 1, + ), + 1 => + array ( + 'dto' => + array ( + 'provider_key' => 'test', + 'provider_id' => 'test', + 'name' => 'Test Part2', + 'description' => 'A part for testing', + 'category' => NULL, + 'manufacturer' => NULL, + 'mpn' => NULL, + 'preview_image_url' => NULL, + 'manufacturing_status' => NULL, + 'provider_url' => NULL, + 'footprint' => NULL, + ), + 'source_field' => 'name', + 'source_keyword' => '1234', + 'localPart' => 2, + 'priority' => 2, + ), + ), + 'errors' => + array ( + 0 => 'Error 1', + ), + ), + ); + + $this->assertEquals($expected, $serialized); } public function testFromSerializableRepresentation(): void { + $input = array ( + 0 => + array ( + 'part_id' => 1, + 'search_results' => + array ( + 0 => + array ( + 'dto' => + array ( + 'provider_key' => 'dummy', + 'provider_id' => '1234', + 'name' => 'Test Part', + 'description' => 'A part for testing', + 'category' => NULL, + 'manufacturer' => NULL, + 'mpn' => NULL, + 'preview_image_url' => NULL, + 'manufacturing_status' => NULL, + 'provider_url' => NULL, + 'footprint' => NULL, + ), + 'source_field' => 'mpn', + 'source_keyword' => '1234', + 'localPart' => NULL, + 'priority' => 1, + ), + 1 => + array ( + 'dto' => + array ( + 'provider_key' => 'test', + 'provider_id' => 'test', + 'name' => 'Test Part2', + 'description' => 'A part for testing', + 'category' => NULL, + 'manufacturer' => NULL, + 'mpn' => NULL, + 'preview_image_url' => NULL, + 'manufacturing_status' => NULL, + 'provider_url' => NULL, + 'footprint' => NULL, + ), + 'source_field' => 'name', + 'source_keyword' => '1234', + 'localPart' => 2, + 'priority' => 2, + ), + ), + 'errors' => + array ( + 0 => 'Error 1', + ), + ), + ); + + $deserialized = BulkSearchResponseDTO::fromSerializableRepresentation($input, $this->entityManager); + $this->assertEquals($this->dummy, $deserialized); + } }