Added tests for various label services.

This commit is contained in:
Jan Böhmer 2020-05-09 20:24:07 +02:00
parent e925bec5b6
commit 236249e4a1
10 changed files with 467 additions and 47 deletions

View file

@ -22,7 +22,7 @@ namespace App\Controller;
use App\Form\LabelSystem\ScanDialogType;
use App\Services\LabelSystem\BarcodeParser;
use App\Services\LabelSystem\Barcodes\BarcodeRedirector;
use App\Services\LabelSystem\Barcodes\BarcodeNormalizer;
use Doctrine\ORM\EntityNotFoundException;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@ -40,7 +40,7 @@ class ScanController extends AbstractController
protected $barcodeParser;
protected $barcodeNormalizer;
public function __construct(BarcodeParser $barcodeParser, BarcodeNormalizer $barcodeNormalizer)
public function __construct(BarcodeRedirector $barcodeParser, BarcodeNormalizer $barcodeNormalizer)
{
$this->barcodeParser = $barcodeParser;
$this->barcodeNormalizer = $barcodeNormalizer;
@ -61,7 +61,7 @@ class ScanController extends AbstractController
try {
[$type, $id] = $this->barcodeNormalizer->normalizeBarcodeContent($input);
try {
return $this->redirect($this->barcodeParser->getQRRedirectTarget($type, $id));
return $this->redirect($this->barcodeParser->getRedirectURL($type, $id));
} catch (EntityNotFoundException $exception) {
$this->addFlash('success', 'scan.qr_not_found');
}
@ -84,7 +84,7 @@ class ScanController extends AbstractController
{
try {
$this->addFlash('success', 'scan.qr_success');
return $this->redirect($this->barcodeParser->getQRRedirectTarget($type, $id));
return $this->redirect($this->barcodeParser->getRedirectURL($type, $id));
} catch (EntityNotFoundException $exception) {
$this->addFlash('success', 'scan.qr_not_found');
return $this->redirectToRoute('homepage');

View file

@ -76,7 +76,7 @@ final class BarcodeContentGenerator
public function get1DBarcodeContent(AbstractDBElement $target): string
{
$prefix = $this->classToString(self::PREFIX_MAP, $target);
$id = sprintf('%04d', $target->getID());
$id = sprintf('%04d', $target->getID() ?? 0);
return $prefix . $id;
}

View file

@ -18,7 +18,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace App\Services\LabelSystem;
namespace App\Services\LabelSystem\Barcodes;
use App\Entity\Parts\PartLot;
@ -26,7 +26,7 @@ use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityNotFoundException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
final class BarcodeParser
final class BarcodeRedirector
{
private $urlGenerator;
private $em;
@ -45,7 +45,7 @@ final class BarcodeParser
* @return string The URL to which should be redirected.
* @throws EntityNotFoundException
*/
public function getQRRedirectTarget(string $type, int $id): string
public function getRedirectURL(string $type, int $id): string
{
switch ($type) {
case 'part':

View file

@ -62,8 +62,6 @@ final class LabelGenerator
$elements = [$elements];
}
$elements_html = [];
foreach ($elements as $element) {
if (!$this->supports($options, $element)) {
throw new \InvalidArgumentException('The given options are not compatible with the given element!');
@ -94,8 +92,14 @@ final class LabelGenerator
return is_a($element, static::CLASS_SUPPORT_MAPPING[$supported_type]);
}
/**
* Converts width and height given in mm to an size array, that can be used by DOMPDF for page size
* @param float $width The width of the paper
* @param float $height The height of the paper
* @return float[]
*/
public function mmToPointsArray(float $width, float $height): array
{
return [0, 0, $width * self::MM_TO_POINTS_FACTOR, $height * self::MM_TO_POINTS_FACTOR];
return [0.0, 0.0, $width * self::MM_TO_POINTS_FACTOR, $height * self::MM_TO_POINTS_FACTOR];
}
}

View file

@ -0,0 +1,80 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 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;
use App\Entity\LabelSystem\LabelOptions;
use App\Entity\Parts\Part;
use App\Services\LabelSystem\BarcodeGenerator;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
final class BarcodeGeneratorTest extends WebTestCase
{
/** @var BarcodeGenerator */
protected $services;
public function setUp(): void
{
self::bootKernel();
$this->services = self::$container->get(BarcodeGenerator::class);
}
public function testGetContent(): void
{
$part = new Part();
$part->setName('Test');
//Test that all barcodes types are supported
foreach (LabelOptions::BARCODE_TYPES as $type) {
$options = new LabelOptions();
$options->setBarcodeType($type);
$content = $this->services->generateSVG($options, $part);
//When type is none, service must return null.
if ($type === 'none') {
$this->assertNull($content);
} else {
$this->assertIsString($content);
}
}
}
public function testGenerateSVG(): void
{
$part = new Part();
$part->setName('Test');
//Test that all barcodes types are supported
foreach (LabelOptions::BARCODE_TYPES as $type) {
$options = new LabelOptions();
$options->setBarcodeType($type);
$svg = $this->services->generateSVG($options, $part);
//When type is none, service must return null.
if ($type === "none") {
$this->assertNull($svg);
} else {
$this->assertStringContainsStringIgnoringCase("SVG", $svg);
}
}
}
}

View file

@ -1,36 +0,0 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 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;
use App\Services\LabelSystem\BarcodeParser;
use PHPUnit\Framework\TestCase;
class BarcodeParserTest extends TestCase
{
public function testGetQRRedirectTarget()
{
}
}

View file

@ -0,0 +1,79 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 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\Barcodes;
use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
use App\Entity\Parts\Storelocation;
use App\Services\LabelSystem\Barcodes\BarcodeContentGenerator;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class BarcodeContentGeneratorTest extends KernelTestCase
{
/** @var BarcodeContentGenerator */
private $service;
public function setUp(): void
{
self::bootKernel();
$this->service = self::$container->get(BarcodeContentGenerator::class);
}
public function Barcode1DDataProvider(): array
{
return [
['P0000', Part::class],
['L0000', PartLot::class],
['S0000', Storelocation::class],
];
}
public function Barcode2DDataProvider(): array
{
return [
['/scan/part/0', Part::class],
['/scan/lot/0', PartLot::class],
['/scan/location/0', Storelocation::class]
];
}
/**
* @dataProvider Barcode1DDataProvider
*/
public function testGet1DBarcodeContent(string $expected, string $class): void
{
$this->assertSame($expected, $this->service->get1DBarcodeContent(new $class()));
}
/**
* @dataProvider Barcode2DDataProvider
*/
public function testGetURLContent(string $expected, string $class): void
{
$url = $this->service->getURLContent(new $class());
//URL must be absolute...
$this->assertStringStartsWith('http', $url);
$this->assertStringEndsWith($expected, $url);
}
}

View file

@ -0,0 +1,70 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 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\Barcodes;
use App\Services\LabelSystem\Barcodes\BarcodeRedirector;
use Doctrine\ORM\EntityNotFoundException;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
class BarcodeRedirectorTest extends KernelTestCase
{
/** @var BarcodeRedirector */
private $service;
public function setUp(): void
{
self::bootKernel();
$this->service = self::$container->get(BarcodeRedirector::class);
}
public function urlDataProvider(): array
{
return [
['part', '/en/part/1'],
//Part lot redirects to Part info page (Part lot 1 is associated with part 3
['lot', '/en/part/3'],
['location', '/en/store_location/1/parts']
];
}
/**
* @dataProvider urlDataProvider
* @group DB
*/
public function testGetRedirectURL(string $type, string $url): void
{
$this->assertSame($url, $this->service->getRedirectURL($type, 1));
}
public function testGetRedirectEntityNotFount(): void
{
$this->expectException(EntityNotFoundException::class);
//If we encounter an invalid lot, we must throw an exception
$this->service->getRedirectURL('lot', 12345678);
}
public function testInvalidType(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->service->getRedirectURL('invalid', 1);
}
}

View file

@ -0,0 +1,100 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 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;
use App\Entity\Base\AbstractDBElement;
use App\Entity\LabelSystem\LabelOptions;
use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
use App\Entity\Parts\Storelocation;
use App\Services\LabelSystem\LabelGenerator;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class LabelGeneratorTest extends WebTestCase
{
/** @var LabelGenerator */
protected $service;
public function setUp(): void
{
self::bootKernel();
$this->service = self::$container->get(LabelGenerator::class);
}
public function supportsDataProvider(): array
{
return [
['part', Part::class],
['part_lot', PartLot::class],
['storelocation', Storelocation::class]
];
}
/**
* @dataProvider supportsDataProvider
*/
public function testSupports(string $type, string $class)
{
$options = new LabelOptions();
$options->setSupportedElement($type);
//Ensure that the given class is supported
$this->assertTrue($this->service->supports($options, new $class()));
//Ensure that another class is not supported
$not_supported = new class extends AbstractDBElement {
public function getIDString(): string
{
return "not_important";
}
};
$this->assertFalse($this->service->supports($options, $not_supported));
}
public function testMmToPointsArray()
{
$this->assertSame(
[0.0, 0.0, 141.7325, 85.0395],
$this->service->mmToPointsArray(50.0, 30.0)
);
}
public function testGenerateLabel()
{
$part = new Part();
$options = new LabelOptions();
$options->setLines('Test');
$options->setSupportedElement('part');
//Test for a single passed element:
$pdf = $this->service->generateLabel($options, $part);
//Just a simple check if a PDF is returned
$this->assertStringStartsWith('%PDF-', $pdf);
//Test for an array of elements
$pdf = $this->service->generateLabel($options, [$part, $part]);
//Just a simple check if a PDF is returned
$this->assertStringStartsWith('%PDF-', $pdf);
}
}

View file

@ -0,0 +1,123 @@
<?php
/**
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
*
* Copyright (C) 2019 - 2020 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;
use App\Entity\LabelSystem\LabelOptions;
use App\Entity\Parts\Part;
use App\Entity\Parts\PartLot;
use App\Entity\Parts\Storelocation;
use App\Services\LabelSystem\Barcodes\BarcodeExampleElementsGenerator;
use App\Services\LabelSystem\SandboxedTwigProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Twig\Sandbox\SecurityError;
class SandboxedTwigProviderTest extends WebTestCase
{
/** @var SandboxedTwigProvider */
private $service;
public function setUp(): void
{
self::bootKernel();
$this->service = self::$container->get(SandboxedTwigProvider::class);
}
public function twigDataProvider(): array
{
return [
[' {% for i in range(1, 3) %}
{{ part.id }}
{{ part.name }}
{{ part.lastModified | format_datetime }}
{% endfor %}
'],
[' {% if part.category %}
{{ part.category }}
{% endif %}
'],
[' {% set a = random(1, 3) %}
{{ 1 + 2 | abs }}
{{ "test" | capitalize | escape | lower | raw }}
{{ "\n" | nl2br | trim | title | url_encode | reverse }}
'],
['
{{ location.isRoot}} {{ location.isChildOf(location) }} {{ location.comment }} {{ location.level }}
{{ location.fullPath }} {% set arr = location.pathArray %} {% set child = location.children %} {{location.childrenNotSelectable}}
'],
['
{{ part.reviewNeeded }} {{ part.tags }} {{ part.mass }}
']
];
}
public function twigNotAllowedDataProvider(): array
{
return [
["{% block test %} {% endblock %}"],
["{% deprecated test %}"],
["{% flush %}"],
["{{ part.setName('test') }}"],
["{{ part.setCategory(null) }}"]
];
}
/**
* @dataProvider twigDataProvider
*/
public function testTwigFeatures(string $twig)
{
$options = new LabelOptions();
$options->setSupportedElement('part');
$options->setLines($twig);
$options->setLinesMode('twig');
$twig = $this->service->getTwig($options);
$str = $twig->render('lines', [
'part' => new Part(),
'lot' => new PartLot(),
'location' => new Storelocation(),
]);
$this->assertIsString($str);
}
/**
* @dataProvider twigNotAllowedDataProvider
*/
public function testTwigForbidden(string $twig)
{
$this->expectException(SecurityError::class);
$options = new LabelOptions();
$options->setSupportedElement('part');
$options->setLines($twig);
$options->setLinesMode('twig');
$twig = $this->service->getTwig($options);
$str = $twig->render('lines', [
'part' => new Part(),
'lot' => new PartLot(),
'location' => new Storelocation(),
]);
}
}