From 31bcd0d43946d88c94bed7040841b80fb3603d76 Mon Sep 17 00:00:00 2001 From: Robbie Averill Date: Mon, 11 Sep 2017 17:53:59 +1200 Subject: [PATCH] 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 --- .scrutinizer.yml | 2 +- .travis.yml | 20 +++- behat.yml | 27 ++++++ composer.json | 7 +- lang/en.yml | 3 +- phpunit.xml.dist | 2 +- src/Extensions/ContentReviewCMSExtension.php | 66 ++++++++----- src/Forms/ReviewContentHandler.php | 69 ++++++-------- src/Forms/ReviewContentHandlerFormAction.php | 19 ---- tests/behat/_manifest_exclude | 0 tests/behat/features/set-up-reviews.feature | 41 ++++++++ tests/{ => php}/ContentReviewBaseTest.php | 0 ...ContentReviewCMSPageEditControllerTest.php | 28 ------ .../ContentReviewNotificationTest.php | 0 tests/{ => php}/ContentReviewReportTest.php | 0 tests/{ => php}/ContentReviewSettingsTest.php | 0 tests/{ => php}/ContentReviewSettingsTest.yml | 0 tests/{ => php}/ContentReviewTest.yml | 0 .../ContentReviewCMSExtensionTest.php | 93 +++++++++++++++++++ tests/php/Forms/ReviewContentHandlerTest.php | 84 +++++++++++++++++ tests/{ => php}/SiteTreeContentReviewTest.php | 9 +- 21 files changed, 350 insertions(+), 120 deletions(-) create mode 100644 behat.yml delete mode 100644 src/Forms/ReviewContentHandlerFormAction.php create mode 100644 tests/behat/_manifest_exclude create mode 100644 tests/behat/features/set-up-reviews.feature rename tests/{ => php}/ContentReviewBaseTest.php (100%) rename tests/{ => php}/ContentReviewCMSPageEditControllerTest.php (78%) rename tests/{ => php}/ContentReviewNotificationTest.php (100%) rename tests/{ => php}/ContentReviewReportTest.php (100%) rename tests/{ => php}/ContentReviewSettingsTest.php (100%) rename tests/{ => php}/ContentReviewSettingsTest.yml (100%) rename tests/{ => php}/ContentReviewTest.yml (100%) create mode 100644 tests/php/Extensions/ContentReviewCMSExtensionTest.php create mode 100644 tests/php/Forms/ReviewContentHandlerTest.php rename tests/{ => php}/SiteTreeContentReviewTest.php (96%) diff --git a/.scrutinizer.yml b/.scrutinizer.yml index 61b0c9f..de09355 100644 --- a/.scrutinizer.yml +++ b/.scrutinizer.yml @@ -6,4 +6,4 @@ checks: duplication: true filter: - paths: [code/*, tests/*] + paths: [src/*, tests/*] diff --git a/.travis.yml b/.travis.yml index 0a95617..839210c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,15 @@ language: php -dist: trusty +dist: precise + +addons: + firefox: "31.0" env: global: - COMPOSER_ROOT_VERSION=4.0.x-dev + - DISPLAY=":99" + - XVFBARGS=":99 -ac -screen 0 1024x768x16" matrix: include: @@ -14,6 +19,8 @@ matrix: env: DB=PGSQL PHPUNIT_TEST=1 - php: 7.1 env: DB=MYSQL PHPUNIT_COVERAGE_TEST=1 + - php: 7.1 + env: DB=MYSQL BEHAT_TEST=1 before_script: # 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 - 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: - if [[ $PHPUNIT_TEST ]]; then vendor/bin/phpunit; 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 [[ $BEHAT_TEST ]]; then vendor/bin/behat @contentreview; fi after_success: - 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/ diff --git a/behat.yml b/behat.yml new file mode 100644 index 0000000..f4dd94e --- /dev/null +++ b/behat.yml @@ -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" diff --git a/composer.json b/composer.json index 0966918..9a226eb 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,10 @@ }, "require-dev": { "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": { "symbiote/silverstripe-queuedjobs": "Automatically schedules content review emails to be sent, only requiring one crontask to be created" @@ -40,7 +43,7 @@ "autoload": { "psr-4": { "SilverStripe\\ContentReview\\": "src/", - "SilverStripe\\ContentReview\\Tests\\": "tests/" + "SilverStripe\\ContentReview\\Tests\\": "tests/php/" } }, "minimum-stability": "dev", diff --git a/lang/en.yml b/lang/en.yml index 447ba37..9feec6d 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -49,8 +49,7 @@ en: SilverStripe\ContentReview\Forms\ReviewContentHandler: ContentDueForReview: Content due for review - ErrorReviewPermissionDenied: It seems you don't have the necessary permissions to submit a content review MarkAsReviewedAction: Mark as reviewed NoComments: (no comments) - ObjectDoesntExist: That object doesn't exist + Placeholder: Add comments (optional) Success: Review successfully added diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 130037b..110f952 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,6 +1,6 @@ - tests/ + tests/php/ diff --git a/src/Extensions/ContentReviewCMSExtension.php b/src/Extensions/ContentReviewCMSExtension.php index 8210bb3..b8cf389 100644 --- a/src/Extensions/ContentReviewCMSExtension.php +++ b/src/Extensions/ContentReviewCMSExtension.php @@ -8,6 +8,7 @@ use SilverStripe\CMS\Model\SiteTree; use SilverStripe\ContentReview\Forms\ReviewContentHandler; use SilverStripe\Control\HTTPRequest; use SilverStripe\Control\HTTPResponse; +use SilverStripe\Control\HTTPResponse_Exception; use SilverStripe\Core\Convert; use SilverStripe\Forms\Form; use SilverStripe\ORM\ValidationResult; @@ -21,7 +22,7 @@ class ContentReviewCMSExtension extends LeftAndMainExtension { private static $allowed_actions = [ 'ReviewContentForm', - 'submitReview', + 'savereview', ]; /** @@ -45,15 +46,9 @@ class ContentReviewCMSExtension extends LeftAndMainExtension */ public function getReviewContentForm($id) { - $record = SiteTree::get()->byID($id); - - if (!$record) { - $this->owner->httpError(404, _t(__CLASS__ . '.ErrorNotFound', 'That object couldn\'t be found')); - return null; - } - + $page = $this->findRecord(['ID' => $id]); $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( __CLASS__.'.ErrorItemPermissionDenied', 'It seems you don\'t have the necessary permissions to review this content' @@ -61,12 +56,10 @@ class ContentReviewCMSExtension extends LeftAndMainExtension return null; } - $handler = ReviewContentHandler::create($this->owner, $record); - $form = $handler->Form($record); - + $form = $this->getReviewContentHandler()->Form($page); $form->setValidationResponseCallback(function (ValidationResult $errors) use ($form, $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; @@ -77,30 +70,59 @@ class ContentReviewCMSExtension extends LeftAndMainExtension * * @param array $data * @param Form $form - * @return DBHTMLText|HTTPResponse + * @return DBHTMLText|HTTPResponse|null */ - public function submitReview($data = '', $form = '') + public function savereview($data, Form $form) { - $id = $data['ID']; - $record = SiteTree::get()->byID($id); + $page = $this->findRecord($data); - $handler = ReviewContentHandler::create($this->owner, $record); - $form = $handler->Form($record); - $results = $handler->submitReview($record, $data); + $results = $this->getReviewContentHandler()->submitReview($page, $data); if (is_null($results)) { return null; } - if ($this->getSchemaRequested()) { // Send extra "message" data with schema response $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 $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. * Used by conditional logic that responds to validation results diff --git a/src/Forms/ReviewContentHandler.php b/src/Forms/ReviewContentHandler.php index bb09164..bea06bd 100644 --- a/src/Forms/ReviewContentHandler.php +++ b/src/Forms/ReviewContentHandler.php @@ -7,6 +7,7 @@ use SilverStripe\Control\HTTPResponse; use SilverStripe\Core\Injector\Injectable; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\Form; +use SilverStripe\Forms\FormAction; use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\TextareaField; use SilverStripe\ORM\DataObject; @@ -24,13 +25,6 @@ class ReviewContentHandler */ protected $controller; - /** - * The submitted form data - * - * @var array - */ - protected $data; - /** * Form name to use * @@ -40,16 +34,11 @@ class ReviewContentHandler /** * @param Controller $controller - * @param array|DataObject $data * @param string $name */ - public function __construct($controller = null, $data = [], $name = 'ReviewContentForm') + public function __construct($controller = null, $name = 'ReviewContentForm') { $this->controller = $controller; - if ($data instanceof DataObject) { - $data = $data->toMap(); - } - $this->data = $data; $this->name = $name; } @@ -61,7 +50,8 @@ class ReviewContentHandler */ 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([ HiddenField::create('ID', null, $object->ID), @@ -71,16 +61,15 @@ class ReviewContentHandler ->setSchemaData(['attributes' => ['placeholder' => $placeholder]]) ]); - $actions = FieldList::create([ - ReviewContentHandlerFormAction::create() - ->setTitle(_t(__CLASS__ . '.MarkAsReviewedAction', 'Mark as reviewed')) - ->addExtraClass('review-content__action') - ]); + $action = FormAction::create('savereview', $title) + ->setTitle($title) + ->setUseButtonTag(false) + ->addExtraClass('review-content__action btn btn-primary'); + $actions = FieldList::create([$action]); - $form = Form::create($this->controller, $this->name, $fields, $actions); - - $form->setHTMLID('Form_EditForm_ReviewContent'); - $form->addExtraClass('form--no-dividers review-content__form'); + $form = Form::create($this->controller, $this->name, $fields, $actions) + ->setHTMLID('Form_EditForm_ReviewContent') + ->addExtraClass('form--no-dividers review-content__form'); return $form; } @@ -91,24 +80,20 @@ class ReviewContentHandler * @param DataObject $record * @param array $data * @return HTTPResponse|string + * @throws ValidationException If the user cannot submit the review */ public function submitReview($record, $data) { - if (!$record || !$record->exists()) { - throw new ValidationException(_t(__CLASS__ . '.ObjectDoesntExist', 'That object doesn\'t exist')); - } - - if (!$record->canEdit() - || !$record->hasMethod('canBeReviewedBy') - || !$record->canBeReviewedBy(Security::getCurrentUser()) - ) { + if (!$this->canSubmitReview($record)) { throw new ValidationException(_t( __CLASS__ . '.ErrorReviewPermissionDenied', '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(); $message = _t(__CLASS__ . '.Success', 'Review successfully added'); @@ -119,21 +104,25 @@ class ReviewContentHandler $response = HTTPResponse::create($message, 200); $response->addHeader('Content-Type', 'text/html; charset=utf-8'); 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 array $data + * @return bool */ - protected function saveRecord($record, $data) + public function canSubmitReview($record) { - $notes = (!empty($data['Review']) ? $data['Review'] : _t(__CLASS__ . '.NoComments', '(no comments)')); - $record->addReviewNote(Security::getCurrentUser(), $notes); - $record->advanceReviewDate(); + if (!$record->canEdit() + || !$record->hasMethod('canBeReviewedBy') + || !$record->canBeReviewedBy(Security::getCurrentUser()) + ) { + return false; + } + return true; } } diff --git a/src/Forms/ReviewContentHandlerFormAction.php b/src/Forms/ReviewContentHandlerFormAction.php deleted file mode 100644 index 321abfd..0000000 --- a/src/Forms/ReviewContentHandlerFormAction.php +++ /dev/null @@ -1,19 +0,0 @@ -setUseButtonTag(false) - ->addExtraClass('review-content-action btn btn-primary'); - } -} diff --git a/tests/behat/_manifest_exclude b/tests/behat/_manifest_exclude new file mode 100644 index 0000000..e69de29 diff --git a/tests/behat/features/set-up-reviews.feature b/tests/behat/features/set-up-reviews.feature new file mode 100644 index 0000000..c6036ee --- /dev/null +++ b/tests/behat/features/set-up-reviews.feature @@ -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"="

Welcome

", "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" diff --git a/tests/ContentReviewBaseTest.php b/tests/php/ContentReviewBaseTest.php similarity index 100% rename from tests/ContentReviewBaseTest.php rename to tests/php/ContentReviewBaseTest.php diff --git a/tests/ContentReviewCMSPageEditControllerTest.php b/tests/php/ContentReviewCMSPageEditControllerTest.php similarity index 78% rename from tests/ContentReviewCMSPageEditControllerTest.php rename to tests/php/ContentReviewCMSPageEditControllerTest.php index cd0f0bc..ab84c64 100644 --- a/tests/ContentReviewCMSPageEditControllerTest.php +++ b/tests/php/ContentReviewCMSPageEditControllerTest.php @@ -90,34 +90,6 @@ class ContentReviewCMSPageEditControllerTest extends ContentReviewBaseTest $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 * diff --git a/tests/ContentReviewNotificationTest.php b/tests/php/ContentReviewNotificationTest.php similarity index 100% rename from tests/ContentReviewNotificationTest.php rename to tests/php/ContentReviewNotificationTest.php diff --git a/tests/ContentReviewReportTest.php b/tests/php/ContentReviewReportTest.php similarity index 100% rename from tests/ContentReviewReportTest.php rename to tests/php/ContentReviewReportTest.php diff --git a/tests/ContentReviewSettingsTest.php b/tests/php/ContentReviewSettingsTest.php similarity index 100% rename from tests/ContentReviewSettingsTest.php rename to tests/php/ContentReviewSettingsTest.php diff --git a/tests/ContentReviewSettingsTest.yml b/tests/php/ContentReviewSettingsTest.yml similarity index 100% rename from tests/ContentReviewSettingsTest.yml rename to tests/php/ContentReviewSettingsTest.yml diff --git a/tests/ContentReviewTest.yml b/tests/php/ContentReviewTest.yml similarity index 100% rename from tests/ContentReviewTest.yml rename to tests/php/ContentReviewTest.yml diff --git a/tests/php/Extensions/ContentReviewCMSExtensionTest.php b/tests/php/Extensions/ContentReviewCMSExtensionTest.php new file mode 100644 index 0000000..b060a90 --- /dev/null +++ b/tests/php/Extensions/ContentReviewCMSExtensionTest.php @@ -0,0 +1,93 @@ +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); + } +} diff --git a/tests/php/Forms/ReviewContentHandlerTest.php b/tests/php/Forms/ReviewContentHandlerTest.php new file mode 100644 index 0000000..7561224 --- /dev/null +++ b/tests/php/Forms/ReviewContentHandlerTest.php @@ -0,0 +1,84 @@ +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()); + } +} diff --git a/tests/SiteTreeContentReviewTest.php b/tests/php/SiteTreeContentReviewTest.php similarity index 96% rename from tests/SiteTreeContentReviewTest.php rename to tests/php/SiteTreeContentReviewTest.php index 098ccea..8960e97 100644 --- a/tests/SiteTreeContentReviewTest.php +++ b/tests/php/SiteTreeContentReviewTest.php @@ -9,6 +9,7 @@ use SilverStripe\ContentReview\Extensions\SiteTreeContentReview; use SilverStripe\ContentReview\Extensions\ContentReviewOwner; use SilverStripe\ContentReview\Extensions\ContentReviewCMSExtension; use SilverStripe\ContentReview\Extensions\ContentReviewDefaultSettings; +use SilverStripe\Forms\LiteralField; use SilverStripe\Security\Group; use SilverStripe\Security\Member; use SilverStripe\SiteConfig\SiteConfig; @@ -294,19 +295,19 @@ class SiteTreeContentReviewTest extends ContentReviewBaseTest 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 */ - $page = $this->objFromFixture(Page::class, "contact"); + $page = $this->objFromFixture(Page::class, 'contact'); /** @var Member $author */ - $author = $this->objFromFixture(Member::class, "author"); + $author = $this->objFromFixture(Member::class, 'author'); $this->logInAs($author); $fields = $page->getCMSActions(); - $this->assertNotNull($fields->fieldByName("ActionMenus.ReviewContent")); + $this->assertInstanceOf(LiteralField::class, $fields->fieldByName('ContentReviewButton')); DBDatetime::clear_mock_now(); }