class TwigSandboxTest

Same name in other branches
  1. 9 core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php \Drupal\Tests\Core\Template\TwigSandboxTest
  2. 8.9.x core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php \Drupal\Tests\Core\Template\TwigSandboxTest
  3. 11.x core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php \Drupal\Tests\Core\Template\TwigSandboxTest

Tests the twig sandbox policy.

@group Template

@coversDefaultClass \Drupal\Core\Template\TwigSandboxPolicy

Hierarchy

Expanded class hierarchy of TwigSandboxTest

File

core/tests/Drupal/Tests/Core/Template/TwigSandboxTest.php, line 23

Namespace

Drupal\Tests\Core\Template
View source
class TwigSandboxTest extends UnitTestCase {
    
    /**
     * The Twig environment loaded with the sandbox extension.
     *
     * @var \Twig\Environment
     */
    protected $twig;
    
    /**
     * {@inheritdoc}
     */
    protected function setUp() : void {
        parent::setUp();
        $loader = new StringLoader();
        $this->twig = new Environment($loader);
        $policy = new TwigSandboxPolicy();
        $sandbox = new SandboxExtension($policy, TRUE);
        $this->twig
            ->addExtension($sandbox);
    }
    
    /**
     * Tests that dangerous methods cannot be called in entity objects.
     *
     * @dataProvider getTwigEntityDangerousMethods
     */
    public function testEntityDangerousMethods($template) : void {
        $entity = $this->createMock('Drupal\\Core\\Entity\\EntityInterface');
        $this->expectException(SecurityError::class);
        $this->twig
            ->render($template, [
            'entity' => $entity,
        ]);
    }
    
    /**
     * Data provider for ::testEntityDangerousMethods.
     *
     * @return array
     */
    public static function getTwigEntityDangerousMethods() {
        return [
            [
                '{{ entity.delete }}',
            ],
            [
                '{{ entity.save }}',
            ],
            [
                '{{ entity.create }}',
            ],
        ];
    }
    
    /**
     * Tests that white listed classes can be extended.
     */
    public function testExtendedClass() : void {
        $this->assertEquals(' class="kitten"', $this->twig
            ->render('{{ attribute.addClass("kitten") }}', [
            'attribute' => new TestAttribute(),
        ]));
    }
    
    /**
     * Tests that prefixed methods can be called from within Twig templates.
     *
     * Currently "get", "has", and "is" are the only allowed prefixes.
     */
    public function testEntitySafePrefixes() : void {
        $entity = $this->createMock('Drupal\\Core\\Entity\\EntityInterface');
        $entity->expects($this->atLeastOnce())
            ->method('hasLinkTemplate')
            ->with('test')
            ->willReturn(TRUE);
        $result = $this->twig
            ->render('{{ entity.hasLinkTemplate("test") }}', [
            'entity' => $entity,
        ]);
        $this->assertTrue((bool) $result, 'Sandbox policy allows has* functions to be called.');
        $entity = $this->createMock('Drupal\\Core\\Entity\\EntityInterface');
        $entity->expects($this->atLeastOnce())
            ->method('isNew')
            ->willReturn(TRUE);
        $result = $this->twig
            ->render('{{ entity.isNew }}', [
            'entity' => $entity,
        ]);
        $this->assertTrue((bool) $result, 'Sandbox policy allows is* functions to be called.');
        $entity = $this->createMock('Drupal\\Core\\Entity\\EntityInterface');
        $entity->expects($this->atLeastOnce())
            ->method('getEntityType')
            ->willReturn('test');
        $result = $this->twig
            ->render('{{ entity.getEntityType }}', [
            'entity' => $entity,
        ]);
        $this->assertEquals('test', $result, 'Sandbox policy allows get* functions to be called.');
    }
    
    /**
     * Tests that valid methods can be called from within Twig templates.
     *
     * Currently the following methods are whitelisted: id, label, bundle, and
     * get.
     */
    public function testEntitySafeMethods() : void {
        $entity = $this->getMockBuilder(ContentEntityBaseMockableClass::class)
            ->disableOriginalConstructor()
            ->getMock();
        $entity->expects($this->atLeastOnce())
            ->method('get')
            ->with('title')
            ->willReturn('test');
        $result = $this->twig
            ->render('{{ entity.get("title") }}', [
            'entity' => $entity,
        ]);
        $this->assertEquals('test', $result, 'Sandbox policy allows get() to be called.');
        $entity = $this->createMock('Drupal\\Core\\Entity\\EntityInterface');
        $entity->expects($this->atLeastOnce())
            ->method('id')
            ->willReturn('1234');
        $result = $this->twig
            ->render('{{ entity.id }}', [
            'entity' => $entity,
        ]);
        $this->assertEquals('1234', $result, 'Sandbox policy allows get() to be called.');
        $entity = $this->createMock('Drupal\\Core\\Entity\\EntityInterface');
        $entity->expects($this->atLeastOnce())
            ->method('label')
            ->willReturn('testing');
        $result = $this->twig
            ->render('{{ entity.label }}', [
            'entity' => $entity,
        ]);
        $this->assertEquals('testing', $result, 'Sandbox policy allows get() to be called.');
        $entity = $this->createMock('Drupal\\Core\\Entity\\EntityInterface');
        $entity->expects($this->atLeastOnce())
            ->method('bundle')
            ->willReturn('testing');
        $result = $this->twig
            ->render('{{ entity.bundle }}', [
            'entity' => $entity,
        ]);
        $this->assertEquals('testing', $result, 'Sandbox policy allows get() to be called.');
    }
    
    /**
     * Tests that safe methods inside Url objects can be called.
     */
    public function testUrlSafeMethods() : void {
        $url = $this->getMockBuilder('Drupal\\Core\\Url')
            ->disableOriginalConstructor()
            ->getMock();
        $url->expects($this->once())
            ->method('toString')
            ->willReturn('http://kittens.cat/are/cute');
        $result = $this->twig
            ->render('{{ url.toString }}', [
            'url' => $url,
        ]);
        $this->assertEquals('http://kittens.cat/are/cute', $result, 'Sandbox policy allows toString() to be called.');
    }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary Overriden Title Overrides
PhpUnitWarnings::$deprecationWarnings private static property Deprecation warnings from PHPUnit to raise with @trigger_error().
PhpUnitWarnings::addWarning public function Converts PHPUnit deprecation warnings to E_USER_DEPRECATED.
RandomGeneratorTrait::getRandomGenerator protected function Gets the random generator for the utility methods.
RandomGeneratorTrait::randomMachineName protected function Generates a unique random string containing letters and numbers.
RandomGeneratorTrait::randomObject public function Generates a random PHP object.
RandomGeneratorTrait::randomString public function Generates a pseudo-random string of ASCII characters of codes 32 to 126.
RandomGeneratorTrait::randomStringValidate Deprecated public function Callback for random string validation.
TwigSandboxTest::$twig protected property The Twig environment loaded with the sandbox extension.
TwigSandboxTest::getTwigEntityDangerousMethods public static function Data provider for ::testEntityDangerousMethods.
TwigSandboxTest::setUp protected function Overrides UnitTestCase::setUp
TwigSandboxTest::testEntityDangerousMethods public function Tests that dangerous methods cannot be called in entity objects.
TwigSandboxTest::testEntitySafeMethods public function Tests that valid methods can be called from within Twig templates.
TwigSandboxTest::testEntitySafePrefixes public function Tests that prefixed methods can be called from within Twig templates.
TwigSandboxTest::testExtendedClass public function Tests that white listed classes can be extended.
TwigSandboxTest::testUrlSafeMethods public function Tests that safe methods inside Url objects can be called.
UnitTestCase::$root protected property The app root. 1
UnitTestCase::getClassResolverStub protected function Returns a stub class resolver.
UnitTestCase::getConfigFactoryStub public function Returns a stub config factory that behaves according to the passed array.
UnitTestCase::getConfigStorageStub public function Returns a stub config storage that returns the supplied configuration.
UnitTestCase::getContainerWithCacheTagsInvalidator protected function Sets up a container with a cache tags invalidator.
UnitTestCase::getStringTranslationStub public function Returns a stub translation manager that just returns the passed string.
UnitTestCase::setUpBeforeClass public static function
UnitTestCase::__get public function

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.