. */ namespace App\Tests\Serializer; use App\Entity\Parts\Part; use App\Entity\Parts\PartLot; use App\Entity\PriceInformations\Orderdetail; use App\Entity\PriceInformations\Pricedetail; use App\Serializer\PartNormalizer; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; final class PartNormalizerTest extends WebTestCase { /** @var PartNormalizer */ protected DenormalizerInterface&NormalizerInterface $service; protected function setUp(): void { //Get a service instance. self::bootKernel(); $this->service = self::getContainer()->get(PartNormalizer::class); //We need to inject the serializer into the normalizer, as we use it directly $serializer = self::getContainer()->get('serializer'); $this->service->setNormalizer($serializer); $this->service->setDenormalizer($serializer); } public function testSupportsNormalization(): void { //Normalizer must only support Part objects (and child classes) $this->assertFalse($this->service->supportsNormalization(new \stdClass())); //Part serialization should only work with csv $this->assertFalse($this->service->supportsNormalization(new Part())); $this->assertTrue($this->service->supportsNormalization(new Part(), 'csv')); } public function testNormalize(): void { $part = new Part(); $part->setName('Test Part'); $partLot1 = new PartLot(); $partLot1->setAmount(1); $partLot2 = new PartLot(); $partLot2->setAmount(5); $part->addPartLot($partLot1); $part->addPartLot($partLot2); //Check that type field is not present in CSV export $data = $this->service->normalize($part, 'csv', ['groups' => ['simple']]); $this->assertSame('Test Part', $data['name']); $this->assertArrayNotHasKey('type', $data); } public function testSupportsDenormalization(): void { //Normalizer must only support Part type with array as input $this->assertFalse($this->service->supportsDenormalization(new \stdClass(), Part::class)); $this->assertFalse($this->service->supportsDenormalization('string', Part::class)); $this->assertFalse($this->service->supportsDenormalization(['a' => 'b'], \stdClass::class)); //Only support denormalization, if CSV import $this->assertFalse($this->service->supportsDenormalization(['a' => 'b'], Part::class)); $this->assertTrue($this->service->supportsDenormalization(['a' => 'b'], Part::class, null, ['partdb_import' => true])); } public function testDenormalize(): void { $input = [ 'name' => 'Test Part', 'description' => 'Test Description', 'notes' => 'Test Note', //Test key normalization 'ipn' => 'Test IPN', 'mpn' => 'Test MPN', 'instock' => '5', 'storage_location' => 'Test Storage Location', 'supplier' => 'Test Supplier', 'price' => '5.5', 'supplier_part_number' => 'TEST123' ]; $part = $this->service->denormalize($input, Part::class, 'json', ['groups' => ['import'], 'create_unknown_datastructures' => true]); $this->assertInstanceOf(Part::class, $part); $this->assertSame('Test Part', $part->getName()); $this->assertSame('Test Description', $part->getDescription()); $this->assertSame('Test Note', $part->getComment()); $this->assertSame('Test IPN', $part->getIpn()); $this->assertSame('Test MPN', $part->getManufacturerProductNumber()); //Check that a new PartLot was created $this->assertCount(1, $part->getPartLots()); /** @var PartLot $partLot */ $partLot = $part->getPartLots()->first(); $this->assertEqualsWithDelta(5.0, $partLot->getAmount(), PHP_FLOAT_EPSILON); $this->assertNotNull($partLot->getStorageLocation()); $this->assertSame('Test Storage Location', $partLot->getStorageLocation()->getName()); //Check that a new orderdetail was created $this->assertCount(1, $part->getOrderdetails()); /** @var Orderdetail $orderDetail */ $orderDetail = $part->getOrderdetails()->first(); $this->assertNotNull($orderDetail->getSupplier()); $this->assertSame('Test Supplier', $orderDetail->getSupplier()->getName()); $this->assertSame('TEST123', $orderDetail->getSupplierPartNr()); //Check that a pricedetail was created $this->assertCount(1, $orderDetail->getPricedetails()); /** @var Pricedetail $priceDetail */ $priceDetail = $orderDetail->getPricedetails()->first(); $this->assertSame("5.50000", (string) $priceDetail->getPrice()); //Must be in base currency $this->assertNull($priceDetail->getCurrency()); //Must be for 1 part and 1 minimum order quantity $this->assertEqualsWithDelta(1.0, $priceDetail->getPriceRelatedQuantity(), PHP_FLOAT_EPSILON); $this->assertEqualsWithDelta(1.0, $priceDetail->getMinDiscountQuantity(), PHP_FLOAT_EPSILON); } public function testDenormalizeEdaFields(): void { $input = [ 'name' => 'EDA Test Part', 'kicad_symbol' => 'Device:R', 'kicad_footprint' => 'Resistor_SMD:R_0805_2012Metric', 'kicad_reference' => 'R', 'kicad_value' => '10k', 'eda_exclude_bom' => 'true', 'eda_exclude_board' => 'false', ]; $part = $this->service->denormalize($input, Part::class, 'json', ['groups' => ['import'], 'partdb_import' => true]); $this->assertInstanceOf(Part::class, $part); $this->assertSame('EDA Test Part', $part->getName()); $edaInfo = $part->getEdaInfo(); $this->assertSame('Device:R', $edaInfo->getKicadSymbol()); $this->assertSame('Resistor_SMD:R_0805_2012Metric', $edaInfo->getKicadFootprint()); $this->assertSame('R', $edaInfo->getReferencePrefix()); $this->assertSame('10k', $edaInfo->getValue()); $this->assertTrue($edaInfo->getExcludeFromBom()); $this->assertFalse($edaInfo->getExcludeFromBoard()); } public function testDenormalizeEdaFieldsEmptyValuesIgnored(): void { $input = [ 'name' => 'Part Without EDA', 'kicad_symbol' => '', 'kicad_footprint' => '', ]; $part = $this->service->denormalize($input, Part::class, 'json', ['groups' => ['import'], 'partdb_import' => true]); $edaInfo = $part->getEdaInfo(); $this->assertNull($edaInfo->getKicadSymbol()); $this->assertNull($edaInfo->getKicadFootprint()); } }