2011-03-18 04:17:04 +01:00
< ? php
2016-06-16 06:57:19 +02:00
2017-08-09 04:53:38 +02:00
namespace SilverStripe\CMS\Tests\Controllers ;
2017-08-09 03:25:12 +02:00
2017-03-21 05:26:46 +01:00
use SilverStripe\Versioned\Versioned ;
2016-07-22 01:32:32 +02:00
use SilverStripe\CMS\Model\SiteTree ;
use SilverStripe\CMS\Controllers\OldPageRedirector ;
use SilverStripe\CMS\Controllers\RootURLController ;
2016-08-23 04:36:06 +02:00
use SilverStripe\Core\Config\Config ;
use SilverStripe\Control\Director ;
use SilverStripe\Control\Controller ;
use SilverStripe\Dev\FunctionalTest ;
2017-08-09 03:25:12 +02:00
use Page ;
2019-01-13 21:17:06 +01:00
use SilverStripe\View\Parsers\URLSegmentFilter ;
2017-08-09 03:25:12 +02:00
2017-01-25 21:59:25 +01:00
class ModelAsControllerTest extends FunctionalTest
{
protected $usesDatabase = true ;
protected $autoFollowRedirection = false ;
/**
* New tests require nested urls to be enabled , but the site might not
* support nested URLs .
* This setup will enable nested - urls for this test and resets the state
* after the tests have been performed .
*/
public function setUp ()
{
parent :: setUp ();
2017-07-17 07:19:00 +02:00
Config :: modify () -> set ( SiteTree :: class , 'nested_urls' , true );
2017-01-25 21:59:25 +01:00
}
protected function generateNestedPagesFixture ()
{
$level1 = new Page ();
$level1 -> Title = 'First Level' ;
$level1 -> URLSegment = 'level1' ;
$level1 -> write ();
$level1 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$level1 -> URLSegment = 'newlevel1' ;
$level1 -> write ();
$level1 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$level2 = new Page ();
$level2 -> Title = 'Second Level' ;
$level2 -> URLSegment = 'level2' ;
$level2 -> ParentID = $level1 -> ID ;
$level2 -> write ();
$level2 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$level2 -> URLSegment = 'newlevel2' ;
$level2 -> write ();
$level2 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$level3 = new Page ();
$level3 -> Title = " Level 3 " ;
$level3 -> URLSegment = 'level3' ;
$level3 -> ParentID = $level2 -> ID ;
$level3 -> write ();
$level3 -> copyVersionToStage ( 'Stage' , 'Live' );
$level3 -> URLSegment = 'newlevel3' ;
$level3 -> write ();
$level3 -> copyVersionToStage ( 'Stage' , 'Live' );
}
/**
* We ' re building up a page hierarchy ( " nested URLs " ) and rename
* all the individual pages afterwards . The assumption is that
* all pages will be found by their old segments .
*
* NOTE : This test requires nested_urls
*
* Original : level1 / level2 / level3
* Republished as : newlevel1 / newlevel2 / newlevel3
*/
public function testRedirectsNestedRenamedPages ()
{
$this -> generateNestedPagesFixture ();
// check a first level URLSegment
$response = $this -> get ( 'level1/action' );
$this -> assertEquals ( $response -> getStatusCode (), 301 );
$this -> assertEquals (
Controller :: join_links ( Director :: baseURL () . 'newlevel1/action' ),
$response -> getHeader ( 'Location' )
);
// check second level URLSegment
$response = $this -> get ( 'newlevel1/level2' );
$this -> assertEquals ( $response -> getStatusCode (), 301 );
$this -> assertEquals (
Controller :: join_links ( Director :: baseURL () . 'newlevel1/newlevel2/' ),
$response -> getHeader ( 'Location' )
);
// check third level URLSegment
$response = $this -> get ( 'newlevel1/newlevel2/level3' );
$this -> assertEquals ( $response -> getStatusCode (), 301 );
$this -> assertEquals (
Controller :: join_links ( Director :: baseURL () . 'newlevel1/newlevel2/newlevel3/' ),
$response -> getHeader ( 'Location' )
);
$response = $this -> get ( 'newlevel1/newlevel2/level3' );
}
/**
* Test that the redirect works even with a lot of nested pages
* Original : / oldurl / level2 / level3 / level4 / level5
* New : / newurl / level2 / level3 / level4 / level5
*/
public function testHeavilyNestedRenamedRedirectedPages ()
{
$page = new Page ();
$page -> Title = 'First Level' ;
$page -> URLSegment = 'oldurl' ;
$page -> write ();
$page -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$page -> URLSegment = 'newurl' ;
$page -> write ();
$page -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$page2 = new Page ();
$page2 -> Title = 'Second Level Page' ;
$page2 -> URLSegment = 'level2' ;
$page2 -> ParentID = $page -> ID ;
$page2 -> write ();
$page2 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$page3 = new Page ();
$page3 -> Title = 'Third Level Page' ;
$page3 -> URLSegment = 'level3' ;
$page3 -> ParentID = $page2 -> ID ;
$page3 -> write ();
$page3 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$page4 = new Page ();
$page4 -> Title = 'Fourth Level Page' ;
$page4 -> URLSegment = 'level4' ;
$page4 -> ParentID = $page3 -> ID ;
$page4 -> write ();
$page4 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$page5 = new Page ();
$page5 -> Title = 'Fifth Level Page' ;
$page5 -> URLSegment = 'level5' ;
$page5 -> ParentID = $page4 -> ID ;
$page5 -> write ();
$page5 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
// Test that the redirect still works fine when trying to access the most nested page
$response = $this -> get ( 'oldurl/level2/level3/level4/level5/' );
$this -> assertEquals ( $response -> getStatusCode (), 301 );
$this -> assertEquals (
Controller :: join_links ( Director :: baseURL () . 'newurl/level2/level3/level4/level5/' ),
$response -> getHeader ( 'Location' )
);
}
public function testRedirectionForPreNestedurlsBookmarks ()
{
$this -> generateNestedPagesFixture ();
// Up-to-date URLs will be redirected to the appropriate subdirectory
$response = $this -> get ( 'newlevel3' );
$this -> assertEquals ( 301 , $response -> getStatusCode ());
$this -> assertEquals (
Director :: baseURL () . 'newlevel1/newlevel2/newlevel3/' ,
$response -> getHeader ( " Location " )
);
// So will the legacy ones
$response = $this -> get ( 'level3' );
$this -> assertEquals ( 301 , $response -> getStatusCode ());
$this -> assertEquals (
Director :: baseURL () . 'newlevel1/newlevel2/newlevel3/' ,
$response -> getHeader ( " Location " )
);
}
public function testDoesntRedirectToNestedChildrenOutsideOfOwnHierarchy ()
{
$this -> generateNestedPagesFixture ();
2020-04-19 06:18:01 +02:00
$otherParent = new Page ([
2017-01-25 21:59:25 +01:00
'URLSegment' => 'otherparent'
2020-04-19 06:18:01 +02:00
]);
2017-01-25 21:59:25 +01:00
$otherParent -> write ();
$otherParent -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$response = $this -> get ( 'level1/otherparent' );
$this -> assertEquals ( $response -> getStatusCode (), 301 );
$response = $this -> get ( 'newlevel1/otherparent' );
$this -> assertEquals (
$response -> getStatusCode (),
404 ,
'Requesting an unrelated page on a renamed parent should be interpreted as a missing action, not a redirect'
);
}
/**
*
* NOTE : This test requires nested_urls
*
*/
public function testRedirectsNestedRenamedPagesWithGetParameters ()
{
$this -> generateNestedPagesFixture ();
// check third level URLSegment
$response = $this -> get ( 'newlevel1/newlevel2/level3/?foo=bar&test=test' );
$this -> assertEquals ( $response -> getStatusCode (), 301 );
$this -> assertEquals (
Controller :: join_links ( Director :: baseURL () . 'newlevel1/newlevel2/newlevel3/' , '?foo=bar&test=test' ),
$response -> getHeader ( 'Location' )
);
}
/**
*
* NOTE : This test requires nested_urls
*
*/
public function testDoesntRedirectToNestedRenamedPageWhenNewExists ()
{
$this -> generateNestedPagesFixture ();
2020-04-19 06:18:01 +02:00
$otherLevel1 = new Page ([
2017-01-25 21:59:25 +01:00
'Title' => " Other Level 1 " ,
'URLSegment' => 'level1'
2020-04-19 06:18:01 +02:00
]);
2017-01-25 21:59:25 +01:00
$otherLevel1 -> write ();
$otherLevel1 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$response = $this -> get ( 'level1' );
$this -> assertEquals (
$response -> getStatusCode (),
200
);
$response = $this -> get ( 'level1/newlevel2' );
$this -> assertEquals (
$response -> getStatusCode (),
404 ,
'The old newlevel2/ URLSegment is checked as an action on the new page, which shouldnt exist.'
);
}
/**
*
* NOTE : This test requires nested_urls
*
*/
public function testFindOldPage ()
{
$page = new Page ();
$page -> Title = 'First Level' ;
$page -> URLSegment = 'oldurl' ;
$page -> write ();
$page -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$page -> URLSegment = 'newurl' ;
$page -> write ();
$page -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$url = OldPageRedirector :: find_old_page ( 'oldurl' );
$matchedPage = SiteTree :: get_by_link ( $url );
$this -> assertEquals ( 'First Level' , $matchedPage -> Title );
$page2 = new Page ();
$page2 -> Title = 'Second Level Page' ;
$page2 -> URLSegment = 'oldpage2' ;
$page2 -> ParentID = $page -> ID ;
$page2 -> write ();
$page2 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$page2 -> URLSegment = 'newpage2' ;
$page2 -> write ();
$page2 -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$url = OldPageRedirector :: find_old_page ( 'oldpage2' , $page2 -> ParentID );
$matchedPage = SiteTree :: get_by_link ( $url );
$this -> assertEquals ( 'Second Level Page' , $matchedPage -> Title );
$url = OldPageRedirector :: find_old_page ( 'oldpage2' , $page2 -> ID );
$matchedPage = SiteTree :: get_by_link ( $url );
$this -> assertEquals ( false , $matchedPage );
}
/**
* go to a page that ' s been published but is child of an unpublished page
*
* NOTE : This test requires nested_urls
*/
public function testChildOfDraft ()
{
RootURLController :: reset ();
2017-07-17 07:19:00 +02:00
Config :: modify () -> set ( SiteTree :: class , 'nested_urls' , true );
2017-01-25 21:59:25 +01:00
$draft = new Page ();
$draft -> Title = 'Root Leve Draft Page' ;
$draft -> URLSegment = 'root' ;
$draft -> write ();
$published = new Page ();
$published -> Title = 'Published Page Under Draft Page' ;
$published -> URLSegment = 'sub-root' ;
$published -> write ();
$published -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$response = $this -> get ( 'root/sub-root' );
$this -> assertEquals (
$response -> getStatusCode (),
404 ,
'The page should not be found since its parent has not been published, in this case http://<yousitename>/root/sub-root or http://<yousitename>/sub-root'
);
}
2019-01-13 21:17:06 +01:00
public function testAllowMultibyte ()
{
Config :: modify () -> set ( URLSegmentFilter :: class , 'default_allow_multibyte' , true );
$parent = new Page ();
$parent -> Title = 'Multibyte test' ;
$parent -> URLSegment = 'بلاگ' ;
$parent -> write ();
$parent -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
$child = new Page ();
$child -> Title = 'Multibyte test' ;
$child -> URLSegment = 'فضة' ;
$child -> ParentID = $parent -> ID ;
$child -> write ();
$child -> copyVersionToStage ( Versioned :: DRAFT , Versioned :: LIVE );
// Emulate browser behaviour around multibyte URL encodings
$response = $this -> get ( rawurlencode ( 'بلاگ' ));
$this -> assertEquals (
$response -> getStatusCode (),
200 ,
'Routes toplevel paths'
);
$response = $this -> get ( join ( '/' , [ rawurlencode ( 'بلاگ' ), rawurlencode ( 'فضة' )]));
$this -> assertEquals (
$response -> getStatusCode (),
200 ,
'Routes nested paths'
);
}
2012-04-12 09:23:20 +02:00
}