silverstripe-subsites/tests/php/SubsiteTest.php

504 lines
18 KiB
PHP
Raw Normal View History

<?php
namespace SilverStripe\Subsites\Tests;
use Page;
use SilverStripe\CMS\Model\SiteTree;
2016-09-22 16:38:29 +02:00
use SilverStripe\Control\Director;
use SilverStripe\Core\Config\Config;
2017-05-24 15:26:28 +02:00
use SilverStripe\ORM\DataObject;
2017-05-29 13:42:42 +02:00
use SilverStripe\Security\Member;
2017-05-24 15:25:34 +02:00
use SilverStripe\Subsites\Model\Subsite;
use SilverStripe\Subsites\Model\SubsiteDomain;
use SilverStripe\Subsites\State\SubsiteState;
use UnexpectedValueException;
2017-05-24 15:25:34 +02:00
2017-05-24 15:26:28 +02:00
class SubsiteTest extends BaseSubsiteTest
{
protected static $fixture_file = 'SubsiteTest.yml';
2017-05-24 15:26:28 +02:00
protected $usesTransactions = false;
2017-05-29 13:42:42 +02:00
/**
* Original value of $_REQUEST
*
* @var array
*/
2017-06-01 15:57:53 +02:00
protected $origServer = [];
2017-05-29 13:42:42 +02:00
2021-10-27 07:24:03 +02:00
protected function setUp(): void
2017-05-24 15:26:28 +02:00
{
parent::setUp();
Config::modify()
->set(Director::class, 'alternate_base_url', '/')
->set(Subsite::class, 'strict_subdomain_matching', false)
->set(Subsite::class, 'write_hostmap', false);
2017-05-29 13:42:42 +02:00
$this->origServer = $_SERVER;
2017-05-24 15:26:28 +02:00
}
2021-10-27 07:24:03 +02:00
protected function tearDown(): void
2017-05-24 15:26:28 +02:00
{
2017-05-29 13:42:42 +02:00
$_SERVER = $this->origServer;
parent::tearDown();
2017-05-24 15:26:28 +02:00
}
/**
* Create a new subsite from the template and verify that all the template's pages are copied
*/
2017-05-29 13:42:42 +02:00
public function testSubsiteCreation()
2017-05-24 15:26:28 +02:00
{
// Create the instance
$template = $this->objFromFixture(Subsite::class, 'main');
// Test that changeSubsite is working
Subsite::changeSubsite($template->ID);
$this->assertEquals($template->ID, SubsiteState::singleton()->getSubsiteId());
2017-05-24 15:26:28 +02:00
$tmplStaff = $this->objFromFixture('Page', 'staff');
$tmplHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
2018-02-01 01:19:02 +01:00
// Publish all the pages in the template, testing that DataObject::get only returns pages
// from the chosen subsite
2017-05-29 13:42:42 +02:00
$pages = DataObject::get(SiteTree::class);
$totalPages = $pages->count();
2017-05-24 15:26:28 +02:00
foreach ($pages as $page) {
$this->assertEquals($template->ID, $page->SubsiteID);
$page->copyVersionToStage('Stage', 'Live');
2017-05-24 15:26:28 +02:00
}
// Create a new site
$subsite = $template->duplicate();
// Check title
$this->assertEquals($subsite->Title, $template->Title);
// Another test that changeSubsite is working
$subsite->activate();
$siteHome = DataObject::get_one('Page', "\"URLSegment\" = 'home'");
$this->assertNotEquals($siteHome, false, 'Home Page for subsite not found');
$this->assertEquals(
$subsite->ID,
$siteHome->SubsiteID,
2017-05-24 15:26:28 +02:00
'createInstance() copies existing pages retaining the same URLSegment'
);
Subsite::changeSubsite(0);
}
/**
* Confirm that domain lookup is working
*/
2017-05-29 13:42:42 +02:00
public function testDomainLookup()
2017-05-24 15:26:28 +02:00
{
// Clear existing fixtures
foreach (DataObject::get(Subsite::class) as $subsite) {
$subsite->delete();
}
foreach (DataObject::get(SubsiteDomain::class) as $domain) {
$domain->delete();
}
// Much more expressive than YML in this case
2017-06-01 15:57:53 +02:00
$subsite1 = $this->createSubsiteWithDomains([
2017-05-24 15:26:28 +02:00
'one.example.org' => true,
'one.*' => false,
2017-06-01 15:57:53 +02:00
]);
$subsite2 = $this->createSubsiteWithDomains([
2017-05-24 15:26:28 +02:00
'two.mysite.com' => true,
'*.mysite.com' => false,
'subdomain.onmultiplesubsites.com' => false,
2017-06-01 15:57:53 +02:00
]);
$subsite3 = $this->createSubsiteWithDomains([
2017-05-24 15:26:28 +02:00
'three.*' => true, // wildcards in primary domain are not recommended
'subdomain.unique.com' => false,
'*.onmultiplesubsites.com' => false,
2017-06-01 15:57:53 +02:00
]);
2017-05-24 15:26:28 +02:00
$this->assertEquals(
$subsite3->ID,
Subsite::getSubsiteIDForDomain('subdomain.unique.com'),
'Full unique match'
);
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('one.example.org'),
'Full match, doesn\'t complain about multiple matches within a single subsite'
);
$failed = false;
try {
Subsite::getSubsiteIDForDomain('subdomain.onmultiplesubsites.com');
} catch (UnexpectedValueException $e) {
$failed = true;
}
$this->assertTrue(
$failed,
'Fails on multiple matches with wildcard vs. www across multiple subsites'
);
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('one.unique.com'),
'Fuzzy match suffixed with wildcard (rule "one.*")'
);
$this->assertEquals(
$subsite2->ID,
Subsite::getSubsiteIDForDomain('two.mysite.com'),
'Matches correct subsite for rule'
);
$this->assertEquals(
$subsite2->ID,
Subsite::getSubsiteIDForDomain('other.mysite.com'),
'Fuzzy match prefixed with wildcard (rule "*.mysite.com")'
);
$this->assertEquals(
0,
Subsite::getSubsiteIDForDomain('unknown.madeup.com'),
"Doesn't match unknown subsite"
);
}
2017-05-29 13:42:42 +02:00
public function testStrictSubdomainMatching()
2017-05-24 15:26:28 +02:00
{
// Clear existing fixtures
foreach (DataObject::get(Subsite::class) as $subsite) {
$subsite->delete();
}
foreach (DataObject::get(SubsiteDomain::class) as $domain) {
$domain->delete();
}
// Much more expressive than YML in this case
2017-06-01 15:57:53 +02:00
$subsite1 = $this->createSubsiteWithDomains([
2017-05-24 15:26:28 +02:00
'example.org' => true,
'example.com' => false,
'*.wildcard.com' => false,
2017-06-01 15:57:53 +02:00
]);
$subsite2 = $this->createSubsiteWithDomains([
2017-05-24 15:26:28 +02:00
'www.example.org' => true,
'www.wildcard.com' => false,
2017-06-01 15:57:53 +02:00
]);
2017-05-24 15:26:28 +02:00
Config::modify()->set(Subsite::class, 'strict_subdomain_matching', false);
2017-05-24 15:26:28 +02:00
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('example.org'),
'Exact matches without strict checking when not using www prefix'
);
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('example.org:1123'),
'Exact matches without strict checking when not using www prefix and ignores port'
);
2017-05-24 15:26:28 +02:00
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('www.example.org'),
2018-02-01 01:19:02 +01:00
'Matches without strict checking when using www prefix, '
.'still matching first domain regardless of www prefix (falling back to subsite primary key ordering)'
2017-05-24 15:26:28 +02:00
);
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('www.example.org:9923'),
'Matches without strict checking when using www prefix, '
.'still matching first domain without prefix (falling back to primary key ordering and ignoring port)'
);
2017-05-24 15:26:28 +02:00
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('www.example.com'),
'Fuzzy matches without strict checking with www prefix'
);
$this->assertEquals(
0,
Subsite::getSubsiteIDForDomain('www.wildcard.com'),
'Doesn\'t match www prefix without strict check, even if a wildcard subdomain is in place'
);
Config::modify()->set(Subsite::class, 'strict_subdomain_matching', true);
2017-05-24 15:26:28 +02:00
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('example.org'),
'Matches with strict checking when not using www prefix'
);
$this->assertEquals(
$subsite1->ID,
Subsite::getSubsiteIDForDomain('example.org:123'),
'Matches with strict checking when not using www prefix and ignores port'
);
2017-05-24 15:26:28 +02:00
$this->assertEquals(
$subsite2->ID, // not 1
Subsite::getSubsiteIDForDomain('www.example.org'),
'Matches with strict checking when using www prefix'
);
$this->assertEquals(
0,
Subsite::getSubsiteIDForDomain('www.example.com'),
'Doesn\'t fuzzy match with strict checking when using www prefix'
);
$failed = false;
try {
Subsite::getSubsiteIDForDomain('www.wildcard.com');
} catch (UnexpectedValueException $e) {
$failed = true;
}
$this->assertTrue(
$failed,
'Fails on multiple matches with strict checking and wildcard vs. www'
);
}
protected function createSubsiteWithDomains($domains)
{
2017-06-01 15:57:53 +02:00
$subsite = new Subsite([
2017-05-24 15:26:28 +02:00
'Title' => 'My Subsite'
2017-06-01 15:57:53 +02:00
]);
2017-05-24 15:26:28 +02:00
$subsite->write();
foreach ($domains as $domainStr => $isPrimary) {
2017-06-01 15:57:53 +02:00
$domain = new SubsiteDomain([
2017-05-24 15:26:28 +02:00
'Domain' => $domainStr,
'IsPrimary' => $isPrimary,
'SubsiteID' => $subsite->ID
2017-06-01 15:57:53 +02:00
]);
2017-05-24 15:26:28 +02:00
$domain->write();
}
return $subsite;
}
/**
* Test the Subsite->domain() method
*/
2017-05-29 13:42:42 +02:00
public function testDefaultDomain()
2017-05-24 15:26:28 +02:00
{
$this->assertEquals(
'one.example.org',
$this->objFromFixture(Subsite::class, 'domaintest1')->domain()
);
2017-05-24 15:26:28 +02:00
$this->assertEquals(
'two.mysite.com',
$this->objFromFixture(Subsite::class, 'domaintest2')->domain()
);
2017-05-24 15:26:28 +02:00
$_SERVER['HTTP_HOST'] = 'www.example.org';
$this->assertEquals(
'three.example.org',
$this->objFromFixture(Subsite::class, 'domaintest3')->domain()
);
2017-05-24 15:26:28 +02:00
$_SERVER['HTTP_HOST'] = 'mysite.example.org';
$this->assertEquals(
'three.mysite.example.org',
$this->objFromFixture(Subsite::class, 'domaintest3')->domain()
);
2017-05-24 15:26:28 +02:00
$this->assertEquals($_SERVER['HTTP_HOST'], singleton(Subsite::class)->PrimaryDomain);
$this->assertEquals(
'http://' . $_SERVER['HTTP_HOST'] . Director::baseURL(),
singleton(Subsite::class)->absoluteBaseURL()
);
2017-05-29 13:42:42 +02:00
}
2017-05-24 15:26:28 +02:00
2017-05-29 13:42:42 +02:00
/**
* Tests that Subsite and SubsiteDomain both respect http protocol correctly
*
* @param string $class Fixture class name
* @param string $identifier Fixture identifier
* @param bool $currentIsSecure Whether the current base URL should be secure
* @param string $expected The expected base URL for the subsite or subsite domain
* @dataProvider domainProtocolProvider
2017-05-29 13:42:42 +02:00
*/
public function testDomainProtocol($class, $identifier, $currentIsSecure, $expected)
{
/** @var Subsite|SubsiteDomain $model */
$model = $this->objFromFixture($class, $identifier);
$protocol = $currentIsSecure ? 'https' : 'http';
Config::modify()->set(Director::class, 'alternate_base_url', $protocol . '://www.mysite.com');
$this->assertSame($expected, $model->absoluteBaseURL());
}
public function domainProtocolProvider()
2017-06-01 15:57:53 +02:00
{
return [
[Subsite::class, 'domaintest2', false, 'http://two.mysite.com/'],
[SubsiteDomain::class, 'dt2a', false, 'http://two.mysite.com/'],
[SubsiteDomain::class, 'dt2b', false, 'http://subsite.mysite.com/'],
[Subsite::class, 'domaintest4', false, 'https://www.primary.com/'],
[SubsiteDomain::class, 'dt4a', false, 'https://www.primary.com/'],
[SubsiteDomain::class, 'dt4b', false, 'http://www.secondary.com/'],
[Subsite::class, 'domaintest5', false, 'http://www.tertiary.com/'],
[SubsiteDomain::class, 'dt5', false, 'http://www.tertiary.com/'],
[Subsite::class, 'domaintest2', true, 'https://two.mysite.com/'],
[SubsiteDomain::class, 'dt2a', true, 'https://two.mysite.com/'],
[SubsiteDomain::class, 'dt2b', true, 'https://subsite.mysite.com/'],
[Subsite::class, 'domaintest4', true, 'https://www.primary.com/'],
[SubsiteDomain::class, 'dt4a', true, 'https://www.primary.com/'],
[SubsiteDomain::class, 'dt4b', true, 'http://www.secondary.com/'],
[Subsite::class, 'domaintest5', true, 'http://www.tertiary.com/'],
[SubsiteDomain::class, 'dt5', true, 'http://www.tertiary.com/'],
];
2017-05-24 15:26:28 +02:00
}
2017-05-29 13:42:42 +02:00
public function testAllSites()
2017-05-24 15:26:28 +02:00
{
$subsites = Subsite::all_sites();
2022-11-28 05:49:50 +01:00
$this->assertListEquals([
2017-06-01 15:57:53 +02:00
['Title' => 'Main site'],
['Title' => 'Template'],
['Title' => 'Subsite1 Template'],
['Title' => 'Subsite2 Template'],
['Title' => 'Test 1'],
['Title' => 'Test 2'],
['Title' => 'Test 3'],
['Title' => 'Test Non-SSL'],
['Title' => 'Test SSL'],
['Title' => 'Test Vagrant VM on port 8080'],
['Title' => 'Locale subsite'],
2017-06-01 15:57:53 +02:00
], $subsites, 'Lists all subsites');
2017-05-24 15:26:28 +02:00
}
2017-05-29 13:42:42 +02:00
public function testAllAccessibleSites()
2017-05-24 15:26:28 +02:00
{
2017-05-29 13:42:42 +02:00
$member = $this->objFromFixture(Member::class, 'subsite1member');
2017-05-24 15:26:28 +02:00
$subsites = Subsite::all_accessible_sites(true, 'Main site', $member);
2022-11-28 05:49:50 +01:00
$this->assertListEquals([
2017-06-01 15:57:53 +02:00
['Title' => 'Subsite1 Template']
], $subsites, 'Lists member-accessible sites.');
2017-05-24 15:26:28 +02:00
}
/**
* Test Subsite::accessible_sites()
*/
2017-05-29 13:42:42 +02:00
public function testAccessibleSites()
2017-05-24 15:26:28 +02:00
{
$member1Sites = Subsite::accessible_sites(
'CMS_ACCESS_CMSMain',
false,
null,
$this->objFromFixture(Member::class, 'subsite1member')
);
$member1SiteTitles = $member1Sites->column('Title');
2017-05-24 15:26:28 +02:00
sort($member1SiteTitles);
$this->assertEquals('Subsite1 Template', $member1SiteTitles[0], 'Member can get to a subsite via a group');
$adminSites = Subsite::accessible_sites(
'CMS_ACCESS_CMSMain',
false,
null,
$this->objFromFixture(Member::class, 'admin')
);
$adminSiteTitles = $adminSites->column('Title');
2017-05-24 15:26:28 +02:00
sort($adminSiteTitles);
2017-06-01 15:57:53 +02:00
$this->assertEquals([
'Locale subsite',
2017-05-24 15:26:28 +02:00
'Subsite1 Template',
'Subsite2 Template',
'Template',
'Test 1',
'Test 2',
'Test 3',
2017-05-29 13:42:42 +02:00
'Test Non-SSL',
'Test SSL',
'Test Vagrant VM on port 8080'
2022-04-13 03:49:48 +02:00
], array_values($adminSiteTitles ?? []));
2017-05-24 15:26:28 +02:00
2017-05-29 13:42:42 +02:00
$member2Sites = Subsite::accessible_sites(
'CMS_ACCESS_CMSMain',
false,
null,
2017-05-29 13:42:42 +02:00
$this->objFromFixture(Member::class, 'subsite1member2')
);
$member2SiteTitles = $member2Sites->column('Title');
2017-05-24 15:26:28 +02:00
sort($member2SiteTitles);
$this->assertEquals('Subsite1 Template', $member2SiteTitles[1], 'Member can get to subsite via a group role');
2017-05-24 15:26:28 +02:00
}
2017-05-29 13:42:42 +02:00
public function testhasMainSitePermission()
2017-05-24 15:26:28 +02:00
{
2017-05-29 13:42:42 +02:00
$admin = $this->objFromFixture(Member::class, 'admin');
$subsite1member = $this->objFromFixture(Member::class, 'subsite1member');
$subsite1admin = $this->objFromFixture(Member::class, 'subsite1admin');
$allsubsitesauthor = $this->objFromFixture(Member::class, 'allsubsitesauthor');
2017-05-24 15:26:28 +02:00
$this->assertTrue(
Subsite::hasMainSitePermission($admin),
'Default permissions granted for super-admin'
);
$this->assertTrue(
2017-06-01 15:57:53 +02:00
Subsite::hasMainSitePermission($admin, ['ADMIN']),
2017-05-24 15:26:28 +02:00
'ADMIN permissions granted for super-admin'
);
$this->assertFalse(
2017-06-01 15:57:53 +02:00
Subsite::hasMainSitePermission($subsite1admin, ['ADMIN']),
2017-05-24 15:26:28 +02:00
'ADMIN permissions (on main site) denied for subsite1 admin'
);
$this->assertFalse(
2017-06-01 15:57:53 +02:00
Subsite::hasMainSitePermission($subsite1admin, ['CMS_ACCESS_CMSMain']),
2017-05-24 15:26:28 +02:00
'CMS_ACCESS_CMSMain (on main site) denied for subsite1 admin'
);
$this->assertFalse(
2017-06-01 15:57:53 +02:00
Subsite::hasMainSitePermission($allsubsitesauthor, ['ADMIN']),
2017-05-24 15:26:28 +02:00
'ADMIN permissions (on main site) denied for CMS author with edit rights on all subsites'
);
$this->assertTrue(
2017-06-01 15:57:53 +02:00
Subsite::hasMainSitePermission($allsubsitesauthor, ['CMS_ACCESS_CMSMain']),
2017-05-24 15:26:28 +02:00
'CMS_ACCESS_CMSMain (on main site) granted for CMS author with edit rights on all subsites'
);
$this->assertFalse(
2017-06-01 15:57:53 +02:00
Subsite::hasMainSitePermission($subsite1member, ['ADMIN']),
2017-05-24 15:26:28 +02:00
'ADMIN (on main site) denied for subsite1 subsite1 cms author'
);
$this->assertFalse(
2017-06-01 15:57:53 +02:00
Subsite::hasMainSitePermission($subsite1member, ['CMS_ACCESS_CMSMain']),
2017-05-24 15:26:28 +02:00
'CMS_ACCESS_CMSMain (on main site) denied for subsite1 cms author'
);
}
2017-05-29 13:42:42 +02:00
public function testDuplicateSubsite()
2017-05-24 15:26:28 +02:00
{
// get subsite1 & create page
$subsite1 = $this->objFromFixture(Subsite::class, 'domaintest1');
$subsite1->activate();
$page1 = new Page();
$page1->Title = 'MyAwesomePage';
$page1->write();
2022-11-28 05:49:50 +01:00
$page1->publishRecursive();
2017-05-24 15:26:28 +02:00
$this->assertEquals($page1->SubsiteID, $subsite1->ID);
// duplicate
$subsite2 = $subsite1->duplicate();
$subsite2->activate();
// change content on dupe
$page2 = DataObject::get_one('Page', "\"Title\" = 'MyAwesomePage'");
$page2->Title = 'MyNewAwesomePage';
$page2->write();
2022-11-28 05:49:50 +01:00
$page2->publishRecursive();
2017-05-24 15:26:28 +02:00
// check change & check change has not affected subiste1
$subsite1->activate();
$this->assertEquals('MyAwesomePage', DataObject::get_by_id('Page', $page1->ID)->Title);
$subsite2->activate();
$this->assertEquals('MyNewAwesomePage', DataObject::get_by_id('Page', $page2->ID)->Title);
}
public function testDefaultPageCreatedWhenCreatingSubsite()
2018-05-04 03:57:25 +02:00
{
2018-05-04 03:56:26 +02:00
$subsite = new Subsite();
$subsite->Title = 'New Subsite';
$subsite->write();
2018-05-04 03:57:25 +02:00
$subsite->activate();
2018-05-04 03:57:25 +02:00
$pages = SiteTree::get();
$this->assertGreaterThanOrEqual(1, $pages->count());
}
}