View source
<?php
namespace Drupal\Tests\Core\Template;
use Drupal\Component\Utility\Html;
use Drupal\Core\Render\Markup;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Template\AttributeArray;
use Drupal\Core\Template\AttributeString;
use Drupal\Tests\UnitTestCase;
use Drupal\Component\Render\MarkupInterface;
class AttributeTest extends UnitTestCase {
public function testConstructor() {
$attribute = new Attribute(array(
'class' => array(
'example-class',
),
));
$this
->assertTrue(isset($attribute['class']));
$this
->assertEquals(new AttributeArray('class', array(
'example-class',
)), $attribute['class']);
$attribute = new Attribute([
'selected' => TRUE,
'checked' => FALSE,
]);
$this
->assertTrue($attribute['selected']
->value());
$this
->assertFalse($attribute['checked']
->value());
$attribute = new Attribute(array(
'class' => 'example-class',
));
$this
->assertTrue(isset($attribute['class']));
$this
->assertEquals(new AttributeArray('class', array(
'example-class',
)), $attribute['class']);
$safe_string = $this
->prophesize(MarkupInterface::class);
$safe_string
->__toString()
->willReturn('example-class');
$attribute = new Attribute(array(
'class' => $safe_string
->reveal(),
));
$this
->assertTrue(isset($attribute['class']));
$this
->assertEquals(new AttributeArray('class', array(
'example-class',
)), $attribute['class']);
}
public function testSet() {
$attribute = new Attribute();
$attribute['class'] = array(
'example-class',
);
$this
->assertTrue(isset($attribute['class']));
$this
->assertEquals(new AttributeArray('class', array(
'example-class',
)), $attribute['class']);
}
public function testAdd() {
$attribute = new Attribute(array(
'class' => array(
'example-class',
),
));
$attribute['class'][] = 'other-class';
$this
->assertEquals(new AttributeArray('class', array(
'example-class',
'other-class',
)), $attribute['class']);
}
public function testRemove() {
$attribute = new Attribute(array(
'class' => array(
'example-class',
),
));
unset($attribute['class']);
$this
->assertFalse(isset($attribute['class']));
}
public function testSetAttribute() {
$attribute = new Attribute();
$attributes = [
'alt',
'id',
'src',
'title',
'value',
];
foreach ($attributes as $key) {
foreach ([
'kitten',
'',
] as $value) {
$attribute = new Attribute();
$attribute
->setAttribute($key, $value);
$this
->assertEquals($value, $attribute[$key]);
}
}
$attribute = new Attribute();
$attribute
->setAttribute('class', [
'kitten',
'cat',
]);
$this
->assertArrayEquals([
'kitten',
'cat',
], $attribute['class']
->value());
$attribute = new Attribute();
$attribute['checked'] = TRUE;
$this
->assertTrue($attribute['checked']
->value());
}
public function testRemoveAttribute() {
$attributes = [
'alt' => 'Alternative text',
'id' => 'bunny',
'src' => 'zebra',
'style' => 'color: pink;',
'title' => 'kitten',
'value' => 'ostrich',
'checked' => TRUE,
];
$attribute = new Attribute($attributes);
$attribute
->removeAttribute('alt');
$this
->assertEmpty($attribute['alt']);
$attribute
->removeAttribute('id', 'src');
$this
->assertEmpty($attribute['id']);
$this
->assertEmpty($attribute['src']);
$attribute
->removeAttribute([
'style',
]);
$this
->assertEmpty($attribute['style']);
$attribute
->removeAttribute('checked');
$this
->assertEmpty($attribute['checked']);
$attribute
->removeAttribute([
'title',
'value',
]);
$this
->assertEmpty((string) $attribute);
}
public function testAddClasses() {
$attribute = new Attribute();
$attribute
->addClass();
$this
->assertEmpty($attribute['class']);
foreach (array(
NULL,
FALSE,
'',
[],
) as $value) {
$attribute
->addClass($value);
$this
->assertEmpty((string) $attribute);
$attribute
->addClass($value, $value);
$this
->assertEmpty((string) $attribute);
$attribute
->addClass([
$value,
]);
$this
->assertEmpty((string) $attribute);
$attribute
->addClass([
$value,
], [
$value,
]);
$this
->assertEmpty((string) $attribute);
}
$attribute
->addClass('banana');
$this
->assertArrayEquals(array(
'banana',
), $attribute['class']
->value());
$attribute
->addClass('aa');
$this
->assertArrayEquals(array(
'banana',
'aa',
), $attribute['class']
->value());
$attribute
->addClass('xx', 'yy');
$this
->assertArrayEquals(array(
'banana',
'aa',
'xx',
'yy',
), $attribute['class']
->value());
$attribute
->addClass(array(
'red',
'green',
'blue',
));
$this
->assertArrayEquals(array(
'banana',
'aa',
'xx',
'yy',
'red',
'green',
'blue',
), $attribute['class']
->value());
$attribute
->addClass(array(
'red',
'green',
'blue',
), array(
'aa',
'aa',
'banana',
), 'yy');
$this
->assertEquals('banana aa xx yy red green blue', (string) $attribute['class']);
}
public function testRemoveClasses() {
$classes = array(
'example-class',
'aa',
'xx',
'yy',
'red',
'green',
'blue',
'red',
);
$attribute = new Attribute(array(
'class' => $classes,
));
$attribute
->removeClass('example-class');
$this
->assertNotContains('example-class', $attribute['class']
->value());
$attribute
->removeClass('xx', 'yy');
$this
->assertNotContains(array(
'xx',
'yy',
), $attribute['class']
->value());
$attribute
->removeClass(array(
'red',
'green',
'blue',
));
$this
->assertNotContains(array(
'red',
'green',
'blue',
), $attribute['class']
->value());
$attribute
->removeClass('gg');
$this
->assertNotContains(array(
'gg',
), $attribute['class']
->value());
$this
->assertArrayEquals(array(
'aa',
), $attribute['class']
->value());
$attribute
->removeClass('aa');
$this
->assertEmpty((string) $attribute);
}
public function testHasClass() {
$attribute = new Attribute();
$this
->assertFalse($attribute
->hasClass('a-class-nowhere-to-be-found'));
$attribute
->addClass('we-totally-have-this-class');
$this
->assertTrue($attribute
->hasClass('we-totally-have-this-class'));
}
public function testChainAddRemoveClasses() {
$attribute = new Attribute(array(
'class' => array(
'example-class',
'red',
'green',
'blue',
),
));
$attribute
->removeClass(array(
'red',
'green',
'pink',
))
->addClass(array(
'apple',
'lime',
'grapefruit',
))
->addClass(array(
'banana',
));
$expected = array(
'example-class',
'blue',
'apple',
'lime',
'grapefruit',
'banana',
);
$this
->assertArrayEquals($expected, $attribute['class']
->value(), 'Attributes chained');
}
public function testTwigAddRemoveClasses($template, $expected, $seed_attributes = array()) {
$loader = new \Twig_Loader_String();
$twig = new \Twig_Environment($loader);
$data = array(
'attributes' => new Attribute($seed_attributes),
);
$result = $twig
->render($template, $data);
$this
->assertEquals($expected, $result);
}
public function providerTestAttributeClassHelpers() {
return array(
array(
"{{ attributes.class }}",
'',
),
array(
"{{ attributes.addClass('everest').class }}",
'everest',
),
array(
"{{ attributes.addClass(['k2', 'kangchenjunga']).class }}",
'k2 kangchenjunga',
),
array(
"{{ attributes.addClass('lhotse', 'makalu', 'cho-oyu').class }}",
'lhotse makalu cho-oyu',
),
array(
"{{ attributes.addClass('nanga-parbat').class }}",
'dhaulagiri manaslu nanga-parbat',
array(
'class' => array(
'dhaulagiri',
'manaslu',
),
),
),
array(
"{{ attributes.removeClass('annapurna').class }}",
'gasherbrum-i',
array(
'class' => array(
'annapurna',
'gasherbrum-i',
),
),
),
array(
"{{ attributes.removeClass(['broad peak']).class }}",
'gasherbrum-ii',
array(
'class' => array(
'broad peak',
'gasherbrum-ii',
),
),
),
array(
"{{ attributes.removeClass('gyachung-kang', 'shishapangma').class }}",
'',
array(
'class' => array(
'shishapangma',
'gyachung-kang',
),
),
),
array(
"{{ attributes.removeClass('nuptse').addClass('annapurna-ii').class }}",
'himalchuli annapurna-ii',
array(
'class' => array(
'himalchuli',
'nuptse',
),
),
),
array(
"{{ attributes.addClass('rakaposhi', '').class }}",
'rakaposhi',
),
);
}
public function testIterate() {
$attribute = new Attribute(array(
'class' => array(
'example-class',
),
'id' => 'example-id',
));
$counter = 0;
foreach ($attribute as $key => $value) {
if ($counter == 0) {
$this
->assertEquals('class', $key);
$this
->assertEquals(new AttributeArray('class', array(
'example-class',
)), $value);
}
if ($counter == 1) {
$this
->assertEquals('id', $key);
$this
->assertEquals(new AttributeString('id', 'example-id'), $value);
}
$counter++;
}
}
public function testPrint() {
$attribute = new Attribute(array(
'class' => array(
'example-class',
),
'id' => 'example-id',
'enabled' => TRUE,
));
$content = $this
->randomMachineName();
$html = '<div' . (string) $attribute . '>' . $content . '</div>';
$this
->assertClass('example-class', $html);
$this
->assertNoClass('example-class2', $html);
$this
->assertID('example-id', $html);
$this
->assertNoID('example-id2', $html);
$this
->assertTrue(strpos($html, 'enabled') !== FALSE);
}
public function testAttributeValues(array $attributes, $expected) {
$this
->assertEquals($expected, (new Attribute($attributes))
->__toString());
}
public function providerTestAttributeValues() {
$data = [];
$string = '"> <script>alert(123)</script>"';
$data['safe-object-xss1'] = [
[
'title' => Markup::create($string),
],
' title=""> alert(123)""',
];
$data['non-safe-object-xss1'] = [
[
'title' => $string,
],
' title="' . Html::escape($string) . '"',
];
$string = '"><script>alert(123)</script>';
$data['safe-object-xss2'] = [
[
'title' => Markup::create($string),
],
' title="">alert(123)"',
];
$data['non-safe-object-xss2'] = [
[
'title' => $string,
],
' title="' . Html::escape($string) . '"',
];
return $data;
}
protected function assertClass($class, $html) {
$xpath = "//*[@class='{$class}']";
self::assertTrue((bool) $this
->getXPathResultCount($xpath, $html));
}
protected function assertNoClass($class, $html) {
$xpath = "//*[@class='{$class}']";
self::assertFalse((bool) $this
->getXPathResultCount($xpath, $html));
}
protected function assertID($id, $html) {
$xpath = "//*[@id='{$id}']";
self::assertTrue((bool) $this
->getXPathResultCount($xpath, $html));
}
protected function assertNoID($id, $html) {
$xpath = "//*[@id='{$id}']";
self::assertFalse((bool) $this
->getXPathResultCount($xpath, $html));
}
protected function getXPathResultCount($query, $html) {
$document = new \DOMDocument();
$document
->loadHTML($html);
$xpath = new \DOMXPath($document);
return $xpath
->query($query)->length;
}
public function testStorage() {
$attribute = new Attribute(array(
'class' => array(
'example-class',
),
));
$this
->assertEquals(array(
'class' => new AttributeArray('class', array(
'example-class',
)),
), $attribute
->storage());
}
}