[SiteTreeContentReview::class], Group::class => [ContentReviewOwner::class], Member::class => [ContentReviewOwner::class], CMSPageEditController::class => [ContentReviewCMSExtension::class], SiteConfig::class => [ContentReviewDefaultSettings::class], ]; public function testOwnerNames() { /** @var Member $editor */ $editor = $this->objFromFixture(Member::class, "editor"); $this->logInAs($editor); /** @var Page|SiteTreeContentReview $page */ $page = new Page(); $page->ReviewPeriodDays = 10; $page->ContentReviewType = "Custom"; $page->ContentReviewUsers()->push($editor); $page->write(); $this->assertTrue($page->canPublish()); $this->assertTrue($page->publishRecursive()); $this->assertEquals($page->OwnerNames, "Test Editor", "Test Editor should be the owner"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "about"); $page->OwnerUsers()->removeAll(); $page->write(); $this->assertTrue($page->canPublish()); $this->assertTrue($page->publishRecursive()); $this->assertEquals("", $page->OwnerNames); } public function testPermissionsExists() { $perms = singleton(SiteTreeContentReview::class)->providePermissions(); $this->assertTrue(isset($perms["EDIT_CONTENT_REVIEW_FIELDS"])); } public function testUserWithPermissionCanEdit() { /** @var Member $editor */ $editor = $this->objFromFixture(Member::class, "editor"); $this->logInAs($editor); /** @var Page|SiteTreeContentReview $page */ $page = new Page(); $fields = $page->getSettingsFields(); $this->assertNotNull($fields->dataFieldByName("NextReviewDate")); } public function testUserWithoutPermissionCannotEdit() { /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); $this->logInAs($author); /** @var Page|SiteTreeContentReview $page */ $page = new Page(); $fields = $page->getSettingsFields(); $this->assertNull($fields->dataFieldByName("NextReviewDate")); } public function testAutomaticallyToNotSetReviewDate() { /** @var Member $editor */ $editor = $this->objFromFixture(Member::class, "editor"); $this->logInAs($editor); /** @var Page|SiteTreeContentReview $page */ $page = new Page(); $page->ReviewPeriodDays = 10; $page->write(); $this->assertTrue($page->publishRecursive()); $this->assertEquals(null, $page->NextReviewDate); } public function testAdvanceReviewDate() { $page = new Page(); $page->Title = 'Test page'; $page->ReviewPeriodDays = 0; // Set timestamp to a time in the past $timestamp = DBDatetime::now()->getTimestamp() - 100000; $page->NextReviewDate = DBDate::create()->setValue($timestamp)->Format(DBDate::ISO_DATE); $page->write(); $page->advanceReviewDate(); $this->assertNull(Page::get()->find('Title', 'Test page')->NextReviewDate); } public function testAddReviewNote() { /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "home"); $page->addReviewNote($author, "This is a message"); /** @var Page|SiteTreeContentReview $page */ $homepage = $this->objFromFixture(Page::class, "home"); $this->assertEquals(1, $homepage->ReviewLogs()->count()); $this->assertEquals("This is a message", $homepage->ReviewLogs()->first()->Note); } public function testGetContentReviewOwners() { /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "group-owned"); $owners = $page->ContentReviewOwners(); $this->assertEquals(1, $owners->count()); $this->assertEquals("author@example.com", $owners->first()->Email); } public function testCanNotBeReviewBecauseNoReviewDate() { DBDatetime::set_mock_now("2010-01-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "no-review"); $this->assertFalse($page->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testCanNotBeReviewedBecauseInFuture() { DBDatetime::set_mock_now("2010-01-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "staff"); $this->assertFalse($page->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testCanNotBeReviewedByUser() { DBDatetime::set_mock_now("2010-03-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "home"); $this->assertFalse($page->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testCanBeReviewedByUser() { DBDatetime::set_mock_now("2010-03-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "staff"); $this->assertTrue($page->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testCanNotBeReviewedByGroup() { DBDatetime::set_mock_now("2010-03-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "editor"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "contact"); $this->assertFalse($page->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testCanBeReviewedByGroup() { DBDatetime::set_mock_now("2010-03-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "contact"); $this->assertTrue($page->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testCanBeReviewedFromInheritedSetting() { DBDatetime::set_mock_now("2013-03-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); /** @var Page|SiteTreeContentReview $parentPage */ $parentPage = $this->objFromFixture(Page::class, "contact"); $parentPage->NextReviewDate = "2013-01-01"; $parentPage->write(); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "contact-child"); $this->assertTrue($page->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testUnModifiedPagesDontChangeEditor() { DBDatetime::set_mock_now("2013-03-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "author"); $this->logInAs($author); // Page which is un-modified doesn't advance version of have an editor assigned $contactPage = $this->objFromFixture(Page::class, "contact"); $contactPageVersion = $contactPage->Version; $contactPage->write(); $this->assertEmpty($contactPage->LastEditedByName); $this->assertEquals( $contactPageVersion, Versioned::get_versionnumber_by_stage(SiteTree::class, 'Stage', $contactPage->ID, false) ); // Page with modifications gets marked $homePage = $this->objFromFixture(Page::class, "home"); $homePageVersion = $homePage->Version; $homePage->Content = '

Welcome!

'; $homePage->write(); $this->assertNotEmpty($homePage->LastEditedByName); $this->assertEquals($author->getTitle(), $homePage->LastEditedByName); $this->assertGreaterThan( $homePageVersion, Versioned::get_versionnumber_by_stage(SiteTree::class, 'Stage', $homePage->ID, false) ); DBDatetime::clear_mock_now(); } public function testReviewActionVisibleForAuthor() { DBDatetime::set_mock_now('2020-03-01 12:00:00'); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, 'contact'); /** @var Member $author */ $author = $this->objFromFixture(Member::class, 'author'); $this->logInAs($author); $fields = $page->getCMSActions(); $this->assertInstanceOf(LiteralField::class, $fields->fieldByName('ContentReviewButton')); DBDatetime::clear_mock_now(); } public function testReviewActionNotVisibleForEditor() { DBDatetime::set_mock_now("2020-03-01 12:00:00"); /** @var Page|SiteTreeContentReview $page */ $page = $this->objFromFixture(Page::class, "contact"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, "editor"); $this->logInAs($author); $fields = $page->getCMSActions(); $this->assertNull($fields->fieldByName("ActionMenus.ReviewContent")); DBDatetime::clear_mock_now(); } public function testSiteConfigSettingsAreUsedAsDefaults() { DBDatetime::set_mock_now("2020-03-01 12:00:00"); /** @var Member $author */ $author = $this->objFromFixture(Member::class, 'editor'); /** @var SiteConfig $siteConfig */ $siteConfig = SiteConfig::current_site_config(); // Set the author to a default user for reviewing $siteConfig->OwnerUsers()->add($author); $emptyPage = new Page; $emptyPage->NextReviewDate = '2020-02-20 12:00:00'; $this->assertTrue($emptyPage->canBeReviewedBy($author)); DBDatetime::clear_mock_now(); } public function testPermissionCheckByOnDataObject() { $reviewer = $this->objFromFixture(Member::class, 'editor'); // Mock Page class with canReviewContent method to return true on first call and false on second call $mock = $this->getMockBuilder(Page::class) ->setMethods(['canReviewContent', 'NextReviewDate', 'OwnerUsers']) ->getMock(); $mock->expects($this->exactly(2))->method('canReviewContent')->willReturnOnConsecutiveCalls(false, true); $mock->method('NextReviewDate')->willReturn('2020-02-20 12:00:00'); $mock->method('OwnerUsers')->willReturn(ArrayList::create([$reviewer])); $mock->ContentReviewType = 'Custom'; /** @var SiteTreeContentReview $extension */ $extension = Injector::inst()->get(SiteTreeContentReview::class); $extension->setOwner($mock); // Assert that the user is not allowed to review content $author = $this->objFromFixture(Member::class, 'author'); $this->assertFalse($extension->canBeReviewedBy($author)); DBDatetime::set_mock_now("2020-03-01 12:00:00"); // Assert that the user is allowed to review content $this->assertTrue($extension->canBeReviewedBy($reviewer)); // Assert tht canBeReviewedBy return true if no user logged in // This is for CLI execution for ContentReviewEmails task $this->logOut(); $this->assertTrue($extension->canBeReviewedBy()); DBDatetime::clear_mock_now(); } }