CommentingControllerTest   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 310
Duplicated Lines 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
eloc 153
c 2
b 1
f 0
dl 0
loc 310
rs 10
wmc 13

11 Methods

Rating   Name   Duplication   Size   Complexity  
A tearDown() 0 8 2
A testCommentsFormUsePreview() 0 31 1
A testSetGetOwnerController() 0 7 1
A testApproveUnmoderatedComment() 0 21 1
A testHam() 0 22 1
A testSpam() 0 20 1
A testCommentsForm() 0 70 1
A testEncodeClassName() 0 4 1
A testDecodeClassName() 0 4 1
A setUp() 0 12 2
A testRSS() 0 32 1
1
<?php
2
3
namespace SilverStripe\Comments\Tests;
4
5
use SilverStripe\Akismet\AkismetSpamProtector;
0 ignored issues
show
Bug introduced by
The type SilverStripe\Akismet\AkismetSpamProtector was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
use SilverStripe\Comments\Controllers\CommentingController;
7
use SilverStripe\Comments\Model\Comment;
8
use SilverStripe\Comments\Model\Comment\SecurityToken as CommentSecurityToken;
9
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
10
use SilverStripe\Control\Controller;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Core\Injector\Injector;
13
use SilverStripe\Dev\FunctionalTest;
14
use SilverStripe\ORM\DataObject;
15
use SilverStripe\Security\Member;
16
use SilverStripe\Security\SecurityToken;
17
18
class CommentingControllerTest extends FunctionalTest
19
{
20
    /**
21
     * {@inheritDoc}
22
     */
23
    protected static $fixture_file = 'CommentsTest.yml';
24
25
    /**
26
     * {@inheritDoc}
27
     */
28
    protected static $extra_dataobjects = [
29
        CommentableItem::class
30
    ];
31
32
    protected $securityEnabled;
33
34
    protected function tearDown()
35
    {
36
        if ($this->securityEnabled) {
37
            SecurityToken::inst()->enable();
38
        } else {
39
            SecurityToken::inst()->disable();
40
        }
41
        parent::tearDown();
42
    }
43
44
    protected function setUp()
45
    {
46
        parent::setUp();
47
        $this->securityEnabled = SecurityToken::inst()->is_enabled();
48
49
        // We will assert against explicit responses, unless handed otherwise in a test for redirects
50
        $this->autoFollowRedirection = false;
51
52
        // Mock Akismet if it's installed
53
        if (class_exists(AkismetSpamProtector::class)) {
54
            $akismetMock = $this->createMock(AkismetSpamProtector::class);
55
            Injector::inst()->registerService($akismetMock, AkismetSpamProtector::class);
56
        }
57
    }
58
59
    public function testCommentsFormUsePreview()
60
    {
61
        $parent = $this->objFromFixture(CommentableItem::class, 'first');
62
        $commController = new CommentingController();
63
        $commController->setOwnerRecord($parent);
64
        $form = $commController->CommentsForm();
65
66
        $commentsFields = $form->Fields()->first()->FieldList();
67
        $expected = array('Name', 'Email', 'URL', 'Comment');
68
        CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
69
70
        // test with preview on
71
        Config::modify()->merge(CommentableItem::class, 'comments', array(
72
            'use_preview' => true
73
        ));
74
75
        $parent = $this->objFromFixture(CommentableItem::class, 'first');
76
        $commController = new CommentingController();
77
        $commController->setOwnerRecord($parent);
78
79
        $this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
80
        $this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
81
        $this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
82
83
        SecurityToken::inst()->disable();
84
        $this->autoFollowRedirection = false;
85
86
        $form = $commController->CommentsForm();
87
        $commentsFields = $form->Fields()->first()->FieldList();
88
        $expected = array('Name', 'Email', 'URL', 'Comment', 'PreviewComment');
89
        CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
90
    }
91
92
    public function testApproveUnmoderatedComment()
93
    {
94
        SecurityToken::inst()->disable();
95
96
        // mark a comment as spam then approve it
97
        $this->logInWithPermission('CMS_ACCESS_CommentAdmin');
98
        $comment = $this->objFromFixture(Comment::class, 'testModeratedComment1');
99
        $st = new CommentSecurityToken($comment);
100
        $url = 'comments/approve/' . $comment->ID;
101
        $url = $st->addToUrl($url, Member::currentUser());
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Security\Member::currentUser() has been deprecated: 5.0.0 use Security::getCurrentUser() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

101
        $url = $st->addToUrl($url, /** @scrutinizer ignore-deprecated */ Member::currentUser());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
102
        $response = $this->get($url, null, ['Referer' => '/']);
103
        $this->assertEquals(302, $response->getStatusCode());
104
        $comment = DataObject::get_by_id(Comment::class, $comment->ID);
105
106
        // Need to use 0,1 here instead of false, true for SQLite
107
        $this->assertEquals(0, $comment->IsSpam);
108
        $this->assertEquals(1, $comment->Moderated);
109
110
        // try and approve a non existent comment
111
        $response = $this->get('comments/approve/100000');
112
        $this->assertEquals(404, $response->getStatusCode());
113
    }
114
115
    public function testSetGetOwnerController()
116
    {
117
        $commController = new CommentingController();
118
        $commController->setOwnerController(Controller::curr());
119
        $this->assertEquals(Controller::curr(), $commController->getOwnerController());
120
        $commController->setOwnerController(null);
121
        $this->assertNull($commController->getOwnerController());
122
    }
123
124
    public function testHam()
125
    {
126
        SecurityToken::inst()->disable();
127
128
        // mark a comment as spam then ham it
129
        $this->logInWithPermission('CMS_ACCESS_CommentAdmin');
130
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
131
        $comment->markSpam();
132
        $st = new CommentSecurityToken($comment);
133
        $url = 'comments/ham/' . $comment->ID;
134
        $url = $st->addToUrl($url, Member::currentUser());
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Security\Member::currentUser() has been deprecated: 5.0.0 use Security::getCurrentUser() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

134
        $url = $st->addToUrl($url, /** @scrutinizer ignore-deprecated */ Member::currentUser());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
135
        $response = $this->get($url);
136
        $this->assertEquals(302, $response->getStatusCode());
137
        $comment = DataObject::get_by_id(Comment::class, $comment->ID);
138
139
        // Need to use 0,1 here instead of false, true for SQLite
140
        $this->assertEquals(0, $comment->IsSpam);
141
        $this->assertEquals(1, $comment->Moderated);
142
143
        // try and ham a non existent comment
144
        $response = $this->get('comments/ham/100000');
145
        $this->assertEquals(404, $response->getStatusCode());
146
    }
147
148
    public function testSpam()
149
    {
150
        // mark a comment as approved then spam it
151
        $this->logInWithPermission('CMS_ACCESS_CommentAdmin');
152
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
153
        $comment->markApproved();
154
        $st = new CommentSecurityToken($comment);
155
        $url = 'comments/spam/' . $comment->ID;
156
        $url = $st->addToUrl($url, Member::currentUser());
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Security\Member::currentUser() has been deprecated: 5.0.0 use Security::getCurrentUser() ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

156
        $url = $st->addToUrl($url, /** @scrutinizer ignore-deprecated */ Member::currentUser());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
157
        $response = $this->get($url);
158
        $this->assertEquals(302, $response->getStatusCode());
159
        $comment = DataObject::get_by_id(Comment::class, $comment->ID);
160
161
        // Need to use 0,1 here instead of false, true for SQLite
162
        $this->assertEquals(1, $comment->IsSpam);
163
        $this->assertEquals(1, $comment->Moderated);
164
165
        // try and spam a non existent comment
166
        $response = $this->get('comments/spam/100000');
167
        $this->assertEquals(404, $response->getStatusCode());
168
    }
169
170
    public function testRSS()
171
    {
172
        // Delete the newly added children of firstComA so as not to have to recalculate values below
173
        $this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
174
        $this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
175
        $this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
176
177
        $item = $this->objFromFixture(CommentableItem::class, 'first');
178
179
        // comments sitewide
180
        $response = $this->get('comments/rss');
181
        $comment = "10 approved, non spam comments on page 1";
182
        $this->assertEquals(10, substr_count($response->getBody(), "<item>"), $comment);
183
184
        $response = $this->get('comments/rss?start=10');
185
        $this->assertEquals(4, substr_count($response->getBody(), "<item>"), "3 approved, non spam comments on page 2");
186
187
        // all comments on a type
188
        $response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem');
189
        $this->assertEquals(10, substr_count($response->getBody(), "<item>"));
190
191
        $response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem?start=10');
192
        $this->assertEquals(4, substr_count($response->getBody(), "<item>"), "3 approved, non spam comments on page 2");
193
194
        // specific page
195
        $response = $this->get('comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem/'.$item->ID);
196
        $this->assertEquals(1, substr_count($response->getBody(), "<item>"));
197
        $this->assertContains('<dc:creator>FA</dc:creator>', $response->getBody());
198
199
        // test accessing comments on a type that doesn't exist
200
        $response = $this->get('comments/rss/Fake');
201
        $this->assertEquals(404, $response->getStatusCode());
202
    }
203
204
    // This is returning a 404 which looks logical code wise but also a bit weird.
205
    // Test module on a clean install and check what the actual URL is first
206
/*    public function testReply() {
207
        $this->logInWithPermission('CMS_ACCESS_CommentAdmin');
208
        $comment = $this->objFromFixture('Comment', 'firstComA');
209
        $item = $this->objFromFixture('CommentableItem', 'first');
210
211
        $st = new CommentSecurityToken($comment);
212
        $url = 'comments/reply/' . $item->ID.'?ParentCommentID=' . $comment->ID;
213
        error_log($url);
214
        $response = $this->get($url);
215
        error_log(print_r($response,1));
216
217
        $this->assertEquals(200, $response->getStatusCode());
218
219
    }
220
*/
221
/*
222
    public function testCommentsFormLoadMemberData() {
223
        Config::modify()->set('CommentableItem', 'comments', array(
224
            'use_preview' => false
225
        ));
226
        $this->logInAs('visitor');
227
        SecurityToken::inst()->disable();
228
        $parent = $this->objFromFixture('CommentableItem', 'first');
229
        $parent->CommentsRequireLogin = true;
230
        $parent->PostingRequiredPermission = true;
231
        //$parent->write();
232
        $commController = new CommentingController();
233
        $commController->setOwnerRecord($parent);
234
235
        $form = $commController->CommentsForm();
236
        $commentsFields = $form->Fields()->first()->FieldList();
237
        $expected = array('Name', 'Email', 'URL', 'Comment', 'PreviewComment');
238
        CommentTestHelper::assertFieldNames($this, $expected, $commentsFields);
239
    }
240
*/
241
242
    public function testCommentsForm()
243
    {
244
        $this->autoFollowRedirection = true;
245
246
        // Delete the newly added children of firstComA so as not to change this test
247
        $this->objFromFixture(Comment::class, 'firstComAChild1')->delete();
248
        $this->objFromFixture(Comment::class, 'firstComAChild2')->delete();
249
        $this->objFromFixture(Comment::class, 'firstComAChild3')->delete();
250
251
        SecurityToken::inst()->disable();
252
        $this->autoFollowRedirection = false;
253
        $parent = $this->objFromFixture(CommentableItem::class, 'first');
254
255
        // Test posting to base comment
256
        $response = $this->post(
257
            'comments/CommentsForm',
258
            array(
259
                'Name' => 'Poster',
260
                'Email' => '[email protected]',
261
                'Comment' => 'My Comment',
262
                'ParentID' => $parent->ID,
263
                'ParentClassName' => CommentableItem::class,
264
                'action_doPostComment' => 'Post'
265
            )
266
        );
267
        $this->assertEquals(302, $response->getStatusCode());
268
        // $this->assertStringStartsWith('CommentableItemController#comment-', $response->getHeader('Location'));
269
        $this->assertDOSEquals(
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Dev\SapphireTest::assertDOSEquals() has been deprecated: 4.0.0:5.0.0 Use assertListEquals() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

269
        /** @scrutinizer ignore-deprecated */ $this->assertDOSEquals(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
270
            array(
271
                array(
272
                    'Name' => 'Poster',
273
                    'Email' => '[email protected]',
274
                    'Comment' => 'My Comment',
275
                    'ParentID' => $parent->ID,
276
                    'ParentClass' => CommentableItem::class,
277
                )
278
            ),
279
            Comment::get()->filter('Email', '[email protected]')
280
        );
281
282
        // Test posting to parent comment
283
        $parentComment = $this->objFromFixture(Comment::class, 'firstComA');
284
        $this->assertEquals(0, $parentComment->ChildComments()->count());
285
286
        $response = $this->post(
287
            'comments/reply/' . $parentComment->ID,
288
            array(
289
                'Name' => 'Test Author',
290
                'Email' => '[email protected]',
291
                'Comment' => 'Making a reply to firstComA',
292
                'ParentID' => $parent->ID,
293
                'ParentClassName' => CommentableItem::class,
294
                'ParentCommentID' => $parentComment->ID,
295
                'action_doPostComment' => 'Post'
296
            )
297
        );
298
        $this->assertEquals(302, $response->getStatusCode());
299
        // $this->assertStringStartsWith('CommentableItemController#comment-', $response->getHeader('Location'));
300
        $this->assertDOSEquals(
0 ignored issues
show
Deprecated Code introduced by
The function SilverStripe\Dev\SapphireTest::assertDOSEquals() has been deprecated: 4.0.0:5.0.0 Use assertListEquals() instead ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

300
        /** @scrutinizer ignore-deprecated */ $this->assertDOSEquals(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
301
            array(
302
                array(
303
                    'Name' => 'Test Author',
304
                    'Email' => '[email protected]',
305
                    'Comment' => 'Making a reply to firstComA',
306
                    'ParentID' => $parent->ID,
307
                    'ParentClass' => CommentableItem::class,
308
                    'ParentCommentID' => $parentComment->ID
309
                )
310
            ),
311
            $parentComment->ChildComments()
312
        );
313
    }
314
315
    /**
316
     * SS4 introduces namespaces. They don't work in URLs, so we encode and decode them here.
317
     */
318
    public function testEncodeClassName()
319
    {
320
        $controller = new CommentingController;
321
        $this->assertSame('SilverStripe-Comments-Model-Comment', $controller->encodeClassName(Comment::class));
322
    }
323
324
    public function testDecodeClassName()
325
    {
326
        $controller = new CommentingController;
327
        $this->assertSame(Comment::class, $controller->decodeClassName('SilverStripe-Comments-Model-Comment'));
328
    }
329
}
330