From 7336bc8114d7f1fe3cb0c524dfc5ff51b2f510d8 Mon Sep 17 00:00:00 2001 From: swdee Date: Mon, 19 Jan 2026 18:49:22 +1300 Subject: [PATCH] added unit tests for meeting code coverage report --- tests/Controller/ScanControllerTest.php | 55 ++++++++++++++ .../BarcodeScanner/BarcodeRedirectorTest.php | 75 +++++++++++++++++++ .../BarcodeScanner/BarcodeScanHelperTest.php | 38 ++++++++++ 3 files changed, 168 insertions(+) diff --git a/tests/Controller/ScanControllerTest.php b/tests/Controller/ScanControllerTest.php index 98992e09..e907e739 100644 --- a/tests/Controller/ScanControllerTest.php +++ b/tests/Controller/ScanControllerTest.php @@ -51,4 +51,59 @@ class ScanControllerTest extends WebTestCase $this->client->request('GET', '/scan/part/1'); $this->assertResponseRedirects('/en/part/1'); } + + public function testLookupReturnsFoundOnKnownPart(): void + { + $this->client->request('POST', '/en/scan/lookup', [ + 'input' => '0000001', + 'mode' => '', + 'info_mode' => 'true', + ]); + + $this->assertResponseIsSuccessful(); + + $data = json_decode((string) $this->client->getResponse()->getContent(), true, 512, JSON_THROW_ON_ERROR); + + $this->assertTrue($data['ok']); + $this->assertTrue($data['found']); + $this->assertSame('/en/part/1', $data['redirectUrl']); + $this->assertTrue($data['infoMode']); + $this->assertIsString($data['html']); + $this->assertNotSame('', trim($data['html'])); + } + + public function testLookupReturnsNotFoundOnUnknownPart(): void + { + $this->client->request('POST', '/en/scan/lookup', [ + // Use a valid LCSC barcode + 'input' => '{pbn:PICK2407080035,on:WM2407080118,pc:C365735,pm:ES8316,qty:12,mc:,cc:1,pdi:120044290,hp:null,wc:ZH}', + 'mode' => '', + 'info_mode' => 'true', + ]); + + $this->assertResponseIsSuccessful(); + + $data = json_decode((string)$this->client->getResponse()->getContent(), true, 512, JSON_THROW_ON_ERROR); + + $this->assertTrue($data['ok']); + $this->assertFalse($data['found']); + $this->assertSame(null, $data['redirectUrl']); + $this->assertTrue($data['infoMode']); + $this->assertIsString($data['html']); + $this->assertNotSame('', trim($data['html'])); + } + + public function testLookupReturnsFalseOnGarbageInput(): void + { + $this->client->request('POST', '/en/scan/lookup', [ + 'input' => 'not-a-real-barcode', + 'mode' => '', + 'info_mode' => 'false', + ]); + + $this->assertResponseIsSuccessful(); + + $data = json_decode((string) $this->client->getResponse()->getContent(), true, 512, JSON_THROW_ON_ERROR); + $this->assertFalse($data['ok']); + } } diff --git a/tests/Services/LabelSystem/BarcodeScanner/BarcodeRedirectorTest.php b/tests/Services/LabelSystem/BarcodeScanner/BarcodeRedirectorTest.php index c40e141d..563f23cf 100644 --- a/tests/Services/LabelSystem/BarcodeScanner/BarcodeRedirectorTest.php +++ b/tests/Services/LabelSystem/BarcodeScanner/BarcodeRedirectorTest.php @@ -49,6 +49,11 @@ use App\Services\LabelSystem\BarcodeScanner\BarcodeSourceType; use App\Services\LabelSystem\BarcodeScanner\LocalBarcodeScanResult; use Doctrine\ORM\EntityNotFoundException; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; +use App\Services\LabelSystem\BarcodeScanner\EIGP114BarcodeScanResult; +use App\Services\LabelSystem\BarcodeScanner\LCSCBarcodeScanResult; +use App\Services\LabelSystem\BarcodeScanner\BarcodeScanResultInterface; +use InvalidArgumentException; + final class BarcodeRedirectorTest extends KernelTestCase { @@ -82,4 +87,74 @@ final class BarcodeRedirectorTest extends KernelTestCase $this->service->getRedirectURL(new LocalBarcodeScanResult(LabelSupportedElement::PART_LOT, 12_345_678, BarcodeSourceType::INTERNAL)); } + + public function testGetRedirectURLThrowsOnUnknownScanType(): void + { + $unknown = new class implements BarcodeScanResultInterface { + public function getDecodedForInfoMode(): array + { + return []; + } + }; + + $this->expectException(InvalidArgumentException::class); + $this->service->getRedirectURL($unknown); + } + + public function testEIGPBarcodeWithoutSupplierPartNumberThrowsEntityNotFound(): void + { + $scan = new EIGP114BarcodeScanResult([]); + + $this->expectException(EntityNotFoundException::class); + $this->service->getRedirectURL($scan); + } + + public function testEIGPBarcodeResolvePartOrNullReturnsNullWhenNotFound(): void + { + $scan = new EIGP114BarcodeScanResult([]); + + $this->assertNull($this->service->resolvePartOrNull($scan)); + } + + public function testLCSCBarcodeMissingPmThrowsEntityNotFound(): void + { + // pc present but no pm => getPartFromLCSC() will throw EntityNotFoundException + // because it falls back to PM when PC doesn't match anything. + $scan = new LCSCBarcodeScanResult( + fields: ['pc' => 'C0000000', 'pm' => ''], // pm becomes null via getPM() + raw_input: '{pc:C0000000,pm:}' + ); + + $this->expectException(EntityNotFoundException::class); + $this->service->getRedirectURL($scan); + } + + public function testLCSCBarcodeResolvePartOrNullReturnsNullWhenNotFound(): void + { + $scan = new LCSCBarcodeScanResult( + fields: ['pc' => 'C0000000', 'pm' => ''], + raw_input: '{pc:C0000000,pm:}' + ); + + $this->assertNull($this->service->resolvePartOrNull($scan)); + } + + public function testLCSCParseRejectsNonLCSCFormat(): void + { + $this->expectException(InvalidArgumentException::class); + LCSCBarcodeScanResult::parse('not-an-lcsc-barcode'); + } + + public function testLCSCParseExtractsFields(): void + { + $scan = LCSCBarcodeScanResult::parse('{pbn:PB1,on:ON1,pc:C138033,pm:RC0402FR-071ML,qty:10}'); + + $this->assertSame('RC0402FR-071ML', $scan->getPM()); + $this->assertSame('C138033', $scan->getPC()); + + $decoded = $scan->getDecodedForInfoMode(); + $this->assertSame('LCSC', $decoded['Barcode type']); + $this->assertSame('RC0402FR-071ML', $decoded['MPN (pm)']); + $this->assertSame('C138033', $decoded['LCSC code (pc)']); + } } diff --git a/tests/Services/LabelSystem/BarcodeScanner/BarcodeScanHelperTest.php b/tests/Services/LabelSystem/BarcodeScanner/BarcodeScanHelperTest.php index fcea7730..6655f510 100644 --- a/tests/Services/LabelSystem/BarcodeScanner/BarcodeScanHelperTest.php +++ b/tests/Services/LabelSystem/BarcodeScanner/BarcodeScanHelperTest.php @@ -49,6 +49,7 @@ use App\Services\LabelSystem\BarcodeScanner\BarcodeSourceType; use App\Services\LabelSystem\BarcodeScanner\EIGP114BarcodeScanResult; use App\Services\LabelSystem\BarcodeScanner\LocalBarcodeScanResult; use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; +use App\Services\LabelSystem\BarcodeScanner\LCSCBarcodeScanResult; class BarcodeScanHelperTest extends WebTestCase { @@ -124,6 +125,14 @@ class BarcodeScanHelperTest extends WebTestCase ]); yield [$eigp114Result, "[)>\x1E06\x1DP596-777A1-ND\x1D1PXAF4444\x1DQ3\x1D10D1452\x1D1TBF1103\x1D4LUS\x1E\x04"]; + + $lcscInput = '{pc:C138033,pm:RC0402FR-071ML,qty:10}'; + $lcscResult = new LCSCBarcodeScanResult( + ['pc' => 'C138033', 'pm' => 'RC0402FR-071ML', 'qty' => '10'], + $lcscInput + ); + + yield [$lcscResult, $lcscInput]; } public static function invalidDataProvider(): \Iterator @@ -153,4 +162,33 @@ class BarcodeScanHelperTest extends WebTestCase $this->expectException(\InvalidArgumentException::class); $this->service->scanBarcodeContent($input); } + + public function testAutoDetectLcscBarcode(): void + { + $input = '{pbn:PB1,on:ON1,pc:C138033,pm:RC0402FR-071ML,qty:10}'; + + $result = $this->service->scanBarcodeContent($input); + + $this->assertInstanceOf(LCSCBarcodeScanResult::class, $result); + $this->assertSame('C138033', $result->getPC()); + $this->assertSame('RC0402FR-071ML', $result->getPM()); + } + + public function testLcscExplicitTypeParses(): void + { + $input = '{pc:C138033,pm:RC0402FR-071ML,qty:10}'; + + $result = $this->service->scanBarcodeContent($input, BarcodeSourceType::LCSC); + + $this->assertInstanceOf(LCSCBarcodeScanResult::class, $result); + $this->assertSame('C138033', $result->getPC()); + $this->assertSame('RC0402FR-071ML', $result->getPM()); + } + + public function testLcscExplicitTypeRejectsNonLcsc(): void + { + $this->expectException(\InvalidArgumentException::class); + + $this->service->scanBarcodeContent('not-an-lcsc', BarcodeSourceType::LCSC); + } }