Skip to content

Commit

Permalink
Add tests for collection removal without triggering validation (#1737)
Browse files Browse the repository at this point in the history
  • Loading branch information
jordisala1991 committed Apr 10, 2023
1 parent 8c47894 commit 18d5bd5
Show file tree
Hide file tree
Showing 9 changed files with 346 additions and 2 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"doctrine/persistence": "^3.0.2",
"sonata-project/admin-bundle": "^4.18",
"sonata-project/exporter": "^2.0 || ^3.0",
"sonata-project/form-extensions": "^1.4",
"sonata-project/form-extensions": "^1.19",
"symfony/config": "^4.4 || ^5.4 || ^6.2",
"symfony/console": "^4.4 || ^5.4 || ^6.2",
"symfony/dependency-injection": "^4.4 || ^5.4 || ^6.2",
Expand Down
40 changes: 40 additions & 0 deletions tests/App/Admin/ChildAdmin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineORMAdminBundle\Tests\App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Child;

/**
* @phpstan-extends AbstractAdmin<Child>
*/
final class ChildAdmin extends AbstractAdmin
{
protected function configureListFields(ListMapper $list): void
{
$list
->add('id')
->addIdentifier('name')
->add('anotherName');
}

protected function configureFormFields(FormMapper $form): void
{
$form
->add('name')
->add('anotherName');
}
}
45 changes: 45 additions & 0 deletions tests/App/Admin/MotherAdmin.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineORMAdminBundle\Tests\App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Mother;
use Sonata\Form\Type\CollectionType;
use Symfony\Component\Validator\Constraints as Assert;

/**
* @phpstan-extends AbstractAdmin<Mother>
*/
final class MotherAdmin extends AbstractAdmin
{
protected function configureListFields(ListMapper $list): void
{
$list->addIdentifier('id');
}

protected function configureFormFields(FormMapper $form): void
{
$form->add('children', CollectionType::class, [
'by_reference' => false,
'constraints' => [
new Assert\Valid(),
],
], [
'edit' => 'inline',
'inline' => 'table',
]);
}
}
47 changes: 47 additions & 0 deletions tests/App/DataFixtures/MotherFixtures.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineORMAdminBundle\Tests\App\DataFixtures;

use Doctrine\Bundle\FixturesBundle\Fixture;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Persistence\ObjectManager;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Child;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Mother;

final class MotherFixtures extends Fixture implements FixtureInterface
{
public const MOTHER = 'mother';

public function load(ObjectManager $manager): void
{
$mother = new Mother();
$this->addChildren($mother, 2);

$manager->persist($mother);
$manager->flush();

$this->addReference(self::MOTHER, $mother);
}

private function addChildren(Mother $mother, int $children): void
{
for ($i = 0; $i < $children; ++$i) {
$child = new Child();
$child->setName('Child '.$i);
$child->setAnotherName('Another Name '.$i);

$mother->addChild($child);
}
}
}
70 changes: 70 additions & 0 deletions tests/App/Entity/Child.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineORMAdminBundle\Tests\App\Entity;

use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity]
class Child implements \Stringable
{
#[ORM\Id]
#[ORM\Column(type: Types::INTEGER)]
#[ORM\GeneratedValue]
private ?int $id = null;

#[ORM\Column(type: Types::STRING)]
#[Assert\NotBlank]
private ?string $name = null;

#[ORM\Column(type: Types::STRING)]
#[Assert\NotBlank]
private ?string $anotherName = null;

public function __toString(): string
{
return $this->name ?? '-';
}

public function getId(): ?int
{
return $this->id;
}

public function setId(?int $id): void
{
$this->id = $id;
}

public function getName(): ?string
{
return $this->name;
}

public function setName(?string $name): void
{
$this->name = $name;
}

public function getAnotherName(): ?string
{
return $this->anotherName;
}

public function setAnotherName(?string $anotherName): void
{
$this->anotherName = $anotherName;
}
}
72 changes: 72 additions & 0 deletions tests/App/Entity/Mother.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineORMAdminBundle\Tests\App\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class Mother implements \Stringable
{
#[ORM\Id]
#[ORM\Column(type: Types::INTEGER)]
#[ORM\GeneratedValue]
private ?int $id = null;

/**
* @var Collection<array-key, Child>
*/
#[ORM\ManyToMany(targetEntity: Child::class, cascade: ['persist', 'remove'])]
private Collection $children;

public function __construct()
{
$this->children = new ArrayCollection();
}

public function __toString(): string
{
return (string) $this->id;
}

public function getId(): ?int
{
return $this->id;
}

public function setId(?int $id): void
{
$this->id = $id;
}

public function addChild(Child $child): void
{
$this->children->add($child);
}

public function removeChild(Child $child): void
{
$this->children->removeElement($child);
}

/**
* @return Collection<array-key, Child>
*/
public function getChildren(): Collection
{
return $this->children;
}
}
6 changes: 5 additions & 1 deletion tests/App/config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ framework:
enabled: true
form:
enabled: true
secret: '%env(APP_SECRET)%'
secret: secret
http_method_override: false
test: true
translator:
Expand All @@ -28,3 +28,7 @@ doctrine:
dir: "%kernel.project_dir%/Entity"
is_bundle: false
prefix: Sonata\DoctrineORMAdminBundle\Tests\App\Entity

sonata_admin:
options:
html5_validate: false
18 changes: 18 additions & 0 deletions tests/App/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@
use Sonata\DoctrineORMAdminBundle\Tests\App\Admin\BookWithAuthorAutocompleteAdmin;
use Sonata\DoctrineORMAdminBundle\Tests\App\Admin\CarAdmin;
use Sonata\DoctrineORMAdminBundle\Tests\App\Admin\CategoryAdmin;
use Sonata\DoctrineORMAdminBundle\Tests\App\Admin\ChildAdmin;
use Sonata\DoctrineORMAdminBundle\Tests\App\Admin\ItemAdmin;
use Sonata\DoctrineORMAdminBundle\Tests\App\Admin\MotherAdmin;
use Sonata\DoctrineORMAdminBundle\Tests\App\Admin\SubAdmin;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Author;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Book;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Car;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Category;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Child;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Item;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Mother;
use Sonata\DoctrineORMAdminBundle\Tests\App\Entity\Sub;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

Expand Down Expand Up @@ -94,5 +98,19 @@
'manager_type' => 'orm',
'model_class' => Sub::class,
'label' => 'Inheritance',
])

->set(MotherAdmin::class)
->tag('sonata.admin', [
'manager_type' => 'orm',
'model_class' => Mother::class,
'label' => 'Mother',
])

->set(ChildAdmin::class)
->tag('sonata.admin', [
'manager_type' => 'orm',
'model_class' => Child::class,
'label' => 'Child',
]);
};
48 changes: 48 additions & 0 deletions tests/Functional/CollectionTypeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Sonata\DoctrineORMAdminBundle\Tests\Functional;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Panther\DomCrawler\Crawler;

final class CollectionTypeTest extends BasePantherTestCase
{
public function testRemoveCollectionItemWithoutValidation(): void
{
$crawler = $this->client->request(Request::METHOD_GET, '/admin/tests/app/mother/1/edit?uniqid=mother');

$form = $crawler->selectButton('Update')->form();
$form['mother[children][0][name]'] = '';

$crawler->filter('#mother_children_0__delete + ins')->each(static function (Crawler $checkbox): void {
$checkbox->click();
});

$this->client->submit($form);

self::assertSelectorTextContains('.alert-success', 'Item "1" has been successfully updated.');
}

public function testTriggerCollectionValidation(): void
{
$crawler = $this->client->request(Request::METHOD_GET, '/admin/tests/app/mother/1/edit?uniqid=mother');

$form = $crawler->selectButton('Update')->form();
$form['mother[children][0][name]'] = '';

$this->client->submit($form);

self::assertSelectorTextContains('.alert-danger', 'An error has occurred during update of item "1".');
}
}

0 comments on commit 18d5bd5

Please sign in to comment.