Source of file ComponentTest.php
Size: 19,619 Bytes - Last Modified: 2021-12-23T10:58:18+00:00
/var/www/docs.ssmods.com/process/src/tests/ComponentTest.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680 | <?php namespace Symbiote\Components\Tests; use Exception; use SilverStripe\Core\Config\Config; use SilverStripe\Dev\SapphireTest; use SilverStripe\View\SSViewer; use SilverStripe\View\SSViewer_FromString; use SilverStripe\ORM\ArrayList; use SilverStripe\View\ArrayData; use SilverStripe\Forms\TextField; use SilverStripe\View\ViewableData; use SilverStripe\View\SSViewer_Scope; use SilverStripe\Core\Injector\Injector; use SilverStripe\View\SSTemplateParseException; use Symbiote\Components\ComponentService; use Symbiote\Components\ComponentReservedPropertyException; class ComponentTest extends SapphireTest { public function setUp() { parent::setUp(); SSViewer::config()->source_file_comments = false; //SSViewer_FromString::config()->cache_template = false; } public function tearDown() { parent::tearDown(); } public function testCustomizedComponentPath() { Config::modify()->set(ComponentService::class, 'component_paths', [ 'components/subfolder' ]); $service = Injector::inst()->get(ComponentService::class); $scope = new SSViewer_Scope(null); try { $resultHTML = $service->renderComponent('SubComponent', [], $scope); } catch (\Exception $e) { $this->assertTrue(strpos($e->getMessage(), "None of the following templates could be found") !== false); } $service->componentTemplatePaths = [ 'components/subfolder' ]; $resultHTML = $service->renderComponent('SubComponent', [], $scope); $expected = '<button class="subcomponent">Text</button>'; $this->assertEquals($expected, trim($resultHTML->getValue())); } /** * */ public function testSimpleCase() { $template = <<<SSTemplate <:MyComponentButton class="btn btn-secondary" > <span class="text"> No submission </span> </:MyComponentButton> SSTemplate; $resultHTML = SSViewer::fromString($template)->process(null); $expectedHTML = <<<HTML <button class="btn btn-secondary" type="button"> <span class="text"> No submission </span> </button> HTML; $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * Make sure that ' characters are escaped. */ public function testSingleQuoteCharacterIsEscaped() { $template = <<<SSTemplate <:MyComponentButton class="btn btn-secondary" type="Test's and Stuff" > <span class="text"> No submission's </span> </:MyComponentButton> SSTemplate; $resultHTML = SSViewer::fromString($template)->process(null); $expectedHTML = <<<HTML <button class="btn btn-secondary" type="Test's and Stuff"> <span class="text"> No submission's </span> </button> HTML; $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * Make sure that \ characters are escaped. */ public function testBackslashCharacterIsEscaped() { $template = <<<SSTemplate <:MyComponentButton class="btn btn-secondary" type="Test\'s and Stuff" > <span class="text"> No submission's </span> </:MyComponentButton> SSTemplate; $resultHTML = SSViewer::fromString($template)->process(null); $expectedHTML = <<<HTML <button class="btn btn-secondary" type="Test\'s and Stuff"> <span class="text"> No submission's </span> </button> HTML; $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * */ public function testPassingOptionalTypeProperty() { $template = <<<SSTemplate <:MyComponentButton class="btn btn-primary" type="submit" > <span class="text"> Submit me! </span> </:MyComponentButton> SSTemplate; $resultHTML = SSViewer::fromString($template)->process(null); $expectedHTML = <<<HTML <button class="btn btn-primary" type="submit"> <span class="text"> Submit me! </span> </button> HTML; $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } public function testSelfClosingSupport() { $template = <<<SSTemplate <:MyComponentButton class="btn btn-primary" type="submit" /> SSTemplate; $expectedHTML = <<<HTML <button class="btn btn-primary" type="submit"></button> HTML; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } public function testNewlineSupport() { $expectedHTML = <<<HTML <button class="btn btn-primary" type="submit"> <span class="text"> Submit me! </span> </button> HTML; $template = <<<SSTemplate <:MyComponentButton class="btn btn-primary" type="submit" > <span class="text"> Submit me! </span> </:MyComponentButton> SSTemplate; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); $template = <<<SSTemplate <:MyComponentButton class="btn btn-primary" type="submit" > <span class="text"> Submit me! </span> </:MyComponentButton> SSTemplate; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); $template = <<<SSTemplate <:MyComponentButton class="btn btn-primary" type="submit"> <span class="text"> Submit me! </span> </:MyComponentButton> SSTemplate; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } public function testIfStatement() { $template = <<<SSTemplate <:MyComponentButtonWithObjectCast class="btn btn-primary" type="submit" attributesHTML="<% if \$Field.getAttributesHTML("class","type") %>\$Field.getAttributesHTML("class","type")<% end_if %> data-test" /> SSTemplate; $expectedHTML = <<<HTML <button class="btn btn-primary" type="submit" name="Name" id="Name" data-test></button> HTML; $formField = new TextField("Name", "Name"); $resultHTML = SSViewer::fromString($template)->process( new ArrayData( array( 'Field' => $formField, ) ) ); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } public function testSSListSupport() { $list = new ArrayList(array( new ArrayData(array( 'Title' => 'Menu Item 1' )), new ArrayData(array( 'Title' => 'Menu Item 2' )) )); $template = <<<SSTemplate <div class="menu-container-count-\$MenuList.Count"> <:SSListComponent Items="\$MenuList" /> </div> SSTemplate; $expectedHTML = <<<HTML <div class="menu-container-count-2"> <ul class="menu menu-count-2"> <li class="menu-item menu-item-1"> Menu Item 1 </li> <li class="menu-item menu-item-2"> Menu Item 2 </li> </ul> </div> HTML; $formField = new TextField("Name", "Name"); $resultHTML = SSViewer::fromString($template)->process( new ArrayData( array( 'MenuList' => $list, ) ) ); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * Test to make sure anything that inherits ViewableData works * inside a template. * * Classes that subclass ViewableData include: * - ArrayData * - DataObject * - SiteTree * */ public function testViewableDataSupport() { /** * Stop PHPStan error as we're using this like "mixed" type. * * @var mixed $record */ $record = new ViewableData(); $record->Title = "ViewableData Title 1"; $template = <<<SSTemplate <:ViewableDataComponent MyRecord="\$MyRecord" /> <:ViewableDataComponent MyRecord="\$MyArrayData" /> SSTemplate; $expectedHTML = <<<HTML <li class="menu-item"> ViewableData Title 1 </li> <li class="menu-item"> ArrayData Title 2 </li> HTML; $formField = new TextField("Name", "Name"); $resultHTML = SSViewer::fromString($template)->process( new ArrayData( array( 'MyRecord' => $record, 'MyArrayData' => new ArrayData(array( 'Title' => 'ArrayData Title 2' )) ) ) ); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * This is to make sure that "double quoting" doesn't occur when passing "getAttributesHTML" * into a component, ie. Resulting HTML looks like: * * <button class="btn btn-secondary" type="button" name="Name" id="Name"></button>' */ public function testAvoidBadXMLEscaping() { $template = <<<SSTemplate <:MyComponentButtonWithObjectCast class="btn btn-primary" type="submit" attributesHTML="\$Field.getAttributesHTML("class","type")" /> <% with \$Field %> <:MyComponentButtonWithObjectCast class="btn btn-secondary" type="button" attributesHTML="\$getAttributesHTML("class","type")" /> <% end_with %> SSTemplate; $expectedHTML = <<<HTML <button class="btn btn-primary" type="submit" name="Name" id="Name"></button> <button class="btn btn-secondary" type="button" name="Name" id="Name"></button> HTML; $formField = new TextField("Name", "Name"); $resultHTML = SSViewer::fromString($template)->process( new ArrayData( array( 'Field' => $formField, ) ) ); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * If you don't pass a $class variable in, $class will end * up defaulting to 'Symbiote\Components\ComponentData' without * additional logic that prevents that (found in ComponentData class) * * This is most likely not necessary in SilverStripe 4.X, but it was * a necessary check in SilverStripe 3.X */ public function testComponentUsingClassButNotPassedIn() { $template = <<<SSTemplate <:ComponentUsingClassButNotPassedIn /> SSTemplate; $expectedHTML = <<<HTML <div class=""></div> HTML; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * If you don't pass a $class variable in, $class will end * up defaulting to 'Symbiote\Components\ComponentData' without * additional logic that prevents that (found in ComponentData class) * * This is most likely not necessary in SilverStripe 4.X, but it was * a necessary check in SilverStripe 3.X * */ public function testCatchReservedProperty() { $template = <<<SSTemplate <:EmptyComponent failover="This is reserved by Viewable Data!" /> SSTemplate; try { $resultHTML = SSViewer::fromString($template)->process(null); } catch (ComponentReservedPropertyException $e) { // Success path! $expectedMessage = 'You cannot use the property "failover" on "EmptyComponent" as it\'s already used by ViewableData.'; $this->assertEquals( $expectedMessage, $e->getMessage(), 'Unexpected exception message given. Was this changed? If so, please update the expected value above.' ); return; } catch (Exception $e) { $this->fail('Incorrect Exception caught. Expected '.ComponentReservedPropertyException::class.' to be thrown.'); return; } $this->fail('No exception thrown. Expected '.ComponentReservedPropertyException::class.' to be thrown.'); } /** * Test custom JSON syntax that allows arbitrary JSON. * */ public function testJSONProperty() { $template = <<<SSTemplate <:JSONSyntaxTest _json='{ "Cards": [ { "Title": "This is the first card", "Summary": "This is the first card summary", "Link": "https://link1.com" }, { "Title": "This is the second card", "Summary": "This is the second card summary", "Link": "https://link2.com" } ] }' /> SSTemplate; $expectedHTML = <<<HTML <div> <h2>This is the first card</h2> <p>This is the first card summary</p> <a href="https://link1.com">Read more</a> </div> <div> <h2>This is the second card</h2> <p>This is the second card summary</p> <a href="https://link2.com">Read more</a> </div> HTML; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } public function testJSONEscapedCharacters() { $template = <<<SSTemplate <:JSONSyntaxTest _json='{ "Cards": [ { "Title": "We are testing escaping single quote\'s" }, { "Title": "We are \"testing\" escaping double quotes" } ] }' /> SSTemplate; $expectedHTML = <<<HTML <div> <h2>We are testing escaping single quote's</h2> <p></p> <a href="">Read more</a> </div> <div> <h2>We are "testing" escaping double quotes</h2> <p></p> <a href="">Read more</a> </div> HTML; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * Test that the error message given when using JSON is useful when debugging. * */ public function testJSONPropertyErrorHandling() { $template = <<<SSTemplate <:JSONSyntaxTest _json='{ "Cards": [ { "Title": "This is the first card", "Summary": "This is the first card summary", "Link": "https://link1.com", }, { "Title": "This is the second card", "Summary": "This is the second card summary", "Link": "https://link2.com" } ] }' /> SSTemplate; try { SSViewer::fromString($template)->process(null); } catch (SSTemplateParseException $e) { // Success path! $expectedMessage = 'Parse error in template on line 16. Error was: JSON Syntax error, did you quote all the property names and remove trailing commas? I suggest running the following through a JSON validator online.'; $this->assertContains( $expectedMessage, $e->getMessage(), 'Unexpected exception message given. Was this changed? If so, please update the expected value above.' ); return; } catch (Exception $e) { $this->fail('Incorrect Exception caught. Expected '.SSTemplateParseException::class.' to be thrown.'); return; } } /** * Test iterating nested arrays in templates */ public function testJSONDeeplyNested() { $template = <<<SSTemplate <:JSONNestedTest _json='{ "NestedData": [ { "Title": "Item 1.1", "Children": [ { "Title": "Item 2.1" }, { "Title": "Item 2.2" }, { "Title": "item 2.3", "Children": [ { "Title": "Item 3.1" }, { "Title": "Item 3.2" } ] } ] }, { "Title": "Item 1.2" }, { "Title": "Item 1.3", "Children": [ { "Title": "Item 2.4", "Children": [ { "Title": "Item 3.3" }, { "Title": "Item 3.4" } ] }, { "Title": "Item 2.5" }, { "Title": "item 2.6" } ] } ] }' /> SSTemplate; $expectedHTML = <<<HTML <h2>Item 1.1</h2> <ul> <li> <h3>Item 2.1</h3> </li> <li> <h3>Item 2.2</h3> </li> <li> <h3>item 2.3</h3> <ul> <li> <h4>Item 3.1</h4> </li> <li> <h4>Item 3.2</h4> </li> </ul> </li> </ul> <h2>Item 1.2</h2> <h2>Item 1.3</h2> <ul> <li> <h3>Item 2.4</h3> <ul> <li> <h4>Item 3.3</h4> </li> <li> <h4>Item 3.4</h4> </li> </ul> </li> <li> <h3>Item 2.5</h3> </li> <li> <h3>item 2.6</h3> </li> </ul> HTML; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * Test iterating multiple root level properties in templates */ public function testJSONMultiRoot() { $template = <<<SSTemplate <:JSONRootTest _json='{ "Title": "Root Test", "Root1": [ {"Title": "one"}, {"Title": "two"} ], "Root2": [ {"Title": "three"}, {"Title": "four"} ] }' /> SSTemplate; $expectedHTML = <<<HTML <h1>Root Test</h1> <div> <h2>one</h2> <h2>two</h2> </div> <div> <h2>three</h2> <h2>four</h2> </div> HTML; $resultHTML = SSViewer::fromString($template)->process(null); $this->assertEqualIgnoringWhitespace($expectedHTML, $resultHTML, 'Unexpected output'); } /** * Taken from "framework\tests\view\SSViewerTest.php" */ protected function assertEqualIgnoringWhitespace($a, $b, $message = '') { $this->assertEquals(preg_replace('/\s+/', '', $a), preg_replace('/\s+/', '', $b), $message); } } |