mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2026-05-19 01:41:37 +00:00
Merge branch 'master' into add-edit-kicad-suggestion-list-editor
This commit is contained in:
commit
5f66ec5ee6
36 changed files with 4324 additions and 4025 deletions
|
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Doctrine\Functions;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\ORM\Query\AST\Node;
|
||||
use Doctrine\ORM\Query\SqlWalker;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
abstract class AbstractDoctrineFunctionTestCase extends TestCase
|
||||
{
|
||||
protected function createSqlWalker(AbstractPlatform $platform, string $serverVersion = '11.0.0-MariaDB'): SqlWalker
|
||||
{
|
||||
$connection = $this->createMock(Connection::class);
|
||||
$connection->method('getDatabasePlatform')->willReturn($platform);
|
||||
$connection->method('getServerVersion')->willReturn($serverVersion);
|
||||
|
||||
$sqlWalker = $this->getMockBuilder(SqlWalker::class)
|
||||
->disableOriginalConstructor()
|
||||
->onlyMethods(['getConnection'])
|
||||
->getMock();
|
||||
|
||||
$sqlWalker->method('getConnection')->willReturn($connection);
|
||||
|
||||
return $sqlWalker;
|
||||
}
|
||||
|
||||
protected function createNode(string $sql): Node
|
||||
{
|
||||
$node = $this->createMock(Node::class);
|
||||
$node->method('dispatch')->willReturn($sql);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
protected function setObjectProperty(object $object, string $property, mixed $value): void
|
||||
{
|
||||
$reflection = new \ReflectionProperty($object, $property);
|
||||
$reflection->setValue($object, $value);
|
||||
}
|
||||
|
||||
protected function setStaticProperty(string $class, string $property, mixed $value): void
|
||||
{
|
||||
$reflection = new \ReflectionProperty($class, $property);
|
||||
$reflection->setValue(null, $value);
|
||||
}
|
||||
}
|
||||
42
tests/Doctrine/Functions/ArrayPositionTest.php
Normal file
42
tests/Doctrine/Functions/ArrayPositionTest.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
|
||||
namespace App\Tests\Doctrine\Functions;
|
||||
|
||||
use App\Doctrine\Functions\ArrayPosition;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
|
||||
final class ArrayPositionTest extends AbstractDoctrineFunctionTestCase
|
||||
{
|
||||
public function testArrayPositionBuildsSql(): void
|
||||
{
|
||||
$function = new ArrayPosition('ARRAY_POSITION');
|
||||
$this->setObjectProperty($function, 'array', $this->createNode(':ids'));
|
||||
$this->setObjectProperty($function, 'field', $this->createNode('p.id'));
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker(new PostgreSQLPlatform()));
|
||||
|
||||
$this->assertSame('ARRAY_POSITION(:ids, p.id)', $sql);
|
||||
}
|
||||
}
|
||||
|
||||
45
tests/Doctrine/Functions/Field2Test.php
Normal file
45
tests/Doctrine/Functions/Field2Test.php
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Doctrine\Functions;
|
||||
|
||||
use App\Doctrine\Functions\Field2;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
|
||||
final class Field2Test extends AbstractDoctrineFunctionTestCase
|
||||
{
|
||||
public function testField2BuildsSql(): void
|
||||
{
|
||||
$function = new Field2('FIELD2');
|
||||
$this->setObjectProperty($function, 'field', $this->createNode('p.id'));
|
||||
$this->setObjectProperty($function, 'values', [
|
||||
$this->createNode('1'),
|
||||
$this->createNode('2'),
|
||||
$this->createNode('3'),
|
||||
]);
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker(new MySQLPlatform()));
|
||||
|
||||
$this->assertSame('FIELD2(p.id, 1, 2, 3)', $sql);
|
||||
}
|
||||
}
|
||||
|
||||
66
tests/Doctrine/Functions/ILikeTest.php
Normal file
66
tests/Doctrine/Functions/ILikeTest.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Doctrine\Functions;
|
||||
|
||||
use App\Doctrine\Functions\ILike;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
final class ILikeTest extends AbstractDoctrineFunctionTestCase
|
||||
{
|
||||
public static function iLikePlatformProvider(): \Generator
|
||||
{
|
||||
yield 'mysql' => [new MySQLPlatform(), '(part_name LIKE :pattern)'];
|
||||
yield 'postgres' => [new PostgreSQLPlatform(), '(part_name ILIKE :pattern)'];
|
||||
yield 'sqlite' => [new SQLitePlatform(), "(part_name LIKE :pattern ESCAPE '\\')"];
|
||||
}
|
||||
|
||||
#[DataProvider('iLikePlatformProvider')]
|
||||
public function testILikeUsesExpectedOperator(AbstractPlatform $platform, string $expectedSql): void
|
||||
{
|
||||
$function = new ILike('ILIKE');
|
||||
$function->value = $this->createNode('part_name');
|
||||
$function->expr = $this->createNode(':pattern');
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker($platform));
|
||||
|
||||
$this->assertSame($expectedSql, $sql);
|
||||
}
|
||||
|
||||
public function testILikeThrowsOnUnsupportedPlatform(): void
|
||||
{
|
||||
$function = new ILike('ILIKE');
|
||||
$function->value = $this->createNode('part_name');
|
||||
$function->expr = $this->createNode(':pattern');
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('does not support case insensitive like expressions');
|
||||
|
||||
$function->getSql($this->createSqlWalker(new SQLServerPlatform()));
|
||||
}
|
||||
}
|
||||
|
||||
95
tests/Doctrine/Functions/NatsortTest.php
Normal file
95
tests/Doctrine/Functions/NatsortTest.php
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Doctrine\Functions;
|
||||
|
||||
use App\Doctrine\Functions\Natsort;
|
||||
use Doctrine\DBAL\Platforms\MariaDBPlatform;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
||||
|
||||
final class NatsortTest extends AbstractDoctrineFunctionTestCase
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
Natsort::allowSlowNaturalSort(false);
|
||||
$this->setStaticProperty(Natsort::class, 'supportsNaturalSort', null);
|
||||
}
|
||||
|
||||
public function testNatsortUsesPostgresCollation(): void
|
||||
{
|
||||
$function = new Natsort('NATSORT');
|
||||
$this->setObjectProperty($function, 'field', $this->createNode('part_name'));
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker(new PostgreSQLPlatform()));
|
||||
|
||||
$this->assertSame('part_name COLLATE numeric', $sql);
|
||||
}
|
||||
|
||||
public function testNatsortUsesMariaDbNativeFunctionOnSupportedVersion(): void
|
||||
{
|
||||
$function = new Natsort('NATSORT');
|
||||
$this->setObjectProperty($function, 'field', $this->createNode('part_name'));
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker(new MariaDBPlatform(), '10.11.2-MariaDB'));
|
||||
|
||||
$this->assertSame('NATURAL_SORT_KEY(part_name)', $sql);
|
||||
}
|
||||
|
||||
public function testNatsortFallsBackWithoutSlowSort(): void
|
||||
{
|
||||
$function = new Natsort('NATSORT');
|
||||
$this->setObjectProperty($function, 'field', $this->createNode('part_name'));
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker(new MariaDBPlatform(), '10.6.10-MariaDB'));
|
||||
|
||||
$this->assertSame('part_name', $sql);
|
||||
}
|
||||
|
||||
public function testNatsortUsesSlowSortFunctionOnMySqlWhenEnabled(): void
|
||||
{
|
||||
Natsort::allowSlowNaturalSort();
|
||||
|
||||
$function = new Natsort('NATSORT');
|
||||
$this->setObjectProperty($function, 'field', $this->createNode('part_name'));
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker(new MySQLPlatform()));
|
||||
|
||||
$this->assertSame('NatSortKey(part_name, 0)', $sql);
|
||||
}
|
||||
|
||||
public function testNatsortUsesSlowSortCollationOnSqliteWhenEnabled(): void
|
||||
{
|
||||
Natsort::allowSlowNaturalSort();
|
||||
|
||||
$function = new Natsort('NATSORT');
|
||||
$this->setObjectProperty($function, 'field', $this->createNode('part_name'));
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker(new SQLitePlatform()));
|
||||
|
||||
$this->assertSame('part_name COLLATE NATURAL_CMP', $sql);
|
||||
}
|
||||
}
|
||||
|
||||
66
tests/Doctrine/Functions/RegexpTest.php
Normal file
66
tests/Doctrine/Functions/RegexpTest.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2026 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Doctrine\Functions;
|
||||
|
||||
use App\Doctrine\Functions\Regexp;
|
||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
||||
use Doctrine\DBAL\Platforms\MySQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
final class RegexpTest extends AbstractDoctrineFunctionTestCase
|
||||
{
|
||||
public static function regexpPlatformProvider(): \Generator
|
||||
{
|
||||
yield 'mysql' => [new MySQLPlatform(), '(part_name REGEXP :regex)'];
|
||||
yield 'sqlite' => [new SQLitePlatform(), '(part_name REGEXP :regex)'];
|
||||
yield 'postgres' => [new PostgreSQLPlatform(), '(part_name ~* :regex)'];
|
||||
}
|
||||
|
||||
#[DataProvider('regexpPlatformProvider')]
|
||||
public function testRegexpUsesExpectedOperator(AbstractPlatform $platform, string $expectedSql): void
|
||||
{
|
||||
$function = new Regexp('REGEXP');
|
||||
$this->setObjectProperty($function, 'value', $this->createNode('part_name'));
|
||||
$this->setObjectProperty($function, 'regexp', $this->createNode(':regex'));
|
||||
|
||||
$sql = $function->getSql($this->createSqlWalker($platform));
|
||||
|
||||
$this->assertSame($expectedSql, $sql);
|
||||
}
|
||||
|
||||
public function testRegexpThrowsOnUnsupportedPlatform(): void
|
||||
{
|
||||
$function = new Regexp('REGEXP');
|
||||
$this->setObjectProperty($function, 'value', $this->createNode('part_name'));
|
||||
$this->setObjectProperty($function, 'regexp', $this->createNode(':regex'));
|
||||
|
||||
$this->expectException(\RuntimeException::class);
|
||||
$this->expectExceptionMessage('does not support regular expressions');
|
||||
|
||||
$function->getSql($this->createSqlWalker(new SQLServerPlatform()));
|
||||
}
|
||||
}
|
||||
|
||||
391
tests/Services/InfoProviderSystem/Providers/TMEProviderTest.php
Normal file
391
tests/Services/InfoProviderSystem/Providers/TMEProviderTest.php
Normal file
|
|
@ -0,0 +1,391 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Services\InfoProviderSystem\Providers;
|
||||
|
||||
use App\Entity\Parts\ManufacturingStatus;
|
||||
use App\Services\InfoProviderSystem\DTOs\PartDetailDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\PurchaseInfoDTO;
|
||||
use App\Services\InfoProviderSystem\DTOs\SearchResultDTO;
|
||||
use App\Services\InfoProviderSystem\Providers\ProviderCapabilities;
|
||||
use App\Services\InfoProviderSystem\Providers\TMEClient;
|
||||
use App\Services\InfoProviderSystem\Providers\TMEProvider;
|
||||
use App\Settings\InfoProviderSystem\TMESettings;
|
||||
use App\Tests\SettingsTestHelper;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpClient\MockHttpClient;
|
||||
use Symfony\Component\HttpClient\Response\MockResponse;
|
||||
|
||||
final class TMEProviderTest extends TestCase
|
||||
{
|
||||
private TMESettings $settings;
|
||||
private TMEProvider $provider;
|
||||
private MockHttpClient $httpClient;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->httpClient = new MockHttpClient();
|
||||
$this->settings = SettingsTestHelper::createSettingsDummy(TMESettings::class);
|
||||
// Use a short (anonymous-style) token so grossPrices is read from settings
|
||||
$this->settings->apiToken = 'test_token_000000000000000000000000000000000000000';
|
||||
$this->settings->apiSecret = 'test_secret';
|
||||
$this->settings->currency = 'EUR';
|
||||
$this->settings->language = 'en';
|
||||
$this->settings->country = 'DE';
|
||||
$this->settings->grossPrices = false;
|
||||
$this->provider = new TMEProvider(new TMEClient($this->httpClient, $this->settings), $this->settings);
|
||||
}
|
||||
|
||||
// --- Mock response helpers ---
|
||||
// Only fields actually read by TMEProvider are included.
|
||||
|
||||
private function mockProductList(array $products): MockResponse
|
||||
{
|
||||
return new MockResponse(json_encode([
|
||||
'Status' => 'OK',
|
||||
'Data' => ['ProductList' => $products],
|
||||
]));
|
||||
}
|
||||
|
||||
private function mockFilesList(array $products): MockResponse
|
||||
{
|
||||
return new MockResponse(json_encode([
|
||||
'Status' => 'OK',
|
||||
'Data' => ['ProductList' => $products],
|
||||
]));
|
||||
}
|
||||
|
||||
private function mockParametersList(array $products): MockResponse
|
||||
{
|
||||
return new MockResponse(json_encode([
|
||||
'Status' => 'OK',
|
||||
'Data' => ['ProductList' => $products],
|
||||
]));
|
||||
}
|
||||
|
||||
private function mockPrices(string $currency, string $priceType, array $products): MockResponse
|
||||
{
|
||||
return new MockResponse(json_encode([
|
||||
'Status' => 'OK',
|
||||
'Data' => [
|
||||
'Currency' => $currency,
|
||||
'PriceType' => $priceType,
|
||||
'ProductList' => $products,
|
||||
],
|
||||
]));
|
||||
}
|
||||
|
||||
// --- Mock data ---
|
||||
|
||||
private function smd0603Products(): MockResponse
|
||||
{
|
||||
return $this->mockProductList([[
|
||||
'Symbol' => 'SMD0603-5K1-1%',
|
||||
'OriginalSymbol' => '0603SAF5101T5E',
|
||||
'Producer' => 'ROYALOHM',
|
||||
'Description' => 'Resistor: thick film; SMD; 0603; 5.1kΩ; 0.1W; ±1%; 50V; -55÷155°C',
|
||||
'Category' => 'SMD resistors',
|
||||
'Photo' => '//ce8dc832c.cloudimg.io/v7/_cdn_/E9/C2/B0/00/0/732318_1.jpg',
|
||||
'ProductStatusList' => [],
|
||||
'ProductInformationPage' => '//www.tme.eu/en/details/smd0603-5k1-1%/smd-resistors/royalohm/0603saf5101t5e/',
|
||||
'Weight' => 0.021,
|
||||
'WeightUnit' => 'g',
|
||||
]]);
|
||||
}
|
||||
|
||||
private function smd0603Files(): MockResponse
|
||||
{
|
||||
return $this->mockFilesList([[
|
||||
'Symbol' => 'SMD0603-5K1-1%',
|
||||
'Files' => [
|
||||
'AdditionalPhotoList' => [],
|
||||
'DocumentList' => [
|
||||
['DocumentUrl' => '//www.tme.eu/Document/b315665a56acbc42df513c99b390ad98/ROYALOHM-THICKFILM.pdf'],
|
||||
['DocumentUrl' => '//www.tme.eu/Document/c283990e907c122bb808207d1578ac7f/POWER_RATING-DTE.pdf'],
|
||||
],
|
||||
],
|
||||
]]);
|
||||
}
|
||||
|
||||
private function smd0603Parameters(): MockResponse
|
||||
{
|
||||
return $this->mockParametersList([[
|
||||
'Symbol' => 'SMD0603-5K1-1%',
|
||||
'ParameterList' => [
|
||||
['ParameterId' => 34, 'ParameterName' => 'Type of resistor', 'ParameterValue' => 'thick film'],
|
||||
['ParameterId' => 35, 'ParameterName' => 'Case - mm', 'ParameterValue' => '1608'],
|
||||
['ParameterId' => 38, 'ParameterName' => 'Resistance', 'ParameterValue' => '5.1kΩ'],
|
||||
['ParameterId' => 39, 'ParameterName' => 'Tolerance', 'ParameterValue' => '±1%'],
|
||||
['ParameterId' => 120, 'ParameterName' => 'Operating voltage', 'ParameterValue' => '50V'],
|
||||
],
|
||||
]]);
|
||||
}
|
||||
|
||||
private function smd0603Prices(): MockResponse
|
||||
{
|
||||
return $this->mockPrices('EUR', 'NET', [[
|
||||
'Symbol' => 'SMD0603-5K1-1%',
|
||||
'PriceList' => [
|
||||
['Amount' => 100, 'PriceValue' => 0.01077],
|
||||
['Amount' => 1000, 'PriceValue' => 0.00291],
|
||||
['Amount' => 5000, 'PriceValue' => 0.00150],
|
||||
],
|
||||
]]);
|
||||
}
|
||||
|
||||
private function etqp3mProducts(): MockResponse
|
||||
{
|
||||
return $this->mockProductList([[
|
||||
'Symbol' => 'ETQP3M6R8KVP',
|
||||
'OriginalSymbol' => 'ETQP3M6R8KVP',
|
||||
'Producer' => 'PANASONIC',
|
||||
'Description' => 'Inductor: wire; SMD; 6.8uH; 2.9A; R: 65.7mΩ; ±20%; ETQP3M; 5.5x5x3mm',
|
||||
'Category' => 'Inductors',
|
||||
'Photo' => '//ce8dc832c.cloudimg.io/v7/_cdn_/9E/27/A0/00/0/684777_1.jpg',
|
||||
'ProductStatusList' => [],
|
||||
'ProductInformationPage' => '//www.tme.eu/en/details/etqp3m6r8kvp/inductors/panasonic/',
|
||||
'Weight' => 0.44,
|
||||
'WeightUnit' => 'g',
|
||||
]]);
|
||||
}
|
||||
|
||||
private function etqp3mFiles(): MockResponse
|
||||
{
|
||||
return $this->mockFilesList([[
|
||||
'Symbol' => 'ETQP3M6R8KVP',
|
||||
'Files' => [
|
||||
'AdditionalPhotoList' => [],
|
||||
'DocumentList' => [
|
||||
['DocumentUrl' => '//www.tme.eu/Document/50a845881f09d8a2248350946e11df38/AGL0000C63.pdf'],
|
||||
['DocumentUrl' => '//www.tme.eu/Document/8480690a42fa577214e35e33d3fc8d77/ETQP3M100KVN-LNK.txt'],
|
||||
],
|
||||
],
|
||||
]]);
|
||||
}
|
||||
|
||||
private function etqp3mParameters(): MockResponse
|
||||
{
|
||||
return $this->mockParametersList([[
|
||||
'Symbol' => 'ETQP3M6R8KVP',
|
||||
'ParameterList' => [
|
||||
['ParameterId' => 566, 'ParameterName' => 'Inductance', 'ParameterValue' => '6.8µH'],
|
||||
['ParameterId' => 370, 'ParameterName' => 'Operating current', 'ParameterValue' => '2.9A'],
|
||||
['ParameterId' => 39, 'ParameterName' => 'Tolerance', 'ParameterValue' => '±20%'],
|
||||
],
|
||||
]]);
|
||||
}
|
||||
|
||||
private function etqp3mPrices(): MockResponse
|
||||
{
|
||||
return $this->mockPrices('EUR', 'NET', [[
|
||||
'Symbol' => 'ETQP3M6R8KVP',
|
||||
'PriceList' => [
|
||||
['Amount' => 1, 'PriceValue' => 0.589],
|
||||
['Amount' => 5, 'PriceValue' => 0.429],
|
||||
['Amount' => 10, 'PriceValue' => 0.399],
|
||||
],
|
||||
]]);
|
||||
}
|
||||
|
||||
// --- Tests ---
|
||||
|
||||
public function testGetProviderInfo(): void
|
||||
{
|
||||
$info = $this->provider->getProviderInfo();
|
||||
|
||||
$this->assertIsArray($info);
|
||||
$this->assertArrayHasKey('name', $info);
|
||||
$this->assertArrayHasKey('description', $info);
|
||||
$this->assertArrayHasKey('url', $info);
|
||||
$this->assertEquals('TME', $info['name']);
|
||||
$this->assertEquals('https://tme.eu/', $info['url']);
|
||||
}
|
||||
|
||||
public function testGetProviderKey(): void
|
||||
{
|
||||
$this->assertSame('tme', $this->provider->getProviderKey());
|
||||
}
|
||||
|
||||
public function testIsActiveWithCredentials(): void
|
||||
{
|
||||
$this->assertTrue($this->provider->isActive());
|
||||
}
|
||||
|
||||
public function testIsActiveWithoutCredentials(): void
|
||||
{
|
||||
$this->settings->apiToken = null;
|
||||
$provider = new TMEProvider(new TMEClient($this->httpClient, $this->settings), $this->settings);
|
||||
$this->assertFalse($provider->isActive());
|
||||
}
|
||||
|
||||
public function testGetCapabilities(): void
|
||||
{
|
||||
$capabilities = $this->provider->getCapabilities();
|
||||
|
||||
$this->assertIsArray($capabilities);
|
||||
$this->assertContains(ProviderCapabilities::BASIC, $capabilities);
|
||||
$this->assertContains(ProviderCapabilities::PICTURE, $capabilities);
|
||||
$this->assertContains(ProviderCapabilities::DATASHEET, $capabilities);
|
||||
$this->assertContains(ProviderCapabilities::PRICE, $capabilities);
|
||||
$this->assertContains(ProviderCapabilities::FOOTPRINT, $capabilities);
|
||||
}
|
||||
|
||||
public function testGetHandledDomains(): void
|
||||
{
|
||||
$this->assertContains('tme.eu', $this->provider->getHandledDomains());
|
||||
}
|
||||
|
||||
public function testGetIDFromURL(): void
|
||||
{
|
||||
$this->assertSame('fi321_se', $this->provider->getIDFromURL('https://www.tme.eu/de/details/fi321_se/kuhler/alutronic/'));
|
||||
$this->assertSame('smd0603-5k1-1%25', $this->provider->getIDFromURL('https://www.tme.eu/en/details/smd0603-5k1-1%25/smd-resistors/royalohm/0603saf5101t5e/'));
|
||||
$this->assertNull($this->provider->getIDFromURL('https://www.tme.eu/en/'));
|
||||
}
|
||||
|
||||
public function testSearchByKeyword(): void
|
||||
{
|
||||
$this->httpClient->setResponseFactory([$this->smd0603Products()]);
|
||||
|
||||
$results = $this->provider->searchByKeyword('SMD0603-5K1-1%');
|
||||
|
||||
$this->assertIsArray($results);
|
||||
$this->assertCount(1, $results);
|
||||
$this->assertInstanceOf(SearchResultDTO::class, $results[0]);
|
||||
$this->assertSame('SMD0603-5K1-1%', $results[0]->provider_id);
|
||||
$this->assertSame('0603SAF5101T5E', $results[0]->name);
|
||||
$this->assertSame('ROYALOHM', $results[0]->manufacturer);
|
||||
$this->assertSame('SMD resistors', $results[0]->category);
|
||||
$this->assertSame(ManufacturingStatus::ACTIVE, $results[0]->manufacturing_status);
|
||||
$this->assertSame(
|
||||
'https://www.tme.eu/en/details/smd0603-5k1-1%25/smd-resistors/royalohm/0603saf5101t5e/',
|
||||
$results[0]->provider_url
|
||||
);
|
||||
}
|
||||
|
||||
public function testGetDetailsWithPercentInPartNumber(): void
|
||||
{
|
||||
$this->httpClient->setResponseFactory([
|
||||
$this->smd0603Products(),
|
||||
$this->smd0603Files(),
|
||||
$this->smd0603Parameters(),
|
||||
$this->smd0603Prices(),
|
||||
]);
|
||||
|
||||
$result = $this->provider->getDetails('SMD0603-5K1-1%');
|
||||
|
||||
$this->assertInstanceOf(PartDetailDTO::class, $result);
|
||||
$this->assertSame('SMD0603-5K1-1%', $result->provider_id);
|
||||
$this->assertSame('0603SAF5101T5E', $result->name);
|
||||
$this->assertSame('Resistor: thick film; SMD; 0603; 5.1kΩ; 0.1W; ±1%; 50V; -55÷155°C', $result->description);
|
||||
$this->assertSame('ROYALOHM', $result->manufacturer);
|
||||
$this->assertSame('0603SAF5101T5E', $result->mpn);
|
||||
$this->assertSame('SMD resistors', $result->category);
|
||||
$this->assertSame(ManufacturingStatus::ACTIVE, $result->manufacturing_status);
|
||||
$this->assertSame(0.021, $result->mass);
|
||||
$this->assertSame('1608', $result->footprint);
|
||||
$this->assertSame(
|
||||
'https://www.tme.eu/en/details/smd0603-5k1-1%25/smd-resistors/royalohm/0603saf5101t5e/',
|
||||
$result->provider_url
|
||||
);
|
||||
|
||||
$this->assertCount(2, $result->datasheets);
|
||||
$this->assertSame('https://www.tme.eu/Document/b315665a56acbc42df513c99b390ad98/ROYALOHM-THICKFILM.pdf', $result->datasheets[0]->url);
|
||||
$this->assertCount(0, $result->images);
|
||||
|
||||
$this->assertCount(1, $result->vendor_infos);
|
||||
$vendorInfo = $result->vendor_infos[0];
|
||||
$this->assertInstanceOf(PurchaseInfoDTO::class, $vendorInfo);
|
||||
$this->assertSame('TME', $vendorInfo->distributor_name);
|
||||
$this->assertSame('SMD0603-5K1-1%', $vendorInfo->order_number);
|
||||
$this->assertSame(
|
||||
'https://www.tme.eu/en/details/smd0603-5k1-1%25/smd-resistors/royalohm/0603saf5101t5e/',
|
||||
$vendorInfo->product_url
|
||||
);
|
||||
$this->assertCount(3, $vendorInfo->prices);
|
||||
$this->assertSame(100.0, $vendorInfo->prices[0]->minimum_discount_amount);
|
||||
$this->assertSame('0.01077', $vendorInfo->prices[0]->price);
|
||||
$this->assertSame('EUR', $vendorInfo->prices[0]->currency_iso_code);
|
||||
$this->assertFalse($vendorInfo->prices[0]->includes_tax);
|
||||
|
||||
$this->assertCount(5, $result->parameters);
|
||||
}
|
||||
|
||||
public function testGetDetailsForEtqp3m6r8kvp(): void
|
||||
{
|
||||
$this->httpClient->setResponseFactory([
|
||||
$this->etqp3mProducts(),
|
||||
$this->etqp3mFiles(),
|
||||
$this->etqp3mParameters(),
|
||||
$this->etqp3mPrices(),
|
||||
]);
|
||||
|
||||
$result = $this->provider->getDetails('ETQP3M6R8KVP');
|
||||
|
||||
$this->assertInstanceOf(PartDetailDTO::class, $result);
|
||||
$this->assertSame('ETQP3M6R8KVP', $result->provider_id);
|
||||
$this->assertSame('ETQP3M6R8KVP', $result->name);
|
||||
$this->assertSame('Inductor: wire; SMD; 6.8uH; 2.9A; R: 65.7mΩ; ±20%; ETQP3M; 5.5x5x3mm', $result->description);
|
||||
$this->assertSame('PANASONIC', $result->manufacturer);
|
||||
$this->assertSame('ETQP3M6R8KVP', $result->mpn);
|
||||
$this->assertSame('Inductors', $result->category);
|
||||
$this->assertSame(ManufacturingStatus::ACTIVE, $result->manufacturing_status);
|
||||
$this->assertSame(0.44, $result->mass);
|
||||
$this->assertNull($result->footprint);
|
||||
$this->assertSame('https://www.tme.eu/en/details/etqp3m6r8kvp/inductors/panasonic/', $result->provider_url);
|
||||
|
||||
$this->assertCount(2, $result->datasheets);
|
||||
$this->assertSame('https://www.tme.eu/Document/50a845881f09d8a2248350946e11df38/AGL0000C63.pdf', $result->datasheets[0]->url);
|
||||
$this->assertCount(0, $result->images);
|
||||
|
||||
$this->assertCount(1, $result->vendor_infos);
|
||||
$vendorInfo = $result->vendor_infos[0];
|
||||
$this->assertSame('TME', $vendorInfo->distributor_name);
|
||||
$this->assertSame('ETQP3M6R8KVP', $vendorInfo->order_number);
|
||||
$this->assertSame('https://www.tme.eu/en/details/etqp3m6r8kvp/inductors/panasonic/', $vendorInfo->product_url);
|
||||
$this->assertCount(3, $vendorInfo->prices);
|
||||
$this->assertSame(1.0, $vendorInfo->prices[0]->minimum_discount_amount);
|
||||
$this->assertSame('0.589', $vendorInfo->prices[0]->price);
|
||||
$this->assertSame('EUR', $vendorInfo->prices[0]->currency_iso_code);
|
||||
$this->assertFalse($vendorInfo->prices[0]->includes_tax);
|
||||
|
||||
$this->assertCount(3, $result->parameters);
|
||||
}
|
||||
|
||||
public function testNormalizeURLEncodesBarePctSign(): void
|
||||
{
|
||||
$method = (new \ReflectionClass($this->provider))->getMethod('normalizeURL');
|
||||
|
||||
$this->assertSame(
|
||||
'https://www.tme.eu/en/details/smd0603-5k1-1%25/smd-resistors/royalohm/0603saf5101t5e/',
|
||||
$method->invoke($this->provider, '//www.tme.eu/en/details/smd0603-5k1-1%/smd-resistors/royalohm/0603saf5101t5e/')
|
||||
);
|
||||
$this->assertSame(
|
||||
'https://www.tme.eu/en/details/smd0603-5k1-1%25/smd-resistors/royalohm/0603saf5101t5e/',
|
||||
$method->invoke($this->provider, '//www.tme.eu/en/details/smd0603-5k1-1%25/smd-resistors/royalohm/0603saf5101t5e/')
|
||||
);
|
||||
$this->assertSame(
|
||||
'https://www.tme.eu/en/details/etqp3m6r8kvp/inductors/panasonic/',
|
||||
$method->invoke($this->provider, '//www.tme.eu/en/details/etqp3m6r8kvp/inductors/panasonic/')
|
||||
);
|
||||
$this->assertSame('https://example.com/path', $method->invoke($this->provider, 'https://example.com/path'));
|
||||
}
|
||||
}
|
||||
|
|
@ -93,6 +93,13 @@ final class EIGP114BarcodeScanResultTest extends TestCase
|
|||
|
||||
//Valid code (digikey, without trailer)
|
||||
$this->assertTrue(EIGP114BarcodeScanResult::isFormat06Code("[)>\x1e06\x1dPQ1045-ND\x1d1P364019-01\x1d30PQ1045-ND\x1dK12432 TRAVIS FOSS P\x1d1K85732873\x1d10K103332956\x1d9D231013\x1d1TQJ13P\x1d11K1\x1d4LTW\x1dQ3\x1d11ZPICK\x1d12Z7360988\x1d13Z999999\x1d20Z0000000000000000000000000000000000000000000000000000000000000000000000000000000000000"));
|
||||
|
||||
//Valid code (without record separator)
|
||||
$this->assertTrue(EIGP114BarcodeScanResult::isFormat06Code("[)>06\x1DP596-777A1-ND\x1D1PXAF4444\x1DQ3\x1D10D1452\x1D1TBF1103\x1D4LUS\x1E\x04"));
|
||||
|
||||
//Old mouser format
|
||||
$this->assertTrue(EIGP114BarcodeScanResult::isFormat06Code(">[)>06\x1DP596-777A1-ND\x1D1PXAF4444\x1DQ3\x1D10D1452\x1D1TBF1103\x1D4LUS\x1E\x04"));
|
||||
|
||||
}
|
||||
|
||||
public function testParseFormat06CodeInvalid(): void
|
||||
|
|
@ -101,6 +108,32 @@ final class EIGP114BarcodeScanResultTest extends TestCase
|
|||
EIGP114BarcodeScanResult::parseFormat06Code('');
|
||||
}
|
||||
|
||||
public function testParseWithoutRecordSeparator(): void
|
||||
{
|
||||
$barcode = EIGP114BarcodeScanResult::parseFormat06Code("[)>06\x1DP596-777A1-ND\x1D1PXAF4444\x1DQ3\x1D10D1452\x1D1TBF1103\x1D4LUS\x1E\x04");
|
||||
$this->assertSame([
|
||||
'P' => '596-777A1-ND',
|
||||
'1P' => 'XAF4444',
|
||||
'Q' => '3',
|
||||
'10D' => '1452',
|
||||
'1T' => 'BF1103',
|
||||
'4L' => 'US',
|
||||
], $barcode->data);
|
||||
}
|
||||
|
||||
public function testParseOldMouserFormat(): void
|
||||
{
|
||||
$barcode = EIGP114BarcodeScanResult::parseFormat06Code(">[)>06\x1DP596-777A1-ND\x1D1PXAF4444\x1DQ3\x1D10D1452\x1D1TBF1103\x1D4LUS\x1E\x04");
|
||||
$this->assertSame([
|
||||
'P' => '596-777A1-ND',
|
||||
'1P' => 'XAF4444',
|
||||
'Q' => '3',
|
||||
'10D' => '1452',
|
||||
'1T' => 'BF1103',
|
||||
'4L' => 'US',
|
||||
], $barcode->data);
|
||||
}
|
||||
|
||||
public function testParseFormat06Code(): void
|
||||
{
|
||||
$barcode = EIGP114BarcodeScanResult::parseFormat06Code("[)>\x1E06\x1DP596-777A1-ND\x1D1PXAF4444\x1DQ3\x1D10D1452\x1D1TBF1103\x1D4LUS\x1E\x04");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
/*
|
||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||
*
|
||||
* Copyright (C) 2019 - 2023 Jan Böhmer (https://github.com/jbtronics)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published
|
||||
* by the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace App\Tests\Services\LabelSystem\BarcodeScanner;
|
||||
|
||||
use App\Services\LabelSystem\BarcodeScanner\BarcodeSourceType;
|
||||
use App\Services\LabelSystem\BarcodeScanner\TMEBarcodeScanResult;
|
||||
use InvalidArgumentException;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class TMEBarcodeScanResultTest extends TestCase
|
||||
{
|
||||
private const EXAMPLE1 = 'QTY:1000 PN:SMD0603-5K1-1% PO:32723349/7 MFR:ROYALOHM MPN:0603SAF5101T5E CoO:TH RoHS https://www.tme.eu/details/SMD0603-5K1-1%25';
|
||||
private const EXAMPLE2 = 'QTY:5 PN:ETQP3M6R8KVP PO:31199729/3 MFR:PANASONIC MPN:ETQP3M6R8KVP RoHS https://www.tme.eu/details/ETQP3M6R8KVP';
|
||||
|
||||
public function testIsTMEBarcode(): void
|
||||
{
|
||||
$this->assertFalse(TMEBarcodeScanResult::isTMEBarcode('invalid'));
|
||||
$this->assertFalse(TMEBarcodeScanResult::isTMEBarcode('QTY:5 PN:ABC MPN:XYZ'));
|
||||
$this->assertFalse(TMEBarcodeScanResult::isTMEBarcode(''));
|
||||
|
||||
$this->assertTrue(TMEBarcodeScanResult::isTMEBarcode(self::EXAMPLE1));
|
||||
$this->assertTrue(TMEBarcodeScanResult::isTMEBarcode(self::EXAMPLE2));
|
||||
}
|
||||
|
||||
public function testParseInvalidThrows(): void
|
||||
{
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
TMEBarcodeScanResult::parse('not-a-tme-barcode');
|
||||
}
|
||||
|
||||
public function testParseExample1(): void
|
||||
{
|
||||
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE1);
|
||||
|
||||
$this->assertSame(1000, $scan->quantity);
|
||||
$this->assertSame('SMD0603-5K1-1%', $scan->tmePartNumber);
|
||||
$this->assertSame('32723349/7', $scan->purchaseOrder);
|
||||
$this->assertSame('ROYALOHM', $scan->manufacturer);
|
||||
$this->assertSame('0603SAF5101T5E', $scan->mpn);
|
||||
$this->assertSame('TH', $scan->countryOfOrigin);
|
||||
$this->assertTrue($scan->rohs);
|
||||
$this->assertSame('https://www.tme.eu/details/SMD0603-5K1-1%25', $scan->productUrl);
|
||||
$this->assertSame(self::EXAMPLE1, $scan->rawInput);
|
||||
}
|
||||
|
||||
public function testParseExample2(): void
|
||||
{
|
||||
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE2);
|
||||
|
||||
$this->assertSame(5, $scan->quantity);
|
||||
$this->assertSame('ETQP3M6R8KVP', $scan->tmePartNumber);
|
||||
$this->assertSame('31199729/3', $scan->purchaseOrder);
|
||||
$this->assertSame('PANASONIC', $scan->manufacturer);
|
||||
$this->assertSame('ETQP3M6R8KVP', $scan->mpn);
|
||||
$this->assertNull($scan->countryOfOrigin);
|
||||
$this->assertTrue($scan->rohs);
|
||||
$this->assertSame('https://www.tme.eu/details/ETQP3M6R8KVP', $scan->productUrl);
|
||||
}
|
||||
|
||||
public function testGetSourceType(): void
|
||||
{
|
||||
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE2);
|
||||
$this->assertSame(BarcodeSourceType::TME, $scan->getSourceType());
|
||||
}
|
||||
|
||||
public function testParseUppercaseUrl(): void
|
||||
{
|
||||
$input = 'QTY:500 PN:M0.6W-10K MFR:ROYAL.OHM MPN:MF006FF1002A50 PO:7792659/8 HTTPS://WWW.TME.EU/DETAILS/M0.6W-10K';
|
||||
$this->assertTrue(TMEBarcodeScanResult::isTMEBarcode($input));
|
||||
|
||||
$scan = TMEBarcodeScanResult::parse($input);
|
||||
$this->assertSame(500, $scan->quantity);
|
||||
$this->assertSame('M0.6W-10K', $scan->tmePartNumber);
|
||||
$this->assertSame('ROYAL.OHM', $scan->manufacturer);
|
||||
$this->assertSame('MF006FF1002A50', $scan->mpn);
|
||||
$this->assertSame('7792659/8', $scan->purchaseOrder);
|
||||
$this->assertSame('HTTPS://WWW.TME.EU/DETAILS/M0.6W-10K', $scan->productUrl);
|
||||
}
|
||||
|
||||
public function testGetDecodedForInfoMode(): void
|
||||
{
|
||||
$scan = TMEBarcodeScanResult::parse(self::EXAMPLE1);
|
||||
$decoded = $scan->getDecodedForInfoMode();
|
||||
|
||||
$this->assertSame('TME', $decoded['Barcode type']);
|
||||
$this->assertSame('SMD0603-5K1-1%', $decoded['TME Part No. (PN)']);
|
||||
$this->assertSame('0603SAF5101T5E', $decoded['MPN']);
|
||||
$this->assertSame('ROYALOHM', $decoded['Manufacturer (MFR)']);
|
||||
$this->assertSame('1000', $decoded['Qty']);
|
||||
$this->assertSame('Yes', $decoded['RoHS']);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue