ENHANCEMENT: Increase test coverage from 54% to 92%

This commit is contained in:
Gordon Anderson 2016-01-07 13:59:10 +07:00
parent 72a7899e3d
commit eba88fe869
14 changed files with 1933 additions and 75 deletions

View File

@ -1,9 +1,12 @@
# See https://github.com/silverstripe-labs/silverstripe-travis-support for setup details
sudo: false
language: php
sudo: true
addons:
apt:
packages:
- tidy
php:
- 5.3
- 5.4
@ -11,11 +14,22 @@ php:
- 5.6
- 7.0
before_install:
- pip install --user codecov
env:
- DB=MYSQL CORE_RELEASE=3.2
global:
- DB=MYSQL CORE_RELEASE=3.1
- MODULE_PATH=comments
# Set to 1 in the matrix to enable code coverage
- COVERAGE=0
matrix:
include:
- php: 5.6
#CommentsListTest breaks with this env: DB=MYSQL CORE_RELEASE=3.2 COVERAGE=1
env: DB=SQLITE CORE_RELEASE=3.2 COVERAGE=1
- php: 5.6
env: DB=MYSQL CORE_RELEASE=3
- php: 5.6
@ -26,11 +40,23 @@ matrix:
- php: 7.0
before_script:
- phpenv rehash
- 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
- git clone https://github.com/gordonbanderson/silverstripe-travis-support.git --branch pull-24 ~/travis-support
# - git clone git://github.com/silverstripe-labs/silverstripe-travis-support.git ~/travis-support
# Install suggested modules in order to maximize test coverage
- php ~/travis-support/travis_setup.php --source `pwd` --target ~/builds/ss --require "ezyang/htmlpurifier:4.*,silverstripe/cms:~3.1"
- cd ~/builds/ss
- composer install
script:
- vendor/bin/phpunit comments/tests
# Execute tests with no coverage. This is the fastest option
- "if [ \"$COVERAGE\" = \"0\" ]; then vendor/bin/phpunit $MODULE_PATH/tests/; fi"
# Execute tests with coverage. Do this for a small
- "if [ \"$COVERAGE\" = \"1\" ]; then vendor/bin/phpunit --coverage-clover=coverage.clover $MODULE_PATH/tests/; fi"
after_script:
- "if [ \"$COVERAGE\" = \"1\" ]; then mv coverage.clover ~/build/$TRAVIS_REPO_SLUG/; fi"
- cd ~/build/$TRAVIS_REPO_SLUG
- wget https://scrutinizer-ci.com/ocular.phar
- "if [ \"$COVERAGE\" = \"1\" ]; then travis_retry codecov && travis_retry php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi"

View File

@ -1,6 +1,21 @@
# Comments
[![Build Status](https://travis-ci.org/gordonbanderson/silverstripe-comments.svg?branch=testing)](https://travis-ci.org/gordonbanderson/silverstripe-comments)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/gordonbanderson/silverstripe-comments/badges/quality-score.png?b=testing)](https://scrutinizer-ci.com/g/gordonbanderson/silverstripe-comments/?branch=testing)
[![Code Coverage](https://scrutinizer-ci.com/g/gordonbanderson/silverstripe-comments/badges/coverage.png?b=testing)](https://scrutinizer-ci.com/g/gordonbanderson/silverstripe-comments/?branch=testing)
[![Build Status](https://scrutinizer-ci.com/g/gordonbanderson/silverstripe-comments/badges/build.png?b=testing)](https://scrutinizer-ci.com/g/gordonbanderson/silverstripe-comments/build-status/testing)
[![codecov.io](https://codecov.io/github/gordonbanderson/silverstripe-comments/coverage.svg?branch=testing)](https://codecov.io/github/gordonbanderson/silverstripe-comments?branch=testing)
[![Build Status](https://secure.travis-ci.org/silverstripe/silverstripe-comments.png?branch=master)](http://travis-ci.org/silverstripe/silverstripe-comments)
[![Latest Stable Version](https://poser.pugx.org/silverstripe/comments/version)](https://packagist.org/packages/silverstripe/comments)
[![Latest Unstable Version](https://poser.pugx.org/silverstripe/comments/v/unstable)](//packagist.org/packages/silverstripe/comments)
[![Total Downloads](https://poser.pugx.org/silverstripe/comments/downloads)](https://packagist.org/packages/silverstripe/comments)
[![License](https://poser.pugx.org/silverstripe/comments/license)](https://packagist.org/packages/silverstripe/comments)
[![Monthly Downloads](https://poser.pugx.org/silverstripe/comments/d/monthly)](https://packagist.org/packages/silverstripe/comments)
[![Daily Downloads](https://poser.pugx.org/silverstripe/comments/d/daily)](https://packagist.org/packages/silverstripe/comments)
[![Dependency Status](https://www.versioneye.com/php/silverstripe:comments/badge.svg)](https://www.versioneye.com/php/silverstripe:comments)
[![Reference Status](https://www.versioneye.com/php/silverstripe:comments/reference_badge.svg?style=flat)](https://www.versioneye.com/php/silverstripe:comments/references)
![codecov.io](https://codecov.io/github/gordonbanderson/silverstripe-comments/branch.svg?branch=testing)
[Changelog](CHANGELOG.md)

View File

@ -0,0 +1,57 @@
<?php
class CommentAdminTest extends SapphireTest {
public function testProvidePermissions() {
$commentAdmin = new CommentAdmin();
$locale = i18n::get_locale();
i18n::set_locale('fr');
$expected = array(
'CMS_ACCESS_CommentAdmin' => array(
# FIXME - this is a bug, missing from lang.yml files
'name' => 'Access to \'Comments\' section',
'category' => 'Accès au CMS'
)
);
$this->assertEquals($expected, $commentAdmin->providePermissions());
i18n::set_locale($locale);
$expected = array(
'CMS_ACCESS_CommentAdmin' => array(
# FIXME - this is a bug, missing from lang.yml files
'name' => 'Access to \'Comments\' section',
'category' => 'CMS Access'
)
);
$this->assertEquals($expected, $commentAdmin->providePermissions());
}
public function testGetEditForm() {
$commentAdmin = new CommentAdmin();
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$form = $commentAdmin->getEditForm();
$names = $this->getFormFieldNames($form);
$expected = array(
'NewComments',
'ApprovedComments',
'SpamComments'
);
$this->assertEquals($expected, $names);
if($member = Member::currentUser()) $member->logOut();
$form = $commentAdmin->getEditForm();
}
private function getFormFieldNames($form) {
$result = array();
$fields = $form->Fields();
$tab = $fields->findOrMakeTab('Root');
$fields = $tab->FieldList();
foreach ($fields as $field) {
array_push($result, $field->getName());
}
return $result;
}
}

138
tests/CommentListTest.php Normal file
View File

@ -0,0 +1,138 @@
<?php
class CommentListTest extends FunctionalTest {
public static $fixture_file = 'comments/tests/CommentsTest.yml';
protected $extraDataObjects = array(
'CommentableItem',
'CommentableItemEnabled',
'CommentableItemDisabled'
);
public function setUp() {
parent::setUp();
Config::nest();
// Set good default values
Config::inst()->update('CommentsExtension', 'comments', array(
'enabled' => true,
'enabled_cms' => false,
'require_login' => false,
'require_login_cms' => false,
'required_permission' => false,
'require_moderation_nonmembers' => false,
'require_moderation' => false,
'require_moderation_cms' => false,
'frontend_moderation' => false,
'frontend_spam' => false,
));
// Configure this dataobject
Config::inst()->update('CommentableItem', 'comments', array(
'enabled_cms' => true
));
}
public function tearDown() {
Config::unnest();
parent::tearDown();
}
public function testGetForeignClass() {
$item = $this->objFromFixture('CommentableItem', 'first');
// This is the class the Comments are related to
$this->assertEquals('CommentableItem',
$item->Comments()->getForeignClass());
}
public function testAddNonComment() {
$item = $this->objFromFixture('CommentableItem', 'first');
$comments = $item->Comments();
$this->assertEquals(4, $comments->count());
$member = Member::get()->first();
try {
$comments->add($member);
$this->fail('Should not have been able to add member to comments');
} catch (InvalidArgumentException $e) {
$this->assertEquals(
'CommentList::add() expecting a Comment object, or ID value',
$e->getMessage()
);
}
}
public function testAddComment() {
$item = $this->objFromFixture('CommentableItem', 'first');
$firstComment = $this->objFromFixture('Comment', 'firstComA');
$comments = $item->Comments();//->sort('Created');
foreach ($comments as $comment) {
error_log($comment->ID . ' ' . $comment->Created .' ' . $comment->Comment);
}
$this->assertEquals(4, $comments->count());
$newComment = new Comment();
$newComment->Name = 'Fred Bloggs';
$newComment->Comment = 'This is a test comment';
$newComment->write();
$comments->add($newComment);
// As a comment has been added, there should be 5 comments now
$this->assertEquals(5, $item->Comments()->count());
$newComment2 = new Comment();
$newComment2->Name = 'John Smith';
$newComment2->Comment = 'This is another test comment';
$newComment2->write();
// test adding the same comment by ID
$comments->add($newComment2->ID);
$this->assertEquals(6, $item->Comments()->count());
$this->setExpectedException(
'InvalidArgumentException',
"CommentList::add() can't be called until a single foreign ID is set"
);
$list = new CommentList('CommentableItem');
$list->add($newComment);
}
public function testRemoveComment() {
// remove by comment
$item = $this->objFromFixture('CommentableItem', 'first');
$this->assertEquals(4, $item->Comments()->count());
$comments = $item->Comments();
$comment = $comments->first();
$comments->remove($comment);
// now remove by ID
$comments = $item->Comments();
$comment = $comments->first();
$comments->remove($comment->ID);
$this->assertEquals(2, $item->Comments()->count());
}
public function testRemoveNonComment() {
$item = $this->objFromFixture('CommentableItem', 'first');
$this->assertEquals(4, $item->Comments()->count());
$comments = $item->Comments();
// try and remove a non comment
$member = Member::get()->first();
try {
$comments->remove($member);
$this->fail('Should not have been able to remove member from comments');
} catch (InvalidArgumentException $e) {
$this->assertEquals(
'CommentList::remove() expecting a Comment object, or ID',
$e->getMessage()
);
}
}
}

View File

@ -0,0 +1,25 @@
<?php
class CommentTestHelper {
/*
This only works if the last section is not a field group, e.g. a Comments
field group inside of a Root.Settings tab will not work
*/
public static function assertFieldsForTab($context, $tabName, $expected, $fields) {
$tab = $fields->findOrMakeTab($tabName);
$fields = $tab->FieldList();
CommentTestHelper::assertFieldNames($context, $expected, $fields);
}
public static function assertFieldNames($context, $expected, $fields) {
$actual = array();
foreach ($fields as $field) {
if (get_class($field) == 'FieldGroup') {
array_push($actual, $field->Name());
} else {
array_push($actual, $field->getName());
}
}
$context->assertEquals($expected, $actual);
}
}

View File

@ -28,8 +28,92 @@ class CommentingControllerTest extends FunctionalTest {
$this->securityEnabled = SecurityToken::is_enabled();
}
public function testApprove() {
SecurityToken::disable();
// mark a comment as spam then approve it
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->markSpam();
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/approve/' . $comment->ID;
$url = $st->addToUrl($url, Member::currentUser());
$response = $this->get($url);
$this->assertEquals(200, $response->getStatusCode());
$comment = DataObject::get_by_id('Comment', $comment->ID);
// 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
$response = $this->get('CommentingController/approve/100000');
$this->assertEquals(404, $response->getStatusCode());
}
public function testSetGetOwnerController() {
$commController = new CommentingController();
$commController->setOwnerController(Controller::curr());
$this->assertEquals(Controller::curr(), $commController->getOwnerController());
$commController->setOwnerController(null);
$this->assertNull($commController->getOwnerController());
}
public function testHam() {
SecurityToken::disable();
// mark a comment as spam then ham it
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->markSpam();
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/ham/' . $comment->ID;
$url = $st->addToUrl($url, Member::currentUser());
$response = $this->get($url);
$this->assertEquals(200, $response->getStatusCode());
$comment = DataObject::get_by_id('Comment', $comment->ID);
// 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
$response = $this->get('CommentingController/ham/100000');
$this->assertEquals(404, $response->getStatusCode());
}
public function testSpam() {
// mark a comment as approved then spam it
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->markApproved();
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/spam/' . $comment->ID;
$url = $st->addToUrl($url, Member::currentUser());
$response = $this->get($url);
$this->assertEquals(200, $response->getStatusCode());
$comment = DataObject::get_by_id('Comment', $comment->ID);
// 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
$response = $this->get('CommentingController/spam/100000');
$this->assertEquals(404, $response->getStatusCode());
}
public function testRSS() {
$item = $this->objFromFixture('CommentableItem', 'first');
// Delete the newly added children of firstComA so as not to have to recalculate values below
$this->objFromFixture('Comment', 'firstComAChild1')->delete();
$this->objFromFixture('Comment', 'firstComAChild2')->delete();
$this->objFromFixture('Comment', 'firstComAChild3')->delete();
$item = $this->objFromFixture('CommentableItem', 'first');
// comments sitewide
$response = $this->get('CommentingController/rss');
@ -55,7 +139,81 @@ class CommentingControllerTest extends FunctionalTest {
$this->assertEquals(404, $response->getStatusCode());
}
// 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');
$st = new Comment_SecurityToken($comment);
$url = 'CommentingController/reply/' . $item->ID.'?ParentCommentID=' . $comment->ID;
error_log($url);
$response = $this->get($url);
error_log(print_r($response,1));
$this->assertEquals(200, $response->getStatusCode());
}
*/
/*
public function testCommentsFormLoadMemberData() {
Config::inst()->update('CommentableItem', 'comments', array(
'use_preview' => false
));
$this->logInAs('visitor');
SecurityToken::disable();
$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);
}
*/
public function testCommentsFormUsePreview() {
// test with preview on
Config::inst()->update('CommentableItem', 'comments', array(
'use_preview' => true
));
$this->objFromFixture('Comment', 'firstComAChild1')->delete();
$this->objFromFixture('Comment', 'firstComAChild2')->delete();
$this->objFromFixture('Comment', 'firstComAChild3')->delete();
SecurityToken::disable();
$this->autoFollowRedirection = false;
$parent = $this->objFromFixture('CommentableItem', 'first');
$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);
// Turn off preview. Assert lack of preview field
Config::inst()->update('CommentableItem', 'comments', array(
'use_preview' => false
));
$form = $commController->CommentsForm();
$commentsFields = $form->Fields()->first()->FieldList();
$expected = array('Name', 'Email', 'URL', 'Comment');
CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
}
public function testCommentsForm() {
// Delete the newly added children of firstComA so as not to change this test
$this->objFromFixture('Comment', 'firstComAChild1')->delete();
$this->objFromFixture('Comment', 'firstComAChild2')->delete();
$this->objFromFixture('Comment', 'firstComAChild3')->delete();
SecurityToken::disable();
$this->autoFollowRedirection = false;
$parent = $this->objFromFixture('CommentableItem', 'first');
@ -110,5 +268,7 @@ class CommentingControllerTest extends FunctionalTest {
'BaseClass' => 'CommentableItem',
'ParentCommentID' => $parentComment->ID
)), $parentComment->ChildComments());
}
}

173
tests/CommentingTest.php Normal file
View File

@ -0,0 +1,173 @@
<?php
class CommentingTest extends SapphireTest {
public function setUpOnce() {
parent::setUpOnce();
}
public function testDeprecatedMethods() {
$methods = array('add', 'remove', 'has_commenting');
foreach ($methods as $methodName) {
try {
Commenting::$methodName('Member');
} catch (PHPUnit_Framework_Error_Deprecated $e) {
$expected = 'Using Commenting:' . $methodName .' is deprecated.'
. ' Please use the config API instead';
$this->assertEquals($expected, $e->getMessage());
}
}
}
public function test_set_config_value() {
// public static function set_config_value($class, $key, $value = false) {
Commenting::set_config_value(
'CommentableItem',
'comments_holder_id',
'commentable_item'
);
$config = Config::inst()->get(
'CommentableItem',
'comments'
);
$actual = $config['comments_holder_id'];
$this->assertEquals(
'commentable_item',
$actual
);
Commenting::set_config_value(
'all',
'comments_holder_id',
'all_items_actually_commentsextension'
);
$config = Config::inst()->get(
'CommentsExtension',
'comments'
);
$actual = $config['comments_holder_id'];
$this->assertEquals(
'all_items_actually_commentsextension',
$actual
);
}
public function test_get_config_value() {
Config::inst()->update('CommentableItem', 'comments',
array(
'comments_holder_id' => 'commentable_item'
)
);
$this->assertEquals(
'commentable_item',
Commenting::get_config_value('CommentableItem', 'comments_holder_id')
);
Config::inst()->update('CommentsExtension', 'comments',
array(
'comments_holder_id' => 'comments_extension'
)
);
// if class is null, method uses the CommentsExtension property
$this->assertEquals(
'comments_extension',
Commenting::get_config_value(null, 'comments_holder_id')
);
$this->setExpectedException(
'InvalidArgumentException',
'Member does not have commenting enabled'
);
Commenting::get_config_value('Member', 'comments_holder_id');
}
public function test_config_value_equals() {
Config::inst()->update('CommentableItem', 'comments',
array(
'comments_holder_id' => 'some_value'
)
);
$this->assertTrue(
Commenting::config_value_equals(
'CommentableItem',
'comments_holder_id',
'some_value'
)
);
$this->assertNull(
Commenting::config_value_equals(
'CommentableItem',
'comments_holder_id',
'not_some_value'
)
);
}
public function test_add() {
Commenting::add('Member', array('comments_holder_id' => 'test_add_value'));
$config = Config::inst()->get(
'Member',
'comments'
);
$actual = $config['comments_holder_id'];
$this->assertEquals(
'test_add_value',
$actual
);
Commenting::add('Member');
$config = Config::inst()->get(
'Member',
'comments'
);
$actual = $config['comments_holder_id'];
// no settings updated
$this->assertEquals(
'test_add_value',
$actual
);
$this->setExpectedException('InvalidArgumentException', "\$settings needs to be an array or null");
Commenting::add('Member', 'illegal format, not an array');
}
public function test_can_member_post() {
// logout
if($member = Member::currentUser()) $member->logOut();
Config::inst()->update('CommentableItem', 'comments',
array(
'require_login' => false
)
);
$this->assertTrue(Commenting::can_member_post('CommentableItem'));
Config::inst()->update('CommentableItem', 'comments',
array(
'require_login' => true
)
);
$this->assertFalse(Commenting::can_member_post('CommentableItem'));
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$this->assertTrue(Commenting::can_member_post('CommentableItem'));
Config::inst()->update('CommentableItem', 'comments',
array(
'require_login' => false
)
);
$this->assertTrue(Commenting::can_member_post('CommentableItem'));
}
}

View File

@ -0,0 +1,407 @@
<?php
class CommentsExtensionTest extends SapphireTest {
public static $fixture_file = 'comments/tests/CommentsTest.yml';
protected $extraDataObjects = array(
'CommentableItem',
'CommentableItemEnabled',
'CommentableItemDisabled'
);
public function setUp() {
parent::setUp();
Config::nest();
// Set good default values
Config::inst()->update('CommentsExtension', 'comments', array(
'enabled' => true,
'enabled_cms' => false,
'require_login' => false,
'require_login_cms' => false,
'required_permission' => false,
'require_moderation_nonmembers' => false,
'require_moderation' => false,
'require_moderation_cms' => false,
'frontend_moderation' => false,
'Member' => false,
));
$this->requiredExtensions = array(
'CommentableItem' => 'CommentsExtension'
);
// Configure this dataobject
Config::inst()->update('CommentableItem', 'comments', array(
'enabled_cms' => true
));
}
public function tearDown() {
Config::unnest();
parent::tearDown();
}
public function testPopulateDefaults() {
$this->markTestSkipped('TODO');
}
public function testUpdateSettingsFields() {
$this->markTestSkipped('This needs SiteTree installed');
}
public function testGetModerationRequired() {
// the 3 options take precedence in this order, executed if true
Config::inst()->update('CommentableItem', 'comments', array(
'require_moderation_cms' => true,
'require_moderation' => true,
'require_moderation_nonmembers' => true
));
// With require moderation CMS set to true, the value of the field
// 'ModerationRequired' is returned
$item = $this->objFromFixture('CommentableItem', 'first');
$item->ModerationRequired = 'None';
$this->assertEquals('None', $item->getModerationRequired());
$item->ModerationRequired = 'Required';
$this->assertEquals('Required', $item->getModerationRequired());
$item->ModerationRequired = 'NonMembersOnly';
$this->assertEquals('NonMembersOnly', $item->getModerationRequired());
Config::inst()->update('CommentableItem', 'comments', array(
'require_moderation_cms' => false,
'require_moderation' => true,
'require_moderation_nonmembers' => true
));
$this->assertEquals('Required', $item->getModerationRequired());
Config::inst()->update('CommentableItem', 'comments', array(
'require_moderation_cms' => false,
'require_moderation' => false,
'require_moderation_nonmembers' => true
));
$this->assertEquals('NonMembersOnly', $item->getModerationRequired());
Config::inst()->update('CommentableItem', 'comments', array(
'require_moderation_cms' => false,
'require_moderation' => false,
'require_moderation_nonmembers' => false
));
$this->assertEquals('None', $item->getModerationRequired());
}
public function testGetCommentsRequireLogin() {
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => true
));
// With require moderation CMS set to true, the value of the field
// 'ModerationRequired' is returned
$item = $this->objFromFixture('CommentableItem', 'first');
$item->CommentsRequireLogin = true;
$this->assertTrue($item->getCommentsRequireLogin());
$item->CommentsRequireLogin = false;
$this->assertFalse($item->getCommentsRequireLogin());
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => false,
'require_login' => false
));
$this->assertFalse($item->getCommentsRequireLogin());
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => false,
'require_login' => true
));
$this->assertTrue($item->getCommentsRequireLogin());
}
public function testAllComments() {
$this->markTestSkipped('TODO');
}
public function testAllVisibleComments() {
$this->markTestSkipped('TODO');
}
public function testComments() {
$this->markTestSkipped('TODO');
}
public function testGetCommentsEnabled() {
$this->markTestSkipped('TODO');
}
public function testGetCommentHolderID() {
$item = $this->objFromFixture('CommentableItem', 'first');
Config::inst()->update('CommentableItem', 'comments', array(
'comments_holder_id' => 'commentid_test1',
));
$this->assertEquals('commentid_test1', $item->getCommentHolderID());
Config::inst()->update('CommentableItem', 'comments', array(
'comments_holder_id' => 'commtentid_test_another',
));
$this->assertEquals('commtentid_test_another', $item->getCommentHolderID());
}
public function testGetPostingRequiredPermission() {
$this->markTestSkipped('TODO');
}
public function testCanModerateComments() {
// ensure nobody logged in
if(Member::currentUser()) { Member::currentUser()->logOut(); }
$item = $this->objFromFixture('CommentableItem', 'first');
$this->assertFalse($item->canModerateComments());
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$this->assertTrue($item->canModerateComments());
}
public function testGetCommentRSSLink() {
$item = $this->objFromFixture('CommentableItem', 'first');
$link = $item->getCommentRSSLink();
$this->assertEquals('/CommentingController/rss', $link);
}
public function testGetCommentRSSLinkPage() {
$item = $this->objFromFixture('CommentableItem', 'first');
$page = $item->getCommentRSSLinkPage();
$this->assertEquals(
'/CommentingController/rss/CommentableItem/' . $item->ID,
$page
);
}
public function testCommentsForm() {
Config::inst()->update('CommentableItem', 'comments', array(
'include_js' => false
)
);
$item = $this->objFromFixture('CommentableItem', 'first');
// The comments form is HTML to do assertions by contains
$cf = $item->CommentsForm();
$expected = '<form id="Form_CommentsForm" action="/CommentingController'
. '/CommentsForm" method="post" enctype="application/x-www-form-urlenco'
. 'ded">';
$this->assertContains($expected, $cf);
$this->assertContains('<h4>Post your comment</h4>', $cf);
// check the comments form exists
$expected = '<input type="text" name="Name" value="ADMIN User" class="text" id="Form_CommentsForm_Name" required="required"';
$this->assertContains($expected, $cf);
$expected = '<input type="email" name="Email" value="ADMIN@example.org" class="email text" id="Form_CommentsForm_Email"';
$this->assertContains($expected, $cf);
$expected = '<input type="text" name="URL" class="text" id="Form_CommentsForm_URL" data-msg-url="Please enter a valid URL"';
$this->assertContains($expected, $cf);
$expected = '<input type="hidden" name="ParentID" value="' . $item->ID . '" class="hidden" id="Form_CommentsForm_ParentID" />';
$this->assertContains($expected, $cf);
$expected = '<textarea name="Comment" class="textarea" id="Form_CommentsForm_Comment" required="required"';
$this->assertContains($expected, $cf);
$expected = '<input type="submit" name="action_doPostComment" value="Post" class="action" id="Form_CommentsForm_action_doPostComment"';
$this->assertContains($expected, $cf);
$expected = '<a href="/CommentingController/spam/';
$this->assertContains($expected, $cf);
$expected = '<p>Reply to firstComA 1</p>';
$this->assertContains($expected, $cf);
$expected = '<a href="/CommentingController/delete';
$this->assertContains($expected, $cf);
$expected = '<p>Reply to firstComA 2</p>';
$this->assertContains($expected, $cf);
$expected = '<p>Reply to firstComA 3</p>';
$this->assertContains($expected, $cf);
// Check for JS inclusion
$backend = Requirements::backend();
$this->assertEquals(
array(),
$backend->get_javascript()
);
Config::inst()->update('CommentableItem', 'comments', array(
'include_js' => true
)
);
$cf = $item->CommentsForm();
$backend = Requirements::backend();
$this->assertEquals(
array(
'framework/thirdparty/jquery/jquery.js',
'framework/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js',
'framework/thirdparty/jquery-validate/lib/jquery.form.js',
'comments/thirdparty/jquery-validate/jquery.validate.min.js',
'comments/javascript/CommentsInterface.js'
),
$backend->get_javascript()
);
}
public function testAttachedToSiteTree() {
$this->markTestSkipped('TODO');
}
public function testPagedComments() {
$item = $this->objFromFixture('CommentableItem', 'first');
// Ensure Created times are set, as order not guaranteed if all set to 0
$comments = $item->PagedComments()->sort('ID');
$ctr = 0;
$timeBase = time()-10000;
foreach ($comments as $comment) {
$comment->Created = $timeBase + $ctr * 1000;
$comment->write();
$ctr++;
}
$results = $item->PagedComments()->toArray();
foreach ($results as $result) {
$result->sourceQueryParams = null;
}
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComA')->Comment,
$results[3]->Comment
);
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComAChild1')->Comment,
$results[2]->Comment
);
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComAChild2')->Comment,
$results[1]->Comment
);
$this->assertEquals(
$this->objFromFixture('Comment', 'firstComAChild3')->Comment,
$results[0]->Comment
);
$this->assertEquals(4, sizeof($results));
}
public function testGetCommentsOption() {
$this->markTestSkipped('TODO');
}
public function testUpdateModerationFields() {
$this->markTestSkipped('TODO');
}
public function testUpdateCMSFields() {
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => false
)
);
$this->logInWithPermission('ADMIN');
$item = $this->objFromFixture('CommentableItem', 'first');
$item->ProvideComments = true;
$item->write();
$fields = $item->getCMSFields();
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments',
array('CommentsNewCommentsTab', 'CommentsCommentsTab', 'CommentsSpamCommentsTab'),
$fields
);
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments.CommentsNewCommentsTab',
array('NewComments'),
$fields
);
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments.CommentsCommentsTab',
array('ApprovedComments'),
$fields
);
CommentTestHelper::assertFieldsForTab($this, 'Root.Comments.CommentsSpamCommentsTab',
array('SpamComments'),
$fields
);
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => true
)
);
$fields = $item->getCMSFields();
CommentTestHelper::assertFieldsForTab($this, 'Root.Settings', array('Comments'), $fields);
$settingsTab = $fields->findOrMakeTab('Root.Settings');
$settingsChildren = $settingsTab->getChildren();
$this->assertEquals(1, $settingsChildren->count());
$fieldGroup = $settingsChildren->first();
$fields = $fieldGroup->getChildren();
CommentTestHelper::assertFieldNames(
$this,
array('ProvideComments', 'CommentsRequireLogin'),
$fields
);
Config::inst()->update('CommentableItem', 'comments', array(
'require_login_cms' => true,
'require_moderation_cms' => true
)
);
$fields = $item->getCMSFields();
CommentTestHelper::assertFieldsForTab(
$this,
'Root.Settings',
array('Comments', 'ModerationRequired'), $fields
);
$settingsTab = $fields->findOrMakeTab('Root.Settings');
$settingsChildren = $settingsTab->getChildren();
$this->assertEquals(2, $settingsChildren->count());
$fieldGroup = $settingsChildren->first();
$fields = $fieldGroup->getChildren();
CommentTestHelper::assertFieldNames(
$this,
array('ProvideComments', 'CommentsRequireLogin'),
$fields
);
}
public function testDeprecatedMethods() {
$item = $this->objFromFixture('CommentableItem', 'first');
$methodNames = array(
'getRssLinkPage',
'getRssLink',
'PageComments',
'getPostingRequiresPermission',
'canPost',
'getCommentsConfigured'
);
foreach ($methodNames as $methodName) {
try {
$item->$methodName();
$this->fail('Method ' . $methodName .' should be depracated');
} catch (PHPUnit_Framework_Error_Deprecated $e) {
$expected = 'CommentsExtension->' . $methodName . ' is '.
'deprecated.';
$this->assertStringStartsWith($expected, $e->getMessage());
}
}
// ooh, $this->setExpectedException('ExpectedException', 'Expected Message');
}
}

View File

@ -0,0 +1,133 @@
<?php
class CommentsGridFieldActionTest extends SapphireTest {
/** @var ArrayList */
protected $list;
/** @var GridField */
protected $gridField;
/** @var Form */
protected $form;
public function setUp() {
parent::setUp();
$this->list = new DataList('GridFieldAction_Delete_Team');
$config = CommentsGridFieldConfig::create()->addComponent(new GridFieldDeleteAction());
$this->gridField = new CommentsGridField('testfield', 'testfield', $this->list, $config);
$this->form = new Form(new Controller(), 'mockform', new FieldList(array($this->gridField)), new FieldList());
}
public function testAugmentColumns() {
$action = new CommentsGridFieldAction();
// an entry called 'Actions' is added to the columns array
$columns = array();
$action->augmentColumns($this->gridField, $columns);
$expected = array('Actions');
$this->assertEquals($expected, $columns);
$columns = array('Actions');
$action->augmentColumns($this->gridField, $columns);
$expected = array('Actions');
$this->assertEquals($expected, $columns);
}
public function testGetColumnAttributes() {
$action = new CommentsGridFieldAction();
$record = new Comment();
$attrs = $action->getColumnAttributes($this->gridField, $record, 'Comment');
$this->assertEquals(array('class' => 'col-buttons'), $attrs);
}
public function testGetColumnMetadata() {
$action = new CommentsGridFieldAction();
$result = $action->getColumnMetadata($this->gridField, 'Actions');
$this->assertEquals(array('title' => ''), $result);
$result = $action->getColumnMetadata($this->gridField, 'SomethingElse');
$this->assertNull($result);
}
public function testGetColumnsHandled() {
$action = new CommentsGridFieldAction();
$result = $action->getColumnsHandled($this->gridField);
$this->assertEquals(array('Actions'), $result);
}
public function testGetColumnContent() {
$this->logInWithPermission('CMS_ACCESS_CommentAdmin');
$action = new CommentsGridFieldAction();
$record = new Comment();
$record->Name = 'Name of commeter';
$record->Comment = 'This is a comment';
$record->write();
$recordID = $record->ID;
$html = $action->getColumnContent($this->gridField, $record, 'Comment');
$this->assertContains('data-url="Controller/mockform/field/testfield',
$html);
$spamAction = 'value="Spam" class="action" id="action_CustomAction' .
$recordID . 'Spam"';
$this->assertContains($spamAction, $html);
$approveAction = 'value="Approve" class="action" id="action_CustomAction' .
$recordID . 'Approve"';
$this->assertContains($approveAction, $html);
// If marked as spam, only the approve button should be available
$record->markSpam();
$record->write();
$html = $action->getColumnContent($this->gridField, $record, 'Comment');
$this->assertContains($approveAction, $html);
$this->assertNotContains($spamAction, $html);
// If marked as spam, only the approve button should be available
$record->markApproved();
$record->write();
$html = $action->getColumnContent($this->gridField, $record, 'Comment');
$this->assertNotContains($approveAction, $html);
$this->assertContains($spamAction, $html);
}
public function testGetActions() {
$action = new CommentsGridFieldAction();
$result = $action->getActions($this->gridField);
$this->assertEquals(array('spam', 'approve'), $result);
}
public function testHandleAction() {
$action = new CommentsGridFieldAction();
$record = new Comment();
$record->Name = 'Name of commeter';
$record->Comment = 'This is a comment';
$record->write();
$recordID = $record->ID;
$arguments = array('RecordID' => $recordID);
$data = array();
$result = $action->handleAction($this->gridField, 'spam', $arguments, $data );
$this->assertEquals(200, Controller::curr()->getResponse()->getStatusCode());
$this->assertEquals(
'Comment marked as spam.',
Controller::curr()->getResponse()->getStatusDescription()
);
$record = DataObject::get_by_id('Comment', $recordID);
$this->assertEquals(1, $record->Moderated);
$this->assertEquals(1, $record->IsSpam);
//getStatusDescription
$result = $action->handleAction($this->gridField, 'approve', $arguments, $data );
$this->assertEquals(200, Controller::curr()->getResponse()->getStatusCode());
$this->assertEquals(
'Comment approved.',
Controller::curr()->getResponse()->getStatusDescription()
);
$record = DataObject::get_by_id('Comment', $recordID);
$this->assertEquals(1, $record->Moderated);
$this->assertEquals(0, $record->IsSpam);
error_log(Controller::curr()->getResponse()->getStatusCode());
}
}

View File

@ -0,0 +1,12 @@
<?php
class CommentsGridFieldBulkActionTest extends SapphireTest {
public function testSpam() {
$this->markTestSkipped('TODO');
}
public function testApprove() {
$this->markTestSkipped('TODO');
}
}

View File

@ -0,0 +1,9 @@
<?php
class CommentsGridFieldConfigTest extends SapphireTest {
public function test__construct() {
$config = new CommentsGridFieldConfigTest();
$this->markTestSkipped('TODO');
}
}

View File

@ -0,0 +1,40 @@
<?php
class CommentsGridFieldTest extends SapphireTest {
public function testNewRow() {
$gridfield = new CommentsGridField('testfield', 'testfield');
// protected function newRow($total, $index, $record, $attributes, $content) {
$comment = new Comment();
$comment->Name = 'Fred Bloggs';
$comment->Comment = 'This is a comment';
$attr = array();
try {
$class = new ReflectionClass($gridfield);
$method = $class->getMethod('newRow');
$method->setAccessible(true);
}
catch (ReflectionException $e) {
$this->fail($e->getMessage());
}
$params = array(1, 1, $comment, $attr, $comment->Comment);
$newRow = $method->invokeArgs($gridfield, $params);
$this->assertEquals('<tr>This is a comment</tr>', $newRow);
$attr = array('class' => 'cssClass');
$params = array(1, 1, $comment, $attr, $comment->Comment);
$newRow = $method->invokeArgs($gridfield, $params);
$this->assertEquals('<tr class="cssClass">This is a comment</tr>', $newRow);
$comment->markSpam();
$params = array(1, 1, $comment, $attr, $comment->Comment);
$newRow = $method->invokeArgs($gridfield, $params);
$this->assertEquals('<tr class="cssClass spam">This is a comment</tr>', $newRow);
}
}

View File

@ -214,48 +214,6 @@ class CommentsTest extends FunctionalTest {
$this->assertTrue($item2->canPostComment());
}
public function testCanView() {
$visitor = $this->objFromFixture('Member', 'visitor');
$admin = $this->objFromFixture('Member', 'commentadmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertTrue($comment->canView($visitor),
'Unauthenticated members can view comments associated to a object with ProvideComments=1'
);
$this->assertTrue($comment->canView($admin),
'Admins with CMS_ACCESS_CommentAdmin permissions can view comments associated to a page with ProvideComments=1'
);
$disabledComment = $this->objFromFixture('Comment', 'disabledCom');
$this->assertFalse($disabledComment->canView($visitor),
'Unauthenticated members can not view comments associated to a object with ProvideComments=0'
);
$this->assertTrue($disabledComment->canView($admin),
'Admins with CMS_ACCESS_CommentAdmin permissions can view comments associated to a page with ProvideComments=0'
);
}
public function testCanEdit() {
$visitor = $this->objFromFixture('Member', 'visitor');
$admin = $this->objFromFixture('Member', 'commentadmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertFalse($comment->canEdit($visitor));
$this->assertTrue($comment->canEdit($admin));
}
public function testCanDelete() {
$visitor = $this->objFromFixture('Member', 'visitor');
$admin = $this->objFromFixture('Member', 'commentadmin');
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertFalse($comment->canEdit($visitor));
$this->assertTrue($comment->canEdit($admin));
}
public function testDeleteComment() {
// Test anonymous user
if($member = Member::currentUser()) $member->logOut();
@ -445,10 +403,15 @@ class CommentsTest extends FunctionalTest {
return;
}
$origAllowed = Commenting::get_config_value('CommentableItem','html_allowed');
// Add p for paragraph
// NOTE: The config method appears to append to the existing array
Config::inst()->update('CommentableItem', 'comments', array(
'html_allowed_elements' => array('p'),
));
// Without HTML allowed
$comment1 = new Comment();
$comment1->AllowHtml = false;
$comment1->BaseClass = 'CommentableItem';
$comment1->Comment = '<p><script>alert("w00t")</script>my comment</p>';
$comment1->write();
@ -460,8 +423,8 @@ class CommentsTest extends FunctionalTest {
);
// With HTML allowed
Commenting::set_config_value('CommentableItem','html_allowed', true);
$comment2 = new Comment();
$comment2->AllowHtml = true;
$comment2->BaseClass = 'CommentableItem';
$comment2->Comment = '<p><script>alert("w00t")</script>my comment</p>';
$comment2->write();
@ -470,8 +433,6 @@ class CommentsTest extends FunctionalTest {
$comment2->Comment,
'Removes HTML tags which are not on the whitelist'
);
Commenting::set_config_value('CommentableItem','html_allowed', $origAllowed);
}
public function testDefaultTemplateRendersHtmlWithAllowHtml() {
@ -479,13 +440,17 @@ class CommentsTest extends FunctionalTest {
$this->markTestSkipped('HTMLPurifier class not found');
}
$origAllowed = Commenting::get_config_value('CommentableItem', 'html_allowed');
Config::inst()->update('CommentableItem', 'comments', array(
'html_allowed_elements' => array('p'),
));
$item = new CommentableItem();
$item->write();
// Without HTML allowed
$comment = new Comment();
$comment->Comment = '<p>my comment</p>';
$comment->AllowHtml = false;
$comment->ParentID = $item->ID;
$comment->BaseClass = 'CommentableItem';
$comment->write();
@ -496,14 +461,14 @@ class CommentsTest extends FunctionalTest {
$html
);
Commenting::set_config_value('CommentableItem','html_allowed', true);
$comment->AllowHtml = true;
$comment->write();
$html = $item->customise(array('CommentsEnabled' => true))->renderWith('CommentsInterface');
$this->assertContains(
'<p>my comment</p>',
$html
);
Commenting::set_config_value('CommentableItem','html_allowed', $origAllowed);
}
@ -559,6 +524,666 @@ class CommentsTest extends FunctionalTest {
$this->assertFalse((bool)$obj->CommentsRequireLogin);
}
/*
When a parent comment is deleted, remove the children
*/
public function testOnBeforeDelete() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$child = new Comment();
$child->Name = 'Fred Bloggs';
$child->Comment = 'Child of firstComA';
$child->write();
$comment->ChildComments()->add($child);
$this->assertEquals(4, $comment->ChildComments()->count());
$commentID = $comment->ID;
$childCommentID = $child->ID;
$comment->delete();
// assert that the new child been deleted
$this->assertFalse(DataObject::get_by_id('Comment', $commentID));
$this->assertFalse(DataObject::get_by_id('Comment', $childCommentID));
}
public function testRequireDefaultRecords() {
$this->markTestSkipped('TODO');
}
public function testLink() {
$comment = $this->objFromFixture('Comment', 'thirdComD');
$this->assertEquals('CommentableItem_Controller#comment-'.$comment->ID,
$comment->Link());
$this->assertEquals($comment->ID, $comment->ID);
// An orphan comment has no link
$comment->ParentID = 0;
$comment->write();
$this->assertEquals('', $comment->Link());
}
public function testPermalink() {
$comment = $this->objFromFixture('Comment', 'thirdComD');
$this->assertEquals('comment-' . $comment->ID, $comment->Permalink());
}
/*
Test field labels in 2 languages
*/
public function testFieldLabels() {
$locale = i18n::get_locale();
i18n::set_locale('fr');
$comment = $this->objFromFixture('Comment', 'firstComA');
$labels = $comment->FieldLabels();
$expected = array(
'Name' => 'Nom de l\'Auteur',
'Comment' => 'Commentaire',
'Email' => 'Email',
'URL' => 'URL',
'BaseClass' => 'Base Class',
'Moderated' => 'Modéré?',
'IsSpam' => 'Spam?',
'ParentID' => 'Parent ID',
'AllowHtml' => 'Allow Html',
'SecretToken' => 'Secret Token',
'Depth' => 'Depth',
'Author' => 'Author Member',
'ParentComment' => 'Parent Comment',
'ChildComments' => 'Child Comments',
'ParentTitle' => 'Parent',
'Created' => 'Date de publication'
);
i18n::set_locale($locale);
$this->assertEquals($expected, $labels);
$labels = $comment->FieldLabels();
$expected = array(
'Name' => 'Author Name',
'Comment' => 'Comment',
'Email' => 'Email',
'URL' => 'URL',
'BaseClass' => 'Base Class',
'Moderated' => 'Moderated?',
'IsSpam' => 'Spam?',
'ParentID' => 'Parent ID',
'AllowHtml' => 'Allow Html',
'SecretToken' => 'Secret Token',
'Depth' => 'Depth',
'Author' => 'Author Member',
'ParentComment' => 'Parent Comment',
'ChildComments' => 'Child Comments',
'ParentTitle' => 'Parent',
'Created' => 'Date posted'
);
$this->assertEquals($expected, $labels);
}
public function testGetOption() {
$this->markTestSkipped('TODO');
}
public function testGetParent() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$item = $this->objFromFixture('CommentableItem', 'first');
$parent = $comment->getParent();
$this->assertEquals($item, $parent);
}
public function testGetParentTitle() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$title = $comment->getParentTitle();
$this->assertEquals('First', $title);
// Title from a comment with no parent is blank
$comment->ParentID = 0;
$comment->write();
$this->assertEquals('', $comment->getParentTitle());
}
public function testGetParentClassName() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$className = $comment->getParentClassName();
$this->assertEquals('CommentableItem', $className);
}
public function testCastingHelper() {
$this->markTestSkipped('TODO');
}
public function testGetEscapedComment() {
$this->markTestSkipped('TODO');
}
public function testIsPreview() {
$comment = new Comment();
$comment->Name = 'Fred Bloggs';
$comment->Comment = 'this is a test comment';
$this->assertTrue($comment->isPreview());
$comment->write();
$this->assertFalse($comment->isPreview());
}
public function testCanCreate() {
$comment = $this->objFromFixture('Comment', 'firstComA');
// admin can create - this is always false
$this->logInAs('commentadmin');
$this->assertFalse($comment->canCreate());
// visitor can view
$this->logInAs('visitor');
$this->assertFalse($comment->canCreate());
}
public function testCanView() {
$comment = $this->objFromFixture('Comment', 'firstComA');
// admin can view
$this->logInAs('commentadmin');
$this->assertTrue($comment->canView());
// visitor can view
$this->logInAs('visitor');
$this->assertTrue($comment->canView());
$comment->ParentID = 0;
$comment->write();
$this->assertFalse($comment->canView());
}
public function testCanEdit() {
$comment = $this->objFromFixture('Comment', 'firstComA');
// admin can edit
$this->logInAs('commentadmin');
$this->assertTrue($comment->canEdit());
// visitor cannot
$this->logInAs('visitor');
$this->assertFalse($comment->canEdit());
$comment->ParentID = 0;
$comment->write();
$this->assertFalse($comment->canEdit());
}
public function testCanDelete() {
$comment = $this->objFromFixture('Comment', 'firstComA');
// admin can delete
$this->logInAs('commentadmin');
$this->assertTrue($comment->canDelete());
// visitor cannot
$this->logInAs('visitor');
$this->assertFalse($comment->canDelete());
$comment->ParentID = 0;
$comment->write();
$this->assertFalse($comment->canDelete());
}
public function testGetMember() {
$this->logInAs('visitor');
$current = Member::currentUser();
$comment = $this->objFromFixture('Comment', 'firstComA');
$method = $this->getMethod('getMember');
// null case
$member = $method->invokeArgs($comment, array());
$this->assertEquals($current, $member);
// numeric ID case
$member = $method->invokeArgs($comment, array($current->ID));
$this->assertEquals($current, $member);
// identity case
$member = $method->invokeArgs($comment, array($current));
$this->assertEquals($current, $member);
}
public function testGetAuthorName() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertEquals(
'FA',
$comment->getAuthorName()
);
$comment->Name = '';
$this->assertEquals(
'',
$comment->getAuthorName()
);
$author = $this->objFromFixture('Member', 'visitor');
$comment->AuthorID = $author->ID;
$comment->write();
$this->assertEquals(
'visitor',
$comment->getAuthorName()
);
// null the names, expect null back
$comment->Name = null;
$comment->AuthorID = 0;
$this->assertNull($comment->getAuthorName());
}
public function testLinks() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->logInAs('commentadmin');
$method = $this->getMethod('ActionLink');
// test with starts of strings and tokens and salts change each time
$this->assertStringStartsWith(
'/CommentingController/theaction/'.$comment->ID,
$method->invokeArgs($comment, array('theaction'))
);
$this->assertStringStartsWith(
'/CommentingController/delete/'.$comment->ID,
$comment->DeleteLink()
);
$this->assertStringStartsWith(
'/CommentingController/spam/'.$comment->ID,
$comment->SpamLink()
);
$comment->markSpam();
$this->assertStringStartsWith(
'/CommentingController/ham/'.$comment->ID,
$comment->HamLink()
);
//markApproved
$comment->markUnapproved();
$this->assertStringStartsWith(
'/CommentingController/approve/'.$comment->ID,
$comment->ApproveLink()
);
}
public function testMarkSpam() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->markSpam();
$this->assertTrue($comment->Moderated);
$this->assertTrue($comment->IsSpam);
}
public function testMarkApproved() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->markApproved();
$this->assertTrue($comment->Moderated);
$this->assertFalse($comment->IsSpam);
}
public function testMarkUnapproved() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->markApproved();
$this->assertTrue($comment->Moderated);
}
public function testSpamClass() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertEquals('notspam', $comment->spamClass());
$comment->Moderated = false;
$this->assertEquals('unmoderated', $comment->spamClass());
$comment->IsSpam = true;
$this->assertEquals('spam', $comment->spamClass());
}
public function testGetTitle() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertEquals(
'Comment by FA on First',
$comment->getTitle()
);
}
public function testGetCMSFields() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$fields = $comment->getCMSFields();
$names = array();
foreach ($fields as $field) {
$names[] = $field->getName();
}
$expected = array(
'Created',
'Name',
'Comment',
'Email',
'URL',
null #FIXME this is suspicious
);
$this->assertEquals($expected, $names);
}
public function testGetCMSFieldsCommentHasAuthor() {
$member = Member::get()->filter('FirstName', 'visitor')->first();
$comment = $this->objFromFixture('Comment', 'firstComA');
$comment->AuthorID = $member->ID;
$comment->write();
$fields = $comment->getCMSFields();
$names = array();
foreach ($fields as $field) {
$names[] = $field->getName();
}
$expected = array(
'Created',
'Name',
'AuthorMember',
'Comment',
'Email',
'URL',
null #FIXME this is suspicious
);
$this->assertEquals($expected, $names);
}
public function testGetCMSFieldsWithParentComment() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$child = new Comment();
$child->Name = 'John Smith';
$child->Comment = 'This is yet another test commnent';
$child->ParentCommentID = $comment->ID;
$child->write();
$fields = $child->getCMSFields();
$names = array();
foreach ($fields as $field) {
$names[] = $field->getName();
}
$expected = array(
'Created',
'Name',
'Comment',
'Email',
'URL',
null, #FIXME this is suspicious
'ParentComment_Title',
'ParentComment_Created',
'ParentComment_AuthorName',
'ParentComment_EscapedComment'
);
$this->assertEquals($expected, $names);
}
public function testPurifyHtml() {
$comment = $this->objFromFixture('Comment', 'firstComA');
$dirtyHTML = '<p><script>alert("w00t")</script>my comment</p>';
$this->assertEquals(
'my comment',
$comment->purifyHtml($dirtyHTML)
);
}
public function testGravatar() {
// Turn gravatars on
Config::inst()->update('CommentableItem', 'comments', array(
'use_gravatar' => true
));
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertEquals(
'http://www.gravatar.com/avatar/d41d8cd98f00b204e9800998ecf8427e?s'.
'=80&d=identicon&r=g',
$comment->gravatar()
);
// Turn gravatars off
Config::inst()->update('CommentableItem', 'comments', array(
'use_gravatar' => false
));
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertEquals(
'',
$comment->gravatar()
);
}
public function testGetRepliesEnabled() {
$comment = $this->objFromFixture('Comment', 'firstComA');
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
$this->assertFalse($comment->getRepliesEnabled());
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => true,
'nested_depth' => 4
));
$this->assertTrue($comment->getRepliesEnabled());
$comment->Depth = 4;
$this->assertFalse($comment->getRepliesEnabled());
}
public function testAllReplies() {
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => true,
'nested_depth' => 4
));
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertEquals(
3,
$comment->allReplies()->count()
);
$child = new Comment();
$child->Name = 'Fred Smith';
$child->Comment = 'This is a child comment';
$child->ParentCommentID = $comment->ID;
// spam should be returned by this method
$child->markSpam();
$child->write();
$replies = $comment->allReplies();
$this->assertEquals(
4,
$comment->allReplies()->count()
);
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
$this->assertEquals(0, $comment->allReplies()->count());
}
public function testReplies() {
CommentableItem::add_extension('CommentsExtension');
$this->logInWithPermission('ADMIN');
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => true,
'nested_depth' => 4
));
$comment = $this->objFromFixture('Comment', 'firstComA');
$this->assertEquals(
3,
$comment->Replies()->count()
);
// Test that spam comments are not returned
$childComment = $comment->Replies()->first();
$childComment->IsSpam = 1;
$childComment->write();
$this->assertEquals(
2,
$comment->Replies()->count()
);
// Test that unmoderated comments are not returned
//
$childComment = $comment->Replies()->first();
// FIXME - moderation settings scenarios need checked here
$childComment->Moderated = 0;
$childComment->IsSpam = 0;
$childComment->write();
$this->assertEquals(
2,
$comment->Replies()->count()
);
// Test moderation required on the front end
$item = $this->objFromFixture('CommentableItem', 'first');
$item->ModerationRequired = 'Required';
$item->write();
Config::inst()->update('CommentableItemDisabled', 'comments', array(
'nested_comments' => true,
'nested_depth' => 4,
'frontend_moderation' => true
));
$comment = DataObject::get_by_id('Comment', $comment->ID);
$this->assertEquals(
2,
$comment->Replies()->count()
);
// Turn off nesting, empty array should be returned
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
$this->assertEquals(
0,
$comment->Replies()->count()
);
CommentableItem::remove_extension('CommentsExtension');
}
public function testPagedReplies() {
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => true,
'nested_depth' => 4,
'comments_per_page' => 2 #Force 2nd page for 3 items
));
$comment = $this->objFromFixture('Comment', 'firstComA');
$pagedList = $comment->pagedReplies();
$this->assertEquals(
2,
$pagedList->TotalPages()
);
$this->assertEquals(
3,
$pagedList->getTotalItems()
);
//TODO - 2nd page requires controller
//
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false
));
$this->assertEquals(0, $comment->PagedReplies()->count());
}
public function testReplyForm() {
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => false,
'nested_depth' => 4
));
$comment = $this->objFromFixture('Comment', 'firstComA');
// No nesting, no reply form
$form = $comment->replyForm();
$this->assertNull($form);
// parent item so show form
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => true,
'nested_depth' => 4
));
$form = $comment->replyForm();
$names = array();
foreach ($form->Fields() as $field) {
array_push($names, $field->getName());
}
$this->assertEquals(
array(
null, #FIXME suspicious
'ParentID',
'ReturnURL',
'ParentCommentID',
'BaseClass'
),
$names
);
// no parent, no reply form
$comment->ParentID = 0;
$comment->write();
$form = $comment->replyForm();
$this->assertNull($form);
}
public function testUpdateDepth() {
Config::inst()->update('CommentableItem', 'comments', array(
'nested_comments' => true,
'nested_depth' => 4
));
$comment = $this->objFromFixture('Comment', 'firstComA');
$children = $comment->allReplies()->toArray();
// Make the second child a child of the first
// Make the third child a child of the second
$reply1 = $children[0];
$reply2 = $children[1];
$reply3 = $children[2];
$reply2->ParentCommentID = $reply1->ID;
$reply2->write();
$this->assertEquals(3, $reply2->Depth);
$reply3->ParentCommentID = $reply2->ID;
$reply3->write();
$this->assertEquals(4, $reply3->Depth);
}
public function testGetToken() {
$this->markTestSkipped('TODO');
}
public function testMemberSalt() {
$this->markTestSkipped('TODO');
}
public function testAddToUrl() {
$this->markTestSkipped('TODO');
}
public function testCheckRequest() {
$this->markTestSkipped('TODO');
}
public function testGenerate() {
$this->markTestSkipped('TODO');
}
protected static function getMethod($name) {
$class = new ReflectionClass('Comment');
$method = $class->getMethod($name);
$method->setAccessible(true);
return $method;
}
}
@ -581,8 +1206,18 @@ class CommentableItem extends DataObject implements TestOnly {
}
public function canView($member = null) {
return true;
}
return true;
}
// This is needed for canModerateComments
public function canEdit($member = null) {
if($member instanceof Member) $memberID = $member->ID;
else if(is_numeric($member)) $memberID = $member;
else $memberID = Member::currentUserID();
if($memberID && Permission::checkMember($memberID, array("ADMIN", "CMS_ACCESS_CommentAdmin"))) return true;
return false;
}
public function Link() {
return $this->RelativeLink();

View File

@ -43,7 +43,35 @@ Comment:
Comment: textFA
BaseClass: CommentableItem
Moderated: 1
IsSpam:
Depth: 1
firstComAChild1:
ParentID: =>CommentableItem.first
ParentCommentID: =>Comment.firstComA
Name: John Smith
Comment: Reply to firstComA 1
BaseClass: CommentableItem
Moderated: 1
IsSpam: 0
Depth: 2
firstComAChild2:
ParentID: =>CommentableItem.first
ParentCommentID: =>Comment.firstComA
Name: John Smith
Comment: Reply to firstComA 2
BaseClass: CommentableItem
Moderated: 1
IsSpam: 0
Depth: 2
firstComAChild3:
ParentID: =>CommentableItem.first
ParentCommentID: =>Comment.firstComA
Name: John Smith
Comment: Reply to firstComA 3
BaseClass: CommentableItem
Moderated: 1
IsSpam: 0
Depth: 2
secondComA:
ParentID: =>CommentableItem.second
Name: SA