Completed
Pull Request — master (#216)
by Will
01:39
created

CommentsExtensionTest::testPopulateDefaults()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
dl 0
loc 25
rs 8.8571
c 1
b 1
f 0
cc 1
eloc 15
nc 1
nop 0
1
<?php
2
3
namespace SilverStripe\Comments\Tests;
4
5
use SilverStripe\Comments\Extensions\CommentsExtension;
6
use SilverStripe\Comments\Model\Comment;
7
use SilverStripe\Comments\Tests\CommentTestHelper;
8
use SilverStripe\Comments\Tests\Stubs\CommentableItem;
9
use SilverStripe\Comments\Tests\Stubs\CommentableItemDisabled;
10
use SilverStripe\Comments\Tests\Stubs\CommentableItemEnabled;
11
use SilverStripe\Core\Config\Config;
12
use SilverStripe\Dev\SapphireTest;
13
use SilverStripe\Security\Member;
14
use SilverStripe\View\Requirements;
15
16
class CommentsExtensionTest extends SapphireTest
17
{
18
    /**
19
     * {@inheritDoc}
20
     */
21
    protected static $fixture_file = 'comments/tests/CommentsTest.yml';
22
23
    /**
24
     * {@inheritDoc}
25
     */
26
    protected static $extra_dataobjects = array(
27
        CommentableItem::class,
28
        CommentableItemEnabled::class,
29
        CommentableItemDisabled::class
30
    );
31
32 View Code Duplication
    public function setUp()
0 ignored issues
show
Duplication introduced by
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...
33
    {
34
        parent::setUp();
35
        Config::nest();
36
37
        // Set good default values
38
        Config::inst()->update(CommentsExtension::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
39
            'enabled' => true,
40
            'enabled_cms' => false,
41
            'require_login' => false,
42
            'require_login_cms' => false,
43
            'required_permission' => false,
44
            'require_moderation_nonmembers' => false,
45
            'require_moderation' => false,
46
            'require_moderation_cms' => false,
47
            'frontend_moderation' => false,
48
            'Member' => false,
49
        ));
50
51
        $this->requiredExtensions = array(
0 ignored issues
show
Bug introduced by
The property requiredExtensions does not seem to exist. Did you mean required_extensions?

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...
52
            'CommentableItem' => CommentsExtension::class
53
        );
54
55
        // Configure this dataobject
56
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
57
            'enabled_cms' => true
58
        ));
59
    }
60
61
    public function tearDown()
62
    {
63
        Config::unnest();
64
        parent::tearDown();
65
    }
66
67
    public function testPopulateDefaults()
68
    {
69
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
70
            'require_moderation_cms' => true,
71
            'require_moderation' => true,
72
            'require_moderation_nonmembers' => true
73
        ));
74
75
        $item = $this->objFromFixture(CommentableItem::class, 'first');
76
        $item->populateDefaults();
77
78
        $this->assertTrue($item->CommentsRequireLogin);
79
80
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
81
            'require_moderation_cms' => true,
82
            'require_moderation' => true,
83
            'require_moderation_nonmembers' => true
84
        ));
85
86
        $item = $this->objFromFixture(CommentableItem::class, 'first');
87
        $item->populateDefaults();
88
89
        $this->assertFalse($item->CommentsRequireLogin);
90
91
    }
92
93
    public function testUpdateSettingsFields()
94
    {
95
        $this->markTestSkipped('This needs SiteTree installed');
96
    }
97
98
    public function testGetModerationRequired()
99
    {
100
101
        // the 3 options take precedence in this order, executed if true
102
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
103
            'require_moderation_cms' => true,
104
            'require_moderation' => true,
105
            'require_moderation_nonmembers' => true
106
        ));
107
108
        // With require moderation CMS set to true, the value of the field
109
        // 'ModerationRequired' is returned
110
        $item = $this->objFromFixture(CommentableItem::class, 'first');
111
        $item->ModerationRequired = 'None';
112
        $item->write();
113
114
        $this->assertEquals('None', $item->getModerationRequired());
115
        $item->ModerationRequired = 'Required';
116
        $item->write();
117
118
        $this->assertEquals('Required', $item->getModerationRequired());
119
120
        $item->ModerationRequired = 'NonMembersOnly';
121
        $item->write();
122
123
        $this->assertEquals('NonMembersOnly', $item->getModerationRequired());
124
125
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
126
            'require_moderation_cms' => false,
127
            'require_moderation' => true,
128
            'require_moderation_nonmembers' => true
129
        ));
130
        $this->assertEquals('Required', $item->getModerationRequired());
131
132
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
133
            'require_moderation_cms' => false,
134
            'require_moderation' => false,
135
            'require_moderation_nonmembers' => true
136
        ));
137
        $this->assertEquals('NonMembersOnly', $item->getModerationRequired());
138
139
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
140
            'require_moderation_cms' => false,
141
            'require_moderation' => false,
142
            'require_moderation_nonmembers' => false
143
        ));
144
        $this->assertEquals('None', $item->getModerationRequired());
145
    }
146
147
    public function testGetCommentsRequireLogin()
148
    {
149
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
150
            'require_login_cms' => true
151
        ));
152
153
        // With require moderation CMS set to true, the value of the field
154
        // 'ModerationRequired' is returned
155
        $item = $this->objFromFixture(CommentableItem::class, 'first');
156
        $item->CommentsRequireLogin = true;
157
        $this->assertTrue($item->getCommentsRequireLogin());
158
        $item->CommentsRequireLogin = false;
159
        $this->assertFalse($item->getCommentsRequireLogin());
160
161
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
162
            'require_login_cms' => false,
163
            'require_login' => false
164
        ));
165
        $this->assertFalse($item->getCommentsRequireLogin());
166
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
167
            'require_login_cms' => false,
168
            'require_login' => true
169
        ));
170
        $this->assertTrue($item->getCommentsRequireLogin());
171
    }
172
173
    public function testAllComments()
174
    {
175
        $item = $this->objFromFixture(CommentableItem::class, 'first');
0 ignored issues
show
Unused Code introduced by
$item is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
176
        $this->assertEquals(4, $items->AllComments()->count());
0 ignored issues
show
Bug introduced by
The variable $items does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
177
    }
178
179
    public function testAllVisibleComments()
180
    {
181
        if (Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by
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...
182
            Member::currentUser()->logOut();
0 ignored issues
show
Deprecated Code introduced by
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...
183
        }
184
185
        $item = $this->objFromFixture(CommentableItem::class, 'second');
0 ignored issues
show
Unused Code introduced by
$item is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
186
        $this->assertEquals(4, $items->AllVisibleComments()->count());
0 ignored issues
show
Bug introduced by
The variable $items does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
187
    }
188
189
    public function testComments()
190
    {
191
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
192
            'nested_comments' => false
193
        ));
194
195
        $item = $this->objFromFixture(CommentableItem::class, 'first');
0 ignored issues
show
Unused Code introduced by
$item is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
196
        $this->assertEquals(4, $items->Comments()->count());
0 ignored issues
show
Bug introduced by
The variable $items does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
197
198
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
199
            'nested_comments' => true
200
        ));
201
202
        $this->assertEquals(1, $items->Comments()->count());
203
    }
204
205
    public function testGetCommentsEnabled()
206
    {
207
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
208
            'enabled_cms' => true
209
        ));
210
211
        $item = $this->objFromFixture(CommentableItem::class, 'first');
212
        $this->assertTrue($item->getCommentsEnabled());
213
214
        $item->ProvideComments = 0;
215
        $this->assertFalse($item->getCommentsEnabled());
216
    }
217
218
    public function testGetCommentHolderID()
219
    {
220
        $item = $this->objFromFixture(CommentableItem::class, 'first');
221
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
222
            'comments_holder_id' => 'comments-holder',
223
        ));
224
        $this->assertEquals('commentid_test1', $item->getCommentHolderID());
225
226
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
227
            'comments_holder_id' => 'commtentid_test_another',
228
        ));
229
        $this->assertEquals('commtentid_test_another', $item->getCommentHolderID());
230
    }
231
232
233
    public function testGetPostingRequiredPermission()
234
    {
235
        $this->markTestSkipped('TODO');
236
    }
237
238
    public function testCanModerateComments()
239
    {
240
        // ensure nobody logged in
241
        if (Member::currentUser()) {
0 ignored issues
show
Deprecated Code introduced by
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...
242
            Member::currentUser()->logOut();
0 ignored issues
show
Deprecated Code introduced by
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...
243
        }
244
245
        $item = $this->objFromFixture(CommentableItem::class, 'first');
246
        $this->assertFalse($item->canModerateComments());
247
248
        $this->logInWithPermission('CMS_ACCESS_CommentAdmin');
249
        $this->assertTrue($item->canModerateComments());
250
    }
251
252 View Code Duplication
    public function testGetCommentRSSLink()
0 ignored issues
show
Duplication introduced by
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...
253
    {
254
        Config::inst()->update('SilverStripe\\Control\\Director', 'alternate_base_url', 'http://unittesting.local');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
255
256
        $item = $this->objFromFixture(CommentableItem::class, 'first');
257
        $link = $item->getCommentRSSLink();
258
        $this->assertEquals('http://unittesting.local/comments/rss', $link);
259
    }
260
261 View Code Duplication
    public function testGetCommentRSSLinkPage()
0 ignored issues
show
Duplication introduced by
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...
262
    {
263
        Config::inst()->update('SilverStripe\\Control\\Director', 'alternate_base_url', 'http://unittesting.local');
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
264
265
        $item = $this->objFromFixture(CommentableItem::class, 'first');
266
        $page = $item->getCommentRSSLinkPage();
267
        $this->assertEquals(
268
            'http://unittesting.local/comments/rss/SilverStripe-Comments-Tests-Stubs-CommentableItem/' . $item->ID,
269
            $page
270
        );
271
    }
272
273
    public function testCommentsForm()
274
    {
275
        Config::inst()->update(CommentableItem::class, 'comments', array(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
276
            'include_js' => false,
277
            'comments_holder_id' => 'comments-holder',
278
        ));
279
280
        $item = $this->objFromFixture(CommentableItem::class, 'first');
281
282
        // The comments form is HTML to do assertions by contains
283
        $cf = $item->CommentsForm();
284
        $expected = '<form id="comments-holder" action="/comments'
285
        . '/CommentsForm/" method="post" enctype="application/x-www-form-urlenco'
286
        . 'ded">';
287
288
        $this->assertContains($expected, $cf);
289
        $this->assertContains('<h4>Post your comment</h4>', $cf);
290
291
        // check the comments form exists
292
        $expected = '<input type="text" name="Name" value="ADMIN User" class="text" id="comments-holder_Name" required="required"';
293
        $this->assertContains($expected, $cf);
294
295
        $expected = '<input type="email" name="Email" value="[email protected]" class="email text" id="comments-holder_Email"';
296
        $this->assertContains($expected, $cf);
297
298
        $expected = '<input type="text" name="URL" class="text" id="comments-holder_URL" data-msg-url="Please enter a valid URL"';
299
        $this->assertContains($expected, $cf);
300
301
        $expected = '<input type="hidden" name="ParentID" value="' . $item->ID . '" class="hidden" id="comments-holder_ParentID" />';
302
        $this->assertContains($expected, $cf);
303
304
        $expected = '<textarea name="Comment" class="textarea" id="comments-holder_Comment" required="required"';
305
        $this->assertContains($expected, $cf);
306
307
        $expected = '<input type="submit" name="action_doPostComment" value="Post" class="action" id="comments-holder_action_doPostComment"';
308
        $this->assertContains($expected, $cf);
309
310
        $expected = '<a href="/comments/spam/';
311
        $this->assertContains($expected, $cf);
312
313
        $expected = '<p>Reply to firstComA 1</p>';
314
        $this->assertContains($expected, $cf);
315
316
        $expected = '<a href="/comments/delete';
317
        $this->assertContains($expected, $cf);
318
319
        $expected = '<p>Reply to firstComA 2</p>';
320
        $this->assertContains($expected, $cf);
321
322
        $expected = '<p>Reply to firstComA 3</p>';
323
        $this->assertContains($expected, $cf);
324
325
        // Check for JS inclusion
326
        $backend = Requirements::backend();
327
        $this->assertEquals(
328
            array(),
329
            $backend->getJavascript()
330
        );
331
332
        Config::inst()->update(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
333
            CommentableItem::class,
334
            'comments',
335
            array(
336
                'include_js' => true
337
            )
338
        );
339
        $cf = $item->CommentsForm();
0 ignored issues
show
Unused Code introduced by
$cf is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
340
341
        $backend = Requirements::backend();
342
        $javascriptRequirements = $backend->getJavascript();
343
        $expected = array(
344
            'framework/admin/thirdparty/jquery/jquery.js',
345
            'framework/admin/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js',
346
            'framework/admin/thirdparty/jquery-form/jquery.form.js',
347
            'comments/thirdparty/jquery-validate/jquery.validate.min.js',
348
            /**
349
             * @todo: Is there a replacement for this? The docs are unclear
350
             */
351
            // 'framework/admin/client/src/i18n.js',
352
            'comments/javascript/lang/en.js',
353
            'comments/javascript/CommentsInterface.js'
354
        );
355
356
        foreach ($expected as $javascript) {
357
            $this->assertArrayHasKey($javascript, $javascriptRequirements);
358
        };
359
    }
360
361
    public function testAttachedToSiteTree()
362
    {
363
        $this->markTestSkipped('TODO');
364
    }
365
366
    public function testPagedComments()
367
    {
368
        $item = $this->objFromFixture(CommentableItem::class, 'first');
369
        // Ensure Created times are set, as order not guaranteed if all set to 0
370
        $comments = $item->PagedComments()->sort('ID');
371
        $ctr = 0;
372
        $timeBase = time()-10000;
373
        foreach ($comments as $comment) {
374
            $comment->Created = $timeBase + $ctr * 1000;
375
            $comment->write();
376
            $ctr++;
377
        }
378
379
        $results = $item->PagedComments()->toArray();
380
381
        foreach ($results as $result) {
382
            $result->sourceQueryParams = null;
383
        }
384
385
        $this->assertEquals(
386
            $this->objFromFixture(Comment::class, 'firstComA')->Comment,
387
            $results[3]->Comment
388
        );
389
        $this->assertEquals(
390
            $this->objFromFixture(Comment::class, 'firstComAChild1')->Comment,
391
            $results[2]->Comment
392
        );
393
        $this->assertEquals(
394
            $this->objFromFixture(Comment::class, 'firstComAChild2')->Comment,
395
            $results[1]->Comment
396
        );
397
        $this->assertEquals(
398
            $this->objFromFixture(Comment::class, 'firstComAChild3')->Comment,
399
            $results[0]->Comment
400
        );
401
402
        $this->assertEquals(4, sizeof($results));
403
    }
404
405
    public function testGetCommentsOption()
406
    {
407
        $this->markTestSkipped('TODO');
408
    }
409
410
    public function testUpdateModerationFields()
411
    {
412
        $this->markTestSkipped('TODO');
413
    }
414
415
    public function testUpdateCMSFields()
416
    {
417
        Config::inst()->update(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
418
            CommentableItem::class,
419
            'comments',
420
            array(
421
                'require_login_cms' => false
422
            )
423
        );
424
        $this->logInWithPermission('ADMIN');
425
        $item = $this->objFromFixture(CommentableItem::class, 'first');
426
        $item->ProvideComments = true;
427
        $item->write();
428
        $fields = $item->getCMSFields();
429
        CommentTestHelper::assertFieldsForTab(
430
            $this,
431
            'Root.Comments',
432
            array('CommentsNewCommentsTab', 'CommentsCommentsTab', 'CommentsSpamCommentsTab'),
433
            $fields
434
        );
435
436
        CommentTestHelper::assertFieldsForTab(
437
            $this,
438
            'Root.Comments.CommentsNewCommentsTab',
439
            array('NewComments'),
440
            $fields
441
        );
442
443
        CommentTestHelper::assertFieldsForTab(
444
            $this,
445
            'Root.Comments.CommentsCommentsTab',
446
            array('ApprovedComments'),
447
            $fields
448
        );
449
450
        CommentTestHelper::assertFieldsForTab(
451
            $this,
452
            'Root.Comments.CommentsSpamCommentsTab',
453
            array('SpamComments'),
454
            $fields
455
        );
456
457
        Config::inst()->update(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
458
            CommentableItem::class,
459
            'comments',
460
            array(
461
                'require_login_cms' => true
462
            )
463
        );
464
        $fields = $item->getCMSFields();
465
        CommentTestHelper::assertFieldsForTab($this, 'Root.Settings', array('Comments'), $fields);
466
        $settingsTab = $fields->findOrMakeTab('Root.Settings');
467
        $settingsChildren = $settingsTab->getChildren();
468
        $this->assertEquals(1, $settingsChildren->count());
469
        $fieldGroup = $settingsChildren->first();
470
        $fields = $fieldGroup->getChildren();
471
        CommentTestHelper::assertFieldNames(
472
            $this,
473
            array('ProvideComments', 'CommentsRequireLogin'),
474
            $fields
475
        );
476
477
        Config::inst()->update(
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface SilverStripe\Config\Coll...nfigCollectionInterface as the method update() does only exist in the following implementations of said interface: SilverStripe\Config\Coll...\MemoryConfigCollection.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
478
            CommentableItem::class,
479
            'comments',
480
            array(
481
                'require_login_cms' => true,
482
                'require_moderation_cms' => true
483
            )
484
        );
485
486
        $fields = $item->getCMSFields();
487
        CommentTestHelper::assertFieldsForTab(
488
            $this,
489
            'Root.Settings',
490
            array('Comments', 'ModerationRequired'),
491
            $fields
492
        );
493
        $settingsTab = $fields->findOrMakeTab('Root.Settings');
494
        $settingsChildren = $settingsTab->getChildren();
495
        $this->assertEquals(2, $settingsChildren->count());
496
        $fieldGroup = $settingsChildren->first();
497
        $fields = $fieldGroup->getChildren();
498
        CommentTestHelper::assertFieldNames(
499
            $this,
500
            array('ProvideComments', 'CommentsRequireLogin'),
501
            $fields
502
        );
503
    }
504
}
505