2015-04-07 05:56:00 +02:00
|
|
|
<?php
|
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
namespace SilverStripe\Comments\Tests;
|
|
|
|
|
2018-06-15 06:50:14 +02:00
|
|
|
use SilverStripe\Akismet\AkismetSpamProtector;
|
2017-01-16 20:57:37 +01:00
|
|
|
use SilverStripe\Comments\Controllers\CommentingController;
|
|
|
|
use SilverStripe\Comments\Model\Comment;
|
|
|
|
use SilverStripe\Comments\Model\Comment\SecurityToken as CommentSecurityToken;
|
|
|
|
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
|
|
|
|
use SilverStripe\Control\Controller;
|
|
|
|
use SilverStripe\Core\Config\Config;
|
2018-06-15 06:50:14 +02:00
|
|
|
use SilverStripe\Core\Injector\Injector;
|
2017-01-16 20:57:37 +01:00
|
|
|
use SilverStripe\Dev\FunctionalTest;
|
|
|
|
use SilverStripe\ORM\DataObject;
|
|
|
|
use SilverStripe\Security\Member;
|
|
|
|
use SilverStripe\Security\SecurityToken;
|
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
class CommentingControllerTest extends FunctionalTest
|
|
|
|
{
|
2017-01-16 20:57:37 +01:00
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
2017-01-27 04:20:14 +01:00
|
|
|
protected static $fixture_file = 'CommentsTest.yml';
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
2017-09-14 00:28:29 +02:00
|
|
|
protected static $extra_dataobjects = [
|
2017-01-16 20:57:37 +01:00
|
|
|
CommentableItem::class
|
2017-09-14 00:28:29 +02:00
|
|
|
];
|
2016-01-07 07:59:10 +01:00
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
protected $securityEnabled;
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2021-10-27 07:03:55 +02:00
|
|
|
protected function tearDown(): void
|
2016-02-19 01:48:25 +01:00
|
|
|
{
|
|
|
|
if ($this->securityEnabled) {
|
2017-01-16 20:57:37 +01:00
|
|
|
SecurityToken::inst()->enable();
|
2016-02-19 01:48:25 +01:00
|
|
|
} else {
|
2017-01-16 20:57:37 +01:00
|
|
|
SecurityToken::inst()->disable();
|
2016-02-19 01:48:25 +01:00
|
|
|
}
|
|
|
|
parent::tearDown();
|
|
|
|
}
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2021-10-27 07:03:55 +02:00
|
|
|
protected function setUp(): void
|
2016-02-19 01:48:25 +01:00
|
|
|
{
|
|
|
|
parent::setUp();
|
2017-01-16 20:57:37 +01:00
|
|
|
$this->securityEnabled = SecurityToken::inst()->is_enabled();
|
|
|
|
|
|
|
|
// We will assert against explicit responses, unless handed otherwise in a test for redirects
|
|
|
|
$this->autoFollowRedirection = false;
|
2018-06-15 06:50:14 +02:00
|
|
|
|
|
|
|
// Mock Akismet if it's installed
|
|
|
|
if (class_exists(AkismetSpamProtector::class)) {
|
|
|
|
$akismetMock = $this->createMock(AkismetSpamProtector::class);
|
|
|
|
Injector::inst()->registerService($akismetMock, AkismetSpamProtector::class);
|
|
|
|
}
|
2016-02-19 01:48:25 +01:00
|
|
|
}
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2017-09-18 04:16:24 +02:00
|
|
|
public function testCommentsFormUsePreview()
|
|
|
|
{
|
|
|
|
$parent = $this->objFromFixture(CommentableItem::class, 'first');
|
|
|
|
$commController = new CommentingController();
|
|
|
|
$commController->setOwnerRecord($parent);
|
|
|
|
$form = $commController->CommentsForm();
|
|
|
|
|
|
|
|
$commentsFields = $form->Fields()->first()->FieldList();
|
|
|
|
$expected = array('Name', 'Email', 'URL', 'Comment');
|
|
|
|
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
|
|
|
|
|
|
|
|
// test with preview on
|
|
|
|
Config::modify()->merge(CommentableItem::class, 'comments', array(
|
|
|
|
'use_preview' => true
|
|
|
|
));
|
|
|
|
|
|
|
|
$parent = $this->objFromFixture(CommentableItem::class, 'first');
|
|
|
|
$commController = new CommentingController();
|
|
|
|
$commController->setOwnerRecord($parent);
|
|
|
|
|
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
|
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
|
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
|
|
|
|
|
|
|
|
SecurityToken::inst()->disable();
|
|
|
|
$this->autoFollowRedirection = false;
|
|
|
|
|
|
|
|
$form = $commController->CommentsForm();
|
|
|
|
$commentsFields = $form->Fields()->first()->FieldList();
|
|
|
|
$expected = array('Name', 'Email', 'URL', 'Comment', 'PreviewComment');
|
|
|
|
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
|
|
|
|
}
|
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
public function testApproveUnmoderatedComment()
|
2016-02-19 01:48:25 +01:00
|
|
|
{
|
2017-01-16 20:57:37 +01:00
|
|
|
SecurityToken::inst()->disable();
|
2016-01-07 07:59:10 +01:00
|
|
|
|
|
|
|
// mark a comment as spam then approve it
|
|
|
|
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
|
2017-01-16 20:57:37 +01:00
|
|
|
$comment = $this->objFromFixture(Comment::class, 'testModeratedComment1');
|
|
|
|
$st = new CommentSecurityToken($comment);
|
|
|
|
$url = 'comments/approve/' . $comment->ID;
|
2016-01-07 07:59:10 +01:00
|
|
|
$url = $st->addToUrl($url, Member::currentUser());
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get($url, null, ['Referer' => '/']);
|
|
|
|
$this->assertEquals(302, $response->getStatusCode());
|
|
|
|
$comment = DataObject::get_by_id(Comment::class, $comment->ID);
|
2016-01-07 07:59:10 +01:00
|
|
|
|
|
|
|
// Need to use 0,1 here instead of false, true for SQLite
|
|
|
|
$this->assertEquals(0, $comment->IsSpam);
|
|
|
|
$this->assertEquals(1, $comment->Moderated);
|
|
|
|
|
|
|
|
// try and approve a non existent comment
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/approve/100000');
|
2016-01-07 07:59:10 +01:00
|
|
|
$this->assertEquals(404, $response->getStatusCode());
|
|
|
|
}
|
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
public function testSetGetOwnerController()
|
|
|
|
{
|
2016-01-07 07:59:10 +01:00
|
|
|
$commController = new CommentingController();
|
|
|
|
$commController->setOwnerController(Controller::curr());
|
|
|
|
$this->assertEquals(Controller::curr(), $commController->getOwnerController());
|
|
|
|
$commController->setOwnerController(null);
|
|
|
|
$this->assertNull($commController->getOwnerController());
|
|
|
|
}
|
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
public function testHam()
|
|
|
|
{
|
2017-01-16 20:57:37 +01:00
|
|
|
SecurityToken::inst()->disable();
|
2016-01-07 07:59:10 +01:00
|
|
|
|
|
|
|
// mark a comment as spam then ham it
|
|
|
|
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
|
2017-01-16 20:57:37 +01:00
|
|
|
$comment = $this->objFromFixture(Comment::class, 'firstComA');
|
2016-01-07 07:59:10 +01:00
|
|
|
$comment->markSpam();
|
2017-01-16 20:57:37 +01:00
|
|
|
$st = new CommentSecurityToken($comment);
|
|
|
|
$url = 'comments/ham/' . $comment->ID;
|
2016-01-07 07:59:10 +01:00
|
|
|
$url = $st->addToUrl($url, Member::currentUser());
|
|
|
|
$response = $this->get($url);
|
2017-01-16 20:57:37 +01:00
|
|
|
$this->assertEquals(302, $response->getStatusCode());
|
|
|
|
$comment = DataObject::get_by_id(Comment::class, $comment->ID);
|
2016-01-07 07:59:10 +01:00
|
|
|
|
|
|
|
// Need to use 0,1 here instead of false, true for SQLite
|
|
|
|
$this->assertEquals(0, $comment->IsSpam);
|
|
|
|
$this->assertEquals(1, $comment->Moderated);
|
|
|
|
|
|
|
|
// try and ham a non existent comment
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/ham/100000');
|
2016-01-07 07:59:10 +01:00
|
|
|
$this->assertEquals(404, $response->getStatusCode());
|
|
|
|
}
|
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
public function testSpam()
|
|
|
|
{
|
2016-01-07 07:59:10 +01:00
|
|
|
// mark a comment as approved then spam it
|
|
|
|
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
|
2017-01-16 20:57:37 +01:00
|
|
|
$comment = $this->objFromFixture(Comment::class, 'firstComA');
|
2016-01-07 07:59:10 +01:00
|
|
|
$comment->markApproved();
|
2017-01-16 20:57:37 +01:00
|
|
|
$st = new CommentSecurityToken($comment);
|
|
|
|
$url = 'comments/spam/' . $comment->ID;
|
2016-01-07 07:59:10 +01:00
|
|
|
$url = $st->addToUrl($url, Member::currentUser());
|
|
|
|
$response = $this->get($url);
|
2017-01-16 20:57:37 +01:00
|
|
|
$this->assertEquals(302, $response->getStatusCode());
|
|
|
|
$comment = DataObject::get_by_id(Comment::class, $comment->ID);
|
2016-01-07 07:59:10 +01:00
|
|
|
|
|
|
|
// Need to use 0,1 here instead of false, true for SQLite
|
|
|
|
$this->assertEquals(1, $comment->IsSpam);
|
|
|
|
$this->assertEquals(1, $comment->Moderated);
|
|
|
|
|
|
|
|
// try and spam a non existent comment
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/spam/100000');
|
2016-01-07 07:59:10 +01:00
|
|
|
$this->assertEquals(404, $response->getStatusCode());
|
|
|
|
}
|
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
public function testRSS()
|
|
|
|
{
|
2016-01-07 07:59:10 +01:00
|
|
|
// Delete the newly added children of firstComA so as not to have to recalculate values below
|
2017-01-16 20:57:37 +01:00
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
|
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
|
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
|
2016-01-07 07:59:10 +01:00
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
$item = $this->objFromFixture(CommentableItem::class, 'first');
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
// comments sitewide
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/rss');
|
2017-09-13 23:41:11 +02:00
|
|
|
$comment = "10 approved, non spam comments on page 1";
|
|
|
|
$this->assertEquals(10, substr_count($response->getBody(), "<item>"), $comment);
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/rss?start=10');
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->assertEquals(4, substr_count($response->getBody(), "<item>"), "3 approved, non spam comments on page 2");
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
// all comments on a type
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem');
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->assertEquals(10, substr_count($response->getBody(), "<item>"));
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem?start=10');
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->assertEquals(4, substr_count($response->getBody(), "<item>"), "3 approved, non spam comments on page 2");
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
// specific page
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem/'.$item->ID);
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->assertEquals(1, substr_count($response->getBody(), "<item>"));
|
2021-10-27 07:03:55 +02:00
|
|
|
$this->assertStringContainsString('<dc:creator>FA</dc:creator>', $response->getBody());
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
// test accessing comments on a type that doesn't exist
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->get('comments/rss/Fake');
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->assertEquals(404, $response->getStatusCode());
|
|
|
|
}
|
2015-04-07 05:56:00 +02:00
|
|
|
|
2016-01-07 07:59:10 +01:00
|
|
|
// This is returning a 404 which looks logical code wise but also a bit weird.
|
|
|
|
// Test module on a clean install and check what the actual URL is first
|
|
|
|
/* public function testReply() {
|
|
|
|
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
|
|
|
|
$comment = $this->objFromFixture('Comment', 'firstComA');
|
|
|
|
$item = $this->objFromFixture('CommentableItem', 'first');
|
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
$st = new CommentSecurityToken($comment);
|
|
|
|
$url = 'comments/reply/' . $item->ID.'?ParentCommentID=' . $comment->ID;
|
2016-01-07 07:59:10 +01:00
|
|
|
error_log($url);
|
|
|
|
$response = $this->get($url);
|
|
|
|
error_log(print_r($response,1));
|
|
|
|
|
|
|
|
$this->assertEquals(200, $response->getStatusCode());
|
|
|
|
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
public function testCommentsFormLoadMemberData() {
|
2017-09-18 04:16:24 +02:00
|
|
|
Config::modify()->set('CommentableItem', 'comments', array(
|
2016-01-07 07:59:10 +01:00
|
|
|
'use_preview' => false
|
|
|
|
));
|
|
|
|
$this->logInAs('visitor');
|
2017-01-16 20:57:37 +01:00
|
|
|
SecurityToken::inst()->disable();
|
2016-01-07 07:59:10 +01:00
|
|
|
$parent = $this->objFromFixture('CommentableItem', 'first');
|
|
|
|
$parent->CommentsRequireLogin = true;
|
|
|
|
$parent->PostingRequiredPermission = true;
|
|
|
|
//$parent->write();
|
|
|
|
$commController = new CommentingController();
|
|
|
|
$commController->setOwnerRecord($parent);
|
|
|
|
|
|
|
|
$form = $commController->CommentsForm();
|
|
|
|
$commentsFields = $form->Fields()->first()->FieldList();
|
|
|
|
$expected = array('Name', 'Email', 'URL', 'Comment', 'PreviewComment');
|
|
|
|
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
2016-02-19 01:48:25 +01:00
|
|
|
public function testCommentsForm()
|
|
|
|
{
|
2017-01-16 20:57:37 +01:00
|
|
|
$this->autoFollowRedirection = true;
|
|
|
|
|
2016-01-07 07:59:10 +01:00
|
|
|
// Delete the newly added children of firstComA so as not to change this test
|
2017-01-16 20:57:37 +01:00
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
|
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
|
|
|
|
$this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
|
2016-01-07 07:59:10 +01:00
|
|
|
|
2017-01-16 20:57:37 +01:00
|
|
|
SecurityToken::inst()->disable();
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->autoFollowRedirection = false;
|
2017-01-16 20:57:37 +01:00
|
|
|
$parent = $this->objFromFixture(CommentableItem::class, 'first');
|
2016-02-19 01:48:25 +01:00
|
|
|
|
|
|
|
// Test posting to base comment
|
2017-01-16 20:57:37 +01:00
|
|
|
$response = $this->post(
|
|
|
|
'comments/CommentsForm',
|
2016-02-19 01:48:25 +01:00
|
|
|
array(
|
|
|
|
'Name' => 'Poster',
|
|
|
|
'Email' => 'guy@test.com',
|
|
|
|
'Comment' => 'My Comment',
|
|
|
|
'ParentID' => $parent->ID,
|
2017-01-16 20:57:37 +01:00
|
|
|
'ParentClassName' => CommentableItem::class,
|
2016-02-19 01:48:25 +01:00
|
|
|
'action_doPostComment' => 'Post'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
$this->assertEquals(302, $response->getStatusCode());
|
2017-01-16 20:57:37 +01:00
|
|
|
// $this->assertStringStartsWith('CommentableItemController#comment-', $response->getHeader('Location'));
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->assertDOSEquals(
|
2017-01-16 20:57:37 +01:00
|
|
|
array(
|
|
|
|
array(
|
|
|
|
'Name' => 'Poster',
|
|
|
|
'Email' => 'guy@test.com',
|
|
|
|
'Comment' => 'My Comment',
|
|
|
|
'ParentID' => $parent->ID,
|
|
|
|
'ParentClass' => CommentableItem::class,
|
|
|
|
)
|
|
|
|
),
|
2016-02-19 01:48:25 +01:00
|
|
|
Comment::get()->filter('Email', 'guy@test.com')
|
|
|
|
);
|
|
|
|
|
|
|
|
// Test posting to parent comment
|
2017-01-16 20:57:37 +01:00
|
|
|
$parentComment = $this->objFromFixture(Comment::class, 'firstComA');
|
2016-02-19 01:48:25 +01:00
|
|
|
$this->assertEquals(0, $parentComment->ChildComments()->count());
|
|
|
|
|
|
|
|
$response = $this->post(
|
2017-01-16 20:57:37 +01:00
|
|
|
'comments/reply/' . $parentComment->ID,
|
2016-02-19 01:48:25 +01:00
|
|
|
array(
|
|
|
|
'Name' => 'Test Author',
|
|
|
|
'Email' => 'test@test.com',
|
|
|
|
'Comment' => 'Making a reply to firstComA',
|
|
|
|
'ParentID' => $parent->ID,
|
2017-01-16 20:57:37 +01:00
|
|
|
'ParentClassName' => CommentableItem::class,
|
2016-02-19 01:48:25 +01:00
|
|
|
'ParentCommentID' => $parentComment->ID,
|
|
|
|
'action_doPostComment' => 'Post'
|
|
|
|
)
|
|
|
|
);
|
|
|
|
$this->assertEquals(302, $response->getStatusCode());
|
2017-01-16 20:57:37 +01:00
|
|
|
// $this->assertStringStartsWith('CommentableItemController#comment-', $response->getHeader('Location'));
|
|
|
|
$this->assertDOSEquals(
|
|
|
|
array(
|
|
|
|
array(
|
|
|
|
'Name' => 'Test Author',
|
|
|
|
'Email' => 'test@test.com',
|
|
|
|
'Comment' => 'Making a reply to firstComA',
|
|
|
|
'ParentID' => $parent->ID,
|
|
|
|
'ParentClass' => CommentableItem::class,
|
|
|
|
'ParentCommentID' => $parentComment->ID
|
|
|
|
)
|
|
|
|
),
|
|
|
|
$parentComment->ChildComments()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* SS4 introduces namespaces. They don't work in URLs, so we encode and decode them here.
|
|
|
|
*/
|
|
|
|
public function testEncodeClassName()
|
|
|
|
{
|
|
|
|
$controller = new CommentingController;
|
|
|
|
$this->assertSame('SilverStripe-Comments-Model-Comment', $controller->encodeClassName(Comment::class));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testDecodeClassName()
|
|
|
|
{
|
|
|
|
$controller = new CommentingController;
|
|
|
|
$this->assertSame(Comment::class, $controller->decodeClassName('SilverStripe-Comments-Model-Comment'));
|
2016-02-19 01:48:25 +01:00
|
|
|
}
|
2015-04-07 05:56:00 +02:00
|
|
|
}
|