diff --git a/.travis.yml b/.travis.yml index 0a558db1..db545d93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,24 +1,30 @@ # See https://github.com/silverstripe-labs/silverstripe-travis-support for setup details -language: php -php: - - 5.3 - sudo: false +language: php + +php: + - 5.5 + - 5.6 + - 7.0 + env: - - DB=MYSQL CORE_RELEASE=master - - DB=PGSQL CORE_RELEASE=master + - DB=MYSQL CORE_RELEASE=master matrix: include: - - php: 5.4 - env: DB=MYSQL CORE_RELEASE=master + - php: 5.6 + env: DB=PGSQL CORE_RELEASE=master + allow_failures: + - php: 7.0 before_script: - - git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support - - php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss - - cd ~/builds/ss + - composer self-update || true + - git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support + - php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss + - cd ~/builds/ss + - composer install -script: - - phpunit reports/tests/ +script: + - vendor/bin/phpunit reports/tests diff --git a/code/Report.php b/code/Report.php index a0153404..b8e8f298 100644 --- a/code/Report.php +++ b/code/Report.php @@ -31,131 +31,137 @@ */ class SS_Report extends ViewableData { - /** - * This is the title of the report, - * used by the ReportAdmin templates. - * - * @var string - */ - protected $title = ''; + /** + * This is the title of the report, + * used by the ReportAdmin templates. + * + * @var string + */ + protected $title = ''; - /** - * This is a description about what this - * report does. Used by the ReportAdmin - * templates. - * - * @var string - */ - protected $description = ''; - - /** - * The class of object being managed by this report. - * Set by overriding in your subclass. - */ - protected $dataClass = 'SiteTree'; + /** + * This is a description about what this + * report does. Used by the ReportAdmin + * templates. + * + * @var string + */ + protected $description = ''; + + /** + * The class of object being managed by this report. + * Set by overriding in your subclass. + */ + protected $dataClass = 'SiteTree'; - /** - * A field that specifies the sort order of this report - * @var int - */ - protected $sort = 0; + /** + * A field that specifies the sort order of this report + * @var int + */ + protected $sort = 0; - /** - * Reports which should not be collected and returned in get_reports - * @var array - */ - public static $excluded_reports = array( - 'SS_Report', - 'SS_ReportWrapper', - 'SideReportWrapper' - ); - - /** - * Return the title of this report. - * - * You have two ways of specifying the description: - * - overriding description(), which lets you support i18n - * - defining the $description property - */ + /** + * Reports which should not be collected and returned in get_reports + * @var array + */ + public static $excluded_reports = array( + 'SS_Report', + 'SS_ReportWrapper', + 'SideReportWrapper', + 'SideReport_RecentlyEdited', // @deprecated 3.2..4.0 + 'SideReport_EmptyPages', // @deprecated 3.2..4.0 + 'SideReport_BrokenVirtualPages', // @deprecated 3.2..4.0 + 'SideReport_BrokenRedirectorPages', // @deprecated 3.2..4.0 + 'SideReport_BrokenLinks', // @deprecated 3.2..4.0 + 'SideReport_BrokenFiles' // @deprecated 3.2..4.0 + ); + + /** + * Return the title of this report. + * + * You have two ways of specifying the description: + * - overriding description(), which lets you support i18n + * - defining the $description property + */ public function title() { - return $this->title; - } - - /** - * Allows access to title as a property - * - * @return string - */ + return $this->title; + } + + /** + * Allows access to title as a property + * + * @return string + */ public function getTitle() { - return $this->title(); - } - - /** - * Return the description of this report. - * - * You have two ways of specifying the description: - * - overriding description(), which lets you support i18n - * - defining the $description property - */ + return $this->title(); + } + + /** + * Return the description of this report. + * + * You have two ways of specifying the description: + * - overriding description(), which lets you support i18n + * - defining the $description property + */ public function description() { - return $this->description; - } - - /** - * Return the {@link SQLQuery} that provides your report data. - */ + return $this->description; + } + + /** + * Return the {@link SQLQuery} that provides your report data. + */ public function sourceQuery($params) { - if ($this->hasMethod('sourceRecords')) { - return $this->sourceRecords()->dataQuery(); - } else { - user_error("Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()", E_USER_ERROR); - } - } - - /** - * Return a SS_List records for this report. - */ + if($this->hasMethod('sourceRecords')) { + return $this->sourceRecords($params, null, null)->dataQuery(); + } else { + user_error("Please override sourceQuery()/sourceRecords() and columns() or, if necessary, override getReportField()", E_USER_ERROR); + } + } + + /** + * Return a SS_List records for this report. + */ public function records($params) { - if ($this->hasMethod('sourceRecords')) { - return $this->sourceRecords($params, null, null); - } else { - $query = $this->sourceQuery(); - $results = new ArrayList(); - foreach ($query->execute() as $data) { - $class = $this->dataClass(); - $result = new $class($data); - $results->push($result); - } - return $results; - } - } + if($this->hasMethod('sourceRecords')) { + return $this->sourceRecords($params, null, null); + } else { + $query = $this->sourceQuery(); + $results = new ArrayList(); + foreach($query->execute() as $data) { + $class = $this->dataClass(); + $result = new $class($data); + $results->push($result); + } + return $results; + } + } - /** - * Return the data class for this report - */ + /** + * Return the data class for this report + */ public function dataClass() { - return $this->dataClass; - } + return $this->dataClass; + } public function getLink($action = null) { - return Controller::join_links( - 'admin/reports/', - "$this->class", - '/', // trailing slash needed if $action is null! - "$action" - ); - } + return Controller::join_links( + 'admin/reports/', + "$this->class", + '/', // trailing slash needed if $action is null! + "$action" + ); + } - /** + /** * counts the number of objects returned * @param Array $params - any parameters for the sourceRecords * @return Int @@ -171,159 +177,159 @@ class SS_Report extends ViewableData } /** - * Exclude certain reports classes from the list of Reports in the CMS - * @param $reportClass Can be either a string with the report classname or an array of reports classnames - */ + * Exclude certain reports classes from the list of Reports in the CMS + * @param $reportClass Can be either a string with the report classname or an array of reports classnames + */ public static function add_excluded_reports($reportClass) { - if (is_array($reportClass)) { - self::$excluded_reports = array_merge(self::$excluded_reports, $reportClass); - } else { - if (is_string($reportClass)) { - //add to the excluded reports, so this report doesn't get used - self::$excluded_reports[] = $reportClass; - } - } - } + if (is_array($reportClass)) { + self::$excluded_reports = array_merge(self::$excluded_reports, $reportClass); + } else { + if (is_string($reportClass)) { + //add to the excluded reports, so this report doesn't get used + self::$excluded_reports[] = $reportClass; + } + } + } - /** - * Return an array of excluded reports. That is, reports that will not be included in - * the list of reports in report admin in the CMS. - * @return array - */ + /** + * Return an array of excluded reports. That is, reports that will not be included in + * the list of reports in report admin in the CMS. + * @return array + */ public static function get_excluded_reports() { - return self::$excluded_reports; - } + return self::$excluded_reports; + } - /** - * Return the SS_Report objects making up the given list. - * @return Array of SS_Report objects - */ + /** + * Return the SS_Report objects making up the given list. + * @return Array of SS_Report objects + */ public static function get_reports() { - $reports = ClassInfo::subclassesFor(get_called_class()); + $reports = ClassInfo::subclassesFor(get_called_class()); - $reportsArray = array(); - if ($reports && count($reports) > 0) { - //collect reports into array with an attribute for 'sort' - foreach ($reports as $report) { + $reportsArray = array(); + if ($reports && count($reports) > 0) { + //collect reports into array with an attribute for 'sort' + foreach($reports as $report) { if (in_array($report, self::$excluded_reports)) { continue; } //don't use the SS_Report superclass - $reflectionClass = new ReflectionClass($report); + $reflectionClass = new ReflectionClass($report); if ($reflectionClass->isAbstract()) { continue; } //don't use abstract classes - $reportObj = new $report; + $reportObj = new $report; if (method_exists($reportObj, 'sort')) { $reportObj->sort = $reportObj->sort(); } //use the sort method to specify the sort field - $reportsArray[$report] = $reportObj; - } - } + $reportsArray[$report] = $reportObj; + } + } - uasort($reportsArray, function ($a, $b) { + uasort($reportsArray, function($a, $b) { if ($a->sort == $b->sort) { return 0; } else { return ($a->sort < $b->sort) ? -1 : 1; } - }); + }); - return $reportsArray; - } + return $reportsArray; + } - /////////////////////// UI METHODS /////////////////////// + /////////////////////// UI METHODS /////////////////////// - /** - * Returns a FieldList with which to create the CMS editing form. - * You can use the extend() method of FieldList to create customised forms for your other - * data objects. - * - * @uses getReportField() to render a table, or similar field for the report. This - * method should be defined on the SS_Report subclasses. - * - * @return FieldList - */ + /** + * Returns a FieldList with which to create the CMS editing form. + * You can use the extend() method of FieldList to create customised forms for your other + * data objects. + * + * @uses getReportField() to render a table, or similar field for the report. This + * method should be defined on the SS_Report subclasses. + * + * @return FieldList + */ public function getCMSFields() { - $fields = new FieldList(); + $fields = new FieldList(); - if ($title = $this->title()) { - $fields->push(new LiteralField('ReportTitle', "

{$title}

")); - } - - if ($description = $this->description()) { - $fields->push(new LiteralField('ReportDescription', "

" . $description . "

")); - } - - // Add search fields is available - if ($this->hasMethod('parameterFields') && $parameterFields = $this->parameterFields()) { - foreach ($parameterFields as $field) { - // Namespace fields for easier handling in form submissions - $field->setName(sprintf('filters[%s]', $field->getName())); - $field->addExtraClass('no-change-track'); // ignore in changetracker - $fields->push($field); - } + if($title = $this->title()) { + $fields->push(new LiteralField('ReportTitle', "

{$title}

")); + } + + if($description = $this->description()) { + $fields->push(new LiteralField('ReportDescription', "

" . $description . "

")); + } + + // Add search fields is available + if($this->hasMethod('parameterFields') && $parameterFields = $this->parameterFields()) { + foreach($parameterFields as $field) { + // Namespace fields for easier handling in form submissions + $field->setName(sprintf('filters[%s]', $field->getName())); + $field->addExtraClass('no-change-track'); // ignore in changetracker + $fields->push($field); + } - // Add a search button - $fields->push(new FormAction('updatereport', _t('GridField.Filter'))); - } - - $fields->push($this->getReportField()); + // Add a search button + $fields->push(new FormAction('updatereport', _t('GridField.Filter'))); + } + + $fields->push($this->getReportField()); - $this->extend('updateCMSFields', $fields); - - return $fields; - } - + $this->extend('updateCMSFields', $fields); + + return $fields; + } + public function getCMSActions() { - // getCMSActions() can be extended with updateCMSActions() on a extension - $actions = new FieldList(); - $this->extend('updateCMSActions', $actions); - return $actions; - } - - /** - * Return a field, such as a {@link GridField} that is - * used to show and manipulate data relating to this report. - * - * Generally, you should override {@link columns()} and {@link records()} to make your report, - * but if they aren't sufficiently flexible, then you can override this method. - * - * @return FormField subclass - */ + // getCMSActions() can be extended with updateCMSActions() on a extension + $actions = new FieldList(); + $this->extend('updateCMSActions', $actions); + return $actions; + } + + /** + * Return a field, such as a {@link GridField} that is + * used to show and manipulate data relating to this report. + * + * Generally, you should override {@link columns()} and {@link records()} to make your report, + * but if they aren't sufficiently flexible, then you can override this method. + * + * @return FormField subclass + */ public function getReportField() { - // TODO Remove coupling with global state - $params = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : array(); - $items = $this->sourceRecords($params, null, null); + // TODO Remove coupling with global state + $params = isset($_REQUEST['filters']) ? $_REQUEST['filters'] : array(); + $items = $this->sourceRecords($params, null, null); - $gridFieldConfig = GridFieldConfig::create()->addComponents( - new GridFieldToolbarHeader(), - new GridFieldSortableHeader(), - new GridFieldDataColumns(), - new GridFieldPaginator(), - new GridFieldButtonRow('after'), - new GridFieldPrintButton('buttons-after-left'), - new GridFieldExportButton('buttons-after-left') - ); - $gridField = new GridField('Report', $this->title(), $items, $gridFieldConfig); - $columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns'); - $displayFields = array(); - $fieldCasting = array(); - $fieldFormatting = array(); + $gridFieldConfig = GridFieldConfig::create()->addComponents( + new GridFieldToolbarHeader(), + new GridFieldSortableHeader(), + new GridFieldDataColumns(), + new GridFieldPaginator(), + new GridFieldButtonRow('after'), + new GridFieldPrintButton('buttons-after-left'), + new GridFieldExportButton('buttons-after-left') + ); + $gridField = new GridField('Report',$this->title(), $items, $gridFieldConfig); + $columns = $gridField->getConfig()->getComponentByType('GridFieldDataColumns'); + $displayFields = array(); + $fieldCasting = array(); + $fieldFormatting = array(); - // Parse the column information - foreach ($this->columns() as $source => $info) { + // Parse the column information + foreach($this->columns() as $source => $info) { if (is_string($info)) { $info = array('title' => $info); } - + if (isset($info['formatting'])) { $fieldFormatting[$source] = $info['formatting']; } @@ -334,46 +340,76 @@ class SS_Report extends ViewableData $fieldCasting[$source] = $info['casting']; } - if (isset($info['link']) && $info['link']) { - $link = singleton('CMSPageEditController')->Link('show'); - $fieldFormatting[$source] = '$value'; - } + if(isset($info['link']) && $info['link']) { + $link = singleton('CMSPageEditController')->Link('show'); + $fieldFormatting[$source] = '$value'; + } - $displayFields[$source] = isset($info['title']) ? $info['title'] : $source; - } - $columns->setDisplayFields($displayFields); - $columns->setFieldCasting($fieldCasting); - $columns->setFieldFormatting($fieldFormatting); + $displayFields[$source] = isset($info['title']) ? $info['title'] : $source; + } + $columns->setDisplayFields($displayFields); + $columns->setFieldCasting($fieldCasting); + $columns->setFieldFormatting($fieldFormatting); - return $gridField; - } - - /** - * @param Member $member - * @return boolean - */ + return $gridField; + } + + /** + * @param Member $member + * @return boolean + */ public function canView($member = null) { if (!$member && $member !== false) { - $member = Member::currentUser(); - } - - return true; - } - + $member = Member::currentUser(); + } + + $extended = $this->extendedCan('canView', $member); + if($extended !== null) { + return $extended; + } - /** - * Return the name of this report, which - * is used by the templates to render the - * name of the report in the report tree, - * the left hand pane inside ReportAdmin. - * - * @return string - */ + if($member && Permission::checkMember($member, array('CMS_ACCESS_LeftAndMain', 'CMS_ACCESS_ReportAdmin'))) { + return true; + } + + return false; + } + + /** + * Helper to assist with permission extension + * + * {@see DataObject::extendedCan()} + * + * @param string $methodName Method on the same object, e.g. {@link canEdit()} + * @param Member|int $member + * @return boolean|null + */ + public function extendedCan($methodName, $member) { + $results = $this->extend($methodName, $member); + if($results && is_array($results)) { + // Remove NULLs + $results = array_filter($results, function($v) {return !is_null($v);}); + // If there are any non-NULL responses, then return the lowest one of them. + // If any explicitly deny the permission, then we don't get access + if($results) return min($results); + } + return null; + } + + + /** + * Return the name of this report, which + * is used by the templates to render the + * name of the report in the report tree, + * the left hand pane inside ReportAdmin. + * + * @return string + */ public function TreeTitle() { - return $this->title(); - } + return $this->title(); + } } /** @@ -393,102 +429,102 @@ class SS_Report extends ViewableData */ abstract class SS_ReportWrapper extends SS_Report { - protected $baseReport; + protected $baseReport; public function __construct($baseReport) { - $this->baseReport = is_string($baseReport) ? new $baseReport : $baseReport; - $this->dataClass = $this->baseReport->dataClass(); - parent::__construct(); - } + $this->baseReport = is_string($baseReport) ? new $baseReport : $baseReport; + $this->dataClass = $this->baseReport->dataClass(); + parent::__construct(); + } public function ID() { - return get_class($this->baseReport) . '_' . get_class($this); - } + return get_class($this->baseReport) . '_' . get_class($this); + } - /////////////////////////////////////////////////////////////////////////////////////////// - // Filtering + /////////////////////////////////////////////////////////////////////////////////////////// + // Filtering public function parameterFields() { - return $this->baseReport->parameterFields(); - } + return $this->baseReport->parameterFields(); + } - /////////////////////////////////////////////////////////////////////////////////////////// - // Columns + /////////////////////////////////////////////////////////////////////////////////////////// + // Columns public function columns() { - return $this->baseReport->columns(); - } + return $this->baseReport->columns(); + } - /////////////////////////////////////////////////////////////////////////////////////////// - // Querying + /////////////////////////////////////////////////////////////////////////////////////////// + // Querying - /** - * Override this method to perform some actions prior to querying. - */ + /** + * Override this method to perform some actions prior to querying. + */ public function beforeQuery($params) { - } + } - /** - * Override this method to perform some actions after querying. - */ + /** + * Override this method to perform some actions after querying. + */ public function afterQuery() { } public function sourceQuery($params) { - if ($this->baseReport->hasMethod('sourceRecords')) { - // The default implementation will create a fake query from our sourceRecords() method - return parent::sourceQuery($params); - } elseif ($this->baseReport->hasMethod('sourceQuery')) { - $this->beforeQuery($params); - $query = $this->baseReport->sourceQuery($params); - $this->afterQuery(); - return $query; - } else { - user_error("Please override sourceQuery()/sourceRecords() and columns() in your base report", E_USER_ERROR); - } - } + if($this->baseReport->hasMethod('sourceRecords')) { + // The default implementation will create a fake query from our sourceRecords() method + return parent::sourceQuery($params); + } else if($this->baseReport->hasMethod('sourceQuery')) { + $this->beforeQuery($params); + $query = $this->baseReport->sourceQuery($params); + $this->afterQuery(); + return $query; + } else { + user_error("Please override sourceQuery()/sourceRecords() and columns() in your base report", E_USER_ERROR); + } + } public function sourceRecords($params = array(), $sort = null, $limit = null) { - $this->beforeQuery($params); - $records = $this->baseReport->sourceRecords($params, $sort, $limit); - $this->afterQuery(); - return $records; - } + $this->beforeQuery($params); + $records = $this->baseReport->sourceRecords($params, $sort, $limit); + $this->afterQuery(); + return $records; + } - /////////////////////////////////////////////////////////////////////////////////////////// - // Pass-through + /////////////////////////////////////////////////////////////////////////////////////////// + // Pass-through public function title() { - return $this->baseReport->title(); - } - + return $this->baseReport->title(); + } + public function group() { - return $this->baseReport->hasMethod('group') ? $this->baseReport->group() : 'Group'; - } - + return $this->baseReport->hasMethod('group') ? $this->baseReport->group() : 'Group'; + } + public function sort() { - return $this->baseReport->hasMethod('sort') ? $this->baseReport->sort() : 0; - } + return $this->baseReport->hasMethod('sort') ? $this->baseReport->sort() : 0; + } public function description() { - return $this->baseReport->description(); - } + return $this->baseReport->description(); + } public function canView($member = null) { - return $this->baseReport->canView($member); - } + return $this->baseReport->canView($member); + } } diff --git a/composer.json b/composer.json index 035a831f..1887f221 100644 --- a/composer.json +++ b/composer.json @@ -1,23 +1,30 @@ { "name": "silverstripe/reports", "type": "silverstripe-module", + "description": "Reports module for SilverStripe CMS", "homepage": "http://silverstripe.org", "license": "BSD-3-Clause", "keywords": ["silverstripe", "cms", "reports"], - "authors": [{ + "authors": [ + { "name": "SilverStripe", "homepage": "http://silverstripe.com" - }, { + }, + { "name": "The SilverStripe Community", "homepage": "http://silverstripe.org" - }], + } + ], "require": { "php": ">=5.3.3", - "silverstripe/framework": ">=3.1.x-dev" + "silverstripe/framework": "~3.3" }, "extra": { "branch-alias": { "dev-master": "4.0.x-dev" } + }, + "require-dev": { + "phpunit/PHPUnit": "~3.7" } } diff --git a/tests/ReportTest.php b/tests/ReportTest.php index 14c85826..7a3b00f1 100644 --- a/tests/ReportTest.php +++ b/tests/ReportTest.php @@ -9,57 +9,77 @@ class ReportTest extends SapphireTest public function testGetReports() { - $reports = SS_Report::get_reports(); - $this->assertNotNull($reports, "Reports returned"); - $previousSort = 0; - foreach ($reports as $report) { - $this->assertGreaterThanOrEqual($previousSort, $report->sort, "Reports are in correct sort order"); - $previousSort = $report->sort; - } - } + $reports = SS_Report::get_reports(); + $this->assertNotNull($reports, "Reports returned"); + $previousSort = 0; + foreach($reports as $report) { + $this->assertGreaterThanOrEqual($previousSort, $report->sort, "Reports are in correct sort order"); + $previousSort = $report->sort; + } + } public function testExcludeReport() { - $reports = SS_Report::get_reports(); - $reportNames = array(); - foreach ($reports as $report) { - $reportNames[] = $report->class; - } - $this->assertContains('ReportTest_FakeTest', $reportNames, 'ReportTest_FakeTest is in reports list'); + $reports = SS_Report::get_reports(); + $reportNames = array(); + foreach($reports as $report) { + $reportNames[] = $report->class; + } + $this->assertContains('ReportTest_FakeTest',$reportNames,'ReportTest_FakeTest is in reports list'); - //exclude one report - SS_Report::add_excluded_reports('ReportTest_FakeTest'); + //exclude one report + SS_Report::add_excluded_reports('ReportTest_FakeTest'); - $reports = SS_Report::get_reports(); - $reportNames = array(); - foreach ($reports as $report) { - $reportNames[] = $report->class; - } - $this->assertNotContains('ReportTest_FakeTest', $reportNames, 'ReportTest_FakeTest is NOT in reports list'); + $reports = SS_Report::get_reports(); + $reportNames = array(); + foreach($reports as $report) { + $reportNames[] = $report->class; + } + $this->assertNotContains('ReportTest_FakeTest',$reportNames,'ReportTest_FakeTest is NOT in reports list'); - //exclude two reports - SS_Report::add_excluded_reports(array('ReportTest_FakeTest', 'ReportTest_FakeTest2')); + //exclude two reports + SS_Report::add_excluded_reports(array('ReportTest_FakeTest','ReportTest_FakeTest2')); - $reports = SS_Report::get_reports(); - $reportNames = array(); - foreach ($reports as $report) { - $reportNames[] = $report->class; - } - $this->assertNotContains('ReportTest_FakeTest', $reportNames, 'ReportTest_FakeTest is NOT in reports list'); - $this->assertNotContains('ReportTest_FakeTest2', $reportNames, 'ReportTest_FakeTest2 is NOT in reports list'); - } + $reports = SS_Report::get_reports(); + $reportNames = array(); + foreach($reports as $report) { + $reportNames[] = $report->class; + } + $this->assertNotContains('ReportTest_FakeTest',$reportNames,'ReportTest_FakeTest is NOT in reports list'); + $this->assertNotContains('ReportTest_FakeTest2',$reportNames,'ReportTest_FakeTest2 is NOT in reports list'); + } public function testAbstractClassesAreExcluded() { - $reports = SS_Report::get_reports(); - $reportNames = array(); - foreach ($reports as $report) { - $reportNames[] = $report->class; - } - $this->assertNotContains('ReportTest_FakeTest_Abstract', - $reportNames, - 'ReportTest_FakeTest_Abstract is NOT in reports list as it is abstract'); - } + $reports = SS_Report::get_reports(); + $reportNames = array(); + foreach($reports as $report) { + $reportNames[] = $report->class; + } + $this->assertNotContains('ReportTest_FakeTest_Abstract', + $reportNames, + 'ReportTest_FakeTest_Abstract is NOT in reports list as it is abstract'); + } + + public function testPermissions() { + $report = new ReportTest_FakeTest2(); + + // Visitor cannot view + Session::clear("loggedInAs"); + $this->assertFalse($report->canView()); + + // Logged in user that cannot view reports + $this->logInWithPermission('SITETREE_REORGANISE'); + $this->assertFalse($report->canView()); + + // Logged in with report permissions + $this->logInWithPermission('CMS_ACCESS_ReportAdmin'); + $this->assertTrue($report->canView()); + + // Admin can view + $this->logInWithPermission('ADMIN'); + $this->assertTrue($report->canView()); + } } /** @@ -70,25 +90,25 @@ class ReportTest_FakeTest extends SS_Report implements TestOnly { public function title() { - return 'Report title'; - } + return 'Report title'; + } public function columns() { - return array( - "Title" => array( - "title" => "Page Title" - ) - ); - } + return array( + "Title" => array( + "title" => "Page Title" + ) + ); + } public function sourceRecords($params, $sort, $limit) { - return new ArrayList(); - } + return new ArrayList(); + } public function sort() { - return 100; - } + return 100; + } } /** @@ -99,25 +119,25 @@ class ReportTest_FakeTest2 extends SS_Report implements TestOnly { public function title() { - return 'Report title 2'; - } + return 'Report title 2'; + } public function columns() { - return array( - "Title" => array( - "title" => "Page Title 2" - ) - ); - } + return array( + "Title" => array( + "title" => "Page Title 2" + ) + ); + } public function sourceRecords($params, $sort, $limit) { - return new ArrayList(); - } + return new ArrayList(); + } public function sort() { - return 98; - } + return 98; + } } /** @@ -126,27 +146,27 @@ class ReportTest_FakeTest2 extends SS_Report implements TestOnly */ abstract class ReportTest_FakeTest_Abstract extends SS_Report implements TestOnly { - + public function title() { - return 'Report title Abstract'; - } + return 'Report title Abstract'; + } public function columns() { - return array( - "Title" => array( - "title" => "Page Title Abstract" - ) - ); - } + return array( + "Title" => array( + "title" => "Page Title Abstract" + ) + ); + } public function sourceRecords($params, $sort, $limit) { - return new ArrayList(); - } + return new ArrayList(); + } public function sort() { - return 5; - } + return 5; + } }