diff --git a/tests/Command/PopulateKicadCommandTest.php b/tests/Command/PopulateKicadCommandTest.php index 94c13696..6029c716 100644 --- a/tests/Command/PopulateKicadCommandTest.php +++ b/tests/Command/PopulateKicadCommandTest.php @@ -388,4 +388,91 @@ final class PopulateKicadCommandTest extends KernelTestCase $this->entityManager->remove($reloadedCategory); $this->entityManager->flush(); } + + public function testMappingFileWithBothFootprintsAndCategories(): void + { + $footprint = new Footprint(); + $footprint->setName('CustomPkg'); + $this->entityManager->persist($footprint); + + $category = new Category(); + $category->setName('CustomType'); + $this->entityManager->persist($category); + + $this->entityManager->flush(); + + $footprintId = $footprint->getId(); + $categoryId = $category->getId(); + + $mappingFile = sys_get_temp_dir() . '/partdb_test_both_' . uniqid() . '.json'; + file_put_contents($mappingFile, json_encode([ + 'footprints' => [ + 'CustomPkg' => 'Custom:Footprint', + ], + 'categories' => [ + 'CustomType' => 'Custom:Symbol', + ], + ])); + + try { + $this->commandTester->execute(['--mapping-file' => $mappingFile]); + + $output = $this->commandTester->getDisplay(); + $this->assertEquals(0, $this->commandTester->getStatusCode()); + $this->assertStringContainsString('custom footprint mappings', $output); + $this->assertStringContainsString('custom category mappings', $output); + + $this->entityManager->clear(); + + $reloadedFp = $this->entityManager->find(Footprint::class, $footprintId); + $this->assertEquals('Custom:Footprint', $reloadedFp->getEdaInfo()->getKicadFootprint()); + + $reloadedCat = $this->entityManager->find(Category::class, $categoryId); + $this->assertEquals('Custom:Symbol', $reloadedCat->getEdaInfo()->getKicadSymbol()); + + // Cleanup + $this->entityManager->remove($reloadedFp); + $this->entityManager->remove($reloadedCat); + $this->entityManager->flush(); + } finally { + @unlink($mappingFile); + } + } + + public function testMappingFileWithOnlyCategoriesSection(): void + { + $category = new Category(); + $category->setName('OnlyCatType'); + $this->entityManager->persist($category); + $this->entityManager->flush(); + + $categoryId = $category->getId(); + + $mappingFile = sys_get_temp_dir() . '/partdb_test_catonly_' . uniqid() . '.json'; + file_put_contents($mappingFile, json_encode([ + 'categories' => [ + 'OnlyCatType' => 'Custom:CatSymbol', + ], + ])); + + try { + $this->commandTester->execute(['--categories' => true, '--mapping-file' => $mappingFile]); + + $output = $this->commandTester->getDisplay(); + $this->assertEquals(0, $this->commandTester->getStatusCode()); + $this->assertStringContainsString('custom category mappings', $output); + // Should NOT mention footprint mappings since they weren't in the file + $this->assertStringNotContainsString('custom footprint mappings', $output); + + $this->entityManager->clear(); + + $reloaded = $this->entityManager->find(Category::class, $categoryId); + $this->assertEquals('Custom:CatSymbol', $reloaded->getEdaInfo()->getKicadSymbol()); + + $this->entityManager->remove($reloaded); + $this->entityManager->flush(); + } finally { + @unlink($mappingFile); + } + } } diff --git a/tests/Services/EDA/KiCadHelperTest.php b/tests/Services/EDA/KiCadHelperTest.php index 6d049c55..baadbe02 100644 --- a/tests/Services/EDA/KiCadHelperTest.php +++ b/tests/Services/EDA/KiCadHelperTest.php @@ -26,9 +26,12 @@ use App\Entity\Attachments\AttachmentType; use App\Entity\Attachments\PartAttachment; use App\Entity\Parameters\PartParameter; use App\Entity\Parts\Category; +use App\Entity\Parts\Manufacturer; use App\Entity\Parts\Part; use App\Entity\Parts\PartLot; use App\Entity\Parts\StorageLocation; +use App\Entity\Parts\Supplier; +use App\Entity\PriceInformations\Orderdetail; use App\Services\EDA\KiCadHelper; use Doctrine\ORM\EntityManagerInterface; use PHPUnit\Framework\Attributes\Group; @@ -464,4 +467,138 @@ final class KiCadHelperTest extends KernelTestCase // The hardcoded description should win self::assertSame('The real description', $result['fields']['description']['value']); } + + /** + * Test that orderdetails without explicit eda_visibility are all exported (backward compat). + */ + public function testOrderdetailsExportedWhenNoEdaVisibilitySet(): void + { + $category = $this->em->find(Category::class, 1); + + $supplier = new Supplier(); + $supplier->setName('TestSupplier'); + $this->em->persist($supplier); + + $part = new Part(); + $part->setName('Part with Supplier'); + $part->setCategory($category); + + $od = new Orderdetail(); + $od->setSupplier($supplier); + $od->setSupplierpartnr('TS-001'); + // eda_visibility is null (default) + $part->addOrderdetail($od); + + $this->em->persist($part); + $this->em->flush(); + + $result = $this->helper->getKiCADPart($part); + + // Should export since no explicit flags are set (backward compat) + self::assertArrayHasKey('TestSupplier SPN', $result['fields']); + self::assertSame('TS-001', $result['fields']['TestSupplier SPN']['value']); + // KiCost field should also be present + self::assertArrayHasKey('testsupplier#', $result['fields']); + self::assertSame('TS-001', $result['fields']['testsupplier#']['value']); + } + + /** + * Test that only orderdetails with eda_visibility=true are exported when explicit flags exist. + */ + public function testOrderdetailsFilteredByExplicitEdaVisibility(): void + { + $category = $this->em->find(Category::class, 1); + + $supplier1 = new Supplier(); + $supplier1->setName('VisibleSupplier'); + $this->em->persist($supplier1); + + $supplier2 = new Supplier(); + $supplier2->setName('HiddenSupplier'); + $this->em->persist($supplier2); + + $part = new Part(); + $part->setName('Part with Mixed Visibility'); + $part->setCategory($category); + + $od1 = new Orderdetail(); + $od1->setSupplier($supplier1); + $od1->setSupplierpartnr('VIS-001'); + $od1->setEdaVisibility(true); + $part->addOrderdetail($od1); + + $od2 = new Orderdetail(); + $od2->setSupplier($supplier2); + $od2->setSupplierpartnr('HID-001'); + $od2->setEdaVisibility(false); + $part->addOrderdetail($od2); + + $this->em->persist($part); + $this->em->flush(); + + $result = $this->helper->getKiCADPart($part); + + // Visible supplier should be exported + self::assertArrayHasKey('VisibleSupplier SPN', $result['fields']); + self::assertSame('VIS-001', $result['fields']['VisibleSupplier SPN']['value']); + + // Hidden supplier should NOT be exported + self::assertArrayNotHasKey('HiddenSupplier SPN', $result['fields']); + } + + /** + * Test that manufacturer fields (manf, manf#) are always exported. + */ + public function testManufacturerFieldsExported(): void + { + $category = $this->em->find(Category::class, 1); + + $manufacturer = new Manufacturer(); + $manufacturer->setName('Acme Corp'); + $this->em->persist($manufacturer); + + $part = new Part(); + $part->setName('Acme Widget'); + $part->setCategory($category); + $part->setManufacturer($manufacturer); + $part->setManufacturerProductNumber('ACM-1234'); + + $this->em->persist($part); + $this->em->flush(); + + $result = $this->helper->getKiCADPart($part); + + self::assertArrayHasKey('manf', $result['fields']); + self::assertSame('Acme Corp', $result['fields']['manf']['value']); + self::assertArrayHasKey('manf#', $result['fields']); + self::assertSame('ACM-1234', $result['fields']['manf#']['value']); + self::assertArrayHasKey('Manufacturer', $result['fields']); + self::assertArrayHasKey('MPN', $result['fields']); + } + + /** + * Test that a parameter with empty name is not exported even with eda_visibility=true. + */ + public function testParameterWithEmptyNameIsSkipped(): void + { + $category = $this->em->find(Category::class, 1); + + $part = new Part(); + $part->setName('Part with Empty Param Name'); + $part->setCategory($category); + + $param = new PartParameter(); + $param->setName(''); + $param->setValueText('some value'); + $param->setEdaVisibility(true); + $part->addParameter($param); + + $this->em->persist($part); + $this->em->flush(); + + $result = $this->helper->getKiCADPart($part); + + // Empty-named parameter should not appear + self::assertArrayNotHasKey('', $result['fields']); + } }