mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 09:35:49 +02:00
Added some more tests.
This commit is contained in:
parent
24e4a554f8
commit
3438f15274
6 changed files with 219 additions and 30 deletions
20
composer.lock
generated
20
composer.lock
generated
|
@ -4955,16 +4955,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/http-client-contracts",
|
"name": "symfony/http-client-contracts",
|
||||||
"version": "v1.1.7",
|
"version": "v1.1.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/http-client-contracts.git",
|
"url": "https://github.com/symfony/http-client-contracts.git",
|
||||||
"reference": "353b2a3e907e5c34cf8f74827a4b21eb745aab1d"
|
"reference": "088bae75cfa2ec5eb6d33dce17dbd8613150ce6e"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/353b2a3e907e5c34cf8f74827a4b21eb745aab1d",
|
"url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/088bae75cfa2ec5eb6d33dce17dbd8613150ce6e",
|
||||||
"reference": "353b2a3e907e5c34cf8f74827a4b21eb745aab1d",
|
"reference": "088bae75cfa2ec5eb6d33dce17dbd8613150ce6e",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -5008,7 +5008,7 @@
|
||||||
"interoperability",
|
"interoperability",
|
||||||
"standards"
|
"standards"
|
||||||
],
|
],
|
||||||
"time": "2019-09-26T22:09:58+00:00"
|
"time": "2019-11-07T12:44:51+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/http-foundation",
|
"name": "symfony/http-foundation",
|
||||||
|
@ -6566,16 +6566,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/service-contracts",
|
"name": "symfony/service-contracts",
|
||||||
"version": "v1.1.7",
|
"version": "v1.1.8",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/service-contracts.git",
|
"url": "https://github.com/symfony/service-contracts.git",
|
||||||
"reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0"
|
"reference": "ffc7f5692092df31515df2a5ecf3b7302b3ddacf"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
|
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/ffc7f5692092df31515df2a5ecf3b7302b3ddacf",
|
||||||
"reference": "ffcde9615dc5bb4825b9f6aed07716f1f57faae0",
|
"reference": "ffc7f5692092df31515df2a5ecf3b7302b3ddacf",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -6620,7 +6620,7 @@
|
||||||
"interoperability",
|
"interoperability",
|
||||||
"standards"
|
"standards"
|
||||||
],
|
],
|
||||||
"time": "2019-09-17T11:12:18+00:00"
|
"time": "2019-10-14T12:27:06+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/stopwatch",
|
"name": "symfony/stopwatch",
|
||||||
|
|
|
@ -199,16 +199,21 @@ abstract class BaseAdminController extends AbstractController
|
||||||
if ($mass_creation_form->isSubmitted() && $mass_creation_form->isValid()) {
|
if ($mass_creation_form->isSubmitted() && $mass_creation_form->isValid()) {
|
||||||
$data = $mass_creation_form->getData();
|
$data = $mass_creation_form->getData();
|
||||||
|
|
||||||
dump($data);
|
|
||||||
|
|
||||||
//Create entries based on input
|
//Create entries based on input
|
||||||
$errors = $importer->massCreation($data['lines'], $this->entity_class, $data['parent']);
|
$errors = [];
|
||||||
|
$results = $importer->massCreation($data['lines'], $this->entity_class, $data['parent'], $errors);
|
||||||
|
|
||||||
//Show errors to user:
|
//Show errors to user:
|
||||||
foreach ($errors as $name => $error) {
|
foreach ($errors as $error) {
|
||||||
/* @var $error ConstraintViolationList */
|
dump($error);
|
||||||
$this->addFlash('error', $name.':'.$error);
|
$this->addFlash('error', $error['entity']->getFullPath().':'.$error['violations']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Persist valid entities to DB
|
||||||
|
foreach ($results as $result) {
|
||||||
|
$em->persist($result);
|
||||||
|
}
|
||||||
|
$em->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->render($this->twig_template, [
|
return $this->render($this->twig_template, [
|
||||||
|
|
|
@ -111,14 +111,15 @@ class ElementTypeNameGenerator
|
||||||
* @param bool $use_html If set to true, a html string is returned, where the type is set italic
|
* @param bool $use_html If set to true, a html string is returned, where the type is set italic
|
||||||
*
|
*
|
||||||
* @return string The localized string
|
* @return string The localized string
|
||||||
|
* @throws EntityNotSupportedException When the passed entity is not supported.
|
||||||
*/
|
*/
|
||||||
public function getTypeNameCombination(NamedDBElement $entity, bool $use_html = false): string
|
public function getTypeNameCombination(NamedDBElement $entity, bool $use_html = false): string
|
||||||
{
|
{
|
||||||
$type = $this->getLocalizedTypeLabel($entity);
|
$type = $this->getLocalizedTypeLabel($entity);
|
||||||
if ($use_html) {
|
if ($use_html) {
|
||||||
return '<i>'.$type.':</i> '.$entity->getName();
|
return '<i>'.$type.':</i> '.htmlspecialchars($entity->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
return $type.': '.htmlspecialchars($entity->getName());
|
return $type.': '.$entity->getName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
namespace App\Services;
|
namespace App\Services;
|
||||||
|
|
||||||
|
use App\Entity\Base\DBElement;
|
||||||
use App\Entity\Base\StructuralDBElement;
|
use App\Entity\Base\StructuralDBElement;
|
||||||
use Doctrine\ORM\EntityManagerInterface;
|
use Doctrine\ORM\EntityManagerInterface;
|
||||||
use Symfony\Component\HttpFoundation\File\File;
|
use Symfony\Component\HttpFoundation\File\File;
|
||||||
|
@ -44,7 +45,7 @@ class EntityImporter
|
||||||
protected function configureOptions(OptionsResolver $resolver)
|
protected function configureOptions(OptionsResolver $resolver)
|
||||||
{
|
{
|
||||||
$resolver->setDefaults([
|
$resolver->setDefaults([
|
||||||
'csv_separator' => ';',
|
'csv_separator' => ';',
|
||||||
'format' => 'json',
|
'format' => 'json',
|
||||||
'preserve_children' => true,
|
'preserve_children' => true,
|
||||||
'parent' => null,
|
'parent' => null,
|
||||||
|
@ -53,24 +54,37 @@ class EntityImporter
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates many entries at once, based on a (text) list of names.
|
* Creates many entries at once, based on a (text) list of name.
|
||||||
|
* The created enties are not persisted to database yet, so you have to do it yourself.
|
||||||
*
|
*
|
||||||
* @param string $lines The list of names seperated by \n
|
* @param string $lines The list of names seperated by \n
|
||||||
* @param string $class_name The name of the class for which the entities should be created
|
* @param string $class_name The name of the class for which the entities should be created
|
||||||
* @param StructuralDBElement|null $parent The element which will be used as parent element for new elements.
|
* @param StructuralDBElement|null $parent The element which will be used as parent element for new elements.
|
||||||
|
* @param array $errors An associative array containing all validation errors.
|
||||||
*
|
*
|
||||||
* @return array An associative array containing an ConstraintViolationList and the entity name as key are returned,
|
* @return StructuralDBElement[] An array containing all valid imported entities (with the type $class_name)
|
||||||
* if an error happened during validation. When everything was successfull, the array should be empty.
|
|
||||||
*/
|
*/
|
||||||
public function massCreation(string $lines, string $class_name, ?StructuralDBElement $parent): array
|
public function massCreation(string $lines, string $class_name, ?StructuralDBElement $parent = null, array &$errors = []): array
|
||||||
{
|
{
|
||||||
//Expand every line to a single entry:
|
//Expand every line to a single entry:
|
||||||
$names = explode("\n", $lines);
|
$names = explode("\n", $lines);
|
||||||
|
|
||||||
|
if (!is_a($class_name, StructuralDBElement::class, true)) {
|
||||||
|
throw new \InvalidArgumentException('$class_name must be a StructuralDBElement type!');
|
||||||
|
}
|
||||||
|
if ($parent !== null && !is_a($parent, $class_name)) {
|
||||||
|
throw new \InvalidArgumentException('$parent must have the same type as specified in $class_name!');
|
||||||
|
}
|
||||||
|
|
||||||
$errors = [];
|
$errors = [];
|
||||||
|
$valid_entities = [];
|
||||||
|
|
||||||
foreach ($names as $name) {
|
foreach ($names as $name) {
|
||||||
$name = trim($name);
|
$name = trim($name);
|
||||||
|
if ($name === '') {
|
||||||
|
//Skip empty lines (StrucuralDBElements must have a name)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
/** @var $entity StructuralDBElement */
|
/** @var $entity StructuralDBElement */
|
||||||
//Create new element with given name
|
//Create new element with given name
|
||||||
$entity = new $class_name();
|
$entity = new $class_name();
|
||||||
|
@ -81,17 +95,13 @@ class EntityImporter
|
||||||
$tmp = $this->validator->validate($entity);
|
$tmp = $this->validator->validate($entity);
|
||||||
//If no error occured, write entry to DB:
|
//If no error occured, write entry to DB:
|
||||||
if (0 === \count($tmp)) {
|
if (0 === \count($tmp)) {
|
||||||
$this->em->persist($entity);
|
$valid_entities[] = $entity;
|
||||||
} else { //Otherwise log error
|
} else { //Otherwise log error
|
||||||
dump($tmp);
|
$errors[] = ['entity' => $entity, 'violations' => $tmp];
|
||||||
$errors[$entity->getFullPath()] = $tmp;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Save changes to database
|
return $valid_entities;
|
||||||
$this->em->flush();
|
|
||||||
|
|
||||||
return $errors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
89
tests/Services/ElementTypeNameGeneratorTest.php
Normal file
89
tests/Services/ElementTypeNameGeneratorTest.php
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Tests\Services;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Entity\Attachments\PartAttachment;
|
||||||
|
use App\Entity\Base\DBElement;
|
||||||
|
use App\Entity\Base\NamedDBElement;
|
||||||
|
use App\Entity\Parts\Category;
|
||||||
|
use App\Entity\Parts\Part;
|
||||||
|
use App\Exceptions\EntityNotSupportedException;
|
||||||
|
use App\Services\AmountFormatter;
|
||||||
|
use App\Services\ElementTypeNameGenerator;
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
|
||||||
|
class ElementTypeNameGeneratorTest extends WebTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AmountFormatter
|
||||||
|
*/
|
||||||
|
protected $service;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
//Get an service instance.
|
||||||
|
self::bootKernel();
|
||||||
|
$this->service = self::$container->get(ElementTypeNameGenerator::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetLocalizedTypeNameCombination()
|
||||||
|
{
|
||||||
|
//We only test in english
|
||||||
|
$this->assertEquals('Part', $this->service->getLocalizedTypeLabel(new Part()));
|
||||||
|
$this->assertEquals('Category', $this->service->getLocalizedTypeLabel(new Category()));
|
||||||
|
|
||||||
|
//Test inheritance
|
||||||
|
$this->assertEquals('Attachment', $this->service->getLocalizedTypeLabel(new PartAttachment()));
|
||||||
|
|
||||||
|
//Test exception for unknpwn type
|
||||||
|
$this->expectException(EntityNotSupportedException::class);
|
||||||
|
$this->service->getLocalizedTypeLabel(new class extends DBElement {
|
||||||
|
public function getIDString(): string
|
||||||
|
{
|
||||||
|
return 'Stub';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testGetTypeNameCombination()
|
||||||
|
{
|
||||||
|
$part = new Part();
|
||||||
|
$part->setName('Test<Part');
|
||||||
|
//When the text version is used, dont escape the name
|
||||||
|
$this->assertEquals('Part: Test<Part', $this->service->getTypeNameCombination($part, false));
|
||||||
|
|
||||||
|
$this->assertEquals('<i>Part:</i> Test<Part', $this->service->getTypeNameCombination($part, true));
|
||||||
|
|
||||||
|
//Test exception
|
||||||
|
$this->expectException(EntityNotSupportedException::class);
|
||||||
|
$this->service->getTypeNameCombination(new class extends NamedDBElement {
|
||||||
|
public function getIDString(): string
|
||||||
|
{
|
||||||
|
return 'Stub';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
84
tests/Services/EntityImporterTest.php
Normal file
84
tests/Services/EntityImporterTest.php
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 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 General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace App\Tests\Services;
|
||||||
|
|
||||||
|
|
||||||
|
use App\Entity\Attachments\AttachmentType;
|
||||||
|
use App\Services\AmountFormatter;
|
||||||
|
use App\Services\ElementTypeNameGenerator;
|
||||||
|
use App\Services\EntityImporter;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
|
||||||
|
class EntityImporterTest extends WebTestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var AmountFormatter
|
||||||
|
*/
|
||||||
|
protected $service;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
//Get an service instance.
|
||||||
|
self::bootKernel();
|
||||||
|
$this->service = self::$container->get(EntityImporter::class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMassCreationResults()
|
||||||
|
{
|
||||||
|
$errors = [];
|
||||||
|
$results = $this->service->massCreation('', AttachmentType::class, null, $errors);
|
||||||
|
$this->assertEmpty($results);
|
||||||
|
$this->assertEmpty($errors);
|
||||||
|
|
||||||
|
$errors = [];
|
||||||
|
$lines = "Test 1 \n Test 2 \n Test 3";
|
||||||
|
$results = $this->service->massCreation($lines, AttachmentType::class, null, $errors);
|
||||||
|
$this->assertCount(0, $errors);
|
||||||
|
$this->assertCount(3, $results);
|
||||||
|
//Check type
|
||||||
|
$this->assertInstanceOf(AttachmentType::class, $results[0]);
|
||||||
|
//Check names
|
||||||
|
$this->assertEquals('Test 1', $results[0]->getName());
|
||||||
|
$this->assertEquals('Test 2', $results[1]->getName());
|
||||||
|
//Check parent
|
||||||
|
$this->assertNull($results[0]->getMasterPictureAttachment());
|
||||||
|
|
||||||
|
$parent = new AttachmentType();
|
||||||
|
$results = $this->service->massCreation($lines, AttachmentType::class, $parent, $errors);
|
||||||
|
$this->assertCount(3, $results);
|
||||||
|
$this->assertEquals($parent, $results[0]->getParent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMassCreationErrors()
|
||||||
|
{
|
||||||
|
$errors = [];
|
||||||
|
//Node 1 and Node 2 are created in datafixtures, so their attemp to create them again must fail.
|
||||||
|
$lines = "Test 1 \n Node 1 \n Node 2";
|
||||||
|
$results = $this->service->massCreation($lines, AttachmentType::class, null, $errors);
|
||||||
|
$this->assertCount(1, $results);
|
||||||
|
$this->assertEquals('Test 1', $results[0]->getName());
|
||||||
|
$this->assertCount(2, $errors);
|
||||||
|
$this->assertEquals('Node 1', $errors[0]['entity']->getName());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue