2008-08-12 04:59:27 +02:00
< ? php
2009-03-22 23:58:18 +01:00
/**
* @ package cms
* @ subpackage tests
*/
2009-04-29 04:49:43 +02:00
class CMSMainTest extends FunctionalTest {
2012-09-02 18:06:25 +02:00
2013-03-18 11:47:15 +01:00
protected static $fixture_file = 'CMSMainTest.yml' ;
2008-08-12 04:59:27 +02:00
2009-10-21 21:57:47 +02:00
static protected $orig = array ();
2012-12-03 16:33:06 +01:00
function testSiteTreeHints () {
$cache = SS_Cache :: factory ( 'CMSMain_SiteTreeHints' );
2015-03-11 06:54:08 +01:00
// Login as user with root creation privileges
$user = $this -> objFromFixture ( 'Member' , 'rootedituser' );
$user -> logIn ();
2012-12-03 16:33:06 +01:00
$cache -> clean ( Zend_Cache :: CLEANING_MODE_ALL );
$rawHints = singleton ( 'CMSMain' ) -> SiteTreeHints ();
$this -> assertNotNull ( $rawHints );
$rawHints = preg_replace ( '/^"(.*)"$/' , '$1' , Convert :: xml2raw ( $rawHints ));
$hints = Convert :: json2array ( $rawHints );
$this -> assertArrayHasKey ( 'Root' , $hints );
$this -> assertArrayHasKey ( 'Page' , $hints );
$this -> assertArrayHasKey ( 'All' , $hints );
$this -> assertArrayHasKey (
'CMSMainTest_ClassA' ,
$hints [ 'All' ],
'Global list shows allowed classes'
);
$this -> assertArrayNotHasKey (
'CMSMainTest_HiddenClass' ,
$hints [ 'All' ],
'Global list does not list hidden classes'
);
$this -> assertNotContains (
'CMSMainTest_ClassA' ,
$hints [ 'Root' ][ 'disallowedChildren' ],
'Limits root classes'
);
$this -> assertContains (
'CMSMainTest_NotRoot' ,
$hints [ 'Root' ][ 'disallowedChildren' ],
'Limits root classes'
);
2015-03-11 06:54:08 +01:00
}
public function testChildFilter () {
$this -> logInWithPermission ( 'ADMIN' );
// Check page A
$pageA = new CMSMainTest_ClassA ();
$pageA -> write ();
$pageB = new CMSMainTest_ClassB ();
$pageB -> write ();
// Check query
$response = $this -> get ( 'CMSMain/childfilter?ParentID=' . $pageA -> ID );
$children = json_decode ( $response -> getBody ());
$this -> assertFalse ( $response -> isError ());
// Page A can't have unrelated children
2012-12-03 16:33:06 +01:00
$this -> assertContains (
'Page' ,
2015-03-11 06:54:08 +01:00
$children ,
2012-12-03 16:33:06 +01:00
'Limited parent lists disallowed classes'
);
2015-03-11 06:54:08 +01:00
// But it can create a ClassB
2012-12-03 16:33:06 +01:00
$this -> assertNotContains (
'CMSMainTest_ClassB' ,
2015-03-11 06:54:08 +01:00
$children ,
2012-12-03 16:33:06 +01:00
'Limited parent omits explicitly allowed classes in disallowedChildren'
);
}
2009-10-21 21:57:47 +02:00
2008-08-12 04:59:27 +02:00
/**
* @ todo Test the results of a publication better
*/
2012-09-19 12:07:46 +02:00
public function testPublish () {
2010-10-15 05:31:30 +02:00
$page1 = $this -> objFromFixture ( 'Page' , " page1 " );
$page2 = $this -> objFromFixture ( 'Page' , " page2 " );
2009-04-29 04:49:43 +02:00
$this -> session () -> inst_set ( 'loggedInAs' , $this -> idFromFixture ( 'Member' , 'admin' ));
2012-05-22 07:16:29 +02:00
$response = $this -> get ( 'admin/pages/publishall?confirm=1' );
2008-11-01 14:42:19 +01:00
$this -> assertContains (
2012-05-09 11:54:33 +02:00
'Done: Published 30 pages' ,
2008-11-01 14:42:19 +01:00
$response -> getBody ()
);
2013-03-18 11:47:15 +01:00
$actions = CMSBatchActionHandler :: config () -> batch_actions ;
2009-11-21 04:20:50 +01:00
2010-04-12 12:04:49 +02:00
// Some modules (e.g., cmsworkflow) will remove this action
2013-02-27 03:00:34 +01:00
$actions = CMSBatchActionHandler :: config () -> batch_actions ;
if ( isset ( $actions [ 'publish' ])) {
2012-11-23 15:25:10 +01:00
$response = $this -> get ( 'admin/pages/batchactions/publish?ajax=1&csvIDs=' . implode ( ',' , array ( $page1 -> ID , $page2 -> ID )));
2010-04-12 12:04:49 +02:00
$responseData = Convert :: json2array ( $response -> getBody ());
2012-03-30 05:25:21 +02:00
$this -> assertArrayHasKey ( $page1 -> ID , $responseData [ 'modified' ]);
$this -> assertArrayHasKey ( $page2 -> ID , $responseData [ 'modified' ]);
2010-04-12 12:04:49 +02:00
}
2010-10-15 04:35:17 +02:00
2010-10-15 04:35:52 +02:00
// Get the latest version of the redirector page
$pageID = $this -> idFromFixture ( 'RedirectorPage' , 'page5' );
2013-06-21 00:45:33 +02:00
$latestID = DB :: prepared_query ( 'select max("Version") from "RedirectorPage_versions" where "RecordID" = ?' , array ( $pageID )) -> value ();
$dsCount = DB :: prepared_query ( 'select count("Version") from "RedirectorPage_versions" where "RecordID" = ? and "Version"= ?' , array ( $pageID , $latestID )) -> value ();
$this -> assertEquals ( 1 , $dsCount , " Published page has no duplicate version records: it has " . $dsCount . " for version " . $latestID );
2008-08-12 04:59:27 +02:00
2009-04-29 04:49:43 +02:00
$this -> session () -> clear ( 'loggedInAs' );
2008-08-12 04:59:27 +02:00
//$this->assertRegexp('/Done: Published 4 pages/', $response->getBody())
/*
2012-04-18 23:33:37 +02:00
$response = Director :: test ( " admin/pages/publishitems " , array (
2008-08-12 04:59:27 +02:00
'ID' => ''
'Title' => ''
'action_publish' => 'Save and publish' ,
), $session );
$this -> assertRegexp ( '/Done: Published 4 pages/' , $response -> getBody ())
*/
}
2008-10-08 05:38:32 +02:00
/**
* Test publication of one of every page type
*/
2012-09-19 12:07:46 +02:00
public function testPublishOneOfEachKindOfPage () {
2012-11-23 15:52:00 +01:00
$this -> markTestIncomplete ();
// $classes = ClassInfo::subclassesFor("SiteTree");
// array_shift($classes);
2010-04-14 05:07:25 +02:00
2012-11-23 15:52:00 +01:00
// foreach($classes as $class) {
// $page = new $class();
// if($class instanceof TestOnly) continue;
2008-10-08 05:38:32 +02:00
2012-11-23 15:52:00 +01:00
// $page->Title = "Test $class page";
2008-10-08 05:38:32 +02:00
2012-11-23 15:52:00 +01:00
// $page->write();
// $this->assertEquals("Test $class page", DB::query("SELECT \"Title\" FROM \"SiteTree\" WHERE \"ID\" = $page->ID")->value());
2008-10-08 05:38:32 +02:00
2012-11-23 15:52:00 +01:00
// $page->doPublish();
// $this->assertEquals("Test $class page", DB::query("SELECT \"Title\" FROM \"SiteTree_Live\" WHERE \"ID\" = $page->ID")->value());
2008-10-08 05:38:32 +02:00
2012-11-23 15:52:00 +01:00
// // Check that you can visit the page
// $this->get($page->URLSegment);
// }
2008-10-08 05:38:32 +02:00
}
2010-04-14 05:07:25 +02:00
2008-10-08 05:38:32 +02:00
/**
* Test that getCMSFields works on each page type .
* Mostly , this is just checking that the method doesn ' t return an error
*/
2012-09-19 12:07:46 +02:00
public function testThatGetCMSFieldsWorksOnEveryPageType () {
2008-10-08 05:38:32 +02:00
$classes = ClassInfo :: subclassesFor ( " SiteTree " );
array_shift ( $classes );
2010-04-14 05:07:25 +02:00
2008-10-08 05:38:32 +02:00
foreach ( $classes as $class ) {
$page = new $class ();
2009-04-22 06:23:56 +02:00
if ( $page instanceof TestOnly ) continue ;
2012-01-30 17:31:22 +01:00
if ( ! $page -> stat ( 'can_be_root' )) continue ;
2010-04-14 05:07:25 +02:00
2008-10-08 05:38:32 +02:00
$page -> Title = " Test $class page " ;
$page -> write ();
$page -> flushCache ();
$page = DataObject :: get_by_id ( " SiteTree " , $page -> ID );
2012-04-13 15:55:32 +02:00
$this -> assertTrue ( $page -> getCMSFields () instanceof FieldList );
2008-10-08 05:38:32 +02:00
}
2010-10-04 07:27:20 +02:00
}
2012-09-19 12:07:46 +02:00
public function testCanPublishPageWithUnpublishedParentWithStrictHierarchyOff () {
2010-10-13 04:06:29 +02:00
$this -> logInWithPermission ( 'ADMIN' );
2010-10-04 07:27:20 +02:00
2013-03-18 11:47:15 +01:00
Config :: inst () -> update ( 'SiteTree' , 'enforce_strict_hierarchy' , true );
2010-10-04 07:27:20 +02:00
$parentPage = $this -> objFromFixture ( 'Page' , 'page3' );
$childPage = $this -> objFromFixture ( 'Page' , 'page1' );
$parentPage -> doUnpublish ();
$childPage -> doUnpublish ();
2012-12-14 01:11:52 +01:00
$actions = $childPage -> getCMSActions () -> dataFields ();
$this -> assertArrayHasKey (
2010-10-04 07:27:20 +02:00
'action_publish' ,
2012-12-14 01:11:52 +01:00
$actions ,
2010-10-04 07:27:20 +02:00
'Can publish a page with an unpublished parent with strict hierarchy off'
);
2013-03-18 11:47:15 +01:00
Config :: inst () -> update ( 'SiteTree' , 'enforce_strict_hierarchy' , false );
2008-10-08 05:38:32 +02:00
}
2010-04-14 05:07:25 +02:00
2009-05-01 00:47:28 +02:00
/**
* Test that a draft - deleted page can still be opened in the CMS
*/
2012-09-19 12:07:46 +02:00
public function testDraftDeletedPageCanBeOpenedInCMS () {
2009-10-19 07:26:03 +02:00
$this -> session () -> inst_set ( 'loggedInAs' , $this -> idFromFixture ( 'Member' , 'admin' ));
2010-04-14 05:07:25 +02:00
2009-05-01 00:47:28 +02:00
// Set up a page that is delete from live
$page = $this -> objFromFixture ( 'Page' , 'page1' );
$pageID = $page -> ID ;
$page -> doPublish ();
$page -> delete ();
2012-05-22 07:35:04 +02:00
$response = $this -> get ( 'admin/pages/edit/show/' . $pageID );
2010-04-14 05:07:25 +02:00
2013-06-21 00:45:33 +02:00
$livePage = Versioned :: get_one_by_stage ( " SiteTree " , " Live " , array (
'"SiteTree"."ID"' => $pageID
));
2012-05-09 13:06:55 +02:00
$this -> assertInstanceOf ( 'SiteTree' , $livePage );
2009-10-19 07:26:03 +02:00
$this -> assertTrue ( $livePage -> canDelete ());
2010-04-14 05:07:25 +02:00
2010-04-12 12:04:49 +02:00
// Check that the 'restore' button exists as a simple way of checking that the correct page is returned.
2012-02-16 22:59:47 +01:00
$this -> assertRegExp ( '/<button[^>]+name="action_(restore|revert)"/i' , $response -> getBody ());
2009-05-01 00:47:28 +02:00
}
/**
* Test CMSMain :: getRecord ()
*/
2012-09-19 12:07:46 +02:00
public function testGetRecord () {
2009-05-01 00:47:28 +02:00
// Set up a page that is delete from live
$page1 = $this -> objFromFixture ( 'Page' , 'page1' );
$page1ID = $page1 -> ID ;
$page1 -> doPublish ();
$page1 -> delete ();
$cmsMain = new CMSMain ();
2010-04-14 05:07:25 +02:00
2009-05-01 00:47:28 +02:00
// Bad calls
$this -> assertNull ( $cmsMain -> getRecord ( '0' ));
$this -> assertNull ( $cmsMain -> getRecord ( 'asdf' ));
// Pages that are on draft and aren't on draft should both work
2012-05-09 13:06:55 +02:00
$this -> assertInstanceOf ( 'Page' , $cmsMain -> getRecord ( $page1ID ));
$this -> assertInstanceOf ( 'Page' , $cmsMain -> getRecord ( $this -> idFromFixture ( 'Page' , 'page2' )));
2010-04-14 05:07:25 +02:00
2009-05-01 00:47:28 +02:00
// This functionality isn't actually used any more.
$newPage = $cmsMain -> getRecord ( 'new-Page-5' );
2012-05-09 13:06:55 +02:00
$this -> assertInstanceOf ( 'Page' , $newPage );
2009-05-01 00:47:28 +02:00
$this -> assertEquals ( '5' , $newPage -> ParentID );
2010-04-14 05:07:25 +02:00
2009-05-01 00:47:28 +02:00
}
2010-04-12 12:08:00 +02:00
2012-09-19 12:07:46 +02:00
public function testDeletedPagesSiteTreeFilter () {
2010-04-12 12:08:00 +02:00
$id = $this -> idFromFixture ( 'Page' , 'page3' );
2010-04-28 09:16:31 +02:00
$this -> logInWithPermission ( 'ADMIN' );
2012-01-24 14:02:02 +01:00
$result = $this -> get ( 'admin/pages/getsubtree?filter=CMSSiteTreeFilter_DeletedPages&ajax=1&ID=' . $id );
2010-04-12 12:08:00 +02:00
$this -> assertEquals ( 200 , $result -> getStatusCode ());
}
2010-04-14 03:36:42 +02:00
2012-09-19 12:07:46 +02:00
public function testCreationOfTopLevelPage (){
2012-11-23 15:25:10 +01:00
$origFollow = $this -> autoFollowRedirection ;
$this -> autoFollowRedirection = false ;
2010-04-14 03:36:42 +02:00
$cmsUser = $this -> objFromFixture ( 'Member' , 'allcmssectionsuser' );
$rootEditUser = $this -> objFromFixture ( 'Member' , 'rootedituser' );
// with insufficient permissions
$cmsUser -> logIn ();
2012-04-18 23:33:37 +02:00
$this -> get ( 'admin/pages/add' );
2011-07-06 11:42:17 +02:00
$response = $this -> post (
2012-04-18 23:33:37 +02:00
'admin/pages/add/AddForm' ,
2015-02-24 05:27:48 +01:00
array (
'ParentID' => '0' ,
2015-06-02 09:23:48 +02:00
'PageType' => 'Page' ,
2015-02-24 05:27:48 +01:00
'Locale' => 'en_US' ,
'action_doAdd' => 1 ,
'ajax' => 1 ,
), array (
'X-Pjax' => 'CurrentForm,Breadcrumbs' ,
)
2010-04-14 05:07:25 +02:00
);
2010-04-14 03:36:42 +02:00
// should redirect, which is a permission error
$this -> assertEquals ( 403 , $response -> getStatusCode (), 'Add TopLevel page must fail for normal user' );
// with correct permissions
$rootEditUser -> logIn ();
2012-04-18 23:33:37 +02:00
$response = $this -> get ( 'admin/pages/add' );
2011-07-06 11:42:17 +02:00
$response = $this -> post (
2012-04-18 23:33:37 +02:00
'admin/pages/add/AddForm' ,
2015-02-24 05:27:48 +01:00
array (
'ParentID' => '0' ,
2015-06-02 09:23:48 +02:00
'PageType' => 'Page' ,
2015-02-24 05:27:48 +01:00
'Locale' => 'en_US' ,
'action_doAdd' => 1 ,
'ajax' => 1 ,
), array (
'X-Pjax' => 'CurrentForm,Breadcrumbs' ,
)
2010-04-14 05:07:25 +02:00
);
2011-07-06 11:42:17 +02:00
2015-02-24 05:27:48 +01:00
$location = $response -> getHeader ( 'X-ControllerURL' );
$this -> assertNotEmpty ( $location , 'Must be a redirect on success' );
2010-04-14 03:36:42 +02:00
$this -> assertContains ( '/show/' , $location , 'Must redirect to /show/ the new page' );
// TODO Logout
$this -> session () -> inst_set ( 'loggedInAs' , NULL );
2012-11-23 15:25:10 +01:00
$this -> autoFollowRedirection = $origFollow ;
2010-04-14 03:36:42 +02:00
}
2012-02-14 16:01:07 +01:00
2012-09-19 12:07:46 +02:00
public function testCreationOfRestrictedPage (){
2012-11-23 15:25:10 +01:00
$origFollow = $this -> autoFollowRedirection ;
$this -> autoFollowRedirection = false ;
2012-09-02 18:06:25 +02:00
$adminUser = $this -> objFromFixture ( 'Member' , 'admin' );
$adminUser -> logIn ();
// Create toplevel page
$this -> get ( 'admin/pages/add' );
$response = $this -> post (
'admin/pages/add/AddForm' ,
array ( 'ParentID' => '0' , 'PageType' => 'CMSMainTest_ClassA' , 'Locale' => 'en_US' , 'action_doAdd' => 1 )
);
$this -> assertFalse ( $response -> isError ());
preg_match ( '/edit\/show\/(\d*)/' , $response -> getHeader ( 'Location' ), $matches );
$newPageId = $matches [ 1 ];
// Create allowed child
$this -> get ( 'admin/pages/add' );
$response = $this -> post (
'admin/pages/add/AddForm' ,
array ( 'ParentID' => $newPageId , 'PageType' => 'CMSMainTest_ClassB' , 'Locale' => 'en_US' , 'action_doAdd' => 1 )
);
$this -> assertFalse ( $response -> isError ());
$this -> assertNull ( $response -> getBody ());
// Create disallowed child
$this -> get ( 'admin/pages/add' );
$response = $this -> post (
'admin/pages/add/AddForm' ,
array ( 'ParentID' => $newPageId , 'PageType' => 'Page' , 'Locale' => 'en_US' , 'action_doAdd' => 1 )
);
2015-03-11 06:54:08 +01:00
$this -> assertEquals ( 403 , $response -> getStatusCode (), 'Add disallowed child should fail' );
2012-09-02 18:06:25 +02:00
$this -> session () -> inst_set ( 'loggedInAs' , NULL );
2012-11-23 15:25:10 +01:00
$this -> autoFollowRedirection = $origFollow ;
2012-09-02 18:06:25 +02:00
}
2012-09-19 12:07:46 +02:00
public function testBreadcrumbs () {
2015-06-26 02:48:29 +02:00
$page3 = $this -> objFromFixture ( 'Page' , 'page3' );
$page31 = $this -> objFromFixture ( 'Page' , 'page31' );
2012-02-14 16:01:07 +01:00
$adminuser = $this -> objFromFixture ( 'Member' , 'admin' );
$this -> session () -> inst_set ( 'loggedInAs' , $adminuser -> ID );
2012-04-18 23:40:27 +02:00
$response = $this -> get ( 'admin/pages/edit/show/' . $page31 -> ID );
2012-02-14 16:01:07 +01:00
$parser = new CSSContentParser ( $response -> getBody ());
2012-04-18 23:40:27 +02:00
$crumbs = $parser -> getBySelector ( '.breadcrumbs-wrapper .crumb' );
2012-02-14 16:01:07 +01:00
$this -> assertNotNull ( $crumbs );
2015-06-26 02:48:29 +02:00
$this -> assertEquals ( 2 , count ( $crumbs ));
$this -> assertEquals ( 'Page 3' , ( string ) $crumbs [ 0 ]);
$this -> assertEquals ( 'Page 3.1' , ( string ) $crumbs [ 1 ]);
2012-02-14 16:01:07 +01:00
$this -> session () -> inst_set ( 'loggedInAs' , null );
}
2014-03-19 07:27:39 +01:00
public function testGetNewItem () {
$controller = new CMSMain ();
$id = 'new-Page-0' ;
// Test success
$page = $controller -> getNewItem ( $id , false );
$this -> assertEquals ( $page -> Title , 'New Page' );
$this -> assertNotEquals ( $page -> Sort , 0 );
$this -> assertInstanceOf ( 'Page' , $page );
// Test failure
try {
$id = 'new-Member-0' ;
$member = $controller -> getNewItem ( $id , false );
$this -> fail ( 'Should not be able to create a Member object' );
} catch ( SS_HTTPResponse_Exception $e ) {
$this -> assertEquals ( $controller -> getResponse () -> getStatusCode (), 302 );
}
}
2014-08-06 05:00:48 +02:00
/**
* Tests filtering in { @ see CMSMain :: getList ()}
*/
public function testGetList () {
$controller = new CMSMain ();
// Test all pages (stage)
$pages = $controller -> getList () -> sort ( 'Title' );
$this -> assertEquals ( 28 , $pages -> count ());
$this -> assertEquals (
array ( 'Home' , 'Page 1' , 'Page 10' , 'Page 11' , 'Page 12' ),
$pages -> Limit ( 5 ) -> column ( 'Title' )
);
// Change state of tree
$page1 = $this -> objFromFixture ( 'Page' , 'page1' );
$page3 = $this -> objFromFixture ( 'Page' , 'page3' );
$page11 = $this -> objFromFixture ( 'Page' , 'page11' );
$page12 = $this -> objFromFixture ( 'Page' , 'page12' );
// Deleted
$page1 -> doUnpublish ();
$page1 -> delete ();
// Live and draft
$page11 -> publish ( 'Stage' , 'Live' );
// Live only
$page12 -> publish ( 'Stage' , 'Live' );
$page12 -> delete ();
// Re-test all pages (stage)
$pages = $controller -> getList () -> sort ( 'Title' );
$this -> assertEquals ( 26 , $pages -> count ());
$this -> assertEquals (
array ( 'Home' , 'Page 10' , 'Page 11' , 'Page 13' , 'Page 14' ),
$pages -> Limit ( 5 ) -> column ( 'Title' )
);
// Test deleted page filter
$params = array (
'FilterClass' => 'CMSSiteTreeFilter_StatusDeletedPages'
);
$pages = $controller -> getList ( $params );
$this -> assertEquals ( 1 , $pages -> count ());
$this -> assertEquals (
array ( 'Page 1' ),
$pages -> column ( 'Title' )
);
// Test live, but not on draft filter
$params = array (
'FilterClass' => 'CMSSiteTreeFilter_StatusRemovedFromDraftPages'
);
$pages = $controller -> getList ( $params );
$this -> assertEquals ( 1 , $pages -> count ());
$this -> assertEquals (
array ( 'Page 12' ),
$pages -> column ( 'Title' )
);
// Test live pages filter
$params = array (
'FilterClass' => 'CMSSIteTreeFilter_PublishedPages'
);
$pages = $controller -> getList ( $params );
$this -> assertEquals ( 2 , $pages -> count ());
$this -> assertEquals (
array ( 'Page 11' , 'Page 12' ),
$pages -> column ( 'Title' )
);
// Test that parentID is ignored when filtering
$pages = $controller -> getList ( $params , $page3 -> ID );
$this -> assertEquals ( 2 , $pages -> count ());
$this -> assertEquals (
array ( 'Page 11' , 'Page 12' ),
$pages -> column ( 'Title' )
);
// Test that parentID is respected when not filtering
$pages = $controller -> getList ( array (), $page3 -> ID );
$this -> assertEquals ( 2 , $pages -> count ());
$this -> assertEquals (
array ( 'Page 3.1' , 'Page 3.2' ),
$pages -> column ( 'Title' )
);
}
2010-12-14 02:29:38 +01:00
}
2012-09-02 18:06:25 +02:00
class CMSMainTest_ClassA extends Page implements TestOnly {
2013-03-18 11:47:15 +01:00
private static $allowed_children = array ( 'CMSMainTest_ClassB' );
2012-09-02 18:06:25 +02:00
}
class CMSMainTest_ClassB extends Page implements TestOnly {
2012-12-03 16:33:06 +01:00
}
class CMSMainTest_NotRoot extends Page implements TestOnly {
2013-03-18 11:47:15 +01:00
private static $can_be_root = false ;
2012-12-03 16:33:06 +01:00
}
class CMSMainTest_HiddenClass extends Page implements TestOnly , HiddenClass {
2014-03-19 07:27:39 +01:00
}