mirror of
https://github.com/silverstripe/silverstripe-reports
synced 2024-10-22 11:05:53 +02:00
Minor Moved from RedirectorPageTest, SiteTreeActionsTest, SiteTreeBackLinksTest, SiteTreePermissionsTest, SiteTreeTest, WidgetAreaTest /Sites/cgps/sapphire/tests to cms module cms/tests/
This commit is contained in:
parent
e280929b29
commit
d4af221e0a
53
tests/RedirectorPageTest.php
Normal file
53
tests/RedirectorPageTest.php
Normal file
@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
class RedirectorPageTest extends FunctionalTest {
|
||||
static $fixture_file = 'sapphire/tests/RedirectorPageTest.yml';
|
||||
static $use_draft_site = true;
|
||||
|
||||
function testGoodRedirectors() {
|
||||
/* For good redirectors, the final destination URL will be returned */
|
||||
$this->assertEquals("http://www.google.com", $this->objFromFixture('RedirectorPage','goodexternal')->Link());
|
||||
$this->assertEquals(Director::baseURL() . "redirection-dest/", $this->objFromFixture('RedirectorPage','goodinternal')->redirectionLink());
|
||||
$this->assertEquals(Director::baseURL() . "redirection-dest/", $this->objFromFixture('RedirectorPage','goodinternal')->Link());
|
||||
}
|
||||
|
||||
function testEmptyRedirectors() {
|
||||
/* If a redirector page is misconfigured, then its link method will just return the usual URLSegment-generated value */
|
||||
$page1 = $this->objFromFixture('RedirectorPage','badexternal');
|
||||
$this->assertEquals(Director::baseURL() . 'bad-external/', $page1->Link());
|
||||
|
||||
/* An error message will be shown if you visit it */
|
||||
$content = $this->get(Director::makeRelative($page1->Link()))->getBody();
|
||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||
|
||||
/* This also applies for internal links */
|
||||
$page2 = $this->objFromFixture('RedirectorPage','badinternal');
|
||||
$this->assertEquals(Director::baseURL() . 'bad-internal/', $page2->Link());
|
||||
$content = $this->get(Director::makeRelative($page2->Link()))->getBody();
|
||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||
}
|
||||
|
||||
function testReflexiveAndTransitiveInternalRedirectors() {
|
||||
/* Reflexive redirectors are those that point to themselves. They should behave the same as an empty redirector */
|
||||
$page = $this->objFromFixture('RedirectorPage','reflexive');
|
||||
$this->assertEquals(Director::baseURL() . 'reflexive/', $page->Link());
|
||||
$content = $this->get(Director::makeRelative($page->Link()))->getBody();
|
||||
$this->assertContains('message-setupWithoutRedirect', $content);
|
||||
|
||||
/* Transitive redirectors are those that point to another redirector page. They should send people to the URLSegment
|
||||
* of the destination page - the middle-stop, so to speak. That should redirect to the final destination */
|
||||
$page = $this->objFromFixture('RedirectorPage','transitive');
|
||||
$this->assertEquals(Director::baseURL() . 'good-internal/', $page->Link());
|
||||
|
||||
$this->autoFollowRedirection = false;
|
||||
$response = $this->get(Director::makeRelative($page->Link()));
|
||||
$this->assertEquals(Director::baseURL() . "redirection-dest/", $response->getHeader("Location"));
|
||||
}
|
||||
|
||||
function testExternalURLGetsPrefixIfNotSet() {
|
||||
$page = $this->objFromFixture('RedirectorPage', 'externalnoprefix');
|
||||
$this->assertEquals($page->ExternalURL, 'http://google.com', 'onBeforeWrite has prefixed with http');
|
||||
$page->write();
|
||||
$this->assertEquals($page->ExternalURL, 'http://google.com', 'onBeforeWrite will not double prefix if written again!');
|
||||
}
|
||||
}
|
39
tests/RedirectorPageTest.yml
Normal file
39
tests/RedirectorPageTest.yml
Normal file
@ -0,0 +1,39 @@
|
||||
Page:
|
||||
dest:
|
||||
Title: Redirection Dest
|
||||
URLSegment: redirection-dest
|
||||
|
||||
RedirectorPage:
|
||||
goodexternal:
|
||||
Title: Good External
|
||||
URLSegment: good-external
|
||||
RedirectionType: External
|
||||
ExternalURL: http://www.google.com
|
||||
goodinternal:
|
||||
Title: Good Internal
|
||||
URLSegment: good-internal
|
||||
RedirectionType: Internal
|
||||
LinkTo: =>Page.dest
|
||||
badexternal:
|
||||
Title: Bad External
|
||||
RedirectionType: External
|
||||
URLSegment: bad-external
|
||||
externalnoprefix:
|
||||
Title: External no prefix
|
||||
RedirectionType: External
|
||||
URLSegment: external-no-prefix
|
||||
ExternalURL: google.com
|
||||
badinternal:
|
||||
Title: Bad Internal
|
||||
RedirectionType: Internal
|
||||
URLSegment: bad-internal
|
||||
reflexive:
|
||||
Title: Reflexive
|
||||
RedirectionType: Internal
|
||||
LinkTo: =>RedirectorPage.reflexive
|
||||
URLSegment: reflexive
|
||||
transitive:
|
||||
Title: Transitive
|
||||
RedirectionType: Internal
|
||||
LinkTo: =>RedirectorPage.goodinternal
|
||||
URLSegment: transitive
|
186
tests/SiteTreeActionsTest.php
Normal file
186
tests/SiteTreeActionsTest.php
Normal file
@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* Possible actions:
|
||||
* - action_save
|
||||
* - action_publish
|
||||
* - action_unpublish
|
||||
* - action_delete
|
||||
* - action_deletefromlive
|
||||
* - action_rollback
|
||||
* - action_revert
|
||||
*
|
||||
* @package sapphire
|
||||
* @subpackage tests
|
||||
*/
|
||||
class SiteTreeActionsTest extends FunctionalTest {
|
||||
|
||||
static $fixture_file = 'cms/tests/SiteTreeActionsTest.yml';
|
||||
|
||||
static function set_up_once() {
|
||||
SiteTreeTest::set_up_once();
|
||||
|
||||
parent::set_up_once();
|
||||
}
|
||||
|
||||
static function tear_down_once() {
|
||||
SiteTreeTest::tear_down_once();
|
||||
|
||||
parent::tear_down_once();
|
||||
}
|
||||
|
||||
function testActionsReadonly() {
|
||||
if(class_exists('SiteTreeCMSWorkflow')) return true;
|
||||
|
||||
$readonlyEditor = $this->objFromFixture('Member', 'cmsreadonlyeditor');
|
||||
$this->session()->inst_set('loggedInAs', $readonlyEditor->ID);
|
||||
|
||||
$page = new SiteTreeActionsTest_Page();
|
||||
$page->CanEditType = 'LoggedInUsers';
|
||||
$page->write();
|
||||
$page->doPublish();
|
||||
|
||||
$actionsArr = $page->getCMSActions()->column('Name');
|
||||
|
||||
$this->assertNotContains('action_save',$actionsArr);
|
||||
$this->assertNotContains('action_publish',$actionsArr);
|
||||
$this->assertNotContains('action_unpublish',$actionsArr);
|
||||
$this->assertNotContains('action_delete',$actionsArr);
|
||||
$this->assertNotContains('action_deletefromlive',$actionsArr);
|
||||
$this->assertNotContains('action_rollback',$actionsArr);
|
||||
$this->assertNotContains('action_revert',$actionsArr);
|
||||
}
|
||||
|
||||
function testActionsNoDeletePublishedRecord() {
|
||||
if(class_exists('SiteTreeCMSWorkflow')) return true;
|
||||
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
$page = new SiteTreeActionsTest_Page();
|
||||
$page->CanEditType = 'LoggedInUsers';
|
||||
$page->write();
|
||||
$pageID = $page->ID;
|
||||
$page->doPublish();
|
||||
$page->deleteFromStage('Stage');
|
||||
|
||||
// Get the live version of the page
|
||||
$page = Versioned::get_one_by_stage("SiteTree", "Live", "\"SiteTree\".\"ID\" = $pageID");
|
||||
$this->assertType("SiteTree", $page);
|
||||
|
||||
// Check that someone without the right permission can't delete the page
|
||||
$editor = $this->objFromFixture('Member', 'cmsnodeleteeditor');
|
||||
$this->session()->inst_set('loggedInAs', $editor->ID);
|
||||
|
||||
$actionsArr = $page->getCMSActions()->column('Name');
|
||||
$this->assertNotContains('action_deletefromlive',$actionsArr);
|
||||
|
||||
// Check that someone with the right permission can delete the page
|
||||
$this->objFromFixture('Member', 'cmseditor')->logIn();
|
||||
$actionsArr = $page->getCMSActions()->column('Name');
|
||||
$this->assertContains('action_deletefromlive',$actionsArr);
|
||||
}
|
||||
|
||||
function testActionsPublishedRecord() {
|
||||
if(class_exists('SiteTreeCMSWorkflow')) return true;
|
||||
|
||||
$author = $this->objFromFixture('Member', 'cmseditor');
|
||||
$this->session()->inst_set('loggedInAs', $author->ID);
|
||||
|
||||
$page = new Page();
|
||||
$page->CanEditType = 'LoggedInUsers';
|
||||
$page->write();
|
||||
$page->doPublish();
|
||||
|
||||
$actionsArr = $page->getCMSActions()->column('Name');
|
||||
|
||||
$this->assertContains('action_save',$actionsArr);
|
||||
$this->assertContains('action_publish',$actionsArr);
|
||||
$this->assertContains('action_unpublish',$actionsArr);
|
||||
$this->assertContains('action_delete',$actionsArr);
|
||||
$this->assertNotContains('action_deletefromlive',$actionsArr);
|
||||
$this->assertNotContains('action_rollback',$actionsArr);
|
||||
$this->assertNotContains('action_revert',$actionsArr);
|
||||
}
|
||||
|
||||
function testActionsDeletedFromStageRecord() {
|
||||
if(class_exists('SiteTreeCMSWorkflow')) return true;
|
||||
|
||||
$author = $this->objFromFixture('Member', 'cmseditor');
|
||||
$this->session()->inst_set('loggedInAs', $author->ID);
|
||||
|
||||
$page = new Page();
|
||||
$page->CanEditType = 'LoggedInUsers';
|
||||
$page->write();
|
||||
$pageID = $page->ID;
|
||||
$page->doPublish();
|
||||
$page->deleteFromStage('Stage');
|
||||
|
||||
// Get the live version of the page
|
||||
$page = Versioned::get_one_by_stage("SiteTree", "Live", "\"SiteTree\".\"ID\" = $pageID");
|
||||
$this->assertType('SiteTree', $page);
|
||||
|
||||
$actionsArr = $page->getCMSActions()->column('Name');
|
||||
|
||||
$this->assertNotContains('action_save',$actionsArr);
|
||||
$this->assertNotContains('action_publish',$actionsArr);
|
||||
$this->assertNotContains('action_unpublish',$actionsArr);
|
||||
$this->assertNotContains('action_delete',$actionsArr);
|
||||
$this->assertContains('action_deletefromlive',$actionsArr);
|
||||
$this->assertNotContains('action_rollback',$actionsArr);
|
||||
$this->assertContains('action_revert',$actionsArr);
|
||||
}
|
||||
|
||||
function testActionsChangedOnStageRecord() {
|
||||
if(class_exists('SiteTreeCMSWorkflow')) return true;
|
||||
|
||||
$author = $this->objFromFixture('Member', 'cmseditor');
|
||||
$this->session()->inst_set('loggedInAs', $author->ID);
|
||||
|
||||
$page = new Page();
|
||||
$page->CanEditType = 'LoggedInUsers';
|
||||
$page->write();
|
||||
$page->doPublish();
|
||||
$page->Content = 'Changed on Stage';
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
|
||||
$actionsArr = $page->getCMSActions()->column('Name');
|
||||
|
||||
$this->assertContains('action_save',$actionsArr);
|
||||
$this->assertContains('action_publish',$actionsArr);
|
||||
$this->assertContains('action_unpublish',$actionsArr);
|
||||
$this->assertContains('action_delete',$actionsArr);
|
||||
$this->assertNotContains('action_deletefromlive',$actionsArr);
|
||||
$this->assertContains('action_rollback',$actionsArr);
|
||||
$this->assertNotContains('action_revert',$actionsArr);
|
||||
}
|
||||
|
||||
function testActionsViewingOldVersion() {
|
||||
$p = new Page();
|
||||
$p->Content = 'test page first version';
|
||||
$p->write();
|
||||
$p->Content = 'new content';
|
||||
$p->write();
|
||||
|
||||
// Looking at the old version, the ability to rollback to that version is available
|
||||
$version = DB::query('SELECT "Version" FROM "SiteTree_versions" WHERE "Content" = \'test page first version\'')->value();
|
||||
$old = Versioned::get_version('Page', $p->ID, $version);
|
||||
$actions = $old->getCMSActions()->column('Name');
|
||||
$this->assertNotContains('action_save', $actions);
|
||||
$this->assertNotContains('action_publish', $actions);
|
||||
$this->assertNotContains('action_unpublish', $actions);
|
||||
$this->assertNotContains('action_delete', $actions);
|
||||
$this->assertContains('action_email', $actions);
|
||||
$this->assertContains('action_rollback', $actions);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SiteTreeActionsTest_Page extends Page implements TestOnly {
|
||||
function canEdit($member = null) {
|
||||
return Permission::checkMember($member, 'SiteTreeActionsTest_Page_CANEDIT');
|
||||
}
|
||||
|
||||
function canDelete($member = null) {
|
||||
return Permission::checkMember($member, 'SiteTreeActionsTest_Page_CANDELETE');
|
||||
}
|
||||
}
|
33
tests/SiteTreeActionsTest.yml
Normal file
33
tests/SiteTreeActionsTest.yml
Normal file
@ -0,0 +1,33 @@
|
||||
Permission:
|
||||
cmsmain1:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
cmsmain2:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
cmsmain3:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
candelete:
|
||||
Code: SiteTreeActionsTest_Page_CANDELETE
|
||||
canedit1:
|
||||
Code: SiteTreeActionsTest_Page_CANEDIT
|
||||
canedit2:
|
||||
Code: SiteTreeActionsTest_Page_CANEDIT
|
||||
Group:
|
||||
cmseditors:
|
||||
Title: CMS Editors
|
||||
Permissions: =>Permission.cmsmain1,=>Permission.canedit1,=>Permission.candelete
|
||||
cmsreadonly:
|
||||
Title: CMS Readonly
|
||||
Permissions: =>Permission.cmsmain2
|
||||
cmsnodelete:
|
||||
Title: CMS No Delete
|
||||
Permissions: =>Permission.cmsmain3,=>Permission.canedit2
|
||||
Member:
|
||||
cmseditor:
|
||||
Email: cmseditor@test.com
|
||||
Groups: =>Group.cmseditors
|
||||
cmsreadonlyeditor:
|
||||
Email: cmsreadonlyeditor@test.com
|
||||
Groups: =>Group.cmsreadonly
|
||||
cmsnodeleteeditor:
|
||||
Email: cmsnodeleteeditor@test.com
|
||||
Groups: =>Group.cmsnodelete
|
258
tests/SiteTreeBacklinksTest.php
Normal file
258
tests/SiteTreeBacklinksTest.php
Normal file
@ -0,0 +1,258 @@
|
||||
<?php
|
||||
|
||||
class SiteTreeBacklinksTest extends SapphireTest {
|
||||
static $fixture_file = "cms/tests/SiteTreeBacklinksTest.yml";
|
||||
|
||||
protected $requiredExtensions = array(
|
||||
'SiteTree' => array('SiteTreeBacklinksTest_DOD'),
|
||||
);
|
||||
|
||||
static function set_up_once() {
|
||||
SiteTreeTest::set_up_once();
|
||||
|
||||
parent::set_up_once();
|
||||
}
|
||||
|
||||
static function tear_down_once() {
|
||||
SiteTreeTest::tear_down_once();
|
||||
|
||||
parent::tear_down_once();
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
// Log in as admin so that we don't run into permission issues. That's not what we're
|
||||
// testing here.
|
||||
$this->logInWithPermission('ADMIN');
|
||||
}
|
||||
|
||||
function testSavingPageWithLinkAddsBacklink() {
|
||||
// load page 1
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
|
||||
// assert backlink to page 2 doesn't exist
|
||||
$page2 = $this->objFromFixture('Page', 'page2');
|
||||
$this->assertFalse($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 doesn\'t exist');
|
||||
|
||||
// add hyperlink to page 1 on page 2
|
||||
$page2->Content .= '<p><a href="[sitetree_link id='.$page1->ID.']">Testing page 1 link</a></p>';
|
||||
$page2->write();
|
||||
|
||||
// load page 1
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
|
||||
// assert backlink to page 2 exists
|
||||
$this->assertTrue($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 exists');
|
||||
}
|
||||
|
||||
function testRemovingLinkFromPageRemovesBacklink() {
|
||||
// load page 1
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
|
||||
// assert backlink to page 3 exits
|
||||
$page3 = $this->objFromFixture('Page', 'page3');
|
||||
$this->assertTrue($page1->BackLinkTracking()->containsIDs(array($page3->ID)), 'Assert backlink to page 3 exists');
|
||||
|
||||
// remove hyperlink to page 1
|
||||
$page3->Content = '<p>No links anymore!</p>';
|
||||
$page3->write();
|
||||
|
||||
// load page 1
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
|
||||
// assert backlink to page 3 exists
|
||||
$this->assertFalse($page1->BackLinkTracking()->containsIDs(array($page3->ID)), 'Assert backlink to page 3 doesn\'t exist');
|
||||
}
|
||||
|
||||
function testChangingUrlOnDraftSiteRewritesLink() {
|
||||
// load page 1
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
|
||||
// assert backlink to page 3 exists
|
||||
$page3 = $this->objFromFixture('Page', 'page3');
|
||||
$this->assertTrue($page1->BackLinkTracking()->containsIDs(array($page3->ID)), 'Assert backlink to page 3 exists');
|
||||
|
||||
// assert hyperlink to page 1's current url exists on page 3
|
||||
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
|
||||
|
||||
// change url of page 1
|
||||
$page1->URLSegment = 'new-url-segment';
|
||||
$page1->write();
|
||||
|
||||
// load page 3
|
||||
$page3 = $this->objFromFixture('Page', 'page3');
|
||||
|
||||
// assert hyperlink to page 1's new url exists
|
||||
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s new url exists on page 3');
|
||||
}
|
||||
|
||||
function testChangingUrlOnLiveSiteRewritesLink() {
|
||||
// publish page 1 & 3
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
$page3 = $this->objFromFixture('Page', 'page3');
|
||||
$this->assertTrue($page1->doPublish());
|
||||
$this->assertTrue($page3->doPublish());
|
||||
|
||||
// load pages from live
|
||||
$page1live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page1->ID);
|
||||
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
|
||||
|
||||
// assert backlink to page 3 exists
|
||||
$this->assertTrue($page1live->BackLinkTracking()->containsIDs(array($page3live->ID)), 'Assert backlink to page 3 exists');
|
||||
|
||||
// assert hyperlink to page 1's current url exists on page 3
|
||||
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
|
||||
|
||||
// change url of page 1
|
||||
$page1live->URLSegment = 'new-url-segment';
|
||||
$page1live->writeToStage('Live');
|
||||
|
||||
// load page 3 from live
|
||||
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
|
||||
|
||||
// assert hyperlink to page 1's new url exists
|
||||
Versioned::reading_stage('Live');
|
||||
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s new url exists on page 3');
|
||||
}
|
||||
|
||||
function testPublishingPageWithModifiedUrlRewritesLink() {
|
||||
// publish page 1 & 3
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
$page3 = $this->objFromFixture('Page', 'page3');
|
||||
|
||||
$this->assertTrue($page1->doPublish());
|
||||
$this->assertTrue($page3->doPublish());
|
||||
|
||||
// load page 3 from live
|
||||
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
|
||||
|
||||
// assert hyperlink to page 1's current url exists
|
||||
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current url exists on page 3');
|
||||
|
||||
// rename url of page 1 on stage
|
||||
$page1->URLSegment = 'new-url-segment';
|
||||
$page1->write();
|
||||
|
||||
// assert hyperlink to page 1's current publish url exists
|
||||
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
|
||||
Versioned::reading_stage('Live');
|
||||
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
|
||||
|
||||
|
||||
// publish page 1
|
||||
$this->assertTrue($page1->doPublish());
|
||||
|
||||
// assert hyperlink to page 1's new published url exists
|
||||
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
|
||||
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s new published url exists on page 3');
|
||||
}
|
||||
|
||||
function testPublishingPageWithModifiedLinksRewritesLinks() {
|
||||
// publish page 1 & 3
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
$page3 = $this->objFromFixture('Page', 'page3');
|
||||
$this->assertTrue($page1->doPublish());
|
||||
$this->assertTrue($page3->doPublish());
|
||||
|
||||
// assert hyperlink to page 1's current url exists
|
||||
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
|
||||
|
||||
// change page 1 url on draft
|
||||
$page1->URLSegment = 'new-url-segment';
|
||||
|
||||
// save page 1
|
||||
$page1->write();
|
||||
|
||||
// assert page 3 on draft contains new page 1 url
|
||||
$page3 = $this->objFromFixture('Page', 'page3');
|
||||
$links = HTTP::getLinksIn($page3->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s current draft url exists on page 3');
|
||||
|
||||
// publish page 3
|
||||
$this->assertTrue($page3->doPublish());
|
||||
|
||||
// assert page 3 on published site contains old page 1 url
|
||||
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
|
||||
Versioned::reading_stage('Live');
|
||||
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'page1/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
|
||||
|
||||
// publish page 1
|
||||
$this->assertTrue($page1->doPublish());
|
||||
|
||||
// assert page 3 on published site contains new page 1 url
|
||||
$page3live = Versioned::get_one_by_stage('Page', 'Live', '"SiteTree"."ID" = ' . $page3->ID);
|
||||
$links = HTTP::getLinksIn($page3live->obj('Content')->forTemplate());
|
||||
$this->assertContains(Director::baseURL().'new-url-segment/', $links, 'Assert hyperlink to page 1\'s current published url exists on page 3');
|
||||
}
|
||||
|
||||
function testLinkTrackingOnExtraContentFields() {
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
$page2 = $this->objFromFixture('Page', 'page2');
|
||||
$page1->doPublish();
|
||||
$page2->doPublish();
|
||||
|
||||
// assert backlink to page 2 doesn't exist
|
||||
$this->assertFalse($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 doesn\'t exist');
|
||||
|
||||
// add hyperlink to page 1 on page 2
|
||||
$page2->ExtraContent .= '<p><a href="[sitetree_link id='.$page1->ID.']">Testing page 1 link</a></p>';
|
||||
$page2->write();
|
||||
$page2->doPublish();
|
||||
|
||||
// assert backlink to page 2 exists
|
||||
$this->assertTrue($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 exists');
|
||||
|
||||
// update page1 url
|
||||
$page1 = $this->objFromFixture('Page', 'page1');
|
||||
$page1->URLSegment = "page1-new-url";
|
||||
$page1->write();
|
||||
|
||||
// confirm that draft link on page2 has been rewritten
|
||||
$page2 = $this->objFromFixture('Page', 'page2');
|
||||
$this->assertEquals('<p><a href="'.Director::baseURL().'page1-new-url/">Testing page 1 link</a></p>', $page2->obj('ExtraContent')->forTemplate());
|
||||
|
||||
// confirm that published link hasn't
|
||||
$page2Live = Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = $page2->ID");
|
||||
Versioned::reading_stage('Live');
|
||||
$this->assertEquals('<p><a href="'.Director::baseURL().'page1/">Testing page 1 link</a></p>', $page2Live->obj('ExtraContent')->forTemplate());
|
||||
|
||||
// publish page1 and confirm that the link on the published page2 has now been updated
|
||||
$page1->doPublish();
|
||||
$page2Live = Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = $page2->ID");
|
||||
$this->assertEquals('<p><a href="'.Director::baseURL().'page1-new-url/">Testing page 1 link</a></p>', $page2Live->obj('ExtraContent')->forTemplate());
|
||||
|
||||
|
||||
// remove hyperlink to page 1
|
||||
$page2->ExtraContent = '<p>No links anymore!</p>';
|
||||
$page2->write();
|
||||
|
||||
// assert backlink to page 2 no longer exists
|
||||
$this->assertFalse($page1->BackLinkTracking()->containsIDs(array($page2->ID)), 'Assert backlink to page 2 has been removed');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class SiteTreeBacklinksTest_DOD extends DataObjectDecorator implements TestOnly {
|
||||
function extraStatics() {
|
||||
return array(
|
||||
'db' => array(
|
||||
'ExtraContent' => 'HTMLText',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
function updateCMSFields(&$fields) {
|
||||
$fields->addFieldToTab("Root.Content.Main", new HTMLEditorField("ExtraContent"));
|
||||
}
|
||||
}
|
||||
?>
|
17
tests/SiteTreeBacklinksTest.yml
Normal file
17
tests/SiteTreeBacklinksTest.yml
Normal file
@ -0,0 +1,17 @@
|
||||
Page:
|
||||
page1:
|
||||
ID: 1
|
||||
Title: page1
|
||||
URLSegment: page1
|
||||
|
||||
page2:
|
||||
Title: page2
|
||||
URLSegment: page2
|
||||
|
||||
page3:
|
||||
Title: page3
|
||||
URLSegment: page3
|
||||
Content: '<p><a href="[sitetree_link id=1]">Testing page 1 link</a></p>'
|
||||
LinkTracking: =>Page.page1
|
||||
|
||||
|
313
tests/SiteTreeBrokenLinksTest.php
Normal file
313
tests/SiteTreeBrokenLinksTest.php
Normal file
@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* @package sapphire
|
||||
* @subpackage tests
|
||||
*/
|
||||
class SiteTreeBrokenLinksTest extends SapphireTest {
|
||||
static $fixture_file = 'cms/tests/SiteTreeBrokenLinksTest.yml';
|
||||
|
||||
static function set_up_once() {
|
||||
SiteTreeTest::set_up_once();
|
||||
|
||||
parent::set_up_once();
|
||||
}
|
||||
|
||||
static function tear_down_once() {
|
||||
SiteTreeTest::tear_down_once();
|
||||
|
||||
parent::tear_down_once();
|
||||
}
|
||||
|
||||
function testBrokenLinksBetweenPages() {
|
||||
$obj = $this->objFromFixture('Page','content');
|
||||
|
||||
$obj->Content = '<a href="[sitetree_link id=3423423]">this is a broken link</a>';
|
||||
$obj->syncLinkTracking();
|
||||
$this->assertTrue($obj->HasBrokenLink, 'Page has a broken link');
|
||||
|
||||
$obj->Content = '<a href="[sitetree_link id=' . $this->idFromFixture('Page','about') .']">this is not a broken link</a>';
|
||||
$obj->syncLinkTracking();
|
||||
$this->assertFalse($obj->HasBrokenLink, 'Page does NOT have a broken link');
|
||||
}
|
||||
|
||||
function testBrokenVirtualPages() {
|
||||
$obj = $this->objFromFixture('Page','content');
|
||||
$vp = new VirtualPage();
|
||||
|
||||
$vp->CopyContentFromID = $obj->ID;
|
||||
$vp->syncLinkTracking();
|
||||
$this->assertFalse($vp->HasBrokenLink, 'Working virtual page is NOT marked as broken');
|
||||
|
||||
$vp->CopyContentFromID = 12345678;
|
||||
$vp->syncLinkTracking();
|
||||
$this->assertTrue($vp->HasBrokenLink, 'Broken virtual page IS marked as such');
|
||||
}
|
||||
|
||||
function testBrokenInternalRedirectorPages() {
|
||||
$obj = $this->objFromFixture('Page','content');
|
||||
$rp = new RedirectorPage();
|
||||
|
||||
$rp->RedirectionType = 'Internal';
|
||||
|
||||
$rp->LinkToID = $obj->ID;
|
||||
$rp->syncLinkTracking();
|
||||
$this->assertFalse($rp->HasBrokenLink, 'Working redirector page is NOT marked as broken');
|
||||
|
||||
$rp->LinkToID = 12345678;
|
||||
$rp->syncLinkTracking();
|
||||
$this->assertTrue($rp->HasBrokenLink, 'Broken redirector page IS marked as such');
|
||||
}
|
||||
|
||||
function testBrokenAssetLinks() {
|
||||
$obj = $this->objFromFixture('Page','content');
|
||||
|
||||
$obj->Content = '<a href="assets/nofilehere.pdf">this is a broken link to a pdf file</a>';
|
||||
$obj->syncLinkTracking();
|
||||
$this->assertTrue($obj->HasBrokenFile, 'Page has a broken file');
|
||||
|
||||
$obj->Content = '<a href="assets/privacypolicy.pdf">this is not a broken file link</a>';
|
||||
$obj->syncLinkTracking();
|
||||
$this->assertFalse($obj->HasBrokenFile, 'Page does NOT have a broken file');
|
||||
}
|
||||
|
||||
function testDeletingFileMarksBackedPagesAsBroken() {
|
||||
// Test entry
|
||||
$file = new File();
|
||||
$file->Filename = 'test-file.pdf';
|
||||
$file->write();
|
||||
|
||||
$obj = $this->objFromFixture('Page','content');
|
||||
$obj->Content = '<a href="assets/test-file.pdf">link to a pdf file</a>';
|
||||
$obj->write();
|
||||
$this->assertTrue($obj->doPublish());
|
||||
// Confirm that it isn't marked as broken to begin with
|
||||
$obj->flushCache();
|
||||
$obj = DataObject::get_by_id("SiteTree", $obj->ID);
|
||||
$this->assertEquals(0, $obj->HasBrokenFile);
|
||||
|
||||
$liveObj = Versioned::get_one_by_stage("SiteTree", "Live","\"SiteTree\".\"ID\" = $obj->ID");
|
||||
$this->assertEquals(0, $liveObj->HasBrokenFile);
|
||||
|
||||
// Delete the file
|
||||
$file->delete();
|
||||
|
||||
// Confirm that it is marked as broken in both stage and live
|
||||
$obj->flushCache();
|
||||
$obj = DataObject::get_by_id("SiteTree", $obj->ID);
|
||||
$this->assertEquals(1, $obj->HasBrokenFile);
|
||||
|
||||
$liveObj = Versioned::get_one_by_stage("SiteTree", "Live", "\"SiteTree\".\"ID\" = $obj->ID");
|
||||
$this->assertEquals(1, $liveObj->HasBrokenFile);
|
||||
}
|
||||
function testDeletingMarksBackLinkedPagesAsBroken() {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
// Set up two published pages with a link from content -> about
|
||||
$linkDest = $this->objFromFixture('Page','about');
|
||||
$linkDest->doPublish();
|
||||
|
||||
$linkSrc = $this->objFromFixture('Page','content');
|
||||
$linkSrc->Content = "<p><a href=\"[sitetree_link id=$linkDest->ID]\">about us</a></p>";
|
||||
$linkSrc->write();
|
||||
|
||||
$linkSrc->doPublish();
|
||||
|
||||
// Confirm no broken link
|
||||
$this->assertEquals(0, (int)$linkSrc->HasBrokenLink);
|
||||
$this->assertEquals(0, DB::query("SELECT \"HasBrokenLink\" FROM \"SiteTree_Live\"
|
||||
WHERE \"ID\" = $linkSrc->ID")->value());
|
||||
|
||||
// Delete page from draft
|
||||
$linkDestID = $linkDest->ID;
|
||||
$linkDest->delete();
|
||||
|
||||
// Confirm draft has broken link, and published doesn't
|
||||
$linkSrc->flushCache();
|
||||
$linkSrc = $this->objFromFixture('Page', 'content');
|
||||
|
||||
$this->assertEquals(1, (int)$linkSrc->HasBrokenLink);
|
||||
$this->assertEquals(0, DB::query("SELECT \"HasBrokenLink\" FROM \"SiteTree_Live\"
|
||||
WHERE \"ID\" = $linkSrc->ID")->value());
|
||||
|
||||
// Delete from live
|
||||
$linkDest = Versioned::get_one_by_stage("SiteTree", "Live", "\"SiteTree\".\"ID\" = $linkDestID");
|
||||
$linkDest->doDeleteFromLive();
|
||||
|
||||
// Confirm both draft and published have broken link
|
||||
$linkSrc->flushCache();
|
||||
$linkSrc = $this->objFromFixture('Page', 'content');
|
||||
|
||||
$this->assertEquals(1, (int)$linkSrc->HasBrokenLink);
|
||||
$this->assertEquals(1, DB::query("SELECT \"HasBrokenLink\" FROM \"SiteTree_Live\"
|
||||
WHERE \"ID\" = $linkSrc->ID")->value());
|
||||
}
|
||||
|
||||
function testPublishingSourceBeforeDestHasBrokenLink() {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
// Set up two draft pages with a link from content -> about
|
||||
$linkDest = $this->objFromFixture('Page','about');
|
||||
// Ensure that it's not on the published site
|
||||
$linkDest->doDeleteFromLive();
|
||||
|
||||
$linkSrc = $this->objFromFixture('Page','content');
|
||||
$linkSrc->Content = "<p><a href=\"[sitetree_link id=$linkDest->ID]\">about us</a></p>";
|
||||
$linkSrc->write();
|
||||
|
||||
// Publish the source of the link, while the dest is still unpublished.
|
||||
$linkSrc->doPublish();
|
||||
|
||||
// Verify that the link isn't broken on draft but is broken on published
|
||||
$this->assertEquals(0, (int)$linkSrc->HasBrokenLink);
|
||||
$this->assertEquals(1, DB::query("SELECT \"HasBrokenLink\" FROM \"SiteTree_Live\"
|
||||
WHERE \"ID\" = $linkSrc->ID")->value());
|
||||
}
|
||||
|
||||
|
||||
function testRestoreFixesBrokenLinks() {
|
||||
// Create page and virutal page
|
||||
$p = new Page();
|
||||
$p->Title = "source";
|
||||
$p->write();
|
||||
$pageID = $p->ID;
|
||||
$this->assertTrue($p->doPublish());
|
||||
|
||||
// Content links are one kind of link to pages
|
||||
$p2 = new Page();
|
||||
$p2->Title = "regular link";
|
||||
$p2->Content = "<a href=\"[sitetree_link id=$p->ID]\">test</a>";
|
||||
$p2->write();
|
||||
$this->assertTrue($p2->doPublish());
|
||||
|
||||
// Virtual pages are another
|
||||
$vp = new VirtualPage();
|
||||
$vp->CopyContentFromID = $p->ID;
|
||||
$vp->write();
|
||||
|
||||
// Redirector links are a third
|
||||
$rp = new RedirectorPage();
|
||||
$rp->Title = "redirector";
|
||||
$rp->LinkType = 'Internal';
|
||||
$rp->LinkToID = $p->ID;
|
||||
$rp->write();
|
||||
$this->assertTrue($rp->doPublish());
|
||||
|
||||
// Confirm that there are no broken links to begin with
|
||||
$this->assertFalse($p2->HasBrokenLink);
|
||||
$this->assertFalse($vp->HasBrokenLink);
|
||||
$this->assertFalse($rp->HasBrokenLink);
|
||||
|
||||
// Unpublish the source page, confirm that the page 2 and RP has a broken link on published
|
||||
$p->doUnpublish();
|
||||
$p2Live = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $p2->ID);
|
||||
$rpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $rp->ID);
|
||||
$this->assertEquals(1, $p2Live->HasBrokenLink);
|
||||
$this->assertEquals(1, $rpLive->HasBrokenLink);
|
||||
|
||||
// Delete the source page, confirm that the VP, RP and page 2 have broken links on draft
|
||||
$p->delete();
|
||||
$vp->flushCache();
|
||||
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
|
||||
$p2->flushCache();
|
||||
$p2 = DataObject::get_by_id('SiteTree', $p2->ID);
|
||||
$rp->flushCache();
|
||||
$rp = DataObject::get_by_id('SiteTree', $rp->ID);
|
||||
$this->assertEquals(1, $p2->HasBrokenLink);
|
||||
$this->assertEquals(1, $vp->HasBrokenLink);
|
||||
$this->assertEquals(1, $rp->HasBrokenLink);
|
||||
|
||||
// Restore the page to stage, confirm that this fixes the links
|
||||
$p = Versioned::get_latest_version('SiteTree', $pageID);
|
||||
$p->doRestoreToStage();
|
||||
|
||||
$p2->flushCache();
|
||||
$p2 = DataObject::get_by_id('SiteTree', $p2->ID);
|
||||
$vp->flushCache();
|
||||
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
|
||||
$rp->flushCache();
|
||||
$rp = DataObject::get_by_id('SiteTree', $rp->ID);
|
||||
$this->assertFalse((bool)$p2->HasBrokenLink);
|
||||
$this->assertFalse((bool)$vp->HasBrokenLink);
|
||||
$this->assertFalse((bool)$rp->HasBrokenLink);
|
||||
|
||||
// Publish and confirm that the p2 and RP broken links are fixed on published
|
||||
$this->assertTrue($p->doPublish());
|
||||
$p2Live = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $p2->ID);
|
||||
$rpLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $rp->ID);
|
||||
$this->assertFalse((bool)$p2Live->HasBrokenLink);
|
||||
$this->assertFalse((bool)$rpLive->HasBrokenLink);
|
||||
|
||||
}
|
||||
|
||||
function testRevertToLiveFixesBrokenLinks() {
|
||||
// Create page and virutal page
|
||||
$p = new Page();
|
||||
$p->Title = "source";
|
||||
$p->write();
|
||||
$pageID = $p->ID;
|
||||
$this->assertTrue($p->doPublish());
|
||||
|
||||
// Content links are one kind of link to pages
|
||||
$p2 = new Page();
|
||||
$p2->Title = "regular link";
|
||||
$p2->Content = "<a href=\"[sitetree_link id=$p->ID]\">test</a>";
|
||||
$p2->write();
|
||||
$this->assertTrue($p2->doPublish());
|
||||
|
||||
// Virtual pages are another
|
||||
$vp = new VirtualPage();
|
||||
$vp->CopyContentFromID = $p->ID;
|
||||
$vp->write();
|
||||
|
||||
// Redirector links are a third
|
||||
$rp = new RedirectorPage();
|
||||
$rp->Title = "redirector";
|
||||
$rp->LinkType = 'Internal';
|
||||
$rp->LinkToID = $p->ID;
|
||||
$rp->write();
|
||||
$this->assertTrue($rp->doPublish());
|
||||
|
||||
// Confirm that there are no broken links to begin with
|
||||
$this->assertFalse($p2->HasBrokenLink);
|
||||
$this->assertFalse($vp->HasBrokenLink);
|
||||
$this->assertFalse($rp->HasBrokenLink);
|
||||
|
||||
// Delete from draft and confirm that broken links are marked
|
||||
$pID = $p->ID;
|
||||
$p->delete();
|
||||
|
||||
$vp->flushCache();
|
||||
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
|
||||
$p2->flushCache();
|
||||
$p2 = DataObject::get_by_id('SiteTree', $p2->ID);
|
||||
$rp->flushCache();
|
||||
$rp = DataObject::get_by_id('SiteTree', $rp->ID);
|
||||
$this->assertEquals(1, $p2->HasBrokenLink);
|
||||
$this->assertEquals(1, $vp->HasBrokenLink);
|
||||
$this->assertEquals(1, $rp->HasBrokenLink);
|
||||
|
||||
// Call doRevertToLive and confirm that broken links are restored
|
||||
$pLive = Versioned::get_one_by_stage('SiteTree', 'Live', '"SiteTree"."ID" = ' . $pID);
|
||||
$pLive->doRevertToLive();
|
||||
|
||||
$p2->flushCache();
|
||||
$p2 = DataObject::get_by_id('SiteTree', $p2->ID);
|
||||
$vp->flushCache();
|
||||
$vp = DataObject::get_by_id('SiteTree', $vp->ID);
|
||||
$rp->flushCache();
|
||||
$rp = DataObject::get_by_id('SiteTree', $rp->ID);
|
||||
$this->assertFalse((bool)$p2->HasBrokenLink);
|
||||
$this->assertFalse((bool)$vp->HasBrokenLink);
|
||||
$this->assertFalse((bool)$rp->HasBrokenLink);
|
||||
|
||||
// However, the page isn't marked as modified on stage
|
||||
$this->assertFalse($p2->IsModifiedOnStage);
|
||||
$this->assertFalse($rp->IsModifiedOnStage);
|
||||
|
||||
// This is something that we know to be broken
|
||||
//$this->assertFalse($vp->IsModifiedOnStage);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
27
tests/SiteTreeBrokenLinksTest.yml
Normal file
27
tests/SiteTreeBrokenLinksTest.yml
Normal file
@ -0,0 +1,27 @@
|
||||
Page:
|
||||
content:
|
||||
Title: ContentPage
|
||||
Content: This is some happy content.
|
||||
about:
|
||||
Title: About
|
||||
URLSegment: about
|
||||
Content: about us here
|
||||
brokenInternalRedirector:
|
||||
RedirectionType: Internal
|
||||
Title: RedirectorPageToBrokenInteralPage
|
||||
LinkToID: 0
|
||||
workingInternalRedirector:
|
||||
RedirectionType: Internal
|
||||
Title: RedirectorPageToBrokenInteralPage
|
||||
LinkTo: =>Page.content
|
||||
|
||||
File:
|
||||
privacypolicy:
|
||||
Name: privacypolicy.pdf
|
||||
Title: privacypolicy.pdf
|
||||
Filename: assets/privacypolicy.pdf
|
||||
|
||||
ErrorPage:
|
||||
404:
|
||||
Title: Page not Found
|
||||
ErrorCode: 404
|
445
tests/SiteTreePermissionsTest.php
Executable file
445
tests/SiteTreePermissionsTest.php
Executable file
@ -0,0 +1,445 @@
|
||||
<?php
|
||||
/**
|
||||
* @package sapphire
|
||||
* @subpackage tests
|
||||
*
|
||||
* @todo Test canAddChildren()
|
||||
* @todo Test canCreate()
|
||||
*/
|
||||
class SiteTreePermissionsTest extends FunctionalTest {
|
||||
static $fixture_file = "cms/tests/SiteTreePermissionsTest.yml";
|
||||
|
||||
protected $illegalExtensions = array(
|
||||
'SiteTree' => array('SiteTreeSubsites')
|
||||
);
|
||||
|
||||
static function set_up_once() {
|
||||
SiteTreeTest::set_up_once();
|
||||
|
||||
parent::set_up_once();
|
||||
}
|
||||
|
||||
static function tear_down_once() {
|
||||
SiteTreeTest::tear_down_once();
|
||||
|
||||
parent::tear_down_once();
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
$this->useDraftSite();
|
||||
|
||||
// we're testing HTTP status codes before being redirected to login forms
|
||||
$this->autoFollowRedirection = false;
|
||||
}
|
||||
|
||||
|
||||
function testAccessingStageWithBlankStage() {
|
||||
$this->useDraftSite(false);
|
||||
$this->autoFollowRedirection = false;
|
||||
|
||||
$page = $this->objFromFixture('Page', 'draftOnlyPage');
|
||||
|
||||
if($member = Member::currentUser()) {
|
||||
$member->logOut();
|
||||
}
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=Live');
|
||||
$this->assertEquals($response->getStatusCode(), '404');
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=');
|
||||
$this->assertEquals($response->getStatusCode(), '404');
|
||||
|
||||
// should be prompted for a login
|
||||
$response = $this->get($page->URLSegment . '?stage=Stage');
|
||||
$this->assertEquals($response->getStatusCode(), '302');
|
||||
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=Live');
|
||||
$this->assertEquals($response->getStatusCode(), '404');
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=Stage');
|
||||
$this->assertEquals($response->getStatusCode(), '200');
|
||||
|
||||
$response = $this->get($page->URLSegment . '?stage=');
|
||||
$this->assertEquals($response->getStatusCode(), '404');
|
||||
}
|
||||
|
||||
function testPermissionCheckingWorksOnDeletedPages() {
|
||||
// Set up fixture - a published page deleted from draft
|
||||
$this->logInWithPermission("ADMIN");
|
||||
$page = $this->objFromFixture('Page','restrictedEditOnlySubadminGroup');
|
||||
$pageID = $page->ID;
|
||||
$this->assertTrue($page->doPublish());
|
||||
$page->delete();
|
||||
|
||||
// Re-fetch the page from the live site
|
||||
$page = Versioned::get_one_by_stage('SiteTree', 'Live', "\"SiteTree\".\"ID\" = $pageID");
|
||||
|
||||
// subadmin has edit rights on that page
|
||||
$member = $this->objFromFixture('Member','subadmin');
|
||||
$member->logIn();
|
||||
|
||||
// Test can_edit_multiple
|
||||
$this->assertEquals(
|
||||
array($pageID => true),
|
||||
SiteTree::can_edit_multiple(array($pageID), $member->ID)
|
||||
);
|
||||
|
||||
// Test canEdit
|
||||
$member->logIn();
|
||||
$this->assertTrue($page->canEdit());
|
||||
}
|
||||
|
||||
function testPermissionCheckingWorksOnUnpublishedPages() {
|
||||
// Set up fixture - an unpublished page
|
||||
$this->logInWithPermission("ADMIN");
|
||||
$page = $this->objFromFixture('Page','restrictedEditOnlySubadminGroup');
|
||||
$pageID = $page->ID;
|
||||
$page->doUnpublish();
|
||||
|
||||
// subadmin has edit rights on that page
|
||||
$member = $this->objFromFixture('Member','subadmin');
|
||||
$member->logIn();
|
||||
|
||||
// Test can_edit_multiple
|
||||
$this->assertEquals(
|
||||
array($pageID => true),
|
||||
SiteTree::can_edit_multiple(array($pageID), $member->ID)
|
||||
);
|
||||
|
||||
// Test canEdit
|
||||
$member->logIn();
|
||||
$this->assertTrue($page->canEdit());
|
||||
}
|
||||
|
||||
function testCanEditOnPageDeletedFromStageAndLiveReturnsFalse() {
|
||||
// Find a page that exists and delete it from both stage and published
|
||||
$this->logInWithPermission("ADMIN");
|
||||
$page = $this->objFromFixture('Page','restrictedEditOnlySubadminGroup');
|
||||
$pageID = $page->ID;
|
||||
$page->doUnpublish();
|
||||
$page->delete();
|
||||
|
||||
// We'll need to resurrect the page from the version cache to test this case
|
||||
$page = Versioned::get_latest_version('SiteTree', $pageID);
|
||||
|
||||
// subadmin had edit rights on that page, but now it's gone
|
||||
$member = $this->objFromFixture('Member','subadmin');
|
||||
$member->logIn();
|
||||
|
||||
$this->assertFalse($page->canEdit());
|
||||
}
|
||||
|
||||
function testCanViewStage() {
|
||||
$page = $this->objFromFixture('Page', 'standardpage');
|
||||
$editor = $this->objFromFixture('Member', 'editor');
|
||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||
|
||||
$this->assertTrue($page->canViewStage('Live', $websiteuser));
|
||||
$this->assertFalse($page->canViewStage('Stage', $websiteuser));
|
||||
|
||||
$this->assertTrue($page->canViewStage('Live', $editor));
|
||||
$this->assertTrue($page->canViewStage('Stage', $editor));
|
||||
}
|
||||
|
||||
function testAccessTabOnlyDisplaysWithGrantAccessPermissions() {
|
||||
$page = $this->objFromFixture('Page', 'standardpage');
|
||||
|
||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||
$this->session()->inst_set('loggedInAs', $subadminuser->ID);
|
||||
$fields = $page->getCMSFields();
|
||||
$this->assertFalse(
|
||||
$fields->dataFieldByName('CanViewType')->isReadonly(),
|
||||
'Users with SITETREE_GRANT_ACCESS permission can change "view" permissions in cms fields'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$fields->dataFieldByName('CanEditType')->isReadonly(),
|
||||
'Users with SITETREE_GRANT_ACCESS permission can change "edit" permissions in cms fields'
|
||||
);
|
||||
|
||||
$editoruser = $this->objFromFixture('Member', 'editor');
|
||||
$this->session()->inst_set('loggedInAs', $editoruser->ID);
|
||||
$fields = $page->getCMSFields();
|
||||
$this->assertTrue(
|
||||
$fields->dataFieldByName('CanViewType')->isReadonly(),
|
||||
'Users without SITETREE_GRANT_ACCESS permission cannot change "view" permissions in cms fields'
|
||||
);
|
||||
$this->assertTrue(
|
||||
$fields->dataFieldByName('CanEditType')->isReadonly(),
|
||||
'Users without SITETREE_GRANT_ACCESS permission cannot change "edit" permissions in cms fields'
|
||||
);
|
||||
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
}
|
||||
|
||||
function testRestrictedViewLoggedInUsers() {
|
||||
$page = $this->objFromFixture('Page', 'restrictedViewLoggedInUsers');
|
||||
|
||||
// unauthenticated users
|
||||
$this->assertFalse(
|
||||
$page->canView(FALSE),
|
||||
'Unauthenticated members cant view a page marked as "Viewable for any logged in users"'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
$response = $this->get($page->RelativeLink());
|
||||
$this->assertEquals(
|
||||
$response->getStatusCode(),
|
||||
302,
|
||||
'Unauthenticated members cant view a page marked as "Viewable for any logged in users"'
|
||||
);
|
||||
|
||||
// website users
|
||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||
$this->assertTrue(
|
||||
$page->canView($websiteuser),
|
||||
'Authenticated members can view a page marked as "Viewable for any logged in users" even if they dont have access to the CMS'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', $websiteuser->ID);
|
||||
$response = $this->get($page->RelativeLink());
|
||||
$this->assertEquals(
|
||||
$response->getStatusCode(),
|
||||
200,
|
||||
'Authenticated members can view a page marked as "Viewable for any logged in users" even if they dont have access to the CMS'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
}
|
||||
|
||||
function testRestrictedViewOnlyTheseUsers() {
|
||||
$page = $this->objFromFixture('Page', 'restrictedViewOnlyWebsiteUsers');
|
||||
|
||||
// unauthenticcated users
|
||||
$this->assertFalse(
|
||||
$page->canView(FALSE),
|
||||
'Unauthenticated members cant view a page marked as "Viewable by these groups"'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
$response = $this->get($page->RelativeLink());
|
||||
$this->assertEquals(
|
||||
$response->getStatusCode(),
|
||||
302,
|
||||
'Unauthenticated members cant view a page marked as "Viewable by these groups"'
|
||||
);
|
||||
|
||||
// subadmin users
|
||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||
$this->assertFalse(
|
||||
$page->canView($subadminuser),
|
||||
'Authenticated members cant view a page marked as "Viewable by these groups" if theyre not in the listed groups'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', $subadminuser->ID);
|
||||
$response = $this->get($page->RelativeLink());
|
||||
$this->assertEquals(
|
||||
$response->getStatusCode(),
|
||||
403,
|
||||
'Authenticated members cant view a page marked as "Viewable by these groups" if theyre not in the listed groups'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
|
||||
// website users
|
||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||
$this->assertTrue(
|
||||
$page->canView($websiteuser),
|
||||
'Authenticated members can view a page marked as "Viewable by these groups" if theyre in the listed groups'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', $websiteuser->ID);
|
||||
$response = $this->get($page->RelativeLink());
|
||||
$this->assertEquals(
|
||||
$response->getStatusCode(),
|
||||
200,
|
||||
'Authenticated members can view a page marked as "Viewable by these groups" if theyre in the listed groups'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
}
|
||||
|
||||
function testRestrictedEditLoggedInUsers() {
|
||||
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
|
||||
|
||||
// unauthenticcated users
|
||||
$this->assertFalse(
|
||||
$page->canEdit(FALSE),
|
||||
'Unauthenticated members cant edit a page marked as "Editable by logged in users"'
|
||||
);
|
||||
|
||||
// website users
|
||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||
$websiteuser->logIn();
|
||||
$this->assertFalse(
|
||||
$page->canEdit($websiteuser),
|
||||
'Authenticated members cant edit a page marked as "Editable by logged in users" if they dont have cms permissions'
|
||||
);
|
||||
|
||||
// subadmin users
|
||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||
$this->assertTrue(
|
||||
$page->canEdit($subadminuser),
|
||||
'Authenticated members can edit a page marked as "Editable by logged in users" if they have cms permissions and belong to any of these groups'
|
||||
);
|
||||
}
|
||||
|
||||
function testRestrictedEditOnlySubadminGroup() {
|
||||
$page = $this->objFromFixture('Page', 'restrictedEditOnlySubadminGroup');
|
||||
|
||||
// unauthenticated users
|
||||
$this->assertFalse(
|
||||
$page->canEdit(FALSE),
|
||||
'Unauthenticated members cant edit a page marked as "Editable by these groups"'
|
||||
);
|
||||
|
||||
// subadmin users
|
||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||
$this->assertTrue(
|
||||
$page->canEdit($subadminuser),
|
||||
'Authenticated members can view a page marked as "Editable by these groups" if theyre in the listed groups'
|
||||
);
|
||||
|
||||
// website users
|
||||
$websiteuser = $this->objFromFixture('Member', 'websiteuser');
|
||||
$this->assertFalse(
|
||||
$page->canEdit($websiteuser),
|
||||
'Authenticated members cant edit a page marked as "Editable by these groups" if theyre not in the listed groups'
|
||||
);
|
||||
}
|
||||
|
||||
function testRestrictedViewInheritance() {
|
||||
$parentPage = $this->objFromFixture('Page', 'parent_restrictedViewOnlySubadminGroup');
|
||||
$childPage = $this->objFromFixture('Page', 'child_restrictedViewOnlySubadminGroup');
|
||||
|
||||
// unauthenticated users
|
||||
$this->assertFalse(
|
||||
$childPage->canView(FALSE),
|
||||
'Unauthenticated members cant view a page marked as "Viewable by these groups" by inherited permission'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
$response = $this->get($childPage->RelativeLink());
|
||||
$this->assertEquals(
|
||||
$response->getStatusCode(),
|
||||
302,
|
||||
'Unauthenticated members cant view a page marked as "Viewable by these groups" by inherited permission'
|
||||
);
|
||||
|
||||
// subadmin users
|
||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||
$this->assertTrue(
|
||||
$childPage->canView($subadminuser),
|
||||
'Authenticated members can view a page marked as "Viewable by these groups" if theyre in the listed groups by inherited permission'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', $subadminuser->ID);
|
||||
$response = $this->get($childPage->RelativeLink());
|
||||
$this->assertEquals(
|
||||
$response->getStatusCode(),
|
||||
200,
|
||||
'Authenticated members can view a page marked as "Viewable by these groups" if theyre in the listed groups by inherited permission'
|
||||
);
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
}
|
||||
|
||||
function testRestrictedEditInheritance() {
|
||||
$parentPage = $this->objFromFixture('Page', 'parent_restrictedEditOnlySubadminGroup');
|
||||
$childPage = $this->objFromFixture('Page', 'child_restrictedEditOnlySubadminGroup');
|
||||
|
||||
// unauthenticated users
|
||||
$this->assertFalse(
|
||||
$childPage->canEdit(FALSE),
|
||||
'Unauthenticated members cant edit a page marked as "Editable by these groups" by inherited permission'
|
||||
);
|
||||
|
||||
// subadmin users
|
||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||
$this->assertTrue(
|
||||
$childPage->canEdit($subadminuser),
|
||||
'Authenticated members can edit a page marked as "Editable by these groups" if theyre in the listed groups by inherited permission'
|
||||
);
|
||||
}
|
||||
|
||||
function testDeleteRestrictedChild() {
|
||||
$parentPage = $this->objFromFixture('Page', 'deleteTestParentPage');
|
||||
$childPage = $this->objFromFixture('Page', 'deleteTestChildPage');
|
||||
|
||||
// unauthenticated users
|
||||
$this->assertFalse(
|
||||
$parentPage->canDelete(FALSE),
|
||||
'Unauthenticated members cant delete a page if it doesnt have delete permissions on any of its descendants'
|
||||
);
|
||||
$this->assertFalse(
|
||||
$childPage->canDelete(FALSE),
|
||||
'Unauthenticated members cant delete a child page marked as "Editable by these groups"'
|
||||
);
|
||||
}
|
||||
|
||||
function testRestrictedEditLoggedInUsersDeletedFromStage() {
|
||||
$page = $this->objFromFixture('Page', 'restrictedEditLoggedInUsers');
|
||||
$pageID = $page->ID;
|
||||
|
||||
$this->logInWithPermission("ADMIN");
|
||||
|
||||
$page->doPublish();
|
||||
$page->deleteFromStage('Stage');
|
||||
|
||||
// Get the live version of the page
|
||||
$page = Versioned::get_one_by_stage("SiteTree", "Live", "\"SiteTree\".\"ID\" = $pageID");
|
||||
$this->assertTrue(is_object($page), 'Versioned::get_one_by_stage() is returning an object');
|
||||
|
||||
// subadmin users
|
||||
$subadminuser = $this->objFromFixture('Member', 'subadmin');
|
||||
$this->assertTrue(
|
||||
$page->canEdit($subadminuser),
|
||||
'Authenticated members can edit a page that was deleted from stage and marked as "Editable by logged in users" if they have cms permissions and belong to any of these groups'
|
||||
);
|
||||
}
|
||||
|
||||
function testInheritCanViewFromSiteConfig() {
|
||||
$page = $this->objFromFixture('Page', 'inheritWithNoParent');
|
||||
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
|
||||
$editor = $this->objFromFixture('Member', 'editor');
|
||||
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
|
||||
|
||||
$siteconfig->CanViewType = 'Anyone';
|
||||
$siteconfig->write();
|
||||
$this->assertTrue($page->canView(FALSE), 'Anyone can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
||||
|
||||
$siteconfig->CanViewType = 'LoggedInUsers';
|
||||
$siteconfig->write();
|
||||
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
||||
|
||||
$siteconfig->CanViewType = 'LoggedInUsers';
|
||||
$siteconfig->write();
|
||||
$this->assertTrue($page->canView($editor), 'Users can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to LoggedInUsers');
|
||||
|
||||
$siteconfig->CanViewType = 'OnlyTheseUsers';
|
||||
$siteconfig->ViewerGroups()->add($editorGroup);
|
||||
$siteconfig->ViewerGroups()->write();
|
||||
$siteconfig->write();
|
||||
$this->assertTrue($page->canView($editor), 'Editors can view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
|
||||
$this->assertFalse($page->canView(FALSE), 'Anonymous can\'t view a page when set to inherit from the SiteConfig, and SiteConfig has canView set to OnlyTheseUsers');
|
||||
}
|
||||
|
||||
function testInheritCanEditFromSiteConfig() {
|
||||
$page = $this->objFromFixture('Page', 'inheritWithNoParent');
|
||||
$siteconfig = $this->objFromFixture('SiteConfig', 'default');
|
||||
$editor = $this->objFromFixture('Member', 'editor');
|
||||
$user = $this->objFromFixture('Member', 'websiteuser');
|
||||
$editorGroup = $this->objFromFixture('Group', 'editorgroup');
|
||||
|
||||
$siteconfig->CanEditType = 'LoggedInUsers';
|
||||
$siteconfig->write();
|
||||
|
||||
$this->assertFalse($page->canEdit(FALSE), 'Anonymous can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
|
||||
$this->session()->inst_set('loggedInAs', $editor->ID);
|
||||
$this->assertTrue($page->canEdit(), 'Users can edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to LoggedInUsers');
|
||||
|
||||
$siteconfig->CanEditType = 'OnlyTheseUsers';
|
||||
$siteconfig->EditorGroups()->add($editorGroup);
|
||||
$siteconfig->EditorGroups()->write();
|
||||
$siteconfig->write();
|
||||
$this->assertTrue($page->canEdit($editor), 'Editors can edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to OnlyTheseUsers');
|
||||
$this->session()->inst_set('loggedInAs', null);
|
||||
$this->assertFalse($page->canEdit(FALSE), 'Anonymous can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to OnlyTheseUsers');
|
||||
$this->session()->inst_set('loggedInAs', $user->ID);
|
||||
$this->assertFalse($page->canEdit($user), 'Website user can\'t edit a page when set to inherit from the SiteConfig, and SiteConfig has canEdit set to OnlyTheseUsers');
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
88
tests/SiteTreePermissionsTest.yml
Normal file
88
tests/SiteTreePermissionsTest.yml
Normal file
@ -0,0 +1,88 @@
|
||||
SiteConfig:
|
||||
default:
|
||||
Title: My test site
|
||||
Tagline: There is no doubt this is a great test site
|
||||
CanViewType: Anyone
|
||||
CanEditType: LoggedInUsers
|
||||
Permission:
|
||||
cmsmain1:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
cmsmain2:
|
||||
Code: CMS_ACCESS_CMSMain
|
||||
grantaccess:
|
||||
Code: SITETREE_GRANT_ACCESS
|
||||
Group:
|
||||
subadmingroup:
|
||||
Title: Create, edit and delete pages
|
||||
Code: subadmingroup
|
||||
Permissions: =>Permission.cmsmain1,=>Permission.grantaccess
|
||||
editorgroup:
|
||||
Title: Edit existing pages
|
||||
Code: editorgroup
|
||||
Permissions: =>Permission.cmsmain2
|
||||
websiteusers:
|
||||
Title: View certain restricted pages
|
||||
Member:
|
||||
subadmin:
|
||||
Email: subadmin@test.com
|
||||
Password: test
|
||||
Groups: =>Group.subadmingroup
|
||||
editor:
|
||||
Email: editor@test.com
|
||||
Password: test
|
||||
Groups: =>Group.editorgroup
|
||||
websiteuser:
|
||||
Email: websiteuser@test.com
|
||||
Password: test
|
||||
Groups: =>Group.websiteusers
|
||||
Page:
|
||||
standardpage:
|
||||
URLSegment: standardpage
|
||||
restrictedViewLoggedInUsers:
|
||||
CanViewType: LoggedInUsers
|
||||
URLSegment: restrictedViewLoggedInUsers
|
||||
restrictedViewOnlyWebsiteUsers:
|
||||
CanViewType: OnlyTheseUsers
|
||||
ViewerGroups: =>Group.websiteusers
|
||||
URLSegment: restrictedViewOnlyWebsiteUsers
|
||||
restrictedViewOnlySubadminGroup:
|
||||
CanViewType: OnlyTheseUsers
|
||||
ViewerGroups: =>Group.subadmingroup
|
||||
URLSegment: restrictedViewOnlySubadminGroup
|
||||
restrictedEditLoggedInUsers:
|
||||
CanEditType: LoggedInUsers
|
||||
URLSegment: restrictedEditLoggedInUsers
|
||||
restrictedEditOnlySubadminGroup:
|
||||
CanEditType: OnlyTheseUsers
|
||||
EditorGroups: =>Group.subadmingroup
|
||||
URLSegment: restrictedEditOnlySubadminGroup
|
||||
inheritWithNoParent:
|
||||
CanEditType: Inherit
|
||||
CanViewType: Inherit
|
||||
URLSegment: inheritWithNoParent
|
||||
parent_restrictedViewOnlySubadminGroup:
|
||||
CanViewType: OnlyTheseUsers
|
||||
ViewerGroups: =>Group.subadmingroup
|
||||
URLSegment: parent-restrictedViewOnlySubadminGroup
|
||||
child_restrictedViewOnlySubadminGroup:
|
||||
CanViewType: Inherit
|
||||
Parent: =>Page.parent_restrictedViewOnlySubadminGroup
|
||||
URLSegment: child-restrictedViewOnlySubadminGroup
|
||||
parent_restrictedEditOnlySubadminGroup:
|
||||
CanEditType: OnlyTheseUsers
|
||||
EditorGroups: =>Group.subadmingroup
|
||||
URLSegment: parent-restrictedEditOnlySubadminGroup
|
||||
child_restrictedEditOnlySubadminGroup:
|
||||
CanEditType: Inherit
|
||||
Parent: =>Page.parent_restrictedEditOnlySubadminGroup
|
||||
URLSegment: child-restrictedEditOnlySubadminGroup
|
||||
deleteTestParentPage:
|
||||
CanEditType: Inherit
|
||||
URLSegment: deleteTestParentPage
|
||||
deleteTestChildPage:
|
||||
CanEditType: OnlyTheseUsers
|
||||
EditorGroups: =>Group.subadmingroup
|
||||
URLSegment: deleteTestChildPage
|
||||
draftOnlyPage:
|
||||
CanViewType: Anyone
|
||||
URLSegment: draft-only
|
758
tests/SiteTreeTest.php
Executable file
758
tests/SiteTreeTest.php
Executable file
@ -0,0 +1,758 @@
|
||||
<?php
|
||||
/**
|
||||
* @package sapphire
|
||||
* @subpackage tests
|
||||
*/
|
||||
class SiteTreeTest extends SapphireTest {
|
||||
static $fixture_file = 'cms/tests/SiteTreeTest.yml';
|
||||
|
||||
protected $illegalExtensions = array(
|
||||
'SiteTree' => array('SiteTreeSubsites')
|
||||
);
|
||||
|
||||
/**
|
||||
* @todo Necessary because of monolithic Translatable design
|
||||
*/
|
||||
static protected $origTranslatableSettings = array();
|
||||
|
||||
static function set_up_once() {
|
||||
// needs to recreate the database schema with language properties
|
||||
self::kill_temp_db();
|
||||
|
||||
// store old defaults
|
||||
self::$origTranslatableSettings['has_extension'] = singleton('SiteTree')->hasExtension('Translatable');
|
||||
self::$origTranslatableSettings['default_locale'] = Translatable::default_locale();
|
||||
|
||||
// overwrite locale
|
||||
Translatable::set_default_locale("en_US");
|
||||
|
||||
// refresh the decorated statics - different fields in $db with Translatable enabled
|
||||
if(self::$origTranslatableSettings['has_extension']) {
|
||||
Object::remove_extension('SiteTree', 'Translatable');
|
||||
Object::remove_extension('SiteConfig', 'Translatable');
|
||||
}
|
||||
|
||||
// recreate database with new settings
|
||||
$dbname = self::create_temp_db();
|
||||
DB::set_alternative_database_name($dbname);
|
||||
|
||||
parent::set_up_once();
|
||||
}
|
||||
|
||||
static function tear_down_once() {
|
||||
if(self::$origTranslatableSettings['has_extension']) {
|
||||
Object::add_extension('SiteTree', 'Translatable');
|
||||
Object::add_extension('SiteConfig', 'Translatable');
|
||||
}
|
||||
|
||||
|
||||
Translatable::set_default_locale(self::$origTranslatableSettings['default_locale']);
|
||||
Translatable::set_current_locale(self::$origTranslatableSettings['default_locale']);
|
||||
|
||||
self::kill_temp_db();
|
||||
self::create_temp_db();
|
||||
|
||||
parent::tear_down_once();
|
||||
}
|
||||
|
||||
function testCreateDefaultpages() {
|
||||
$remove = DataObject::get('SiteTree');
|
||||
if($remove) foreach($remove as $page) $page->delete();
|
||||
// Make sure the table is empty
|
||||
$this->assertEquals(DB::query('SELECT COUNT("ID") FROM "SiteTree"')->value(), 0);
|
||||
|
||||
// Disable the creation
|
||||
SiteTree::set_create_default_pages(false);
|
||||
singleton('SiteTree')->requireDefaultRecords();
|
||||
|
||||
// The table should still be empty
|
||||
$this->assertEquals(DB::query('SELECT COUNT("ID") FROM "SiteTree"')->value(), 0);
|
||||
|
||||
// Enable the creation
|
||||
SiteTree::set_create_default_pages(true);
|
||||
singleton('SiteTree')->requireDefaultRecords();
|
||||
|
||||
// The table should now have three rows (home, about-us, contact-us)
|
||||
$this->assertEquals(DB::query('SELECT COUNT("ID") FROM "SiteTree"')->value(), 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test generation of the URLSegment values.
|
||||
* - Turns things into lowercase-hyphen-format
|
||||
* - Generates from Title by default, unless URLSegment is explicitly set
|
||||
* - Resolves duplicates by appending a number
|
||||
* - renames classes with a class name conflict
|
||||
*/
|
||||
function testURLGeneration() {
|
||||
$expectedURLs = array(
|
||||
'home' => 'home',
|
||||
'staff' => 'my-staff',
|
||||
'about' => 'about-us',
|
||||
'staffduplicate' => 'my-staff-2',
|
||||
'product1' => '1-1-test-product',
|
||||
'product2' => 'another-product',
|
||||
'product3' => 'another-product-2',
|
||||
'product4' => 'another-product-3',
|
||||
'object' => 'object',
|
||||
'controller' => 'controller-2',
|
||||
'numericonly' => '1930',
|
||||
);
|
||||
|
||||
foreach($expectedURLs as $fixture => $urlSegment) {
|
||||
$obj = $this->objFromFixture('Page', $fixture);
|
||||
$this->assertEquals($urlSegment, $obj->URLSegment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that publication copies data to SiteTree_Live
|
||||
*/
|
||||
function testPublishCopiesToLiveTable() {
|
||||
$obj = $this->objFromFixture('Page','about');
|
||||
$obj->publish('Stage', 'Live');
|
||||
|
||||
$createdID = DB::query("SELECT \"ID\" FROM \"SiteTree_Live\" WHERE \"URLSegment\" = '$obj->URLSegment'")->value();
|
||||
$this->assertEquals($obj->ID, $createdID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that field which are set and then cleared are also transferred to the published site.
|
||||
*/
|
||||
function testPublishDeletedFields() {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
$obj = $this->objFromFixture('Page', 'about');
|
||||
$obj->MetaTitle = "asdfasdf";
|
||||
$obj->write();
|
||||
$this->assertTrue($obj->doPublish());
|
||||
|
||||
$this->assertEquals('asdfasdf', DB::query("SELECT \"MetaTitle\" FROM \"SiteTree_Live\" WHERE \"ID\" = '$obj->ID'")->value());
|
||||
|
||||
$obj->MetaTitle = null;
|
||||
$obj->write();
|
||||
$this->assertTrue($obj->doPublish());
|
||||
|
||||
$this->assertNull(DB::query("SELECT \"MetaTitle\" FROM \"SiteTree_Live\" WHERE \"ID\" = '$obj->ID'")->value());
|
||||
|
||||
}
|
||||
|
||||
function testParentNodeCachedInMemory() {
|
||||
$parent = new SiteTree();
|
||||
$parent->Title = 'Section Title';
|
||||
$child = new SiteTree();
|
||||
$child->Title = 'Page Title';
|
||||
$child->setParent($parent);
|
||||
|
||||
$this->assertType("SiteTree", $child->Parent);
|
||||
$this->assertEquals("Section Title", $child->Parent->Title);
|
||||
}
|
||||
|
||||
function testParentModelReturnType() {
|
||||
$parent = new SiteTreeTest_PageNode();
|
||||
$child = new SiteTreeTest_PageNode();
|
||||
|
||||
$child->setParent($parent);
|
||||
$this->assertType('SiteTreeTest_PageNode', $child->Parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that DataObject::get_one() gets records from SiteTree_Live
|
||||
*/
|
||||
function testGetOneFromLive() {
|
||||
$s = new SiteTree();
|
||||
$s->Title = "V1";
|
||||
$s->URLSegment = "get-one-test-page";
|
||||
$s->write();
|
||||
$s->publish("Stage", "Live");
|
||||
$s->Title = "V2";
|
||||
$s->write();
|
||||
|
||||
$oldMode = Versioned::get_reading_mode();
|
||||
Versioned::reading_stage('Live');
|
||||
|
||||
$checkSiteTree = DataObject::get_one("SiteTree", "\"URLSegment\" = 'get-one-test-page'");
|
||||
$this->assertEquals("V1", $checkSiteTree->Title);
|
||||
|
||||
Versioned::set_reading_mode($oldMode);
|
||||
}
|
||||
|
||||
function testChidrenOfRootAreTopLevelPages() {
|
||||
$pages = DataObject::get("SiteTree");
|
||||
foreach($pages as $page) $page->publish('Stage', 'Live');
|
||||
unset($pages);
|
||||
|
||||
/* If we create a new SiteTree object with ID = 0 */
|
||||
$obj = new SiteTree();
|
||||
/* Then its children should be the top-level pages */
|
||||
$stageChildren = $obj->stageChildren()->toDropDownMap('ID','Title');
|
||||
$liveChildren = $obj->liveChildren()->toDropDownMap('ID','Title');
|
||||
$allChildren = $obj->AllChildrenIncludingDeleted()->toDropDownMap('ID','Title');
|
||||
|
||||
$this->assertContains('Home', $stageChildren);
|
||||
$this->assertContains('Products', $stageChildren);
|
||||
$this->assertNotContains('Staff', $stageChildren);
|
||||
|
||||
$this->assertContains('Home', $liveChildren);
|
||||
$this->assertContains('Products', $liveChildren);
|
||||
$this->assertNotContains('Staff', $liveChildren);
|
||||
|
||||
$this->assertContains('Home', $allChildren);
|
||||
$this->assertContains('Products', $allChildren);
|
||||
$this->assertNotContains('Staff', $allChildren);
|
||||
}
|
||||
|
||||
function testCanSaveBlankToHasOneRelations() {
|
||||
/* DataObject::write() should save to a has_one relationship if you set a field called (relname)ID */
|
||||
$page = new SiteTree();
|
||||
$parentID = $this->idFromFixture('Page', 'home');
|
||||
$page->ParentID = $parentID;
|
||||
$page->write();
|
||||
$this->assertEquals($parentID, DB::query("SELECT \"ParentID\" FROM \"SiteTree\" WHERE \"ID\" = $page->ID")->value());
|
||||
|
||||
/* You should then be able to save a null/0/'' value to the relation */
|
||||
$page->ParentID = null;
|
||||
$page->write();
|
||||
$this->assertEquals(0, DB::query("SELECT \"ParentID\" FROM \"SiteTree\" WHERE \"ID\" = $page->ID")->value());
|
||||
}
|
||||
|
||||
function testStageStates() {
|
||||
// newly created page
|
||||
$createdPage = new SiteTree();
|
||||
$createdPage->write();
|
||||
$this->assertFalse($createdPage->IsDeletedFromStage);
|
||||
$this->assertTrue($createdPage->IsAddedToStage);
|
||||
$this->assertTrue($createdPage->IsModifiedOnStage);
|
||||
|
||||
// published page
|
||||
$publishedPage = new SiteTree();
|
||||
$publishedPage->write();
|
||||
$publishedPage->publish('Stage','Live');
|
||||
$this->assertFalse($publishedPage->IsDeletedFromStage);
|
||||
$this->assertFalse($publishedPage->IsAddedToStage);
|
||||
$this->assertFalse($publishedPage->IsModifiedOnStage);
|
||||
|
||||
// published page, deleted from stage
|
||||
$deletedFromDraftPage = new SiteTree();
|
||||
$deletedFromDraftPage->write();
|
||||
$deletedFromDraftPageID = $deletedFromDraftPage->ID;
|
||||
$deletedFromDraftPage->publish('Stage','Live');
|
||||
$deletedFromDraftPage->deleteFromStage('Stage');
|
||||
$this->assertTrue($deletedFromDraftPage->IsDeletedFromStage);
|
||||
$this->assertFalse($deletedFromDraftPage->IsAddedToStage);
|
||||
$this->assertFalse($deletedFromDraftPage->IsModifiedOnStage);
|
||||
|
||||
// published page, deleted from live
|
||||
$deletedFromLivePage = new SiteTree();
|
||||
$deletedFromLivePage->write();
|
||||
$deletedFromLivePage->publish('Stage','Live');
|
||||
$deletedFromLivePage->deleteFromStage('Stage');
|
||||
$deletedFromLivePage->deleteFromStage('Live');
|
||||
$this->assertTrue($deletedFromLivePage->IsDeletedFromStage);
|
||||
$this->assertFalse($deletedFromLivePage->IsAddedToStage);
|
||||
$this->assertFalse($deletedFromLivePage->IsModifiedOnStage);
|
||||
|
||||
// published page, modified
|
||||
$modifiedOnDraftPage = new SiteTree();
|
||||
$modifiedOnDraftPage->write();
|
||||
$modifiedOnDraftPage->publish('Stage','Live');
|
||||
$modifiedOnDraftPage->Content = 'modified';
|
||||
$modifiedOnDraftPage->write();
|
||||
$this->assertFalse($modifiedOnDraftPage->IsDeletedFromStage);
|
||||
$this->assertFalse($modifiedOnDraftPage->IsAddedToStage);
|
||||
$this->assertTrue($modifiedOnDraftPage->IsModifiedOnStage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a page can be completely deleted and restored to the stage site
|
||||
*/
|
||||
function testRestoreToStage() {
|
||||
$page = $this->objFromFixture('Page', 'about');
|
||||
$pageID = $page->ID;
|
||||
$page->delete();
|
||||
$this->assertTrue(!DataObject::get_by_id("Page", $pageID));
|
||||
|
||||
$deletedPage = Versioned::get_latest_version('SiteTree', $pageID);
|
||||
$resultPage = $deletedPage->doRestoreToStage();
|
||||
|
||||
$requeriedPage = DataObject::get_by_id("Page", $pageID);
|
||||
|
||||
$this->assertEquals($pageID, $resultPage->ID);
|
||||
$this->assertEquals($pageID, $requeriedPage->ID);
|
||||
$this->assertEquals('About Us', $requeriedPage->Title);
|
||||
$this->assertEquals('Page', $requeriedPage->class);
|
||||
|
||||
|
||||
$page2 = $this->objFromFixture('Page', 'products');
|
||||
$page2ID = $page2->ID;
|
||||
$page2->doUnpublish();
|
||||
$page2->delete();
|
||||
|
||||
// Check that if we restore while on the live site that the content still gets pushed to
|
||||
// stage
|
||||
Versioned::reading_stage('Live');
|
||||
$deletedPage = Versioned::get_latest_version('SiteTree', $page2ID);
|
||||
$deletedPage->doRestoreToStage();
|
||||
$this->assertTrue(!Versioned::get_one_by_stage("Page", "Live", "\"SiteTree\".\"ID\" = " . $page2ID));
|
||||
|
||||
Versioned::reading_stage('Stage');
|
||||
$requeriedPage = DataObject::get_by_id("Page", $page2ID);
|
||||
$this->assertEquals('Products', $requeriedPage->Title);
|
||||
$this->assertEquals('Page', $requeriedPage->class);
|
||||
|
||||
}
|
||||
|
||||
public function testGetByLink() {
|
||||
$home = $this->objFromFixture('Page', 'home');
|
||||
$about = $this->objFromFixture('Page', 'about');
|
||||
$staff = $this->objFromFixture('Page', 'staff');
|
||||
$product = $this->objFromFixture('Page', 'product1');
|
||||
$notFound = $this->objFromFixture('ErrorPage', '404');
|
||||
|
||||
SiteTree::disable_nested_urls();
|
||||
|
||||
$this->assertEquals($home->ID, SiteTree::get_by_link('/', false)->ID);
|
||||
$this->assertEquals($home->ID, SiteTree::get_by_link('/home/', false)->ID);
|
||||
$this->assertEquals($about->ID, SiteTree::get_by_link($about->Link(), false)->ID);
|
||||
$this->assertEquals($staff->ID, SiteTree::get_by_link($staff->Link(), false)->ID);
|
||||
$this->assertEquals($product->ID, SiteTree::get_by_link($product->Link(), false)->ID);
|
||||
$this->assertEquals($notFound->ID, SiteTree::get_by_link($notFound->Link(), false)->ID);
|
||||
|
||||
SiteTree::enable_nested_urls();
|
||||
|
||||
$this->assertEquals($home->ID, SiteTree::get_by_link('/', false)->ID);
|
||||
$this->assertEquals($home->ID, SiteTree::get_by_link('/home/', false)->ID);
|
||||
$this->assertEquals($about->ID, SiteTree::get_by_link($about->Link(), false)->ID);
|
||||
$this->assertEquals($staff->ID, SiteTree::get_by_link($staff->Link(), false)->ID);
|
||||
$this->assertEquals($product->ID, SiteTree::get_by_link($product->Link(), false)->ID);
|
||||
$this->assertEquals($notFound->ID, SiteTree::get_by_link($notFound->Link(), false)->ID);
|
||||
|
||||
$this->assertEquals (
|
||||
$staff->ID, SiteTree::get_by_link('/my-staff/', false)->ID, 'Assert a unique URLSegment can be used for b/c.'
|
||||
);
|
||||
}
|
||||
|
||||
function testRelativeLink() {
|
||||
$about = $this->objFromFixture('Page', 'about');
|
||||
$staff = $this->objFromFixture('Page', 'staff');
|
||||
|
||||
SiteTree::enable_nested_urls();
|
||||
|
||||
$this->assertEquals('about-us/', $about->RelativeLink(), 'Matches URLSegment on top level without parameters');
|
||||
$this->assertEquals('about-us/my-staff/', $staff->RelativeLink(), 'Matches URLSegment plus parent on second level without parameters');
|
||||
$this->assertEquals('about-us/edit', $about->RelativeLink('edit'), 'Matches URLSegment plus parameter on top level');
|
||||
$this->assertEquals('about-us/tom&jerry', $about->RelativeLink('tom&jerry'), 'Doesnt url encode parameter');
|
||||
}
|
||||
|
||||
function testDeleteFromStageOperatesRecursively() {
|
||||
SiteTree::set_enforce_strict_hierarchy(false);
|
||||
$pageAbout = $this->objFromFixture('Page', 'about');
|
||||
$pageStaff = $this->objFromFixture('Page', 'staff');
|
||||
$pageStaffDuplicate = $this->objFromFixture('Page', 'staffduplicate');
|
||||
|
||||
$pageAbout->delete();
|
||||
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageAbout->ID));
|
||||
$this->assertTrue(DataObject::get_by_id('Page', $pageStaff->ID) instanceof Page);
|
||||
$this->assertTrue(DataObject::get_by_id('Page', $pageStaffDuplicate->ID) instanceof Page);
|
||||
SiteTree::set_enforce_strict_hierarchy(true);
|
||||
}
|
||||
|
||||
function testDeleteFromStageOperatesRecursivelyStrict() {
|
||||
$pageAbout = $this->objFromFixture('Page', 'about');
|
||||
$pageStaff = $this->objFromFixture('Page', 'staff');
|
||||
$pageStaffDuplicate = $this->objFromFixture('Page', 'staffduplicate');
|
||||
|
||||
$pageAbout->delete();
|
||||
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageAbout->ID));
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageStaff->ID));
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageStaffDuplicate->ID));
|
||||
}
|
||||
|
||||
function testDeleteFromLiveOperatesRecursively() {
|
||||
SiteTree::set_enforce_strict_hierarchy(false);
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
$pageAbout = $this->objFromFixture('Page', 'about');
|
||||
$pageAbout->doPublish();
|
||||
$pageStaff = $this->objFromFixture('Page', 'staff');
|
||||
$pageStaff->doPublish();
|
||||
$pageStaffDuplicate = $this->objFromFixture('Page', 'staffduplicate');
|
||||
$pageStaffDuplicate->doPublish();
|
||||
|
||||
$parentPage = $this->objFromFixture('Page', 'about');
|
||||
$parentPage->doDeleteFromLive();
|
||||
|
||||
Versioned::reading_stage('Live');
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageAbout->ID));
|
||||
$this->assertTrue(DataObject::get_by_id('Page', $pageStaff->ID) instanceof Page);
|
||||
$this->assertTrue(DataObject::get_by_id('Page', $pageStaffDuplicate->ID) instanceof Page);
|
||||
Versioned::reading_stage('Stage');
|
||||
SiteTree::set_enforce_strict_hierarchy(true);
|
||||
}
|
||||
|
||||
function testUnpublishDoesNotDeleteChildrenWithLooseHierachyOn() {
|
||||
SiteTree::set_enforce_strict_hierarchy(false);
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
$pageAbout = $this->objFromFixture('Page', 'about');
|
||||
$pageAbout->doPublish();
|
||||
$pageStaff = $this->objFromFixture('Page', 'staff');
|
||||
$pageStaff->doPublish();
|
||||
$pageStaffDuplicate = $this->objFromFixture('Page', 'staffduplicate');
|
||||
$pageStaffDuplicate->doPublish();
|
||||
|
||||
$parentPage = $this->objFromFixture('Page', 'about');
|
||||
$parentPage->doUnpublish();
|
||||
|
||||
Versioned::reading_stage('Live');
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageAbout->ID));
|
||||
$this->assertTrue(DataObject::get_by_id('Page', $pageStaff->ID) instanceof Page);
|
||||
$this->assertTrue(DataObject::get_by_id('Page', $pageStaffDuplicate->ID) instanceof Page);
|
||||
Versioned::reading_stage('Stage');
|
||||
SiteTree::set_enforce_strict_hierarchy(true);
|
||||
}
|
||||
|
||||
|
||||
function testDeleteFromLiveOperatesRecursivelyStrict() {
|
||||
$this->logInWithPermission('ADMIN');
|
||||
|
||||
$pageAbout = $this->objFromFixture('Page', 'about');
|
||||
$pageAbout->doPublish();
|
||||
$pageStaff = $this->objFromFixture('Page', 'staff');
|
||||
$pageStaff->doPublish();
|
||||
$pageStaffDuplicate = $this->objFromFixture('Page', 'staffduplicate');
|
||||
$pageStaffDuplicate->doPublish();
|
||||
|
||||
$parentPage = $this->objFromFixture('Page', 'about');
|
||||
$parentPage->doDeleteFromLive();
|
||||
|
||||
Versioned::reading_stage('Live');
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageAbout->ID));
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageStaff->ID));
|
||||
$this->assertFalse(DataObject::get_by_id('Page', $pageStaffDuplicate->ID));
|
||||
Versioned::reading_stage('Stage');
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple test to confirm that querying from a particular archive date doesn't throw
|
||||
* an error
|
||||
*/
|
||||
function testReadArchiveDate() {
|
||||
Versioned::reading_archived_date('2009-07-02 14:05:07');
|
||||
|
||||
DataObject::get('SiteTree', "\"ParentID\" = 0");
|
||||
|
||||
Versioned::reading_archived_date(null);
|
||||
}
|
||||
|
||||
function testEditPermissions() {
|
||||
$editor = $this->objFromFixture("Member", "editor");
|
||||
|
||||
$home = $this->objFromFixture("Page", "home");
|
||||
$products = $this->objFromFixture("Page", "products");
|
||||
$product1 = $this->objFromFixture("Page", "product1");
|
||||
$product4 = $this->objFromFixture("Page", "product4");
|
||||
|
||||
// Can't edit a page that is locked to admins
|
||||
$this->assertFalse($home->canEdit($editor));
|
||||
|
||||
// Can edit a page that is locked to editors
|
||||
$this->assertTrue($products->canEdit($editor));
|
||||
|
||||
// Can edit a child of that page that inherits
|
||||
$this->assertTrue($product1->canEdit($editor));
|
||||
|
||||
// Can't edit a child of that page that has its permissions overridden
|
||||
$this->assertFalse($product4->canEdit($editor));
|
||||
}
|
||||
|
||||
function testEditPermissionsOnDraftVsLive() {
|
||||
// Create an inherit-permission page
|
||||
$page = new Page();
|
||||
$page->write();
|
||||
$page->CanEditType = "Inherit";
|
||||
$page->doPublish();
|
||||
$pageID = $page->ID;
|
||||
|
||||
// Lock down the site config
|
||||
$sc = $page->SiteConfig;
|
||||
$sc->CanEditType = 'OnlyTheseUsers';
|
||||
$sc->EditorGroups()->add($this->idFromFixture('Group', 'admins'));
|
||||
$sc->write();
|
||||
|
||||
// Confirm that Member.editor can't edit the page
|
||||
$this->objFromFixture('Member','editor')->logIn();
|
||||
$this->assertFalse($page->canEdit());
|
||||
|
||||
// Change the page to be editable by Group.editors, but do not publish
|
||||
$this->objFromFixture('Member','admin')->logIn();
|
||||
$page->CanEditType = 'OnlyTheseUsers';
|
||||
$page->EditorGroups()->add($this->idFromFixture('Group', 'editors'));
|
||||
$page->write();
|
||||
|
||||
// Confirm that Member.editor can now edit the page
|
||||
$this->objFromFixture('Member','editor')->logIn();
|
||||
$this->assertTrue($page->canEdit());
|
||||
|
||||
// Publish the changes to the page
|
||||
$this->objFromFixture('Member','admin')->logIn();
|
||||
$page->doPublish();
|
||||
|
||||
// Confirm that Member.editor can still edit the page
|
||||
$this->objFromFixture('Member','editor')->logIn();
|
||||
$this->assertTrue($page->canEdit());
|
||||
}
|
||||
|
||||
function testCompareVersions() {
|
||||
$page = new Page();
|
||||
$page->write();
|
||||
$this->assertEquals(1, $page->Version);
|
||||
|
||||
$page->Content = "<p>This is a test</p>";
|
||||
$page->write();
|
||||
$this->assertEquals(2, $page->Version);
|
||||
|
||||
$diff = $page->compareVersions(1, 2);
|
||||
|
||||
$processedContent = trim($diff->Content);
|
||||
$processedContent = preg_replace('/\s*</','<',$processedContent);
|
||||
$processedContent = preg_replace('/>\s*/','>',$processedContent);
|
||||
$this->assertEquals("<ins><p>This is a test</p></ins>", $processedContent);
|
||||
|
||||
}
|
||||
|
||||
function testAuthorIDAndPublisherIDFilledOutOnPublish() {
|
||||
// Ensure that we have a member ID who is doing all this work
|
||||
$member = Member::currentUser();
|
||||
if($member) {
|
||||
$memberID = $member->ID;
|
||||
} else {
|
||||
$memberID = $this->idFromFixture("Member", "admin");
|
||||
Session::set("loggedInAs", $memberID);
|
||||
}
|
||||
|
||||
// Write the page
|
||||
$about = $this->objFromFixture('Page','about');
|
||||
$about->Title = "Another title";
|
||||
$about->write();
|
||||
|
||||
// Check the version created
|
||||
$savedVersion = DB::query("SELECT \"AuthorID\", \"PublisherID\" FROM \"SiteTree_versions\"
|
||||
WHERE \"RecordID\" = $about->ID ORDER BY \"Version\" DESC")->first();
|
||||
$this->assertEquals($memberID, $savedVersion['AuthorID']);
|
||||
$this->assertEquals(0, $savedVersion['PublisherID']);
|
||||
|
||||
// Publish the page
|
||||
$about->doPublish();
|
||||
$publishedVersion = DB::query("SELECT \"AuthorID\", \"PublisherID\" FROM \"SiteTree_versions\"
|
||||
WHERE \"RecordID\" = $about->ID ORDER BY \"Version\" DESC")->first();
|
||||
|
||||
// Check the version created
|
||||
$this->assertEquals($memberID, $publishedVersion['AuthorID']);
|
||||
$this->assertEquals($memberID, $publishedVersion['PublisherID']);
|
||||
|
||||
}
|
||||
|
||||
public function testLinkShortcodeHandler() {
|
||||
$aboutPage = $this->objFromFixture('Page', 'about');
|
||||
$errorPage = $this->objFromFixture('ErrorPage', '404');
|
||||
|
||||
$parser = new ShortcodeParser();
|
||||
$parser->register('sitetree_link', array('SiteTree', 'link_shortcode_handler'));
|
||||
|
||||
$aboutShortcode = sprintf('[sitetree_link id=%d]', $aboutPage->ID);
|
||||
$aboutEnclosed = sprintf('[sitetree_link id=%d]Example Content[/sitetree_link]', $aboutPage->ID);
|
||||
|
||||
$aboutShortcodeExpected = $aboutPage->Link();
|
||||
$aboutEnclosedExpected = sprintf('<a href="%s">Example Content</a>', $aboutPage->Link());
|
||||
|
||||
$this->assertEquals($aboutShortcodeExpected, $parser->parse($aboutShortcode), 'Test that simple linking works.');
|
||||
$this->assertEquals($aboutEnclosedExpected, $parser->parse($aboutEnclosed), 'Test enclosed content is linked.');
|
||||
|
||||
$aboutPage->delete();
|
||||
|
||||
$this->assertEquals($aboutShortcodeExpected, $parser->parse($aboutShortcode), 'Test that deleted pages still link.');
|
||||
$this->assertEquals($aboutEnclosedExpected, $parser->parse($aboutEnclosed));
|
||||
|
||||
$aboutShortcode = '[sitetree_link id="-1"]';
|
||||
$aboutEnclosed = '[sitetree_link id="-1"]Example Content[/sitetree_link]';
|
||||
|
||||
$aboutShortcodeExpected = $errorPage->Link();
|
||||
$aboutEnclosedExpected = sprintf('<a href="%s">Example Content</a>', $errorPage->Link());
|
||||
|
||||
$this->assertEquals($aboutShortcodeExpected, $parser->parse($aboutShortcode), 'Test link to 404 page if no suitable matches.');
|
||||
$this->assertEquals($aboutEnclosedExpected, $parser->parse($aboutEnclosed));
|
||||
|
||||
$this->assertEquals('', $parser->parse('[sitetree_link]'), 'Test that invalid ID attributes are not parsed.');
|
||||
$this->assertEquals('', $parser->parse('[sitetree_link id="text"]'));
|
||||
$this->assertEquals('', $parser->parse('[sitetree_link]Example Content[/sitetree_link]'));
|
||||
}
|
||||
|
||||
public function testIsCurrent() {
|
||||
$aboutPage = $this->objFromFixture('Page', 'about');
|
||||
$errorPage = $this->objFromFixture('ErrorPage', '404');
|
||||
|
||||
Director::set_current_page($aboutPage);
|
||||
$this->assertTrue($aboutPage->isCurrent(), 'Assert that basic isSection checks works.');
|
||||
$this->assertFalse($errorPage->isCurrent());
|
||||
|
||||
Director::set_current_page($errorPage);
|
||||
$this->assertTrue($errorPage->isCurrent(), 'Assert isSection works on error pages.');
|
||||
$this->assertFalse($aboutPage->isCurrent());
|
||||
|
||||
Director::set_current_page($aboutPage);
|
||||
$this->assertTrue (
|
||||
DataObject::get_one('SiteTree', '"Title" = \'About Us\'')->isCurrent(),
|
||||
'Assert that isCurrent works on another instance with the same ID.'
|
||||
);
|
||||
|
||||
Director::set_current_page($newPage = new SiteTree());
|
||||
$this->assertTrue($newPage->isCurrent(), 'Assert that isCurrent works on unsaved pages.');
|
||||
}
|
||||
|
||||
public function testIsSection() {
|
||||
$about = $this->objFromFixture('Page', 'about');
|
||||
$staff = $this->objFromFixture('Page', 'staff');
|
||||
$ceo = $this->objFromFixture('Page', 'ceo');
|
||||
|
||||
Director::set_current_page($about);
|
||||
$this->assertTrue($about->isSection());
|
||||
$this->assertFalse($staff->isSection());
|
||||
$this->assertFalse($ceo->isSection());
|
||||
|
||||
Director::set_current_page($staff);
|
||||
$this->assertTrue($about->isSection());
|
||||
$this->assertTrue($staff->isSection());
|
||||
$this->assertFalse($ceo->isSection());
|
||||
|
||||
Director::set_current_page($ceo);
|
||||
$this->assertTrue($about->isSection());
|
||||
$this->assertTrue($staff->isSection());
|
||||
$this->assertTrue($ceo->isSection());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SiteTree::validURLSegment
|
||||
*/
|
||||
public function testValidURLSegmentURLSegmentConflicts() {
|
||||
$sitetree = new SiteTree();
|
||||
SiteTree::disable_nested_urls();
|
||||
|
||||
$sitetree->URLSegment = 'home';
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'URLSegment conflicts are recognised');
|
||||
$sitetree->URLSegment = 'home-noconflict';
|
||||
$this->assertTrue($sitetree->validURLSegment());
|
||||
|
||||
$sitetree->ParentID = $this->idFromFixture('Page', 'about');
|
||||
$sitetree->URLSegment = 'home';
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'Conflicts are still recognised with a ParentID value');
|
||||
|
||||
SiteTree::enable_nested_urls();
|
||||
|
||||
$sitetree->ParentID = 0;
|
||||
$sitetree->URLSegment = 'home';
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'URLSegment conflicts are recognised');
|
||||
|
||||
$sitetree->ParentID = $this->idFromFixture('Page', 'about');
|
||||
$this->assertTrue($sitetree->validURLSegment(), 'URLSegments can be the same across levels');
|
||||
|
||||
$sitetree->URLSegment = 'my-staff';
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'Nested URLSegment conflicts are recognised');
|
||||
$sitetree->URLSegment = 'my-staff-noconflict';
|
||||
$this->assertTrue($sitetree->validURLSegment());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SiteTree::validURLSegment
|
||||
*/
|
||||
public function testValidURLSegmentClassNameConflicts() {
|
||||
$sitetree = new SiteTree();
|
||||
$sitetree->URLSegment = 'Controller';
|
||||
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'Class name conflicts are recognised');
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers SiteTree::validURLSegment
|
||||
*/
|
||||
public function testValidURLSegmentControllerConflicts() {
|
||||
SiteTree::enable_nested_urls();
|
||||
|
||||
$sitetree = new SiteTree();
|
||||
$sitetree->ParentID = $this->idFromFixture('SiteTreeTest_Conflicted', 'parent');
|
||||
|
||||
$sitetree->URLSegment = 'index';
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'index is not a valid URLSegment');
|
||||
|
||||
$sitetree->URLSegment = 'conflicted-action';
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'allowed_actions conflicts are recognised');
|
||||
|
||||
$sitetree->URLSegment = 'conflicted-template';
|
||||
$this->assertFalse($sitetree->validURLSegment(), 'Action-specific template conflicts are recognised');
|
||||
|
||||
$sitetree->URLSegment = 'valid';
|
||||
$this->assertTrue($sitetree->validURLSegment(), 'Valid URLSegment values are allowed');
|
||||
}
|
||||
|
||||
public function testVersionsAreCreated() {
|
||||
$p = new Page();
|
||||
$p->Content = "one";
|
||||
$p->write();
|
||||
$this->assertEquals(1, $p->Version);
|
||||
|
||||
// No changes don't bump version
|
||||
$p->write();
|
||||
$this->assertEquals(1, $p->Version);
|
||||
|
||||
$p->Content = "two";
|
||||
$p->write();
|
||||
$this->assertEquals(2, $p->Version);
|
||||
|
||||
// Only change meta-data don't bump version
|
||||
$p->HasBrokenLink = true;
|
||||
$p->write();
|
||||
$p->HasBrokenLink = false;
|
||||
$p->write();
|
||||
$this->assertEquals(2, $p->Version);
|
||||
|
||||
$p->Content = "three";
|
||||
$p->write();
|
||||
$this->assertEquals(3, $p->Version);
|
||||
|
||||
}
|
||||
|
||||
function testPageTypeClasses() {
|
||||
$classes = SiteTree::page_type_classes();
|
||||
$this->assertNotContains('SiteTree', $classes, 'Page types do not include base class');
|
||||
$this->assertContains('Page', $classes, 'Page types do contain subclasses');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**#@+
|
||||
* @ignore
|
||||
*/
|
||||
|
||||
class SiteTreeTest_PageNode extends Page implements TestOnly { }
|
||||
class SiteTreeTest_PageNode_Controller extends Page_Controller implements TestOnly {
|
||||
}
|
||||
|
||||
class SiteTreeTest_Conflicted extends Page implements TestOnly { }
|
||||
class SiteTreeTest_Conflicted_Controller extends Page_Controller implements TestOnly {
|
||||
|
||||
public static $allowed_actions = array (
|
||||
'conflicted-action'
|
||||
);
|
||||
|
||||
public function hasActionTemplate($template) {
|
||||
if($template == 'conflicted-template') {
|
||||
return true;
|
||||
} else {
|
||||
return parent::hasActionTemplate($template);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**#@-*/
|
471
tests/WidgetAreaEditorTest.php
Normal file
471
tests/WidgetAreaEditorTest.php
Normal file
@ -0,0 +1,471 @@
|
||||
<?php
|
||||
/**
|
||||
* @package cms
|
||||
* @subpackage tests
|
||||
*/
|
||||
class WidgetAreaEditorTest extends SapphireTest {
|
||||
/**
|
||||
* This is the widget you want to use for your unit tests.
|
||||
*/
|
||||
protected $widgetToTest = 'WidgetAreaEditorTest_TestWidget';
|
||||
|
||||
protected $extraDataObjects = array(
|
||||
'WidgetAreaEditorTest_FakePage',
|
||||
'WidgetAreaEditorTest_TestWidget',
|
||||
);
|
||||
|
||||
protected $usesDatabase = true;
|
||||
|
||||
function testFillingOneArea() {
|
||||
$oldRequest = $_REQUEST;
|
||||
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'BottomBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidget',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide = new WidgetAreaEditor('SideBar');
|
||||
$editorBott = new WidgetAreaEditor('BottomBar');
|
||||
$page = new WidgetAreaEditorTest_FakePage();
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
|
||||
$this->assertEquals($page->BottomBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($page->SideBar()->Widgets()->Count(), 0);
|
||||
|
||||
$_REQUEST = $oldRequest;
|
||||
}
|
||||
|
||||
function testFillingTwoAreas() {
|
||||
$oldRequest = $_REQUEST;
|
||||
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetSide',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide = new WidgetAreaEditor('SideBar');
|
||||
$editorBott = new WidgetAreaEditor('BottomBar');
|
||||
$page = new WidgetAreaEditorTest_FakePage();
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
|
||||
// Make sure they both got saved
|
||||
$this->assertEquals($page->BottomBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($page->SideBar()->Widgets()->Count(), 1);
|
||||
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
$this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide');
|
||||
$this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom');
|
||||
|
||||
$_REQUEST = $oldRequest;
|
||||
}
|
||||
|
||||
function testDeletingOneWidgetFromOneArea() {
|
||||
$oldRequest = $_REQUEST;
|
||||
|
||||
// First get some widgets in there
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetSide',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide = new WidgetAreaEditor('SideBar');
|
||||
$editorBott = new WidgetAreaEditor('BottomBar');
|
||||
$page = new WidgetAreaEditorTest_FakePage();
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
// Save again (after removing the SideBar's widget)
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
),
|
||||
'BottomBar' => array(
|
||||
$bottWidgets[0]->ID => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
$this->assertEquals($page->BottomBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom');
|
||||
$this->assertEquals($page->SideBar()->Widgets()->Count(), 0);
|
||||
|
||||
$_REQUEST = $oldRequest;
|
||||
}
|
||||
|
||||
function testDeletingAWidgetFromEachArea() {
|
||||
$oldRequest = $_REQUEST;
|
||||
|
||||
// First get some widgets in there
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetSide',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide = new WidgetAreaEditor('SideBar');
|
||||
$editorBott = new WidgetAreaEditor('BottomBar');
|
||||
$page = new WidgetAreaEditorTest_FakePage();
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
// Save again (after removing the SideBar's widget)
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
),
|
||||
'BottomBar' => array(
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
$this->assertEquals($page->BottomBar()->Widgets()->Count(), 0);
|
||||
$this->assertEquals($page->SideBar()->Widgets()->Count(), 0);
|
||||
|
||||
$_REQUEST = $oldRequest;
|
||||
}
|
||||
|
||||
function testEditingOneWidget() {
|
||||
$oldRequest = $_REQUEST;
|
||||
|
||||
// First get some widgets in there
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetSide',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide = new WidgetAreaEditor('SideBar');
|
||||
$editorBott = new WidgetAreaEditor('BottomBar');
|
||||
$page = new WidgetAreaEditorTest_FakePage();
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
// Save again (after removing the SideBar's widget)
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
$sideWidgets[0]->ID => array(
|
||||
'Title' => 'MyTestWidgetSide-edited',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
$bottWidgets[0]->ID => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
$this->assertEquals($page->BottomBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($page->SideBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom');
|
||||
$this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide-edited');
|
||||
|
||||
|
||||
$_REQUEST = $oldRequest;
|
||||
}
|
||||
|
||||
function testEditingAWidgetFromEachArea() {
|
||||
$oldRequest = $_REQUEST;
|
||||
|
||||
// First get some widgets in there
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetSide',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide = new WidgetAreaEditor('SideBar');
|
||||
$editorBott = new WidgetAreaEditor('BottomBar');
|
||||
$page = new WidgetAreaEditorTest_FakePage();
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
// Save again (after removing the SideBar's widget)
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
$sideWidgets[0]->ID => array(
|
||||
'Title' => 'MyTestWidgetSide-edited',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
$bottWidgets[0]->ID => array(
|
||||
'Title' => 'MyTestWidgetBottom-edited',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
$this->assertEquals($page->BottomBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($page->SideBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($bottWidgets[0]->Title(), 'MyTestWidgetBottom-edited');
|
||||
$this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide-edited');
|
||||
|
||||
|
||||
$_REQUEST = $oldRequest;
|
||||
}
|
||||
|
||||
function testEditAWidgetFromOneAreaAndDeleteAWidgetFromAnotherArea() {
|
||||
$oldRequest = $_REQUEST;
|
||||
|
||||
// First get some widgets in there
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetSide',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
'new-1' => array(
|
||||
'Title' => 'MyTestWidgetBottom',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$editorSide = new WidgetAreaEditor('SideBar');
|
||||
$editorBott = new WidgetAreaEditor('BottomBar');
|
||||
$page = new WidgetAreaEditorTest_FakePage();
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
// Save again (after removing the SideBar's widget)
|
||||
$_REQUEST = array(
|
||||
'Widget' => array(
|
||||
'SideBar' => array(
|
||||
$sideWidgets[0]->ID => array(
|
||||
'Title' => 'MyTestWidgetSide-edited',
|
||||
'Type' => $this->widgetToTest,
|
||||
'Sort' => 0
|
||||
)
|
||||
),
|
||||
'BottomBar' => array(
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
$editorSide->saveInto($page);
|
||||
$editorBott->saveInto($page);
|
||||
|
||||
$page->write();
|
||||
$page->flushCache();
|
||||
$page->BottomBar()->flushCache();
|
||||
$page->SideBar()->flushCache();
|
||||
$sideWidgets = $page->SideBar()->Widgets()->toArray();
|
||||
$bottWidgets = $page->BottomBar()->Widgets()->toArray();
|
||||
|
||||
$this->assertEquals($page->BottomBar()->Widgets()->Count(), 0);
|
||||
$this->assertEquals($page->SideBar()->Widgets()->Count(), 1);
|
||||
$this->assertEquals($sideWidgets[0]->Title(), 'MyTestWidgetSide-edited');
|
||||
|
||||
|
||||
$_REQUEST = $oldRequest;
|
||||
}
|
||||
}
|
||||
|
||||
class WidgetAreaEditorTest_FakePage extends Page implements TestOnly {
|
||||
public static $has_one = array(
|
||||
"SideBar" => "WidgetArea",
|
||||
"BottomBar" => "WidgetArea",
|
||||
);
|
||||
}
|
||||
|
||||
class WidgetAreaEditorTest_TestWidget extends Widget implements TestOnly {
|
||||
static $cmsTitle = "Test widget";
|
||||
static $title = "Test widget";
|
||||
static $description = "Test widget";
|
||||
static $db = array(
|
||||
'Title' => 'Varchar'
|
||||
);
|
||||
public function getCMSFields() {
|
||||
$fields = new FieldSet();
|
||||
$fields->push(new TextField('Title'));
|
||||
return $fields;
|
||||
}
|
||||
function Title() {
|
||||
return $this->Title ? $this->Title : self::$title;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user