Completed
Push — master ( c5047e...3a177f )
by Gabriel
03:52
created

RecordsTest::testGetRelationClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 9

Duplication

Lines 13
Ratio 100 %

Importance

Changes 0
Metric Value
dl 13
loc 13
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 9
nc 1
nop 0
1
<?php
2
3
namespace Nip\Records\Tests;
4
5
use Mockery as m;
6
use Nip\Database\Connections\Connection;
7
use Nip\Records\Collections\Collection;
8
use Nip\Records\RecordManager as Records;
9
use Nip\Request;
10
use Nip\Records\Tests\AbstractTest;
11
12
/**
13
 * Class RecordsTest
14
 * @package Nip\Records\Tests
15
 */
16
class RecordsTest extends AbstractTest
17
{
18
19
    /**
20
     * @var Records
21
     */
22
    protected $_object;
23
24
    public function testSetModel()
25
    {
26
        $this->_object->setModel('Row');
27
        self::assertEquals($this->_object->getModel(), 'Row');
28
29
        $this->_object->setModel('Row2');
30
        self::assertEquals($this->_object->getModel(), 'Row2');
31
    }
32
33
    public function testGetFullNameTable()
34
    {
35
        self::assertEquals('pages', $this->_object->getFullNameTable());
36
37
        $this->_object->getDB()->setDatabase('database_name');
38
        self::assertEquals('database_name.pages', $this->_object->getFullNameTable());
39
    }
40
41
    // tests
42
43
    public function testGenerateModelClass()
44
    {
45
        self::assertEquals($this->_object->generateModelClass('Notifications\Table'), 'Notifications\Row');
46
        self::assertEquals($this->_object->generateModelClass('Notifications_Tables'), 'Notifications_Table');
47
        self::assertEquals($this->_object->generateModelClass('Notifications'), 'Notification');
48
        self::assertEquals($this->_object->generateModelClass('Persons'), 'Person');
49
    }
50
51
    /**
52
     * @return array
53
     */
54
    public function providerGetController()
55
    {
56
        return [
57
            ["notifications-tables", "Notifications_Tables"],
58
            ["notifications-tables", "Notifications\\Tables\\Tables"],
59
            ["notifications-tables", "App\\Models\\Notifications\\Tables\\Tables"],
60
        ];
61
    }
62
63
    /**
64
     * @dataProvider providerGetController
65
     * @param $controller
66
     * @param $class
67
     */
68
    public function testGetController($controller, $class)
69
    {
70
        /** @var Records $records */
71
        $records = new Records();
72
        $records->setClassName($class);
73
74
        self::assertEquals($controller, $records->getController());
75
    }
76
77
//    public function testInitRelationsFromArrayBelongsToSimple()
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
78
//    {
79
    /** @var Records $users */
80
//        $users = m::namedMock('Users', Records::class)->shouldDeferMissing()
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
81
//            ->shouldReceive('instance')->andReturnSelf()
82
//            ->getMock();
83
84
//        $users->setPrimaryFK('id_user');
0 ignored issues
show
Unused Code Comprehensibility introduced by
55% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
85
//
86
//        m::namedMock('User', Records::class);
87
//        m::namedMock('Articles', Records::class);
88
89
//        $this->_object->setPrimaryFK('id_object');
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
90
//
91
//        $this->_object->initRelationsFromArray('belongsTo', ['User']);
92
//        $this->_testInitRelationsFromArrayBelongsToUser('User');
93
//
94
//        $this->_object->initRelationsFromArray('belongsTo', [
95
//            'UserName' => ['with' => $users],
96
//        ]);
97
//        $this->_testInitRelationsFromArrayBelongsToUser('UserName');
98
//
99
//        self::assertSame($users, $this->_object->getRelation('User')->getWith());
100
//    }
101
102
    public function testNewCollection()
103
    {
104
        $collection = $this->_object->newCollection();
105
        self::assertInstanceOf('Nip\Records\Collections\Collection', $collection);
106
        self::assertSame($this->_object, $collection->getManager());
107
    }
108
109
    public function testRequestFilters()
110
    {
111
        $request = new Request();
112
        $params = [
113
            'title' => 'Test title',
114
            'name' => 'Test name',
115
        ];
116
        $request->query->add($params);
117
118
        $this->_object->getFilterManager()->addFilter(
119
            $this->_object->getFilterManager()->newFilter('Column\BasicFilter')
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Nip\Records\Filters\AbstractFilter as the method setField() does only exist in the following sub-classes of Nip\Records\Filters\AbstractFilter: Nip\Records\Filters\Column\AbstractFilter, Nip\Records\Filters\Column\BasicFilter, Nip\Records\Filters\Column\WildcardFilter. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
120
                ->setField('title')
121
        );
122
123
        $this->_object->getFilterManager()->addFilter(
124
            $this->_object->getFilterManager()->newFilter('Column\BasicFilter')
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Nip\Records\Filters\AbstractFilter as the method setField() does only exist in the following sub-classes of Nip\Records\Filters\AbstractFilter: Nip\Records\Filters\Column\AbstractFilter, Nip\Records\Filters\Column\BasicFilter, Nip\Records\Filters\Column\WildcardFilter. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

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

class MyUser extends 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 sub-classes 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 parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
125
                ->setField('name')
126
        );
127
128
        $filtersArray = $this->_object->requestFilters($request);
129
        self::assertSame($filtersArray, $params);
130
    }
131
132
    /**
133
     * @return array
134
     */
135
    public function providerGetPrimaryFK()
136
    {
137
        return [
138
            ["id_user", "Users"],
139
            ["id_race_entry", "RaceEntries"],
140
            ["id_notifications_table", "Notifications_Tables"],
141
            ["id_notifications_table", "Notifications\\Tables\\Tables"],
142
            ["id_notifications_table", "App\\Models\\Notifications\\Tables\\Tables"],
143
        ];
144
    }
145
146
    /**
147
     * @dataProvider providerGetPrimaryFK
148
     * @param $primaryFK
149
     * @param $class
150
     */
151
    public function testGetPrimaryFK($primaryFK, $class)
152
    {
153
        /** @var Records $records */
154
//        $records = m::namedMock($class, 'Records')->shouldDeferMissing()
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
155
//            ->shouldReceive('instance')->andReturnSelf()
156
//            ->shouldReceive('getPrimaryKey')->andReturn('id')
157
//            ->getMock();
158
        $records = new Records();
159
        $records->setClassName($class);
160
        $records->setPrimaryKey('id');
161
162
        self::assertEquals($primaryFK, $records->getPrimaryFK());
163
    }
164
165
    public function testGetPrimaryKey()
166
    {
167
        $records = new Records();
168
        $tableStructure = unserialize(file_get_contents(TEST_FIXTURE_PATH . '/database_structure/users.serialize'));
169
        $records->setTableStructure($tableStructure);
170
        $records->setPrimaryKey('id');
171
172
        self::assertEquals('id', $records->getPrimaryKey());
173
    }
174
175
    public function testGetCollectionClass()
176
    {
177
        self::assertEquals(Collection::class, $this->_object->getCollectionClass());
178
    }
179
180 View Code Duplication
    protected 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...
181
    {
182
        parent::setUp();
183
184
        $wrapper = new Connection(null);
0 ignored issues
show
Documentation introduced by
null is of type null, but the function expects a object<PDO>|object<Closure>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
185
186
        $this->_object = m::mock(Records::class)->shouldDeferMissing()
187
            ->shouldReceive('getRequest')->andReturn(Request::create('/'))
188
            ->getMock();
189
190
        $this->_object->setDB($wrapper);
191
        $this->_object->setTable('pages');
192
    }
193
}
194