assertEquals(['mytheme', '$default'], SSViewer::get_themes()); // Ensure add_themes() prepends SSViewer::add_themes(['my_more_important_theme']); $this->assertEquals(['my_more_important_theme', 'mytheme', '$default'], SSViewer::get_themes()); // Ensure add_themes() on theme already in cascade promotes it to the top SSViewer::add_themes(['mytheme']); $this->assertEquals(['mytheme', 'my_more_important_theme', '$default'], SSViewer::get_themes()); } public function testRequirementsInjected() { Requirements::clear(); try { Requirements::customCSS('pretend this is real css'); $viewer = new SSViewer([], new DummyTemplateEngine()); $result1 = $viewer->process('pretend this is a model')->getValue(); // if we disable the requirements then we should get nothing $viewer->includeRequirements(false); $result2 = $viewer->process('pretend this is a model')->getValue(); } finally { Requirements::restore(); } $this->assertEqualIgnoringWhitespace( '
', $result1 ); $this->assertEqualIgnoringWhitespace( '', $result2 ); } public function testGetTemplatesByClass() { $this->useTestTheme( __DIR__ . '/SSViewerTest', 'layouttest', function () { // Test passing a string $templates = SSViewer::get_templates_by_class( SSViewerTestModelController::class, '', Controller::class ); $this->assertEquals( [ SSViewerTestModelController::class, [ 'type' => 'Includes', SSViewerTestModelController::class, ], SSViewerTestModel::class, Controller::class, [ 'type' => 'Includes', Controller::class, ], ], $templates ); // Test to ensure we're stopping at the base class. $templates = SSViewer::get_templates_by_class( SSViewerTestModelController::class, '', SSViewerTestModelController::class ); $this->assertEquals( [ SSViewerTestModelController::class, [ 'type' => 'Includes', SSViewerTestModelController::class, ], SSViewerTestModel::class, ], $templates ); // Make sure we can search templates by suffix. $templates = SSViewer::get_templates_by_class( SSViewerTestModel::class, 'Controller', DataObject::class ); $this->assertEquals( [ SSViewerTestModelController::class, [ 'type' => 'Includes', SSViewerTestModelController::class, ], DataObject::class . 'Controller', [ 'type' => 'Includes', DataObject::class . 'Controller', ], ], $templates ); // Let's throw something random in there. $this->expectException(\InvalidArgumentException::class); SSViewer::get_templates_by_class('no-class'); } ); } public function testRewriteHashlinks() { SSViewer::setRewriteHashLinksDefault(true); $oldServerVars = $_SERVER; try { $_SERVER['REQUEST_URI'] = '//file.com?foo"onclick="alert(\'xss\')""'; // Note that leading double slashes have been rewritten to prevent these being mis-interepreted // as protocol-less absolute urls $base = Convert::raw2att('/file.com?foo"onclick="alert(\'xss\')""'); $engine = new DummyTemplateEngine(); $engine->setOutput( '