Source of file SiteTreeSubsitesTest.php
Size: 19,003 Bytes - Last Modified: 2021-12-23T10:35:18+00:00
/var/www/docs.ssmods.com/process/src/tests/php/SiteTreeSubsitesTest.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 | <?php namespace SilverStripe\Subsites\Tests; use Page; use SilverStripe\CMS\Controllers\CMSMain; use SilverStripe\CMS\Controllers\ModelAsController; use SilverStripe\CMS\Forms\SiteTreeURLSegmentField; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\Control\Director; use SilverStripe\Core\Config\Config; use SilverStripe\Core\Convert; use SilverStripe\Core\Injector\Injector; use SilverStripe\ErrorPage\ErrorPage; use SilverStripe\Forms\FieldList; use SilverStripe\Security\Member; use SilverStripe\SiteConfig\SiteConfig; use SilverStripe\Subsites\Extensions\SiteTreeSubsites; use SilverStripe\Subsites\Model\Subsite; use SilverStripe\Subsites\Pages\SubsitesVirtualPage; use SilverStripe\Subsites\Service\ThemeResolver; use SilverStripe\Subsites\Tests\SiteTreeSubsitesTest\TestClassA; use SilverStripe\Subsites\Tests\SiteTreeSubsitesTest\TestClassB; use SilverStripe\Subsites\Tests\SiteTreeSubsitesTest\TestErrorPage; use SilverStripe\Versioned\Versioned; use SilverStripe\View\SSViewer; use TractorCow\Fluent\Extension\FluentSiteTreeExtension; class SiteTreeSubsitesTest extends BaseSubsiteTest { protected static $fixture_file = 'SubsiteTest.yml'; protected static $extra_dataobjects = [ TestClassA::class, TestClassB::class, TestErrorPage::class ]; protected static $illegal_extensions = [ SiteTree::class => [ FluentSiteTreeExtension::class, ], ]; protected function setUp(): void { // We have our own home page fixtures, prevent the default one being created in this test suite. Config::modify()->set(SiteTree::class, 'create_default_pages', false); parent::setUp(); } public function testPagesInDifferentSubsitesCanShareURLSegment() { $subsiteMain = $this->objFromFixture(Subsite::class, 'main'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $pageMain = new SiteTree(); $pageMain->URLSegment = 'testpage'; $pageMain->write(); $pageMain->copyVersionToStage('Stage', 'Live'); $pageMainOther = new SiteTree(); $pageMainOther->URLSegment = 'testpage'; $pageMainOther->write(); $pageMainOther->copyVersionToStage('Stage', 'Live'); $this->assertNotEquals( $pageMain->URLSegment, $pageMainOther->URLSegment, 'Pages in same subsite cant share the same URL' ); Subsite::changeSubsite($subsite1->ID); $pageSubsite1 = new SiteTree(); $pageSubsite1->URLSegment = 'testpage'; $pageSubsite1->write(); $pageSubsite1->copyVersionToStage('Stage', 'Live'); $this->assertEquals( $pageMain->URLSegment, $pageSubsite1->URLSegment, 'Pages in different subsites can share the same URL' ); } public function testBasicSanity() { $this->assertInstanceOf(SiteConfig::class, singleton(SiteTree::class)->getSiteConfig()); // The following assert is breaking in Translatable. $this->assertInstanceOf(FieldList::class, singleton(SiteTree::class)->getCMSFields()); $this->assertInstanceOf(FieldList::class, singleton(SubsitesVirtualPage::class)->getCMSFields()); $this->assertTrue(is_array(singleton(SiteTreeSubsites::class)->extraStatics())); } public function errorPageLocationsProvider() { return [ ['domaintest1', '/error-500-one.example.org.html'], ['domaintestVagrant', '/error-500-localhost8080.html'] ]; } /** * @dataProvider errorPageLocationsProvider */ public function testErrorPageLocations($subsiteFixtureName, $expectedFilename) { $static_path = Config::inst()->get(ErrorPage::class, 'static_filepath'); $subsite = $this->objFromFixture(Subsite::class, $subsiteFixtureName); $expected_path = $static_path . $expectedFilename; Subsite::changeSubsite($subsite->ID); $path = TestErrorPage::get_error_filename_spy(500); $this->assertEquals($expected_path, $path); } public function testCanEditSiteTree() { $admin = $this->objFromFixture(Member::class, 'admin'); $subsite1member = $this->objFromFixture(Member::class, 'subsite1member'); $subsite2member = $this->objFromFixture(Member::class, 'subsite2member'); $mainpage = $this->objFromFixture('Page', 'home'); $subsite1page = $this->objFromFixture('Page', 'subsite1_home'); $subsite2page = $this->objFromFixture('Page', 'subsite2_home'); $subsite1 = $this->objFromFixture(Subsite::class, 'subsite1'); $subsite2 = $this->objFromFixture(Subsite::class, 'subsite2'); // Cant pass member as arguments to canEdit() because of GroupSubsites $this->logInAs($admin); $this->assertTrue( (bool)$subsite1page->canEdit(), 'Administrators can edit all subsites' ); // @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state Subsite::changeSubsite($subsite1); $this->logInAs($subsite1member->ID); $this->assertTrue( (bool)$subsite1page->canEdit(), 'Members can edit pages on a subsite if they are in a group belonging to this subsite' ); $this->logInAs($subsite2member->ID); $this->assertFalse( (bool)$subsite1page->canEdit(), 'Members cant edit pages on a subsite if they are not in a group belonging to this subsite' ); // @todo: Workaround because GroupSubsites->augmentSQL() is relying on session state Subsite::changeSubsite(0); $this->assertFalse( $mainpage->canEdit(), 'Members cant edit pages on the main site if they are not in a group allowing this' ); } /** * Similar to {@link SubsitesVirtualPageTest->testSubsiteVirtualPageCanHaveSameUrlsegmentAsOtherSubsite()}. */ public function testTwoPagesWithSameURLOnDifferentSubsites() { // Set up a couple of pages with the same URL on different subsites $s1 = $this->objFromFixture(Subsite::class, 'domaintest1'); $s2 = $this->objFromFixture(Subsite::class, 'domaintest2'); $p1 = new SiteTree(); $p1->Title = $p1->URLSegment = 'test-page'; $p1->SubsiteID = $s1->ID; $p1->write(); $p2 = new SiteTree(); $p2->Title = $p1->URLSegment = 'test-page'; $p2->SubsiteID = $s2->ID; $p2->write(); // Check that the URLs weren't modified in our set-up $this->assertEquals('test-page', $p1->URLSegment); $this->assertEquals('test-page', $p2->URLSegment); // Check that if we switch between the different subsites, we receive the correct pages Subsite::changeSubsite($s1); $this->assertEquals($p1->ID, SiteTree::get_by_link('test-page')->ID); Subsite::changeSubsite($s2); $this->assertEquals($p2->ID, SiteTree::get_by_link('test-page')->ID); } public function testPageTypesBlacklistInClassDropdown() { $this->logInAs('editor'); $s1 = $this->objFromFixture(Subsite::class, 'domaintest1'); $s2 = $this->objFromFixture(Subsite::class, 'domaintest2'); $page = singleton(SiteTree::class); $s1->PageTypeBlacklist = json_encode([TestClassA::class, ErrorPage::class]); $s1->write(); Subsite::changeSubsite($s1); $settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource(); $this->assertArrayNotHasKey( ErrorPage::class, $settingsFields ); $this->assertArrayNotHasKey( TestClassA::class, $settingsFields ); $this->assertArrayHasKey( TestClassB::class, $settingsFields ); Subsite::changeSubsite($s2); $settingsFields = $page->getSettingsFields()->dataFieldByName('ClassName')->getSource(); $this->assertArrayHasKey( ErrorPage::class, $settingsFields ); $this->assertArrayHasKey( TestClassA::class, $settingsFields ); $this->assertArrayHasKey( TestClassB::class, $settingsFields ); } public function testCopyToSubsite() { // Remove baseurl if testing in subdir Config::modify()->set(Director::class, 'alternate_base_url', '/'); /** @var Subsite $otherSubsite */ $otherSubsite = $this->objFromFixture(Subsite::class, 'subsite1'); $staffPage = $this->objFromFixture(Page::class, 'staff'); // nested page $contactPage = $this->objFromFixture(Page::class, 'contact'); // top level page $staffPage2 = $staffPage->duplicateToSubsite($otherSubsite->ID); $contactPage2 = $contactPage->duplicateToSubsite($otherSubsite->ID); $this->assertNotEquals($staffPage->ID, $staffPage2->ID); $this->assertNotEquals($staffPage->SubsiteID, $staffPage2->SubsiteID); $this->assertNotEquals($contactPage->ID, $contactPage2->ID); $this->assertNotEquals($contactPage->SubsiteID, $contactPage2->SubsiteID); $this->assertEmpty($staffPage2->ParentID); $this->assertEmpty($contactPage2->ParentID); $this->assertNotEmpty($staffPage->ParentID); $this->assertEmpty($contactPage->ParentID); // Staff is shifted to top level and given a unique url segment $domain = $otherSubsite->domain(); $this->assertEquals('http://' . $domain . '/staff-2/', $staffPage2->AbsoluteLink()); $this->assertEquals('http://' . $domain . '/contact-us-2/', $contactPage2->AbsoluteLink()); } public function testPageTypesBlacklistInCMSMain() { $this->logInAs('editor'); $s1 = $this->objFromFixture(Subsite::class, 'domaintest1'); $s2 = $this->objFromFixture(Subsite::class, 'domaintest2'); $s1->PageTypeBlacklist = json_encode([TestClassA::class, ErrorPage::class]); $s1->write(); Subsite::changeSubsite($s1); $cmsmain = CMSMain::create(); $hints = json_decode($cmsmain->SiteTreeHints(), true); $classes = $hints['Root']['disallowedChildren']; $this->assertContains(ErrorPage::class, $classes); $this->assertContains(TestClassA::class, $classes); $this->assertNotContains(TestClassB::class, $classes); Subsite::changeSubsite($s2); // SS 4.1 and above if ($cmsmain->hasMethod('getHintsCache')) { $cmsmain->getHintsCache()->clear(); } $hints = json_decode($cmsmain->SiteTreeHints(), true); $classes = $hints['Root']['disallowedChildren']; $this->assertNotContains(ErrorPage::class, $classes); $this->assertNotContains(TestClassA::class, $classes); $this->assertNotContains(TestClassB::class, $classes); } /** * Tests that url segments between subsites don't conflict, but do conflict within them */ public function testValidateURLSegment() { $this->logInWithPermission('ADMIN'); // Saving existing page in the same subsite doesn't change urls $mainHome = $this->objFromFixture(Page::class, 'home'); $mainSubsiteID = $this->idFromFixture(Subsite::class, 'main'); Subsite::changeSubsite($mainSubsiteID); $mainHome->Content = '<p>Some new content</p>'; $mainHome->write(); $this->assertEquals('home', $mainHome->URLSegment); $mainHome->publishRecursive(); $mainHomeLive = Versioned::get_one_by_stage('Page', 'Live', sprintf('"SiteTree"."ID" = \'%d\'', $mainHome->ID)); $this->assertEquals('home', $mainHomeLive->URLSegment); // Saving existing page in another subsite doesn't change urls Subsite::changeSubsite($mainSubsiteID); $subsite1Home = $this->objFromFixture('Page', 'subsite1_home'); $subsite1Home->Content = '<p>In subsite 1</p>'; $subsite1Home->write(); $this->assertEquals('home', $subsite1Home->URLSegment); $subsite1Home->publishRecursive(); $subsite1HomeLive = Versioned::get_one_by_stage( 'Page', 'Live', sprintf('"SiteTree"."ID" = \'%d\'', $subsite1Home->ID) ); $this->assertEquals('home', $subsite1HomeLive->URLSegment); // Creating a new page in a subsite doesn't conflict with urls in other subsites $subsite1ID = $this->idFromFixture(Subsite::class, 'subsite1'); Subsite::changeSubsite($subsite1ID); $subsite1NewPage = new Page(); $subsite1NewPage->SubsiteID = $subsite1ID; $subsite1NewPage->Title = 'Important Page (Subsite 1)'; $subsite1NewPage->URLSegment = 'important-page'; // Also exists in main subsite $subsite1NewPage->write(); $this->assertEquals('important-page', $subsite1NewPage->URLSegment); $subsite1NewPage->publishRecursive(); $subsite1NewPageLive = Versioned::get_one_by_stage( 'Page', 'Live', sprintf('"SiteTree"."ID" = \'%d\'', $subsite1NewPage->ID) ); $this->assertEquals('important-page', $subsite1NewPageLive->URLSegment); // Creating a new page in a subsite DOES conflict with urls in the same subsite $subsite1NewPage2 = new Page(); $subsite1NewPage2->SubsiteID = $subsite1ID; $subsite1NewPage2->Title = 'Important Page (Subsite 1)'; $subsite1NewPage2->URLSegment = 'important-page'; // Also exists in main subsite $subsite1NewPage2->write(); $this->assertEquals('important-page-2', $subsite1NewPage2->URLSegment); $subsite1NewPage2->publishRecursive(); $subsite1NewPage2Live = Versioned::get_one_by_stage( 'Page', 'Live', sprintf('"SiteTree"."ID" = \'%d\'', $subsite1NewPage2->ID) ); $this->assertEquals('important-page-2', $subsite1NewPage2Live->URLSegment); // Original page is left un-modified $mainSubsiteImportantPageID = $this->idFromFixture('Page', 'importantpage'); $mainSubsiteImportantPage = Page::get()->byID($mainSubsiteImportantPageID); $this->assertEquals('important-page', $mainSubsiteImportantPage->URLSegment); $mainSubsiteImportantPage->Content = '<p>New Important Page Content</p>'; $mainSubsiteImportantPage->write(); $this->assertEquals('important-page', $mainSubsiteImportantPage->URLSegment); } /** * @param bool $withChildren * @param int $expectedChildren * @dataProvider duplicateToSubsiteProvider */ public function testDuplicateToSubsite($withChildren, $expectedChildren) { /** @var SiteTree $page */ $page = $this->objFromFixture(Page::class, 'about'); /** @var Subsite $newSubsite */ $newSubsite = $this->objFromFixture(Subsite::class, 'subsite1'); /** @var SiteTree $duplicatedPage */ $duplicatedPage = $page->duplicateToSubsite($newSubsite->ID, $withChildren); $this->assertInstanceOf(SiteTree::class, $duplicatedPage, 'A new page is returned'); $this->assertEquals($newSubsite->ID, $duplicatedPage->SubsiteID, 'Ensure returned records are on new subsite'); $this->assertCount(1, $page->AllChildren()); $this->assertCount( $expectedChildren, $duplicatedPage->AllChildren(), 'Duplicated page also duplicates children' ); } /** * @return array[] */ public function duplicateToSubsiteProvider() { return [ [true, 1], [false, 0], ]; } public function testThemeResolverIsUsedForSettingThemeList() { $firstResolver = $this->createMock(ThemeResolver::class); $firstResolver->expects($this->never())->method('getThemeList'); Injector::inst()->registerService($firstResolver, ThemeResolver::class); $subsitePage = $this->objFromFixture(Page::class, 'home'); Subsite::changeSubsite($subsitePage->SubsiteID); $controller = ModelAsController::controller_for($subsitePage); SiteTree::singleton()->extend('contentcontrollerInit', $controller); $secondResolver = $this->createMock(ThemeResolver::class); $secondResolver->expects($this->once())->method('getThemeList'); Injector::inst()->registerService($secondResolver, ThemeResolver::class); $subsitePage = $this->objFromFixture(Page::class, 'subsite1_home'); Subsite::changeSubsite($subsitePage->SubsiteID); $controller = ModelAsController::controller_for($subsitePage); SiteTree::singleton()->extend('contentcontrollerInit', $controller); } public function provideAlternateAbsoluteLink() { return [ ['home', null, 'http://localhost/'], ['home', 'myaction', 'http://localhost/home/myaction'], ['contact', null, 'http://localhost/contact-us/'], ['contact', 'myaction', 'http://localhost/contact-us/myaction'], ['subsite1_home', null, 'http://subsite1.localhost/'], ['subsite1_home', 'myaction', 'http://subsite1.localhost/home/myaction'], ['subsite1_contactus', null, 'http://subsite1.localhost/contact-us/'], ['subsite1_contactus', 'myaction', 'http://subsite1.localhost/contact-us/myaction'] ]; } /** * @dataProvider provideAlternateAbsoluteLink * @param string $pageFixtureName * @param string|null $action * @param string $expectedAbsoluteLink */ public function testAlternateAbsoluteLink($pageFixtureName, $action, $expectedAbsoluteLink) { // Setting a control value, in case base url is set for the installation under test Config::modify()->set(Director::class, 'alternate_base_url', 'http://localhost/'); /** @var Page $page */ $page = $this->objFromFixture(Page::class, $pageFixtureName); $result = $page->AbsoluteLink($action); $this->assertEquals($expectedAbsoluteLink, $result); } public function testURLSegmentBaseIsSetToSubsiteBaseURL() { // This subsite has a domain with 'one.example.org' as the primary domain /** @var Subsite $subsite */ $subsite = $this->objFromFixture(Subsite::class, 'domaintest1'); Subsite::changeSubsite($subsite); $page = new SiteTree(); $page->SubsiteID = $subsite->ID; $page->write(); $fields = $page->getCMSFields(); /** @var SiteTreeURLSegmentField $urlSegmentField */ $urlSegmentField = $fields->dataFieldByName('URLSegment'); $this->assertInstanceOf(SiteTreeURLSegmentField::class, $urlSegmentField); $this->assertSame('http://one.example.org/', $urlSegmentField->getURLPrefix()); } } |