mirror of
https://github.com/silverstripe/silverstripe-contentreview
synced 2024-10-22 17:05:47 +02:00
NEW Add behat tests to cover content review configuration and review modal
* Update existing test for review button field name, remove obsolete save review test * Move test classes to tests/php to differentiate from behat * Add behat build to Travis configuration
This commit is contained in:
parent
8b8b8e3620
commit
31bcd0d439
@ -6,4 +6,4 @@ checks:
|
|||||||
duplication: true
|
duplication: true
|
||||||
|
|
||||||
filter:
|
filter:
|
||||||
paths: [code/*, tests/*]
|
paths: [src/*, tests/*]
|
||||||
|
20
.travis.yml
20
.travis.yml
@ -1,10 +1,15 @@
|
|||||||
language: php
|
language: php
|
||||||
|
|
||||||
dist: trusty
|
dist: precise
|
||||||
|
|
||||||
|
addons:
|
||||||
|
firefox: "31.0"
|
||||||
|
|
||||||
env:
|
env:
|
||||||
global:
|
global:
|
||||||
- COMPOSER_ROOT_VERSION=4.0.x-dev
|
- COMPOSER_ROOT_VERSION=4.0.x-dev
|
||||||
|
- DISPLAY=":99"
|
||||||
|
- XVFBARGS=":99 -ac -screen 0 1024x768x16"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
@ -14,6 +19,8 @@ matrix:
|
|||||||
env: DB=PGSQL PHPUNIT_TEST=1
|
env: DB=PGSQL PHPUNIT_TEST=1
|
||||||
- php: 7.1
|
- php: 7.1
|
||||||
env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1
|
env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1
|
||||||
|
- php: 7.1
|
||||||
|
env: DB=MYSQL BEHAT_TEST=1
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
# Init PHP
|
# Init PHP
|
||||||
@ -26,10 +33,21 @@ before_script:
|
|||||||
- if [[ $DB == PGSQL ]]; then composer require --prefer-dist --no-update silverstripe/postgresql:2.0.x-dev; fi
|
- if [[ $DB == PGSQL ]]; then composer require --prefer-dist --no-update silverstripe/postgresql:2.0.x-dev; fi
|
||||||
- composer update
|
- composer update
|
||||||
|
|
||||||
|
# Start behat services
|
||||||
|
- if [[ $BEHAT_TEST ]]; then echo 'SS_BASE_URL=http://localhost:8080/' >> .env; fi
|
||||||
|
- if [[ $BEHAT_TEST ]]; then mkdir artifacts; fi
|
||||||
|
- if [[ $BEHAT_TEST ]]; then sh -e /etc/init.d/xvfb start; sleep 3; fi
|
||||||
|
- if [[ $BEHAT_TEST ]]; then (vendor/bin/selenium-server-standalone > artifacts/selenium.log 2>&1 &); fi
|
||||||
|
- if [[ $BEHAT_TEST ]]; then (vendor/bin/serve --bootstrap-file cms/tests/behat/serve-bootstrap.php &> artifacts/serve.log &); fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit; fi
|
- if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit; fi
|
||||||
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
|
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi
|
||||||
- if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs --standard=framework/phpcs.xml.dist src/ tests/; fi
|
- if [[ $PHPCS_TEST ]]; then vendor/bin/phpcs --standard=framework/phpcs.xml.dist src/ tests/; fi
|
||||||
|
- if [[ $BEHAT_TEST ]]; then vendor/bin/behat @contentreview; fi
|
||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi
|
- if [[ $PHPUNIT_COVERAGE_TEST ]]; then bash <(curl -s https://codecov.io/bash) -f coverage.xml; fi
|
||||||
|
|
||||||
|
after_failure:
|
||||||
|
- php ./framework/tests/behat/travis-upload-artifacts.php --if-env BEHAT_TEST,ARTIFACTS_BUCKET,ARTIFACTS_KEY,ARTIFACTS_SECRET --target-path $TRAVIS_REPO_SLUG/$TRAVIS_BUILD_ID/$TRAVIS_JOB_ID --artifacts-base-url https://s3.amazonaws.com/$ARTIFACTS_BUCKET/ --artifacts-path ./artifacts/
|
||||||
|
27
behat.yml
Normal file
27
behat.yml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
default:
|
||||||
|
suites:
|
||||||
|
contentreview:
|
||||||
|
paths:
|
||||||
|
- %paths.modules.contentreview%/tests/behat/features
|
||||||
|
contexts:
|
||||||
|
- SilverStripe\Framework\Tests\Behaviour\FeatureContext
|
||||||
|
- SilverStripe\Framework\Tests\Behaviour\CmsFormsContext
|
||||||
|
- SilverStripe\Framework\Tests\Behaviour\CmsUiContext
|
||||||
|
- SilverStripe\BehatExtension\Context\BasicContext
|
||||||
|
- SilverStripe\BehatExtension\Context\EmailContext
|
||||||
|
- SilverStripe\CMS\Tests\Behaviour\LoginContext
|
||||||
|
- SilverStripe\CMS\Tests\Behaviour\ThemeContext
|
||||||
|
- SilverStripe\CMS\Tests\Behaviour\FixtureContext:
|
||||||
|
# Note: double indent for args is intentional
|
||||||
|
- %paths.modules.contentreview%/tests/behat/features/files/
|
||||||
|
|
||||||
|
extensions:
|
||||||
|
SilverStripe\BehatExtension\MinkExtension:
|
||||||
|
default_session: selenium2
|
||||||
|
javascript_session: selenium2
|
||||||
|
selenium2:
|
||||||
|
browser: firefox
|
||||||
|
|
||||||
|
SilverStripe\BehatExtension\Extension:
|
||||||
|
screenshot_path: %paths.base%/artifacts/screenshots
|
||||||
|
bootstrap_file: "cms/tests/behat/serve-bootstrap.php"
|
@ -27,7 +27,10 @@
|
|||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpunit/phpunit": "^5.7",
|
"phpunit/phpunit": "^5.7",
|
||||||
"squizlabs/php_codesniffer": "^3.0"
|
"squizlabs/php_codesniffer": "^3.0",
|
||||||
|
"silverstripe/behat-extension": "^3@dev",
|
||||||
|
"silverstripe/serve": "dev-master",
|
||||||
|
"se/selenium-server-standalone": "2.41.0"
|
||||||
},
|
},
|
||||||
"suggest": {
|
"suggest": {
|
||||||
"symbiote/silverstripe-queuedjobs": "Automatically schedules content review emails to be sent, only requiring one crontask to be created"
|
"symbiote/silverstripe-queuedjobs": "Automatically schedules content review emails to be sent, only requiring one crontask to be created"
|
||||||
@ -40,7 +43,7 @@
|
|||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"SilverStripe\\ContentReview\\": "src/",
|
"SilverStripe\\ContentReview\\": "src/",
|
||||||
"SilverStripe\\ContentReview\\Tests\\": "tests/"
|
"SilverStripe\\ContentReview\\Tests\\": "tests/php/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minimum-stability": "dev",
|
"minimum-stability": "dev",
|
||||||
|
@ -49,8 +49,7 @@ en:
|
|||||||
|
|
||||||
SilverStripe\ContentReview\Forms\ReviewContentHandler:
|
SilverStripe\ContentReview\Forms\ReviewContentHandler:
|
||||||
ContentDueForReview: Content due for review
|
ContentDueForReview: Content due for review
|
||||||
ErrorReviewPermissionDenied: It seems you don't have the necessary permissions to submit a content review
|
|
||||||
MarkAsReviewedAction: Mark as reviewed
|
MarkAsReviewedAction: Mark as reviewed
|
||||||
NoComments: (no comments)
|
NoComments: (no comments)
|
||||||
ObjectDoesntExist: That object doesn't exist
|
Placeholder: Add comments (optional)
|
||||||
Success: Review successfully added
|
Success: Review successfully added
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<phpunit bootstrap="cms/tests/bootstrap.php" colors="true">
|
<phpunit bootstrap="cms/tests/bootstrap.php" colors="true">
|
||||||
<testsuite name="Default">
|
<testsuite name="Default">
|
||||||
<directory>tests/</directory>
|
<directory>tests/php/</directory>
|
||||||
</testsuite>
|
</testsuite>
|
||||||
<filter>
|
<filter>
|
||||||
<whitelist addUncoveredFilesFromWhitelist="true">
|
<whitelist addUncoveredFilesFromWhitelist="true">
|
||||||
|
@ -8,6 +8,7 @@ use SilverStripe\CMS\Model\SiteTree;
|
|||||||
use SilverStripe\ContentReview\Forms\ReviewContentHandler;
|
use SilverStripe\ContentReview\Forms\ReviewContentHandler;
|
||||||
use SilverStripe\Control\HTTPRequest;
|
use SilverStripe\Control\HTTPRequest;
|
||||||
use SilverStripe\Control\HTTPResponse;
|
use SilverStripe\Control\HTTPResponse;
|
||||||
|
use SilverStripe\Control\HTTPResponse_Exception;
|
||||||
use SilverStripe\Core\Convert;
|
use SilverStripe\Core\Convert;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
use SilverStripe\ORM\ValidationResult;
|
use SilverStripe\ORM\ValidationResult;
|
||||||
@ -21,7 +22,7 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
|
|||||||
{
|
{
|
||||||
private static $allowed_actions = [
|
private static $allowed_actions = [
|
||||||
'ReviewContentForm',
|
'ReviewContentForm',
|
||||||
'submitReview',
|
'savereview',
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,15 +46,9 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
|
|||||||
*/
|
*/
|
||||||
public function getReviewContentForm($id)
|
public function getReviewContentForm($id)
|
||||||
{
|
{
|
||||||
$record = SiteTree::get()->byID($id);
|
$page = $this->findRecord(['ID' => $id]);
|
||||||
|
|
||||||
if (!$record) {
|
|
||||||
$this->owner->httpError(404, _t(__CLASS__ . '.ErrorNotFound', 'That object couldn\'t be found'));
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = Security::getCurrentUser();
|
$user = Security::getCurrentUser();
|
||||||
if (!$record->canEdit() || ($record->hasMethod('canBeReviewedBy') && !$record->canBeReviewedBy($user))) {
|
if (!$page->canEdit() || ($page->hasMethod('canBeReviewedBy') && !$page->canBeReviewedBy($user))) {
|
||||||
$this->owner->httpError(403, _t(
|
$this->owner->httpError(403, _t(
|
||||||
__CLASS__.'.ErrorItemPermissionDenied',
|
__CLASS__.'.ErrorItemPermissionDenied',
|
||||||
'It seems you don\'t have the necessary permissions to review this content'
|
'It seems you don\'t have the necessary permissions to review this content'
|
||||||
@ -61,12 +56,10 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler = ReviewContentHandler::create($this->owner, $record);
|
$form = $this->getReviewContentHandler()->Form($page);
|
||||||
$form = $handler->Form($record);
|
|
||||||
|
|
||||||
$form->setValidationResponseCallback(function (ValidationResult $errors) use ($form, $id) {
|
$form->setValidationResponseCallback(function (ValidationResult $errors) use ($form, $id) {
|
||||||
$schemaId = $this->owner->join_links($this->owner->Link('schema/ReviewContentForm'), $id);
|
$schemaId = $this->owner->join_links($this->owner->Link('schema/ReviewContentForm'), $id);
|
||||||
return $this->owner->getSchemaResponse($schemaId, $form, $errors);
|
return $this->getSchemaResponse($schemaId, $form, $errors);
|
||||||
});
|
});
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
@ -77,30 +70,59 @@ class ContentReviewCMSExtension extends LeftAndMainExtension
|
|||||||
*
|
*
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param Form $form
|
* @param Form $form
|
||||||
* @return DBHTMLText|HTTPResponse
|
* @return DBHTMLText|HTTPResponse|null
|
||||||
*/
|
*/
|
||||||
public function submitReview($data = '', $form = '')
|
public function savereview($data, Form $form)
|
||||||
{
|
{
|
||||||
$id = $data['ID'];
|
$page = $this->findRecord($data);
|
||||||
$record = SiteTree::get()->byID($id);
|
|
||||||
|
|
||||||
$handler = ReviewContentHandler::create($this->owner, $record);
|
$results = $this->getReviewContentHandler()->submitReview($page, $data);
|
||||||
$form = $handler->Form($record);
|
|
||||||
$results = $handler->submitReview($record, $data);
|
|
||||||
if (is_null($results)) {
|
if (is_null($results)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->getSchemaRequested()) {
|
if ($this->getSchemaRequested()) {
|
||||||
// Send extra "message" data with schema response
|
// Send extra "message" data with schema response
|
||||||
$extraData = ['message' => $results];
|
$extraData = ['message' => $results];
|
||||||
$schemaId = $this->owner->join_links($this->owner->Link('schema/ReviewContentForm'), $id);
|
$schemaId = $this->owner->join_links($this->owner->Link('schema/ReviewContentForm'), $page->ID);
|
||||||
return $this->getSchemaResponse($schemaId, $form, null, $extraData);
|
return $this->getSchemaResponse($schemaId, $form, null, $extraData);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a handler or reviewing content
|
||||||
|
*
|
||||||
|
* @return ReviewContentHandler
|
||||||
|
*/
|
||||||
|
protected function getReviewContentHandler()
|
||||||
|
{
|
||||||
|
return ReviewContentHandler::create($this->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the page this form is updating
|
||||||
|
*
|
||||||
|
* @param array $data Form data
|
||||||
|
* @return SiteTree Record
|
||||||
|
* @throws HTTPResponse_Exception
|
||||||
|
*/
|
||||||
|
protected function findRecord($data)
|
||||||
|
{
|
||||||
|
if (empty($data["ID"])) {
|
||||||
|
throw new HTTPResponse_Exception("No record ID", 404);
|
||||||
|
}
|
||||||
|
$page = null;
|
||||||
|
$id = $data["ID"];
|
||||||
|
if (is_numeric($id)) {
|
||||||
|
$page = SiteTree::get()->byID($id);
|
||||||
|
}
|
||||||
|
if (!$page || !$page->ID) {
|
||||||
|
throw new HTTPResponse_Exception("Bad record ID #{$id}", 404);
|
||||||
|
}
|
||||||
|
return $page;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the current request has a X-Formschema-Request header set.
|
* Check if the current request has a X-Formschema-Request header set.
|
||||||
* Used by conditional logic that responds to validation results
|
* Used by conditional logic that responds to validation results
|
||||||
|
@ -7,6 +7,7 @@ use SilverStripe\Control\HTTPResponse;
|
|||||||
use SilverStripe\Core\Injector\Injectable;
|
use SilverStripe\Core\Injector\Injectable;
|
||||||
use SilverStripe\Forms\FieldList;
|
use SilverStripe\Forms\FieldList;
|
||||||
use SilverStripe\Forms\Form;
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\Forms\FormAction;
|
||||||
use SilverStripe\Forms\HiddenField;
|
use SilverStripe\Forms\HiddenField;
|
||||||
use SilverStripe\Forms\TextareaField;
|
use SilverStripe\Forms\TextareaField;
|
||||||
use SilverStripe\ORM\DataObject;
|
use SilverStripe\ORM\DataObject;
|
||||||
@ -24,13 +25,6 @@ class ReviewContentHandler
|
|||||||
*/
|
*/
|
||||||
protected $controller;
|
protected $controller;
|
||||||
|
|
||||||
/**
|
|
||||||
* The submitted form data
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $data;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Form name to use
|
* Form name to use
|
||||||
*
|
*
|
||||||
@ -40,16 +34,11 @@ class ReviewContentHandler
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Controller $controller
|
* @param Controller $controller
|
||||||
* @param array|DataObject $data
|
|
||||||
* @param string $name
|
* @param string $name
|
||||||
*/
|
*/
|
||||||
public function __construct($controller = null, $data = [], $name = 'ReviewContentForm')
|
public function __construct($controller = null, $name = 'ReviewContentForm')
|
||||||
{
|
{
|
||||||
$this->controller = $controller;
|
$this->controller = $controller;
|
||||||
if ($data instanceof DataObject) {
|
|
||||||
$data = $data->toMap();
|
|
||||||
}
|
|
||||||
$this->data = $data;
|
|
||||||
$this->name = $name;
|
$this->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +50,8 @@ class ReviewContentHandler
|
|||||||
*/
|
*/
|
||||||
public function Form($object)
|
public function Form($object)
|
||||||
{
|
{
|
||||||
$placeholder = 'Add comments (optional)';
|
$placeholder = _t(__CLASS__ . '.Placeholder', 'Add comments (optional)');
|
||||||
|
$title = _t(__CLASS__ . '.MarkAsReviewedAction', 'Mark as reviewed');
|
||||||
|
|
||||||
$fields = FieldList::create([
|
$fields = FieldList::create([
|
||||||
HiddenField::create('ID', null, $object->ID),
|
HiddenField::create('ID', null, $object->ID),
|
||||||
@ -71,16 +61,15 @@ class ReviewContentHandler
|
|||||||
->setSchemaData(['attributes' => ['placeholder' => $placeholder]])
|
->setSchemaData(['attributes' => ['placeholder' => $placeholder]])
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$actions = FieldList::create([
|
$action = FormAction::create('savereview', $title)
|
||||||
ReviewContentHandlerFormAction::create()
|
->setTitle($title)
|
||||||
->setTitle(_t(__CLASS__ . '.MarkAsReviewedAction', 'Mark as reviewed'))
|
->setUseButtonTag(false)
|
||||||
->addExtraClass('review-content__action')
|
->addExtraClass('review-content__action btn btn-primary');
|
||||||
]);
|
$actions = FieldList::create([$action]);
|
||||||
|
|
||||||
$form = Form::create($this->controller, $this->name, $fields, $actions);
|
$form = Form::create($this->controller, $this->name, $fields, $actions)
|
||||||
|
->setHTMLID('Form_EditForm_ReviewContent')
|
||||||
$form->setHTMLID('Form_EditForm_ReviewContent');
|
->addExtraClass('form--no-dividers review-content__form');
|
||||||
$form->addExtraClass('form--no-dividers review-content__form');
|
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
@ -91,24 +80,20 @@ class ReviewContentHandler
|
|||||||
* @param DataObject $record
|
* @param DataObject $record
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @return HTTPResponse|string
|
* @return HTTPResponse|string
|
||||||
|
* @throws ValidationException If the user cannot submit the review
|
||||||
*/
|
*/
|
||||||
public function submitReview($record, $data)
|
public function submitReview($record, $data)
|
||||||
{
|
{
|
||||||
if (!$record || !$record->exists()) {
|
if (!$this->canSubmitReview($record)) {
|
||||||
throw new ValidationException(_t(__CLASS__ . '.ObjectDoesntExist', 'That object doesn\'t exist'));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$record->canEdit()
|
|
||||||
|| !$record->hasMethod('canBeReviewedBy')
|
|
||||||
|| !$record->canBeReviewedBy(Security::getCurrentUser())
|
|
||||||
) {
|
|
||||||
throw new ValidationException(_t(
|
throw new ValidationException(_t(
|
||||||
__CLASS__ . '.ErrorReviewPermissionDenied',
|
__CLASS__ . '.ErrorReviewPermissionDenied',
|
||||||
'It seems you don\'t have the necessary permissions to submit a content review'
|
'It seems you don\'t have the necessary permissions to submit a content review'
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->saveRecord($record, $data);
|
$notes = (!empty($data['Review']) ? $data['Review'] : _t(__CLASS__ . '.NoComments', '(no comments)'));
|
||||||
|
$record->addReviewNote(Security::getCurrentUser(), $notes);
|
||||||
|
$record->advanceReviewDate();
|
||||||
|
|
||||||
$request = $this->controller->getRequest();
|
$request = $this->controller->getRequest();
|
||||||
$message = _t(__CLASS__ . '.Success', 'Review successfully added');
|
$message = _t(__CLASS__ . '.Success', 'Review successfully added');
|
||||||
@ -119,21 +104,25 @@ class ReviewContentHandler
|
|||||||
$response = HTTPResponse::create($message, 200);
|
$response = HTTPResponse::create($message, 200);
|
||||||
$response->addHeader('Content-Type', 'text/html; charset=utf-8');
|
$response->addHeader('Content-Type', 'text/html; charset=utf-8');
|
||||||
return $response;
|
return $response;
|
||||||
} else {
|
|
||||||
return $this->controller->redirectBack();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->controller->redirectBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the review provided in $data to the $record
|
* Determine whether the user can submit a review
|
||||||
*
|
*
|
||||||
* @param DataObject $record
|
* @param DataObject $record
|
||||||
* @param array $data
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function saveRecord($record, $data)
|
public function canSubmitReview($record)
|
||||||
{
|
{
|
||||||
$notes = (!empty($data['Review']) ? $data['Review'] : _t(__CLASS__ . '.NoComments', '(no comments)'));
|
if (!$record->canEdit()
|
||||||
$record->addReviewNote(Security::getCurrentUser(), $notes);
|
|| !$record->hasMethod('canBeReviewedBy')
|
||||||
$record->advanceReviewDate();
|
|| !$record->canBeReviewedBy(Security::getCurrentUser())
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace SilverStripe\ContentReview\Forms;
|
|
||||||
|
|
||||||
use SilverStripe\Forms\FormAction;
|
|
||||||
|
|
||||||
class ReviewContentHandlerFormAction extends FormAction
|
|
||||||
{
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
parent::__construct(
|
|
||||||
'submitReview',
|
|
||||||
_t('SilverStripe\\ContentReview\\Forms\\ReviewContentHandler.MarkAsReviewedAction', 'Mark as reviewed')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->setUseButtonTag(false)
|
|
||||||
->addExtraClass('review-content-action btn btn-primary');
|
|
||||||
}
|
|
||||||
}
|
|
0
tests/behat/_manifest_exclude
Normal file
0
tests/behat/_manifest_exclude
Normal file
41
tests/behat/features/set-up-reviews.feature
Normal file
41
tests/behat/features/set-up-reviews.feature
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
Feature: Set up reviews
|
||||||
|
As a CMS user
|
||||||
|
I can set up content reviews for my content
|
||||||
|
In order to ensure my content gets reviewed regularly
|
||||||
|
|
||||||
|
Background:
|
||||||
|
# Note: the review date is deliberately in the past
|
||||||
|
Given a "page" "Home" with "Content"="<p>Welcome</p>", "NextReviewDate"="01/01/2017", "ReviewPeriodDays"="1"
|
||||||
|
And I am logged in with "ADMIN" permissions
|
||||||
|
And I go to "admin/pages"
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: I can set content review options
|
||||||
|
When I click on "Home" in the tree
|
||||||
|
And I click the "Settings" CMS tab
|
||||||
|
Then I should see a "Content Review" button
|
||||||
|
|
||||||
|
When I click the "Content Review" CMS tab
|
||||||
|
And I select "Custom settings" from "Options" input group
|
||||||
|
And I wait for 1 second
|
||||||
|
And I select "ADMIN group" from "Groups"
|
||||||
|
And I press "Save"
|
||||||
|
Then I should see a "Content due for review" button
|
||||||
|
|
||||||
|
@javascript
|
||||||
|
Scenario: I can enter a review in the modal
|
||||||
|
When I click on "Home" in the tree
|
||||||
|
And I click the "Settings" CMS tab
|
||||||
|
And I click the "Content Review" CMS tab
|
||||||
|
And I select "Custom settings" from "Options" input group
|
||||||
|
And I wait for 1 seconds
|
||||||
|
And I select "ADMIN group" from "Groups"
|
||||||
|
And I press "Save"
|
||||||
|
And I follow "Content due for review"
|
||||||
|
And I wait for 3 seconds
|
||||||
|
Then I should see a "Mark as reviewed" button
|
||||||
|
|
||||||
|
When I fill in "Review" with "LGTM"
|
||||||
|
And I press "Mark as reviewed"
|
||||||
|
And I wait for 3 seconds
|
||||||
|
Then I should see "Review successfully added"
|
@ -90,34 +90,6 @@ class ContentReviewCMSPageEditControllerTest extends ContentReviewBaseTest
|
|||||||
$this->assertEquals(200, $response->getStatusCode());
|
$this->assertEquals(200, $response->getStatusCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSaveReview()
|
|
||||||
{
|
|
||||||
/** @var Member $author */
|
|
||||||
$author = $this->objFromFixture(Member::class, "author");
|
|
||||||
|
|
||||||
$this->logInAs($author);
|
|
||||||
|
|
||||||
/** @var Page|SiteTreeContentReview $page */
|
|
||||||
$page = $this->objFromFixture(Page::class, "home");
|
|
||||||
|
|
||||||
$data = array(
|
|
||||||
"action_savereview" => 1,
|
|
||||||
"ID" => $page->ID,
|
|
||||||
"ReviewNotes" => "This is the best page ever",
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->get('admin/pages/edit/show/' . $page->ID);
|
|
||||||
$response = $this->post($this->getFormAction($page), $data);
|
|
||||||
|
|
||||||
$this->assertEquals("OK", $response->getStatusDescription());
|
|
||||||
$this->assertEquals(200, $response->getStatusCode());
|
|
||||||
$this->assertEquals(1, $page->ReviewLogs()->count());
|
|
||||||
|
|
||||||
$reviewLog = $page->ReviewLogs()->first();
|
|
||||||
|
|
||||||
$this->assertEquals($data["ReviewNotes"], $reviewLog->Note);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a CMS page edit form action via using a dummy request and session
|
* Return a CMS page edit form action via using a dummy request and session
|
||||||
*
|
*
|
93
tests/php/Extensions/ContentReviewCMSExtensionTest.php
Normal file
93
tests/php/Extensions/ContentReviewCMSExtensionTest.php
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ContentReview\Tests\Extensions;
|
||||||
|
|
||||||
|
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
|
||||||
|
use SilverStripe\ContentReview\Forms\ReviewContentHandler;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\Security\Member;
|
||||||
|
|
||||||
|
class ContentReviewCMSExtensionTest extends SapphireTest
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Test that ReviewContentForm finds an ID parameter then returns the result of getReviewContentForm
|
||||||
|
* with the passed ID
|
||||||
|
*/
|
||||||
|
public function testReviewContentForm()
|
||||||
|
{
|
||||||
|
$mock = $this->getMockBuilder(ContentReviewCMSExtension::class)
|
||||||
|
->setMethods(['getReviewContentForm'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$mock->expects($this->once())->method('getReviewContentForm')->with(123)->willReturn(true);
|
||||||
|
|
||||||
|
$request = new HTTPRequest('GET', '/', [], ['ID' => 123]);
|
||||||
|
$result = $mock->ReviewContentForm($request);
|
||||||
|
$this->assertTrue($result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException SilverStripe\Control\HTTPResponse_Exception
|
||||||
|
* @expectedExceptionMessage Bad record ID #1234
|
||||||
|
*/
|
||||||
|
public function testGetReviewContentFormThrowsExceptionWhenPageNotFound()
|
||||||
|
{
|
||||||
|
(new ContentReviewCMSExtension)->getReviewContentForm(1234);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException SilverStripe\Control\HTTPResponse_Exception
|
||||||
|
* @expectedExceptionMessage It seems you don't have the necessary permissions to review this content
|
||||||
|
*/
|
||||||
|
public function testGetReviewContentFormThrowsExceptionWhenObjectCannotBeReviewed()
|
||||||
|
{
|
||||||
|
$this->logOut();
|
||||||
|
|
||||||
|
$mock = $this->getMockBuilder(ContentReviewCMSExtension::class)
|
||||||
|
->setMethods(['findRecord'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$mock->setOwner(new Controller);
|
||||||
|
|
||||||
|
// Return a DataObject without the content review extension applied
|
||||||
|
$mock->expects($this->once())->method('findRecord')->with(['ID' => 123])->willReturn(new Member);
|
||||||
|
|
||||||
|
$mock->getReviewContentForm(123);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure that savereview() calls the ReviewContentHandler and passes the data to it
|
||||||
|
*/
|
||||||
|
public function testSaveReviewCallsHandler()
|
||||||
|
{
|
||||||
|
$mock = $this->getMockBuilder(ContentReviewCMSExtension::class)
|
||||||
|
->setMethods(['findRecord', 'getReviewContentHandler'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$mock->setOwner(new Controller);
|
||||||
|
|
||||||
|
$mockPage = (object) ['ID' => 123];
|
||||||
|
$mock->expects($this->once())->method('findRecord')->willReturn($mockPage);
|
||||||
|
|
||||||
|
$mockHandler = $this->getMockBuilder(ReviewContentHandler::class)
|
||||||
|
->setMethods(['submitReview'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$mockHandler->expects($this->once())
|
||||||
|
->method('submitReview')
|
||||||
|
->with($mockPage, ['foo'])
|
||||||
|
->willReturn('Success');
|
||||||
|
|
||||||
|
$mock->expects($this->once())->method('getReviewContentHandler')->willReturn($mockHandler);
|
||||||
|
|
||||||
|
$form = $this->getMockBuilder(Form::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$result = $mock->savereview(['foo'], $form);
|
||||||
|
$this->assertSame('Success', $result);
|
||||||
|
}
|
||||||
|
}
|
84
tests/php/Forms/ReviewContentHandlerTest.php
Normal file
84
tests/php/Forms/ReviewContentHandlerTest.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace SilverStripe\ContentReview\Tests\Forms;
|
||||||
|
|
||||||
|
use Page;
|
||||||
|
use SilverStripe\CMS\Model\SiteTree;
|
||||||
|
use SilverStripe\Control\Controller;
|
||||||
|
use SilverStripe\Control\HTTPRequest;
|
||||||
|
use SilverStripe\Control\HTTPResponse;
|
||||||
|
use SilverStripe\ContentReview\Forms\ReviewContentHandler;
|
||||||
|
use SilverStripe\Core\Injector\Injector;
|
||||||
|
use SilverStripe\Dev\SapphireTest;
|
||||||
|
use SilverStripe\Forms\Form;
|
||||||
|
use SilverStripe\Forms\HiddenField;
|
||||||
|
use SilverStripe\Forms\TextareaField;
|
||||||
|
use SilverStripe\Security\Member;
|
||||||
|
|
||||||
|
class ReviewContentHandlerTest extends SapphireTest
|
||||||
|
{
|
||||||
|
public function testForm()
|
||||||
|
{
|
||||||
|
$page = Page::create();
|
||||||
|
$page->Title = 'Test';
|
||||||
|
$page->write();
|
||||||
|
|
||||||
|
$form = ReviewContentHandler::create()->Form($page);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Form::class, $form);
|
||||||
|
$this->assertSame('ReviewContentForm', $form->getName());
|
||||||
|
|
||||||
|
$this->assertInstanceOf(HiddenField::class, $form->Fields()->fieldByName('ID'));
|
||||||
|
$this->assertInstanceOf(HiddenField::class, $form->Fields()->fieldByName('ClassName'));
|
||||||
|
$this->assertInstanceOf(TextareaField::class, $form->Fields()->fieldByName('Review'));
|
||||||
|
|
||||||
|
$saveAction = $form->Actions()->first();
|
||||||
|
$this->assertNotNull($saveAction);
|
||||||
|
$this->assertTrue($saveAction->hasClass('review-content__action'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException SilverStripe\ORM\ValidationException
|
||||||
|
* @expectedExceptionMessage It seems you don't have the necessary permissions to submit a content review
|
||||||
|
*/
|
||||||
|
public function testExceptionThrownWhenSubmittingReviewForInvalidObject()
|
||||||
|
{
|
||||||
|
ReviewContentHandler::create()->submitReview(new Member, ['foo' => 'bar']);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testAddReviewNoteCalledWhenSubmittingReview()
|
||||||
|
{
|
||||||
|
$this->logInWithPermission('ADMIN');
|
||||||
|
|
||||||
|
$controller = new Controller;
|
||||||
|
$request = new HTTPRequest('GET', '/');
|
||||||
|
$controller->setRequest($request);
|
||||||
|
Injector::inst()->registerservice($request);
|
||||||
|
|
||||||
|
$mock = $this->getMockBuilder(ReviewContentHandler::class)
|
||||||
|
->setConstructorArgs([$controller])
|
||||||
|
->setMethods(['canSubmitReview'])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$mock->expects($this->exactly(3))->method('canSubmitReview')->willReturn(true);
|
||||||
|
|
||||||
|
// Via CMS
|
||||||
|
$request->addHeader('X-Formschema-Request', true);
|
||||||
|
$result = $mock->submitReview(new SiteTree, ['Review' => 'testing']);
|
||||||
|
$this->assertSame('Review successfully added', $result);
|
||||||
|
$request->removeHeader('X-Formschema-Request');
|
||||||
|
|
||||||
|
// Via AJAX
|
||||||
|
$request->addHeader('X-Requested-With', 'XMLHttpRequest');
|
||||||
|
$result = $mock->submitReview(new SiteTree, ['Review' => 'testing']);
|
||||||
|
$this->assertInstanceOf(HTTPResponse::class, $result);
|
||||||
|
$this->assertSame(200, $result->getStatusCode());
|
||||||
|
$this->assertSame('Review successfully added', $result->getBody());
|
||||||
|
$request->removeHeader('X-Requested-With');
|
||||||
|
|
||||||
|
// Default
|
||||||
|
$result = $mock->submitReview(new SiteTree, ['Review' => 'testing']);
|
||||||
|
$this->assertInstanceOf(HTTPResponse::class, $result);
|
||||||
|
$this->assertSame(302, $result->getStatusCode());
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,7 @@ use SilverStripe\ContentReview\Extensions\SiteTreeContentReview;
|
|||||||
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
|
use SilverStripe\ContentReview\Extensions\ContentReviewOwner;
|
||||||
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
|
use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension;
|
||||||
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
|
use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings;
|
||||||
|
use SilverStripe\Forms\LiteralField;
|
||||||
use SilverStripe\Security\Group;
|
use SilverStripe\Security\Group;
|
||||||
use SilverStripe\Security\Member;
|
use SilverStripe\Security\Member;
|
||||||
use SilverStripe\SiteConfig\SiteConfig;
|
use SilverStripe\SiteConfig\SiteConfig;
|
||||||
@ -294,19 +295,19 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest
|
|||||||
|
|
||||||
public function testReviewActionVisibleForAuthor()
|
public function testReviewActionVisibleForAuthor()
|
||||||
{
|
{
|
||||||
DBDatetime::set_mock_now("2020-03-01 12:00:00");
|
DBDatetime::set_mock_now('2020-03-01 12:00:00');
|
||||||
|
|
||||||
/** @var Page|SiteTreeContentReview $page */
|
/** @var Page|SiteTreeContentReview $page */
|
||||||
$page = $this->objFromFixture(Page::class, "contact");
|
$page = $this->objFromFixture(Page::class, 'contact');
|
||||||
|
|
||||||
/** @var Member $author */
|
/** @var Member $author */
|
||||||
$author = $this->objFromFixture(Member::class, "author");
|
$author = $this->objFromFixture(Member::class, 'author');
|
||||||
|
|
||||||
$this->logInAs($author);
|
$this->logInAs($author);
|
||||||
|
|
||||||
$fields = $page->getCMSActions();
|
$fields = $page->getCMSActions();
|
||||||
|
|
||||||
$this->assertNotNull($fields->fieldByName("ActionMenus.ReviewContent"));
|
$this->assertInstanceOf(LiteralField::class, $fields->fieldByName('ContentReviewButton'));
|
||||||
|
|
||||||
DBDatetime::clear_mock_now();
|
DBDatetime::clear_mock_now();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user