diff --git a/code/controllers/CMSMain.php b/code/controllers/CMSMain.php index 817bf398..a36008c9 100644 --- a/code/controllers/CMSMain.php +++ b/code/controllers/CMSMain.php @@ -1369,7 +1369,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr if(($id = $this->urlParams['ID']) && is_numeric($id)) { $page = DataObject::get_by_id("SiteTree", $id); - if($page && (!$page->canEdit() || !$page->canCreate())) return Security::permissionFailure($this); + if($page && (!$page->canEdit() || !$page->canCreate(null, array('Parent' => $page->Parent())))) { + return Security::permissionFailure($this); + } if(!$page || !$page->ID) throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404); $newPage = $page->duplicate(); @@ -1405,7 +1407,9 @@ class CMSMain extends LeftAndMain implements CurrentPageIdentifier, PermissionPr increase_time_limit_to(); if(($id = $this->urlParams['ID']) && is_numeric($id)) { $page = DataObject::get_by_id("SiteTree", $id); - if($page && (!$page->canEdit() || !$page->canCreate())) return Security::permissionFailure($this); + if($page && (!$page->canEdit() || !$page->canCreate(null, array('Parent' => $page->Parent())))) { + return Security::permissionFailure($this); + } if(!$page || !$page->ID) throw new SS_HTTPResponse_Exception("Bad record ID #$id", 404); $newPage = $page->duplicateWithChildren(); diff --git a/code/model/RedirectorPage.php b/code/model/RedirectorPage.php index c9ec3270..34c0a148 100644 --- a/code/model/RedirectorPage.php +++ b/code/model/RedirectorPage.php @@ -165,7 +165,8 @@ class RedirectorPage_Controller extends Page_Controller { public function init() { parent::init(); - if($link = $this->redirectionLink()) { + // Check we don't already have a redirect code set + if(!$this->getResponse()->isFinished() && $link = $this->redirectionLink()) { $this->redirect($link, 301); return; } diff --git a/code/reports/BrokenLinksReport.php b/code/reports/BrokenLinksReport.php index 447c9abf..6dc1d2c0 100644 --- a/code/reports/BrokenLinksReport.php +++ b/code/reports/BrokenLinksReport.php @@ -80,7 +80,7 @@ class BrokenLinksReport extends SS_Report { return $returnSet; } public function columns() { - if(isset($_REQUEST['CheckSite']) && $_REQUEST['CheckSite'] == 'Draft') { + if(isset($_REQUEST['filters']['CheckSite']) && $_REQUEST['filters']['CheckSite'] == 'Draft') { $dateTitle = _t('BrokenLinksReport.ColumnDateLastModified', 'Date last modified'); } else { $dateTitle = _t('BrokenLinksReport.ColumnDateLastPublished', 'Date last published'); @@ -91,7 +91,7 @@ class BrokenLinksReport extends SS_Report { "Title" => array( "title" => _t('BrokenLinksReport.PageName', 'Page name'), 'formatting' => function($value, $item) use ($linkBase) { - return sprintf('%s', + return sprintf('%s', Controller::join_links($linkBase, $item->ID), _t('BrokenLinksReport.HoverTitleEditPage', 'Edit page'), $value diff --git a/tests/behat/features/insert-an-image.feature b/tests/behat/features/insert-an-image.feature index 146eace0..bc1883e9 100644 --- a/tests/behat/features/insert-an-image.feature +++ b/tests/behat/features/insert-an-image.feature @@ -17,12 +17,12 @@ Feature: Insert an image into a page Then I should see "Choose files to upload..." When I press the "From the web" button - And I fill in "RemoteURL" with "http://www.silverstripe.com/themes/sscom/images/silverstripe_logo_web.png" + And I fill in "RemoteURL" with "http://www.silverstripe.org/themes/ssv3/img/ss_logo.png" And I press the "Add url" button - Then I should see "silverstripe_logo_web.png (www.silverstripe.com)" in the ".ss-assetuploadfield span.name" element + Then I should see "ss_logo.png (www.silverstripe.org)" in the ".ss-assetuploadfield span.name" element When I press the "Insert" button - Then the "Content" HTML field should contain "silverstripe_logo_web.png" + Then the "Content" HTML field should contain "ss_logo.png" # Required to avoid "unsaved changed" browser dialog Then I press the "Save draft" button diff --git a/tests/model/RedirectorPageTest.php b/tests/model/RedirectorPageTest.php index 5e036a16..6d4d29d7 100644 --- a/tests/model/RedirectorPageTest.php +++ b/tests/model/RedirectorPageTest.php @@ -3,6 +3,7 @@ class RedirectorPageTest extends FunctionalTest { protected static $fixture_file = 'RedirectorPageTest.yml'; protected static $use_draft_site = true; + protected $autoFollowRedirection = false; public function testGoodRedirectors() { /* For good redirectors, the final destination URL will be returned */ @@ -64,4 +65,27 @@ class RedirectorPageTest extends FunctionalTest { $protocolRelative->write(); $this->assertEquals('//mydomain.com', $protocolRelative->ExternalURL); } + + /** + * Test that we can trigger a redirection before RedirectorPage_Controller::init() is called + */ + public function testRedirectRespectsFinishedResponse() { + $page = $this->objFromFixture('RedirectorPage', 'goodinternal'); + RedirectorPage_Controller::add_extension('RedirectorPageTest_RedirectExtension'); + + $response = $this->get($page->regularLink()); + $this->assertEquals(302, $response->getStatusCode()); + $this->assertEquals('/foo', $response->getHeader('Location')); + + RedirectorPage_Controller::remove_extension('RedirectorPageTest_RedirectExtension'); + } + +} + +class RedirectorPageTest_RedirectExtension extends Extension implements TestOnly { + + public function onBeforeInit() { + $this->owner->redirect('/foo'); + } + } diff --git a/tests/reports/CmsReportsTest.php b/tests/reports/CmsReportsTest.php index 657fc274..25b14c83 100644 --- a/tests/reports/CmsReportsTest.php +++ b/tests/reports/CmsReportsTest.php @@ -24,6 +24,31 @@ class CmsReportsTest extends SapphireTest { DB::query("UPDATE \"SiteTree\" SET \"Created\"='2009-01-01 00:00:00', \"LastEdited\"='".date('Y-m-d H:i:s', $beforeThreshold)."' WHERE \"ID\"='".$before->ID."'"); } + /** + * ASSERT whether a report is returning the correct results, based on a broken "draft" and/or "published" page. + * + * @parameter ss_report + * @parameter boolean + * @parameter boolean + */ + + public function isReportBroken($report, $isDraftBroken, $isPublishedBroken) { + + $class = get_class($report); + + // ASSERT that the "draft" report is returning the correct results. + + $results = count($report->sourceRecords(array())) > 0; + $isDraftBroken ? $this->assertTrue($results, "{$class} has NOT returned the correct DRAFT results, as NO pages were found.") : $this->assertFalse($results, "{$class} has NOT returned the correct DRAFT results, as pages were found."); + + // ASSERT that the "published" report is returning the correct results. + + $results = count($report->sourceRecords(array( + 'OnLive' => 1 + ))) > 0; + $isPublishedBroken ? $this->assertTrue($results, "{$class} has NOT returned the correct PUBLISHED results, as NO pages were found.") : $this->assertFalse($results, "{$class} has NOT returned the correct PUBLISHED results, as pages were found."); + } + public function testRecentlyEdited() { SS_Datetime::set_mock_now('31-06-2009 00:00:00'); @@ -39,4 +64,265 @@ class CmsReportsTest extends SapphireTest { SS_DateTime::clear_mock_now(); } + + /** + * Test the broken links side report. + */ + + public function testBrokenLinks() { + + // Create a "draft" page with a broken link. + + $page = Page::create(); + $page->Content = "This is a broken link."; + $page->writeToStage('Stage'); + + // Retrieve the broken links side report. + + $reports = SS_Report::get_reports(); + $brokenLinksReport = null; + foreach($reports as $report) { + if($report instanceof SideReport_BrokenLinks) { + $brokenLinksReport = $report; + break; + } + } + + // Determine that the report exists, otherwise it has been excluded. + + if($brokenLinksReport) { + + // ASSERT that the "draft" report has detected the page having a broken link. + // ASSERT that the "published" report has NOT detected the page having a broken link, as the page has not been "published" yet. + + $this->isReportBroken($brokenLinksReport, true, false); + + // Make sure the page is now "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has detected the page having a broken link. + // ASSERT that the "published" report has detected the page having a broken link. + + $this->isReportBroken($brokenLinksReport, true, true); + + // Correct the "draft" broken link. + + $page->Content = str_replace('987654321', $page->ID, $page->Content); + $page->writeToStage('Stage'); + + // ASSERT that the "draft" report has NOT detected the page having a broken link. + // ASSERT that the "published" report has detected the page having a broken link, as the previous content remains "published". + + $this->isReportBroken($brokenLinksReport, false, true); + + // Make sure the change has now been "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has NOT detected the page having a broken link. + // ASSERT that the "published" report has NOT detected the page having a broken link. + + $this->isReportBroken($brokenLinksReport, false, false); + } + } + + /** + * Test the broken files side report. + */ + + public function testBrokenFiles() { + + // Create a "draft" page with a broken file. + + $page = Page::create(); + $page->Content = "This is a broken file."; + $page->writeToStage('Stage'); + + // Retrieve the broken files side report. + + $reports = SS_Report::get_reports(); + $brokenFilesReport = null; + foreach($reports as $report) { + if($report instanceof SideReport_BrokenFiles) { + $brokenFilesReport = $report; + break; + } + } + + // Determine that the report exists, otherwise it has been excluded. + + if($brokenFilesReport) { + + // ASSERT that the "draft" report has detected the page having a broken file. + // ASSERT that the "published" report has NOT detected the page having a broken file, as the page has not been "published" yet. + + $this->isReportBroken($brokenFilesReport, true, false); + + // Make sure the page is now "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has detected the page having a broken file. + // ASSERT that the "published" report has detected the page having a broken file. + + $this->isReportBroken($brokenFilesReport, true, true); + + // Correct the "draft" broken file. + + $file = File::create(); + $file->Filename = 'name.pdf'; + $file->write(); + $page->Content = str_replace('987654321', $file->ID, $page->Content); + $page->writeToStage('Stage'); + + // ASSERT that the "draft" report has NOT detected the page having a broken file. + // ASSERT that the "published" report has detected the page having a broken file, as the previous content remains "published". + + $this->isReportBroken($brokenFilesReport, false, true); + + // Make sure the change has now been "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has NOT detected the page having a broken file. + // ASSERT that the "published" report has NOT detected the page having a broken file. + + $this->isReportBroken($brokenFilesReport, false, false); + } + } + + /** + * Test the broken virtual pages side report. + */ + + public function testBrokenVirtualPages() { + + // Create a "draft" virtual page with a broken link. + + $page = VirtualPage::create(); + $page->CopyContentFromID = 987654321; + $page->writeToStage('Stage'); + + // Retrieve the broken virtual pages side report. + + $reports = SS_Report::get_reports(); + $brokenVirtualPagesReport = null; + foreach($reports as $report) { + if($report instanceof SideReport_BrokenVirtualPages) { + $brokenVirtualPagesReport = $report; + break; + } + } + + // Determine that the report exists, otherwise it has been excluded. + + if($brokenVirtualPagesReport) { + + // ASSERT that the "draft" report has detected the page having a broken link. + // ASSERT that the "published" report has NOT detected the page having a broken link, as the page has not been "published" yet. + + $this->isReportBroken($brokenVirtualPagesReport, true, false); + + // Make sure the page is now "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has detected the page having a broken link. + // ASSERT that the "published" report has detected the page having a broken link. + + $this->isReportBroken($brokenVirtualPagesReport, true, true); + + // Correct the "draft" broken link. + + $contentPage = Page::create(); + $contentPage->Content = 'This is some content.'; + $contentPage->writeToStage('Stage'); + $contentPage->writeToStage('Live'); + $page->CopyContentFromID = $contentPage->ID; + $page->writeToStage('Stage'); + + // ASSERT that the "draft" report has NOT detected the page having a broken link. + // ASSERT that the "published" report has detected the page having a broken link, as the previous content remains "published". + + $this->isReportBroken($brokenVirtualPagesReport, false, true); + + // Make sure the change has now been "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has NOT detected the page having a broken link. + // ASSERT that the "published" report has NOT detected the page having a broken link. + + $this->isReportBroken($brokenVirtualPagesReport, false, false); + } + } + + /** + * Test the broken redirector pages side report. + */ + + public function testBrokenRedirectorPages() { + + // Create a "draft" redirector page with a broken link. + + $page = RedirectorPage::create(); + $page->RedirectionType = 'Internal'; + $page->LinkToID = 987654321; + $page->writeToStage('Stage'); + + // Retrieve the broken redirector pages side report. + + $reports = SS_Report::get_reports(); + $brokenRedirectorPagesReport = null; + foreach($reports as $report) { + if($report instanceof SideReport_BrokenRedirectorPages) { + $brokenRedirectorPagesReport = $report; + break; + } + } + + // Determine that the report exists, otherwise it has been excluded. + + if($brokenRedirectorPagesReport) { + + // ASSERT that the "draft" report has detected the page having a broken link. + // ASSERT that the "published" report has NOT detected the page having a broken link, as the page has not been "published" yet. + + $this->isReportBroken($brokenRedirectorPagesReport, true, false); + + // Make sure the page is now "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has detected the page having a broken link. + // ASSERT that the "published" report has detected the page having a broken link. + + $this->isReportBroken($brokenRedirectorPagesReport, true, true); + + // Correct the "draft" broken link. + + $contentPage = Page::create(); + $contentPage->Content = 'This is some content.'; + $contentPage->writeToStage('Stage'); + $contentPage->writeToStage('Live'); + $page->LinkToID = $contentPage->ID; + $page->writeToStage('Stage'); + + // ASSERT that the "draft" report has NOT detected the page having a broken link. + // ASSERT that the "published" report has detected the page having a broken link, as the previous content remains "published". + + $this->isReportBroken($brokenRedirectorPagesReport, false, true); + + // Make sure the change has now been "published". + + $page->writeToStage('Live'); + + // ASSERT that the "draft" report has NOT detected the page having a broken link. + // ASSERT that the "published" report has NOT detected the page having a broken link. + + $this->isReportBroken($brokenRedirectorPagesReport, false, false); + } + } + }