Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor fixes and cleanup for taxonomies #260

Merged
merged 10 commits into from Jan 16, 2019
4 changes: 2 additions & 2 deletions phpunit.xml.dist
Expand Up @@ -9,15 +9,15 @@
>
<php>
<ini name="error_reporting" value="-1" />
<env name="KERNEL_CLASS" value="App\Kernel" />
<env name="KERNEL_CLASS" value="Bolt\Kernel" />
<env name="APP_ENV" value="test"/>
<env name="APP_DEBUG" value="1"/>
<env name="APP_SECRET" value="5a79a1c866efef9ca1800f971d689f3e"/>
<env name="SYMFONY_PHPUNIT_VERSION" value="7.1"/>
<!-- define your env variables for the test env here -->

<!-- ###+ doctrine/doctrine-bundle ### -->
<env name="DATABASE_URL" value="sqlite:///var/data/blog_test.sqlite"/>
<env name="DATABASE_URL" value="sqlite:///%kernel.project_dir%/var/data/bolt.sqlite"/>
<!-- ###- doctrine/doctrine-bundle ### -->

<!-- ###+ symfony/swiftmailer-bundle ### -->
Expand Down
9 changes: 8 additions & 1 deletion src/Configuration/Parser/TaxonomyParser.php
Expand Up @@ -40,7 +40,14 @@ public function parse(): Collection
$taxonomy['allow_spaces'] = false;
}
if (! isset($taxonomy['allow_empty'])) {
$taxonomy['allow_empty'] = false;
$taxonomy['allow_empty'] = true;
}
if ($taxonomy['behaves_like'] === 'grouping') {
$taxonomy['multiple'] = false;
} elseif ($taxonomy['behaves_like'] === 'tags' || (isset($taxonomy['multiple']) && $taxonomy['multiple'])) {
$taxonomy['multiple'] = true;
} else {
$taxonomy['multiple'] = false;
}

// Make sure the options are $key => $value pairs, and not have implied integers for keys.
Expand Down
12 changes: 6 additions & 6 deletions src/DataFixtures/TaxonomyFixtures.php
Expand Up @@ -46,16 +46,16 @@ private function loadTaxonomies(ObjectManager $manager): void
}

foreach ($options as $key => $value) {
$taxonomy = new Taxonomy();

if (is_numeric($key)) {
$key = $value;
}

$taxonomy->setType($taxonomyDefinition['slug'])
->setSlug(Str::slug($key))
->setName(Str::humanize($value))
->setSortorder($taxonomyDefinition['has_sortorder'] ? $order++ : 0);
$taxonomy = Taxonomy::factory(
$taxonomyDefinition['slug'],
$key,
$value,
$taxonomyDefinition['has_sortorder'] ? $order++ : 0
);

$manager->persist($taxonomy);
$reference = 'taxonomy_' . $taxonomyDefinition['slug'] . '_' . Str::slug($key);
Expand Down
7 changes: 4 additions & 3 deletions src/Entity/Taxonomy.php
Expand Up @@ -69,13 +69,14 @@ public function __construct()
/**
* @return Taxonomy
*/
public static function factory(string $type, string $slug, ?string $name = null): self
public static function factory(string $type, string $slug, ?string $name = null, int $sortorder = 0): self
{
$taxonomy = new self();

$taxonomy->setType($type);
$taxonomy->setSlug($slug);
$taxonomy->setName($name ?: Str::humanize($slug));
$taxonomy->setName($name ?: $slug);
$taxonomy->setSortorder($sortorder);

return $taxonomy;
}
Expand Down Expand Up @@ -130,7 +131,7 @@ public function getSlug(): ?string

public function setSlug(string $slug): self
{
$this->slug = $slug;
$this->slug = Str::slug($slug);

return $this;
}
Expand Down
8 changes: 0 additions & 8 deletions src/Twig/ContentHelperExtension.php
Expand Up @@ -156,14 +156,6 @@ public function taxonomyoptions($taxonomy): \Tightenco\Collect\Support\Collectio
$options[] = [
'key' => $key,
'value' => $value,
'selected' => false, // TODO: determine if we need this.
];
}

if ($taxonomy['allow_empty']) {
$options[] = [
'key' => '',
'value' => '(none selected)',
];
}

Expand Down
47 changes: 18 additions & 29 deletions templates/content/_taxonomies.html.twig
Expand Up @@ -7,35 +7,24 @@
{% set options = taxonomyoptions(definition) %}
{% set value = taxonomyvalues(record.taxonomies, definition) %}

{% if definition.behaves_like == 'grouping' %}
{% set multiple = 'false' %}
{% set taggable = 'false' %}
{% elseif definition.behaves_like == 'categories' %}
{% set multiple = definition.multiple ? 'true' : 'false' %}
{% set taggable = 'false' %}
{% else %} {# so, 'tags' #}
{% set multiple = 'true' %}
{% set taggable = 'true' %}
{% endif %}

<div class="form-group editor--group is-normal">
<label for="field-title">
{{ definition.name }}:
</label>
<div>
<editor-select
:value="{{ value|json_encode() }}"
:name="'taxonomy[{{ definition.slug }}]'"
:id="'taxonomy-{{ definition.slug }}'"
:options="{{ options|json_encode() }}"
:multiple="{{ multiple }}"
:taggable="{{ taggable }}"
></editor-select>

(Current saved value: <code>{{ value|json_encode() }}</code> )
</div>

</div>
<div class="form-group editor--group is-normal">
<label for="field-title">
{{ definition.name }}:
</label>
<div>
<editor-select
:value="{{ value|json_encode() }}"
:name="'taxonomy[{{ definition.slug }}]'"
:id="'taxonomy-{{ definition.slug }}'"
:options="{{ options|json_encode() }}"
:multiple="{{ definition.multiple ? 'true' : 'false' }}"
:taggable="{{ (definition.behaves_like == 'tags') ? 'true' : 'false' }}"
></editor-select>

{# (Current saved value: <code>{{ value|json_encode() }}</code> ) #}
</div>

</div>

{% endif %}

Expand Down
70 changes: 70 additions & 0 deletions tests/php/Entity/TaxonomyTest.php
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

namespace Bolt\Tests\Entity;

use Bolt\Entity\Taxonomy;

class TaxonomyTest extends \PHPUnit\Framework\TestCase
{
public function testFactory(): void
{
$taxonomy = Taxonomy::factory('foo', 'bar', 'Bar');

$this->assertSame('foo', $taxonomy->getType());
$this->assertSame('bar', $taxonomy->getSlug());
$this->assertSame('Bar', $taxonomy->getName());
}

public function testFactoryWithSortOrder(): void
{
$taxonomy = Taxonomy::factory('foo', 'Bår', 'Pømpidöm', 1000);

$this->assertSame('foo', $taxonomy->getType());
$this->assertSame('baar', $taxonomy->getSlug());
$this->assertSame('Pømpidöm', $taxonomy->getName());
$this->assertSame(1000, $taxonomy->getSortorder());
}

public function testFactoryWithMinimalParameters(): void
{
$taxonomy = Taxonomy::factory('foo', 'Døøp');

$this->assertSame('foo', $taxonomy->getType());
$this->assertSame('doeoep', $taxonomy->getSlug());
$this->assertSame('Døøp', $taxonomy->getName());
$this->assertSame(0, $taxonomy->getSortorder());
}

public function testSetSlug(): void
{
$taxonomy = Taxonomy::factory('foo', 'bar', 'baz');

$taxonomy->setSlug('Qüx');

$this->assertSame('quex', $taxonomy->getSlug());
}

public function testSetName(): void
{
$taxonomy = Taxonomy::factory('foo', 'bar', 'baz');

$taxonomy->setName('Føø');

$this->assertSame('Føø', $taxonomy->getName());

$taxonomy->setName('bar');
bobdenotter marked this conversation as resolved.
Show resolved Hide resolved

$this->assertSame('bar', $taxonomy->getName());
}

public function testSetSortorder(): void
{
$taxonomy = Taxonomy::factory('foo', 'bar', 'baz', 1000);

$taxonomy->setSortorder(10);

$this->assertSame(10, $taxonomy->getSortorder());
}
}
92 changes: 92 additions & 0 deletions tests/php/Repository/TaxonomyRepositoryTest.php
@@ -0,0 +1,92 @@
<?php

declare(strict_types=1);

namespace Bolt\Tests\Repository;

use Bolt\Entity\Taxonomy;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
* Class TaxonomyRepositoryTest
*
* @todo Add represenative tests here, when methods are implemented in TaxonomyRepository
*/
class TaxonomyRepositoryTest extends KernelTestCase
bobdenotter marked this conversation as resolved.
Show resolved Hide resolved
{
/** @var \Doctrine\ORM\EntityManager */
private $entityManager;

/**
* {@inheritdoc}
*/
protected function setUp(): void
{
$kernel = self::bootKernel();

$this->entityManager = $kernel->getContainer()
->get('doctrine')
->getManager();
}

public function testSearchByType(): void
{
$taxonomies = $this->entityManager
->getRepository(Taxonomy::class)
->findBy(['type' => 'groups']);

$this->assertCount(3, $taxonomies);
}

public function testSearchBySlug(): void
{
$taxonomies = $this->entityManager
->getRepository(Taxonomy::class)
->findBy(['slug' => 'zombies']);

$this->assertCount(1, $taxonomies);
}

public function testSearchByName(): void
{
$taxonomies = $this->entityManager
->getRepository(Taxonomy::class)
->findBy(['name' => 'Movies']);

$this->assertCount(1, $taxonomies);
}

public function testPersistEntity(): void
{
$taxonomy = Taxonomy::factory('foo', 'bar');

$this->entityManager->persist($taxonomy);
$this->entityManager->flush();

$taxonomies = $this->entityManager
->getRepository(Taxonomy::class)
->findBy(['type' => 'foo']);

$this->assertCount(1, $taxonomies);

$this->entityManager->remove($taxonomy);
$this->entityManager->flush();

$taxonomies = $this->entityManager
->getRepository(Taxonomy::class)
->findBy(['type' => 'foo']);

$this->assertCount(0, $taxonomies);
}

/**
* {@inheritdoc}
*/
protected function tearDown(): void
{
parent::tearDown();

$this->entityManager->close();
$this->entityManager = null; // avoid memory leaks
}
}
25 changes: 14 additions & 11 deletions tests/php/Security/LoginFormAuthenticatorTest.php
Expand Up @@ -17,9 +17,12 @@

class LoginFormAuthenticatorTest extends TestCase
{
const TEST_TOKEN = ['csrf_token' => null, 'username' => null];
public const TEST_TOKEN = [
'csrf_token' => null,
'username' => null,
];

function test_get_login_url()
public function testGetLoginUrl(): void
{
$router = $this->createMock(RouterInterface::class);
$router->expects($this->once())
Expand All @@ -28,39 +31,39 @@ function test_get_login_url()
->willReturn('test_route');

$res = $this->getTestObj(null, $router, null, null)->start($this->createMock(Request::class));
$this->assertEquals('test_route', $res->getTargetUrl());
$this->assertSame('test_route', $res->getTargetUrl());
}

function test_get_user()
public function testGetUser(): void
{
$userRepository = $this->createConfiguredMock(UserRepository::class, [
'findOneBy' => $this->createMock(User::class)
'findOneBy' => $this->createMock(User::class),
]);
$csrfTokenManager = $this->createConfiguredMock(CsrfTokenManagerInterface::class, [
'isTokenValid' => true
'isTokenValid' => true,
]);

$res = $this->getTestObj($userRepository, null, $csrfTokenManager, null)->getUser(self::TEST_TOKEN, $this->createMock(UserProviderInterface::class));
$this->assertInstanceOf(User::class, $res);
}

function test_get_user_throws()
public function testGetUserThrows(): void
{
$csrfTokenManager = $this->createConfiguredMock(CsrfTokenManagerInterface::class, [
'isTokenValid' => false
'isTokenValid' => false,
]);

$this->expectException(InvalidCsrfTokenException::class);
$this->getTestObj(null, null, $csrfTokenManager, null)->getUser(self::TEST_TOKEN, $this->createMock(UserProviderInterface::class));
}

private function getTestObj(?UserRepository $userRepository, ?RouterInterface $router, ?CsrfTokenManagerInterface $csrfTokenManager, ?UserPasswordEncoderInterface $userPasswordEncoder): LoginFormAuthenticator
{
return new LoginFormAuthenticator(
$userRepository ?? $this->createMock(UserRepository::class),
$router ?? $this->createMock(RouterInterface::class),
$router ?? $this->createMock(RouterInterface::class),
$csrfTokenManager ?? $this->createMock(CsrfTokenManagerInterface::class),
$userPasswordEncoder ?? $this->createMock(UserPasswordEncoderInterface::class)
);
}
}
}