1

I'm trying to write some WebTestCases for a simple blog integrated in our web application.

One of the test cases looks like the following:

public function testNewSubmitAction() 
{
    //load necessary data & login as admin
    $fixtureRepo = $this->loadFixtures([LoadUserData::class])->getReferenceRepository();

    $this->loadFixtures([LoadBlogData::class], null, 'doctrine_phpcr');
    $this->loginAs($customer = $fixtureRepo->getReference(LoadUserData::ADMIN_ACCOUNT), $this->getContainer()->getParameter('firewall.name'));

    $client = static::makeClient();

    $crawler = $client->request("GET", "/content/blog/new");

    $form = $crawler->selectButton('Erstellen')->form();

    $client->submit($form, [
        'blog[title]' => 'Testblog',
    ]);

    $this->assertTrue($client->getResponse()->isRedirect());
}

The LoadBlogData Class has a load method with this content:

public function load(ObjectManager $manager)
{
    parent::init($manager);
    NodeHelper::createPath($this->session, '/cms/routes/blog/de');
    NodeHelper::createPath($this->session, '/cms/routes/blog/fr');
    NodeHelper::createPath($this->session, '/cms/routes/blog/it');

    NodeHelper::createPath($this->session, '/cms/routes/categories/de');
    NodeHelper::createPath($this->session, '/cms/routes/categories/fr');
    NodeHelper::createPath($this->session, '/cms/routes/categories/it');

    NodeHelper::createPath($this->session, '/cms/pages/blog');

    NodeHelper::createPath($this->session, '/cms/content/blog');

    NodeHelper::createPath($this->session, '/cms/categories');

    $this->createBlog($manager);

    $manager->flush();
}

The createBlog Method should create a blog entry.

private function createBlog(ObjectManager $manager) 
{
    $blog = new Blog();
    $blog->setTitle('Test');
    $blog->setName('test');
    $blog->setCreatedAt(new \DateTime);
    $blog->setUpdatedAt(new \DateTime);
    $blog->setCreatedBy('Tester');
    $blog->setParentDocument($manager->find(null, '/cms/pages/blog'));

    $manager->persist($blog);
}

And this is where it fails. When running the test I get the error message "Register phpcr:managed node type first.".

Do you have an idea how to fix this?

I know I have to initialize PHPCR first. Could this be done while loading the fixtures?

Edit: I also tried loading this data using a custom initializer. But I get the same error.

2 Answers2

0

That sounds like you are missing a call to the command register-system-node-types to set up the repository you are using in the test. That command would register the type.

dbu
  • 1,497
  • 9
  • 8
  • Thank you for your feedback. I tried to call the init command before running the tests, but it caused some other errors. I use the Liip FunctionalTestBundle and a Sqlite Database for testing. Maybe this has something to do with how the bundle handles the Sqlite File (making copies of the file). – Ramon Rainer Mar 01 '18 at 08:45
  • this is how the cmf sandbox does it: https://github.com/symfony-cmf/cmf-sandbox/blob/d014fa81b0f502e5715c259841abb26958005b1c/.travis.yml#L39-L44 – dbu Mar 01 '18 at 13:05
-1

Found a possible solution. I register the phpcr:managed node type by myself in my initializer. Here's my full initializer class.

<?php

namespace ContentBundle\Initializer;


use Doctrine\Bundle\PHPCRBundle\Initializer\InitializerInterface;
use Doctrine\Bundle\PHPCRBundle\ManagerRegistry;
use PHPCR\Util\NodeHelper;
use Doctrine\ODM\PHPCR\Translation\Translation;

class BlogInitializer implements InitializerInterface
{
    private $basePath;

    private $phpcrNamespace = 'phpcr';
    private $phpcrNamespaceUri = 'http://www.doctrine-project.org/projects/phpcr_odm';
    private $localeNamespace = Translation::LOCALE_NAMESPACE;
    private $localeNamespaceUri = Translation::LOCALE_NAMESPACE_URI;

    /**
     * BlogInitializer constructor.
     * @param string $basePath
     */
    public function __construct($basePath = '/cms/pages/blog')
    {
        $this->basePath = $basePath;
    }

    /**
     * @param ManagerRegistry $registry
     */
    public function init(ManagerRegistry $registry)
    {
        $dm = $registry->getManager();
        if ($dm->find(null, $this->basePath)) {
            return;
        }

        // register phpcr:managed node type
        $cnd = <<<CND
// register phpcr_locale namespace
<$this->localeNamespace='$this->localeNamespaceUri'>
// register phpcr namespace
<$this->phpcrNamespace='$this->phpcrNamespaceUri'>
[phpcr:managed]
mixin
- phpcr:class (STRING)
- phpcr:classparents (STRING) multiple
CND
        ;
        $session = $registry->getConnection();
        $ntm = $session->getWorkspace()->getNodeTypeManager();
        $ntm->registerNodeTypesCnd($cnd, true);

        // create basic paths in repository
        NodeHelper::createPath($session, '/cms/routes/blog/de');
        NodeHelper::createPath($session, '/cms/routes/blog/fr');
        NodeHelper::createPath($session, '/cms/routes/blog/it');

        NodeHelper::createPath($session, '/cms/routes/categories/de');
        NodeHelper::createPath($session, '/cms/routes/categories/fr');
        NodeHelper::createPath($session, '/cms/routes/categories/it');

        NodeHelper::createPath($session, '/cms/pages/blog');

        NodeHelper::createPath($session, '/cms/content/blog');

        NodeHelper::createPath($session, '/cms/categories');

        $session->save();
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'Blog Initializer';
    }
}
  • while this will work, it seems wrong to have to do that like this. there is a command for doing this – dbu Feb 27 '18 at 10:30