Completed
Push — master ( 9dab44...8bd79e )
by Robbie
02:00
created

CommentsTest::testFieldLabels()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 53
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 53
rs 9.5797
c 0
b 0
f 0
cc 3
eloc 43
nc 4
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\Comments\Tests;
4
5
use HTMLPurifier_Config;
6
use HTMLPurifier;
7
use ReflectionClass;
8
use SilverStripe\Comments\Extensions\CommentsExtension;
9
use SilverStripe\Comments\Model\Comment;
10
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
11
use SilverStripe\Comments\Tests\Stubs\CommentableItemDisabled;
12
use SilverStripe\Comments\Tests\Stubs\CommentableItemEnabled;
13
use SilverStripe\Control\Controller;
14
use SilverStripe\Control\Director;
15
use SilverStripe\Core\Config\Config;
16
use SilverStripe\Core\Email\Email;
17
use SilverStripe\Dev\FunctionalTest;
18
use SilverStripe\Dev\TestOnly;
19
use SilverStripe\i18n\i18n;
20
use SilverStripe\ORM\DataObject;
21
use SilverStripe\Security\Member;
22
use SilverStripe\Security\Security;
23
use SilverStripe\Security\Permission;
24
25
class CommentsTest extends FunctionalTest
26
{
27
    protected static $fixture_file = 'CommentsTest.yml';
28
29
    protected static $extra_dataobjects = array(
30
        CommentableItem::class,
31
        CommentableItemEnabled::class,
32
        CommentableItemDisabled::class
33
    );
34
35
    public function setUp()
36
    {
37
        parent::setUp();
38
39
        // Set good default values
40
        Config::modify()->merge(CommentsExtension::class, 'comments', array(
41
            'enabled' => true,
42
            'comment_permalink_prefix' => 'comment-'
43
        ));
44
    }
45
46
    public function testCommentsList()
47
    {
48
        // comments don't require moderation so unmoderated comments can be
49
        // shown but not spam posts
50
        Config::modify()->merge(CommentableItem::class, 'comments', array(
51
            'require_moderation_nonmembers' => false,
52
            'require_moderation' => false,
53
            'require_moderation_cms' => false,
54
        ));
55
56
        $item = $this->objFromFixture(CommentableItem::class, 'spammed');
57
58
        $this->assertDOSEquals(array(
59
            array('Name' => 'Comment 1'),
60
            array('Name' => 'Comment 3')
61
        ), $item->Comments(), 'Only 2 non spam posts should be shown');
0 ignored issues
show
Unused Code introduced by Damian Mooyman
The call to CommentsTest::assertDOSEquals() has too many arguments starting with 'Only 2 non spam posts should be shown'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
62
63
        // when moderated, only moderated, non spam posts should be shown.
64
        Config::modify()->merge(CommentableItem::class, 'comments', array('require_moderation_nonmembers' => true));
65
66
        // Check that require_moderation overrides this option
67
        Config::modify()->merge(CommentableItem::class, 'comments', array('require_moderation' => true));
68
69
        $this->assertDOSEquals(array(
70
            array('Name' => 'Comment 3')
71
        ), $item->Comments(), 'Only 1 non spam, moderated post should be shown');
0 ignored issues
show
Unused Code introduced by Damian Mooyman
The call to CommentsTest::assertDOSEquals() has too many arguments starting with 'Only 1 non spam, moderated post should be shown'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
72
        $this->assertEquals(1, $item->Comments()->Count());
73
74
        // require_moderation_nonmembers still filters out unmoderated comments
75
        Config::modify()->merge(CommentableItem::class, 'comments', array('require_moderation' => false));
76
        $this->assertEquals(1, $item->Comments()->Count());
77
78
        Config::modify()->merge(CommentableItem::class, 'comments', array('require_moderation_nonmembers' => false));
79
        $this->assertEquals(2, $item->Comments()->Count());
80
81
        // With unmoderated comments set to display in frontend
82
        Config::modify()->merge(CommentableItem::class, 'comments', array(
83
            'require_moderation' => true,
84
            'frontend_moderation' => true
85
        ));
86
        $this->assertEquals(1, $item->Comments()->Count());
87
88
        $this->logInWithPermission('ADMIN');
89
        $this->assertEquals(2, $item->Comments()->Count());
90
91
        // With spam comments set to display in frontend
92
        Config::modify()->merge(CommentableItem::class, 'comments', array(
93
            'require_moderation' => true,
94
            'frontend_moderation' => false,
95
            'frontend_spam' => true,
96
        ));
97
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
98
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
99
        }
100
        $this->assertEquals(1, $item->Comments()->Count());
101
102
        $this->logInWithPermission('ADMIN');
103
        $this->assertEquals(2, $item->Comments()->Count());
104
105
106
        // With spam and unmoderated comments set to display in frontend
107
        Config::modify()->merge(CommentableItem::class, 'comments', array(
108
            'require_moderation' => true,
109
            'frontend_moderation' => true,
110
            'frontend_spam' => true,
111
        ));
112
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
113
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
114
        }
115
        $this->assertEquals(1, $item->Comments()->Count());
116
117
        $this->logInWithPermission('ADMIN');
118
        $this->assertEquals(4, $item->Comments()->Count());
119
    }
120
121
    /**
122
     * Test moderation options configured via the CMS
123
     */
124
    public function testCommentCMSModerationList()
125
    {
126
        Config::modify()->merge(CommentableItem::class, 'comments', array(
127
            'require_moderation' => true,
128
            'require_moderation_cms' => true,
129
        ));
130
131
        $item = $this->objFromFixture(CommentableItem::class, 'spammed');
132
133
        $this->assertEquals('None', $item->getModerationRequired());
134
135
        $this->assertDOSEquals(array(
136
            array('Name' => 'Comment 1'),
137
            array('Name' => 'Comment 3')
138
        ), $item->Comments(), 'Only 2 non spam posts should be shown');
0 ignored issues
show
Unused Code introduced by Damian Mooyman
The call to CommentsTest::assertDOSEquals() has too many arguments starting with 'Only 2 non spam posts should be shown'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
139
140
        // when moderated, only moderated, non spam posts should be shown.
141
        $item->ModerationRequired = 'NonMembersOnly';
142
        $item->write();
143
144
        $this->assertEquals('NonMembersOnly', $item->getModerationRequired());
145
146
        // Check that require_moderation overrides this option
147
        $item->ModerationRequired = 'Required';
148
        $item->write();
149
        $this->assertEquals('Required', $item->getModerationRequired());
150
151
        $this->assertDOSEquals(array(
152
            array('Name' => 'Comment 3')
153
        ), $item->Comments(), 'Only 1 non spam, moderated post should be shown');
0 ignored issues
show
Unused Code introduced by Damian Mooyman
The call to CommentsTest::assertDOSEquals() has too many arguments starting with 'Only 1 non spam, moderated post should be shown'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
154
        $this->assertEquals(1, $item->Comments()->Count());
155
156
        // require_moderation_nonmembers still filters out unmoderated comments
157
        $item->ModerationRequired = 'NonMembersOnly';
158
        $item->write();
159
        $this->assertEquals(1, $item->Comments()->Count());
160
161
        $item->ModerationRequired = 'None';
162
        $item->write();
163
        $this->assertEquals(2, $item->Comments()->Count());
164
    }
165
166
    public function testCanPostComment()
167
    {
168
        Config::modify()->merge(CommentableItem::class, 'comments', array(
169
            'require_login' => false,
170
            'require_login_cms' => false,
171
            'required_permission' => false,
172
        ));
173
        $item = $this->objFromFixture(CommentableItem::class, 'first');
174
        $item2 = $this->objFromFixture(CommentableItem::class, 'second');
175
176
        // Test restriction free commenting
177
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
178
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
179
        }
180
        $this->assertFalse($item->CommentsRequireLogin);
181
        $this->assertTrue($item->canPostComment());
182
183
        // Test permission required to post
184
        Config::modify()->merge(CommentableItem::class, 'comments', array(
185
            'require_login' => true,
186
            'required_permission' => 'POSTING_PERMISSION',
187
        ));
188
        $this->assertTrue($item->CommentsRequireLogin);
189
        $this->assertFalse($item->canPostComment());
190
        $this->logInWithPermission('WRONG_ONE');
191
        $this->assertFalse($item->canPostComment());
192
        $this->logInWithPermission('POSTING_PERMISSION');
193
        $this->assertTrue($item->canPostComment());
194
        $this->logInWithPermission('ADMIN');
195
        $this->assertTrue($item->canPostComment());
196
197
        // Test require login to post, but not any permissions
198
        Config::modify()->merge(CommentableItem::class, 'comments', array(
199
            'required_permission' => false,
200
        ));
201
        $this->assertTrue($item->CommentsRequireLogin);
202
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
203
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
204
        }
205
        $this->assertFalse($item->canPostComment());
206
        $this->logInWithPermission('ANY_PERMISSION');
207
        $this->assertTrue($item->canPostComment());
208
209
        // Test options set via CMS
210
        Config::modify()->merge(CommentableItem::class, 'comments', array(
211
            'require_login' => true,
212
            'require_login_cms' => true,
213
        ));
214
        $this->assertFalse($item->CommentsRequireLogin);
215
        $this->assertTrue($item2->CommentsRequireLogin);
216
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
217
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
218
        }
219
        $this->assertTrue($item->canPostComment());
220
        $this->assertFalse($item2->canPostComment());
221
222
        // Login grants permission to post
223
        $this->logInWithPermission('ANY_PERMISSION');
224
        $this->assertTrue($item->canPostComment());
225
        $this->assertTrue($item2->canPostComment());
226
    }
227
    public function testDeleteComment()
228
    {
229
        // Test anonymous user
230
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
231
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
232
        }
233
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
234
        $commentID = $comment->ID;
235
        $this->assertNull($comment->DeleteLink(), 'No permission to see delete link');
236
        $delete = $this->get('comments/delete/' . $comment->ID . '?ajax=1');
237
        $this->assertEquals(403, $delete->getStatusCode());
238
        $check = DataObject::get_by_id(Comment::class, $commentID);
239
        $this->assertTrue($check && $check->exists());
240
241
        // Test non-authenticated user
242
        $this->logInAs('visitor');
243
        $this->assertNull($comment->DeleteLink(), 'No permission to see delete link');
244
245
        // Test authenticated user
246
        $this->logInAs('commentadmin');
247
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
248
        $commentID = $comment->ID;
249
        $adminComment1Link = $comment->DeleteLink();
250
        $this->assertContains('comments/delete/' . $commentID . '?t=', $adminComment1Link);
251
252
        // Test that this link can't be shared / XSS exploited
253
        $this->logInAs('commentadmin2');
254
        $delete = $this->get($adminComment1Link);
255
        $this->assertEquals(400, $delete->getStatusCode());
256
        $check = DataObject::get_by_id(Comment::class, $commentID);
257
        $this->assertTrue($check && $check->exists());
258
259
        // Test that this other admin can delete the comment with their own link
260
        $adminComment2Link = $comment->DeleteLink();
261
        $this->assertNotEquals($adminComment2Link, $adminComment1Link);
262
        $this->autoFollowRedirection = false;
263
        $delete = $this->get($adminComment2Link);
264
        $this->assertEquals(302, $delete->getStatusCode());
265
        $check = DataObject::get_by_id(Comment::class, $commentID);
266
        $this->assertFalse($check && $check->exists());
267
    }
268
269 View Code Duplication
    public function testSpamComment()
0 ignored issues
show
Duplication introduced by Damian Mooyman
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
270
    {
271
        // Test anonymous user
272
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
273
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
274
        }
275
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
276
        $commentID = $comment->ID;
277
        $this->assertNull($comment->SpamLink(), 'No permission to see mark as spam link');
278
        $spam = $this->get('comments/spam/'.$comment->ID.'?ajax=1');
279
        $this->assertEquals(403, $spam->getStatusCode());
280
        $check = DataObject::get_by_id(Comment::class, $commentID);
281
        $this->assertEquals(0, $check->IsSpam, 'No permission to mark as spam');
282
283
        // Test non-authenticated user
284
        $this->logInAs('visitor');
285
        $this->assertNull($comment->SpamLink(), 'No permission to see mark as spam link');
286
287
        // Test authenticated user
288
        $this->logInAs('commentadmin');
289
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
290
        $commentID = $comment->ID;
291
        $adminComment1Link = $comment->SpamLink();
292
        $this->assertContains('comments/spam/' . $commentID . '?t=', $adminComment1Link);
293
294
        // Test that this link can't be shared / XSS exploited
295
        $this->logInAs('commentadmin2');
296
        $spam = $this->get($adminComment1Link);
297
        $this->assertEquals(400, $spam->getStatusCode());
298
        $check = DataObject::get_by_id(Comment::class, $comment->ID);
299
        $this->assertEquals(0, $check->IsSpam, 'No permission to mark as spam');
300
301
        // Test that this other admin can spam the comment with their own link
302
        $adminComment2Link = $comment->SpamLink();
303
        $this->assertNotEquals($adminComment2Link, $adminComment1Link);
304
        $this->autoFollowRedirection = false;
305
        $spam = $this->get($adminComment2Link);
306
        $this->assertEquals(302, $spam->getStatusCode());
307
        $check = DataObject::get_by_id(Comment::class, $commentID);
308
        $this->assertEquals(1, $check->IsSpam);
309
310
        // Cannot re-spam spammed comment
311
        $this->assertNull($check->SpamLink());
312
    }
313
314 View Code Duplication
    public function testHamComment()
0 ignored issues
show
Duplication introduced by Damian Mooyman
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
315
    {
316
        // Test anonymous user
317
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
318
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
319
        }
320
        $comment = $this->objFromFixture(Comment::class, 'secondComC');
321
        $commentID = $comment->ID;
322
        $this->assertNull($comment->HamLink(), 'No permission to see mark as ham link');
323
        $ham = $this->get('comments/ham/' . $comment->ID . '?ajax=1');
324
        $this->assertEquals(403, $ham->getStatusCode());
325
        $check = DataObject::get_by_id(Comment::class, $commentID);
326
        $this->assertEquals(1, $check->IsSpam, 'No permission to mark as ham');
327
328
        // Test non-authenticated user
329
        $this->logInAs('visitor');
330
        $this->assertNull($comment->HamLink(), 'No permission to see mark as ham link');
331
332
        // Test authenticated user
333
        $this->logInAs('commentadmin');
334
        $comment = $this->objFromFixture(Comment::class, 'secondComC');
335
        $commentID = $comment->ID;
336
        $adminComment1Link = $comment->HamLink();
337
        $this->assertContains('comments/ham/' . $commentID . '?t=', $adminComment1Link);
338
339
        // Test that this link can't be shared / XSS exploited
340
        $this->logInAs('commentadmin2');
341
        $ham = $this->get($adminComment1Link);
342
        $this->assertEquals(400, $ham->getStatusCode());
343
        $check = DataObject::get_by_id(Comment::class, $comment->ID);
344
        $this->assertEquals(1, $check->IsSpam, 'No permission to mark as ham');
345
346
        // Test that this other admin can ham the comment with their own link
347
        $adminComment2Link = $comment->HamLink();
348
        $this->assertNotEquals($adminComment2Link, $adminComment1Link);
349
        $this->autoFollowRedirection = false;
350
        $ham = $this->get($adminComment2Link);
351
        $this->assertEquals(302, $ham->getStatusCode());
352
        $check = DataObject::get_by_id(Comment::class, $commentID);
353
        $this->assertEquals(0, $check->IsSpam);
354
355
        // Cannot re-ham hammed comment
356
        $this->assertNull($check->HamLink());
357
    }
358
359 View Code Duplication
    public function testApproveComment()
0 ignored issues
show
Duplication introduced by Damian Mooyman
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
360
    {
361
        // Test anonymous user
362
        if ($member = Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::currentUser() has been deprecated with message: 5.0.0 use Security::getCurrentUser()

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

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

Loading history...
363
            $member->logOut();
0 ignored issues
show
Deprecated Code introduced by Damian Mooyman
The method SilverStripe\Security\Member::logOut() has been deprecated with message: Use Security::setCurrentUser(null) or an IdentityStore
Logs this member out.

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

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

Loading history...
364
        }
365
        $comment = $this->objFromFixture(Comment::class, 'secondComB');
366
        $commentID = $comment->ID;
367
        $this->assertNull($comment->ApproveLink(), 'No permission to see approve link');
368
        $approve = $this->get('comments/approve/' . $comment->ID . '?ajax=1');
369
        $this->assertEquals(403, $approve->getStatusCode());
370
        $check = DataObject::get_by_id(Comment::class, $commentID);
371
        $this->assertEquals(0, $check->Moderated, 'No permission to approve');
372
373
        // Test non-authenticated user
374
        $this->logInAs('visitor');
375
        $this->assertNull($comment->ApproveLink(), 'No permission to see approve link');
376
377
        // Test authenticated user
378
        $this->logInAs('commentadmin');
379
        $comment = $this->objFromFixture(Comment::class, 'secondComB');
380
        $commentID = $comment->ID;
381
        $adminComment1Link = $comment->ApproveLink();
382
        $this->assertContains('comments/approve/' . $commentID . '?t=', $adminComment1Link);
383
384
        // Test that this link can't be shared / XSS exploited
385
        $this->logInAs('commentadmin2');
386
        $approve = $this->get($adminComment1Link);
387
        $this->assertEquals(400, $approve->getStatusCode());
388
        $check = DataObject::get_by_id(Comment::class, $comment->ID);
389
        $this->assertEquals(0, $check->Moderated, 'No permission to approve');
390
391
        // Test that this other admin can approve the comment with their own link
392
        $adminComment2Link = $comment->ApproveLink();
393
        $this->assertNotEquals($adminComment2Link, $adminComment1Link);
394
        $this->autoFollowRedirection = false;
395
        $approve = $this->get($adminComment2Link);
396
        $this->assertEquals(302, $approve->getStatusCode());
397
        $check = DataObject::get_by_id(Comment::class, $commentID);
398
        $this->assertEquals(1, $check->Moderated);
399
400
        // Cannot re-approve approved comment
401
        $this->assertNull($check->ApproveLink());
402
    }
403
404
    public function testCommenterURLWrite()
405
    {
406
        $comment = new Comment();
407
        // We only care about the CommenterURL, so only set that
408
        // Check a http and https URL. Add more test urls here as needed.
409
        $protocols = array(
410
            'Http',
411
            'Https',
412
        );
413
        $url = '://example.com';
414
415
        foreach ($protocols as $protocol) {
416
            $comment->CommenterURL = $protocol . $url;
0 ignored issues
show
Bug introduced by Will Rossiter
The property CommenterURL does not seem to exist. Did you mean Comment?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
417
            // The protocol should stay as if, assuming it is valid
418
            $comment->write();
419
            $this->assertEquals($comment->CommenterURL, $protocol . $url, $protocol . ':// is a valid protocol');
0 ignored issues
show
Bug introduced by Will Rossiter
The property CommenterURL does not seem to exist. Did you mean Comment?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
420
        }
421
    }
422
423
    public function testSanitizesWithAllowHtml()
424
    {
425
        if (!class_exists('\\HTMLPurifier')) {
426
            $this->markTestSkipped('HTMLPurifier class not found');
427
            return;
428
        }
429
430
        // Add p for paragraph
431
        // NOTE: The config method appears to append to the existing array
432
        Config::modify()->merge(CommentableItem::class, 'comments', array(
433
            'html_allowed_elements' => array('p'),
434
        ));
435
436
        // Without HTML allowed
437
        $comment1 = new Comment();
438
        $comment1->AllowHtml = false;
439
        $comment1->ParentClass = CommentableItem::class;
0 ignored issues
show
Documentation introduced by Robbie Averill
The property ParentClass does not exist on object<SilverStripe\Comments\Model\Comment>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
440
        $comment1->Comment = '<p><script>alert("w00t")</script>my comment</p>';
441
        $comment1->write();
442
        $this->assertEquals(
443
            '<p><script>alert("w00t")</script>my comment</p>',
444
            $comment1->Comment,
445
            'Does not remove HTML tags with html_allowed=false, ' .
446
            'which is correct behaviour because the HTML will be escaped'
447
        );
448
449
        // With HTML allowed
450
        $comment2 = new Comment();
451
        $comment2->AllowHtml = true;
452
        $comment2->ParentClass = CommentableItem::class;
0 ignored issues
show
Documentation introduced by Robbie Averill
The property ParentClass does not exist on object<SilverStripe\Comments\Model\Comment>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
453
        $comment2->Comment = '<p><script>alert("w00t")</script>my comment</p>';
454
        $comment2->write();
455
        $this->assertEquals(
456
            '<p>my comment</p>',
457
            $comment2->Comment,
458
            'Removes HTML tags which are not on the whitelist'
459
        );
460
    }
461
462
    public function testDefaultTemplateRendersHtmlWithAllowHtml()
463
    {
464
        if (!class_exists('\\HTMLPurifier')) {
465
            $this->markTestSkipped('HTMLPurifier class not found');
466
        }
467
468
        Config::modify()->merge(CommentableItem::class, 'comments', array(
469
            'html_allowed_elements' => array('p'),
470
        ));
471
472
        $item = new CommentableItem();
473
        $item->write();
474
475
        // Without HTML allowed
476
        $comment = new Comment();
477
        $comment->Comment = '<p>my comment</p>';
478
        $comment->AllowHtml = false;
479
        $comment->ParentID = $item->ID;
480
        $comment->ParentClass = CommentableItem::class;
0 ignored issues
show
Documentation introduced by Robbie Averill
The property ParentClass does not exist on object<SilverStripe\Comments\Model\Comment>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
481
        $comment->write();
482
483
        $html = $item->customise(array('CommentsEnabled' => true))->renderWith('CommentsInterface');
484
        $this->assertContains(
485
            '&lt;p&gt;my comment&lt;/p&gt;',
486
            $html
487
        );
488
489
        $comment->AllowHtml = true;
490
        $comment->write();
491
        $html = $item->customise(array('CommentsEnabled' => true))->renderWith('CommentsInterface');
492
        $this->assertContains(
493
            '<p>my comment</p>',
494
            $html
495
        );
496
    }
497
498
499
    /**
500
     * Tests whether comments are enabled or disabled by default
501
     */
502
    public function testDefaultEnabled()
503
    {
504
        Config::modify()->merge(CommentableItem::class, 'comments', array(
505
            'enabled_cms' => true,
506
            'require_moderation_cms' => true,
507
            'require_login_cms' => true
508
        ));
509
510
        // With default = true
511
        $obj = new CommentableItem();
512
        $this->assertTrue((bool)$obj->getCommentsOption('enabled'), "Default setting is enabled");
0 ignored issues
show
Documentation Bug introduced by Damian Mooyman
The method getCommentsOption does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
513
        $this->assertTrue((bool)$obj->ProvideComments);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ProvideComments does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
514
        $this->assertEquals('None', $obj->ModerationRequired);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ModerationRequired does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
515
        $this->assertFalse((bool)$obj->CommentsRequireLogin);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property CommentsRequireLogin does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
516
517
        $obj = new CommentableItemEnabled();
518
        $this->assertTrue((bool)$obj->ProvideComments);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ProvideComments does not exist on object<SilverStripe\Comm...CommentableItemEnabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
519
        $this->assertEquals('Required', $obj->ModerationRequired);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ModerationRequired does not exist on object<SilverStripe\Comm...CommentableItemEnabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
520
        $this->assertTrue((bool)$obj->CommentsRequireLogin);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property CommentsRequireLogin does not exist on object<SilverStripe\Comm...CommentableItemEnabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
521
522
        $obj = new CommentableItemDisabled();
523
        $this->assertFalse((bool)$obj->ProvideComments);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ProvideComments does not exist on object<SilverStripe\Comm...ommentableItemDisabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
524
        $this->assertEquals('None', $obj->ModerationRequired);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ModerationRequired does not exist on object<SilverStripe\Comm...ommentableItemDisabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
525
        $this->assertFalse((bool)$obj->CommentsRequireLogin);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property CommentsRequireLogin does not exist on object<SilverStripe\Comm...ommentableItemDisabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
526
527
        // With default = false
528
        // Because of config rules about falsey values, apply config to object directly
529
        Config::modify()->merge(CommentableItem::class, 'comments', array(
530
            'enabled' => false,
531
            'require_login' => true,
532
            'require_moderation' => true
533
        ));
534
535
        $obj = new CommentableItem();
536
537
        $this->assertFalse((bool)$obj->getCommentsOption('enabled'), 'Default setting is disabled');
0 ignored issues
show
Documentation Bug introduced by Robbie Averill
The method getCommentsOption does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
538
        $this->assertFalse((bool)$obj->ProvideComments);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ProvideComments does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
539
        $this->assertEquals('Required', $obj->ModerationRequired);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ModerationRequired does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
540
        $this->assertTrue((bool)$obj->CommentsRequireLogin);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property CommentsRequireLogin does not exist on object<SilverStripe\Comm...\Stubs\CommentableItem>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
541
542
        $obj = new CommentableItemEnabled();
543
544
        $this->assertTrue((bool)$obj->ProvideComments);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ProvideComments does not exist on object<SilverStripe\Comm...CommentableItemEnabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
545
        $this->assertEquals('Required', $obj->ModerationRequired);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ModerationRequired does not exist on object<SilverStripe\Comm...CommentableItemEnabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
546
        $this->assertTrue((bool)$obj->CommentsRequireLogin);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property CommentsRequireLogin does not exist on object<SilverStripe\Comm...CommentableItemEnabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
547
548
        $obj = new CommentableItemDisabled();
549
550
        $this->assertFalse((bool)$obj->ProvideComments);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ProvideComments does not exist on object<SilverStripe\Comm...ommentableItemDisabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
551
        $this->assertEquals('None', $obj->ModerationRequired);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property ModerationRequired does not exist on object<SilverStripe\Comm...ommentableItemDisabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
552
        $this->assertFalse((bool)$obj->CommentsRequireLogin);
0 ignored issues
show
Documentation introduced by Damian Mooyman
The property CommentsRequireLogin does not exist on object<SilverStripe\Comm...ommentableItemDisabled>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
553
    }
554
555
    public function testOnBeforeDelete()
556
    {
557
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
558
559
        $child = new Comment();
560
        $child->Name = 'Fred Bloggs';
561
        $child->Comment = 'Child of firstComA';
562
        $child->write();
563
        $comment->ChildComments()->add($child);
564
        $this->assertEquals(4, $comment->ChildComments()->count());
565
566
        $commentID = $comment->ID;
567
        $childCommentID = $child->ID;
568
569
        $comment->delete();
570
571
        // assert that the new child been deleted
572
        $this->assertNull(DataObject::get_by_id(Comment::class, $commentID));
573
        $this->assertNull(DataObject::get_by_id(Comment::class, $childCommentID));
574
    }
575
576
    public function testRequireDefaultRecords()
577
    {
578
        $this->markTestSkipped('TODO');
579
    }
580
581
    public function testLink()
582
    {
583
        $comment = $this->objFromFixture(Comment::class, 'thirdComD');
584
        $this->assertEquals(
585
            'CommentableItemController#comment-' . $comment->ID,
586
            $comment->Link()
587
        );
588
        $this->assertEquals($comment->ID, $comment->ID);
589
590
        // An orphan comment has no link
591
        $comment->ParentID = 0;
592
        $comment->ParentClass = null;
593
        $comment->write();
594
        $this->assertEquals('', $comment->Link());
595
    }
596
597
    public function testPermalink()
598
    {
599
        $comment = $this->objFromFixture(Comment::class, 'thirdComD');
600
        $this->assertEquals('comment-' . $comment->ID, $comment->Permalink());
601
    }
602
603
    /**
604
     * Test field labels in 2 languages
605
     */
606
    public function testFieldLabels()
607
    {
608
        $locale = i18n::get_locale();
609
        i18n::set_locale('fr');
610
611
        /** @var Comment $comment */
612
        $comment = $this->objFromFixture(Comment::class, 'firstComA');
613
614
        $labels = $comment->FieldLabels();
615
        $expected = array(
616
            'Name' => 'Nom de l\'Auteur',
617
            'Comment' => 'Commentaire',
618
            'Email' => 'Email',
619
            'URL' => 'URL',
620
            'Moderated' => 'Modéré?',
621
            'IsSpam' => 'Spam?',
622
            'AllowHtml' => 'Allow Html',
623
            'SecretToken' => 'Secret Token',
624
            'Depth' => 'Depth',
625
            'Author' => 'Author Member',
626
            'ParentComment' => 'Parent Comment',
627
            'ChildComments' => 'Child Comments',
628
            'ParentTitle' => 'Parent',
629
            'Created' => 'Date de publication',
630
            'Parent' => 'Parent'
631
        );
632
        i18n::set_locale($locale);
633
        foreach ($expected as $key => $value) {
634
            $this->assertEquals($value, $labels[$key]);
635
        }
636
637
        $labels = $comment->FieldLabels();
638
        $expected = array(
639
            'Name' => 'Author Name',
640
            'Comment' => 'Comment',
641
            'Email' => 'Email',
642
            'URL' => 'URL',
643
            'Moderated' => 'Moderated?',
644
            'IsSpam' => 'Spam?',
645
            'AllowHtml' => 'Allow Html',
646
            'SecretToken' => 'Secret Token',
647
            'Depth' => 'Depth',
648
            'Author' => 'Author Member',
649
            'ParentComment' => 'Parent Comment',
650
            'ChildComments' => 'Child Comments',
651
            'ParentTitle' => 'Parent',
652
            'Created' => 'Date posted',
653
            'Parent' => 'Parent'
654
        );
655
        foreach ($expected as $key => $value) {
656
            $this->assertEquals($value, $labels[$key]);
657
        }
658
    }
659
660
    public function testGetParent()
661
    {