Skip to content

Commit

Permalink
Add twig extensions tests
Browse files Browse the repository at this point in the history
  • Loading branch information
duboiss committed Jan 25, 2022
1 parent 29e3cbe commit 1ce544d
Show file tree
Hide file tree
Showing 10 changed files with 228 additions and 81 deletions.
19 changes: 2 additions & 17 deletions src/Twig/AppExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,18 @@

namespace App\Twig;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class AppExtension extends AbstractExtension
{
public function __construct(private UrlGeneratorInterface $urlGenerator, private RequestStack $request)
{
}

/**
* @return array|TwigFunction[]
* {@inheritdoc}
*/
public function getFunctions(): array
{
return [
new TwigFunction('login_target_path', [$this, 'loginTargetPath']),
new TwigFunction('login_target_path', [AppRuntime::class, 'loginTargetPath']),
];
}

public function loginTargetPath(): string
{
if ($masterRequest = $this->request->getCurrentRequest()) {
return $this->urlGenerator->generate('security.login', ['redirect' => $masterRequest->getRequestUri()]);
}

return $this->urlGenerator->generate('security.login');
}
}
25 changes: 25 additions & 0 deletions src/Twig/AppRuntime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace App\Twig;

use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extension\RuntimeExtensionInterface;

class AppRuntime implements RuntimeExtensionInterface
{
public function __construct(private UrlGeneratorInterface $urlGenerator, private RequestStack $request)
{
}

public function loginTargetPath(): string
{
if ($masterRequest = $this->request->getCurrentRequest()) {
return $this->urlGenerator->generate('security.login', ['redirect' => $masterRequest->getRequestUri()]);
}

return $this->urlGenerator->generate('security.login');
}
}
55 changes: 5 additions & 50 deletions src/Twig/BreadcrumbExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,30 @@

namespace App\Twig;

use App\Entity\Category;
use App\Entity\Forum;
use InvalidArgumentException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use Twig\TwigFunction;

class BreadcrumbExtension extends AbstractExtension
{
private array $breadcrumbsPaths = [];

public function __construct(private UrlGeneratorInterface $urlGenerator)
{
}

/**
* @return array|TwigFilter[]
* {@inheritdoc}
*/
public function getFilters(): array
{
return [
new TwigFilter('breadcrumb', [$this, 'getBreadcrumbParts']),
new TwigFilter('breadcrumb', [BreadcrumbRuntime::class, 'getBreadcrumbParts']),
];
}

/**
* @return array|TwigFunction[]
* {@inheritdoc}
*/
public function getFunctions(): array
{
return [
new TwigFunction('append_breadcrumb', [$this, 'appendBreadcrumb']),
new TwigFunction('get_breadcrumbs', [$this, 'getBreadcrumbs']),
new TwigFunction('append_breadcrumb', [BreadcrumbRuntime::class, 'appendBreadcrumb']),
new TwigFunction('get_breadcrumbs', [BreadcrumbRuntime::class, 'getBreadcrumbs']),
];
}

public function appendBreadcrumb(string $label, ?string $path = null): void
{
$pair = [$label, $path];
if (!in_array($pair, $this->breadcrumbsPaths, true)) {
$this->breadcrumbsPaths[] = $pair;
}
}

public function getBreadcrumbs(): array
{
return $this->breadcrumbsPaths;
}

/**
* @return string[]
*/
public function getBreadcrumbParts(Category|Forum $item, array &$parts = []): array
{
if ($item instanceof Category) {
$url = $this->urlGenerator->generate('category.show', ['slug' => $item->getSlug()]);
} elseif ($item instanceof Forum) {
$url = $this->urlGenerator->generate('forum.show', ['slug' => $item->getSlug()]);
} else {
throw new InvalidArgumentException('Filtered object must be an instance of Forum or Category.');
}

array_unshift($parts, ['url' => $url, 'title' => $item->getTitle()]);

if ($item instanceof Forum && (($parent = $item->getParent()) || ($parent = $item->getCategory()))) {
return $this->getBreadcrumbParts($parent, $parts);
}

return $parts;
}
}
52 changes: 52 additions & 0 deletions src/Twig/BreadcrumbRuntime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace App\Twig;

use App\Entity\Category;
use App\Entity\Forum;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extension\RuntimeExtensionInterface;

class BreadcrumbRuntime implements RuntimeExtensionInterface
{
private array $breadcrumbsPaths = [];

public function __construct(private UrlGeneratorInterface $urlGenerator)
{
}

public function appendBreadcrumb(string $label, ?string $path = null): void
{
$pair = [$label, $path];
if (!in_array($pair, $this->breadcrumbsPaths, true)) {
$this->breadcrumbsPaths[] = $pair;
}
}

public function getBreadcrumbs(): array
{
return $this->breadcrumbsPaths;
}

/**
* @return string[]
*/
public function getBreadcrumbParts(Category|Forum $item, array &$parts = []): array
{
if ($item instanceof Category) {
$url = $this->urlGenerator->generate('category.show', ['slug' => $item->getSlug()]);
} else {
$url = $this->urlGenerator->generate('forum.show', ['slug' => $item->getSlug()]);
}

array_unshift($parts, ['url' => $url, 'title' => $item->getTitle()]);

if ($item instanceof Forum && (($parent = $item->getParent()) || ($parent = $item->getCategory()))) {
return $this->getBreadcrumbParts($parent, $parts);
}

return $parts;
}
}
22 changes: 22 additions & 0 deletions src/Twig/UserExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace App\Twig;

use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class UserExtension extends AbstractExtension
{
/**
* {@inheritdoc}
*/
public function getFunctions(): array
{
return [
new TwigFunction('user_profile_link', [UserRuntime::class, 'getUserProfileLink'], ['is_safe' => ['html']]),
new TwigFunction('user_profile_role', [UserRuntime::class, 'getUserProfileRole']),
];
}
}
16 changes: 2 additions & 14 deletions src/Twig/UserExtenion.php → src/Twig/UserRuntime.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@

use App\Entity\User;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;
use Twig\Extension\RuntimeExtensionInterface;

class UserExtenion extends AbstractExtension
class UserRuntime implements RuntimeExtensionInterface
{
private const ROLES = [
'ROLE_ADMIN' => 'Administrateur',
Expand All @@ -20,17 +19,6 @@ public function __construct(private UrlGeneratorInterface $urlGenerator)
{
}

/**
* @return array|TwigFunction[]
*/
public function getFunctions(): array
{
return [
new TwigFunction('user_profile_link', [$this, 'getUserProfileLink'], ['is_safe' => ['html']]),
new TwigFunction('user_profile_role', [$this, 'getUserProfileRole']),
];
}

public function getUserProfileLink(?User $user, string $text = null, string $class = null): string
{
if ($user) {
Expand Down
18 changes: 18 additions & 0 deletions tests/Unit/Twig/AppExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\Tests\Unit\Twig;

use App\Twig\AppExtension;
use PHPUnit\Framework\TestCase;
use Twig\TwigFunction;

class AppExtensionTest extends TestCase
{
public function testGetFunctions(): void
{
$functions = (new AppExtension())->getFunctions();
static::assertContainsOnlyInstancesOf(TwigFunction::class, $functions);
}
}
18 changes: 18 additions & 0 deletions tests/Unit/Twig/BreadcrumbExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\Tests\Unit\Twig;

use App\Twig\BreadcrumbExtension;
use PHPUnit\Framework\TestCase;
use Twig\TwigFunction;

class BreadcrumbExtensionTest extends TestCase
{
public function testGetFunctions(): void
{
$functions = (new BreadcrumbExtension())->getFunctions();
static::assertContainsOnlyInstancesOf(TwigFunction::class, $functions);
}
}
66 changes: 66 additions & 0 deletions tests/Unit/Twig/BreadcrumbRuntimeTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace App\Tests\Unit\Twig;

use App\Entity\Category;
use App\Entity\Forum;
use App\Twig\BreadcrumbRuntime;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class BreadcrumbRuntimeTest extends WebTestCase
{
private BreadcrumbRuntime $runtime;

protected function setUp(): void
{
parent::setUp();
$this->runtime = static::getContainer()->get(BreadcrumbRuntime::class);
}

public function testAppendBreadcrumb(): void
{
static::assertCount(0, $this->runtime->getBreadcrumbs());
$this->runtime->appendBreadcrumb('Home', '/');
static::assertCount(1, $this->runtime->getBreadcrumbs());
$this->runtime->appendBreadcrumb('About', '/about');
static::assertCount(2, $this->runtime->getBreadcrumbs());

$this->runtime->appendBreadcrumb('About', '/about');
static::assertCount(2, $this->runtime->getBreadcrumbs());
}

public function testGetBreadcrumbs(): void
{
static::assertIsArray($this->runtime->getBreadcrumbs());
}

public function testGetBreadcrumbParts(): void
{
$category = (new Category())
->setTitle('Category')
->setSlug('lorem')
;

$forum = (new Forum())
->setTitle('Forum')
->setSlug('forum')
->setCategory($category)
;

$categoryParts = $this->runtime->getBreadcrumbParts($category);
static::assertIsArray($categoryParts);
static::assertCount(1, $categoryParts);
static::assertArrayHasKey('url', $categoryParts[0]);
static::assertArrayHasKey('title', $categoryParts[0]);

$forumParts = $this->runtime->getBreadcrumbParts($forum);
static::assertIsArray($forumParts);
static::assertCount(2, $forumParts);
static::assertArrayHasKey('url', $forumParts[0]);
static::assertArrayHasKey('title', $forumParts[0]);
static::assertArrayHasKey('url', $forumParts[1]);
static::assertArrayHasKey('title', $forumParts[1]);
}
}
18 changes: 18 additions & 0 deletions tests/Unit/Twig/UserExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace App\Tests\Unit\Twig;

use App\Twig\UserExtension;
use PHPUnit\Framework\TestCase;
use Twig\TwigFunction;

class UserExtensionTest extends TestCase
{
public function testGetFunctions(): void
{
$functions = (new UserExtension())->getFunctions();
static::assertContainsOnlyInstancesOf(TwigFunction::class, $functions);
}
}

0 comments on commit 1ce544d

Please sign in to comment.