Passed
Push — master ( 964b09...302996 )
by Daniel
59:27 queued 48:09
created

ManyManyThroughListTest::testPolymorphicManyMany()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 67
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 53
nc 1
nop 0
dl 0
loc 67
rs 9.2815
c 0
b 0
f 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\ORM\Tests;
4
5
use SilverStripe\Dev\SapphireTest;
6
use SilverStripe\ORM\DataObject;
7
use SilverStripe\ORM\ManyManyThroughList;
8
use SilverStripe\ORM\Tests\ManyManyThroughListTest\PolyItem;
9
10
class ManyManyThroughListTest extends SapphireTest
11
{
12
    protected static $fixture_file = 'ManyManyThroughListTest.yml';
13
14
    protected static $extra_dataobjects = [
15
        ManyManyThroughListTest\Item::class,
16
        ManyManyThroughListTest\JoinObject::class,
17
        ManyManyThroughListTest\TestObject::class,
18
        ManyManyThroughListTest\PolyItem::class,
19
        ManyManyThroughListTest\PolyJoinObject::class,
20
        ManyManyThroughListTest\PolyObjectA::class,
21
        ManyManyThroughListTest\PolyObjectB::class,
22
    ];
23
24
    protected function setUp()
25
    {
26
        parent::setUp();
27
        DataObject::reset();
28
    }
29
30
    protected function tearDown()
31
    {
32
        DataObject::reset();
33
        parent::tearDown();
34
    }
35
36
    public function testSelectJoin()
37
    {
38
        /** @var ManyManyThroughListTest\TestObject $parent */
39
        $parent = $this->objFromFixture(ManyManyThroughListTest\TestObject::class, 'parent1');
40
        $this->assertListEquals(
41
            [
42
                ['Title' => 'item 1'],
43
                ['Title' => 'item 2']
44
            ],
45
            $parent->Items()
46
        );
47
        // Check filters on list work
48
        $item1 = $parent->Items()->filter('Title', 'item 1')->first();
49
        $this->assertNotNull($item1);
50
        $this->assertNotNull($item1->getJoin());
51
        $this->assertEquals('join 1', $item1->getJoin()->Title);
52
        $this->assertInstanceOf(
53
            ManyManyThroughListTest\JoinObject::class,
54
            $item1->ManyManyThroughListTest_JoinObject
0 ignored issues
show
Bug Best Practice introduced by
The property ManyManyThroughListTest_JoinObject does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
55
        );
56
        $this->assertEquals('join 1', $item1->ManyManyThroughListTest_JoinObject->Title);
57
58
        // Check filters on list work
59
        $item2 = $parent->Items()->filter('Title', 'item 2')->first();
60
        $this->assertNotNull($item2);
61
        $this->assertNotNull($item2->getJoin());
62
        $this->assertEquals('join 2', $item2->getJoin()->Title);
63
        $this->assertEquals('join 2', $item2->ManyManyThroughListTest_JoinObject->Title);
64
65
        // To filter on join table need to use some raw sql
66
        $item2 = $parent->Items()->where(['"ManyManyThroughListTest_JoinObject"."Title"' => 'join 2'])->first();
67
        $this->assertNotNull($item2);
68
        $this->assertEquals('item 2', $item2->Title);
69
        $this->assertNotNull($item2->getJoin());
70
        $this->assertEquals('join 2', $item2->getJoin()->Title);
71
        $this->assertEquals('join 2', $item2->ManyManyThroughListTest_JoinObject->Title);
72
73
        // Test sorting on join table
74
        $items = $parent->Items()->sort('"ManyManyThroughListTest_JoinObject"."Sort"');
75
        $this->assertListEquals(
76
            [
77
                ['Title' => 'item 2'],
78
                ['Title' => 'item 1'],
79
            ],
80
            $items
81
        );
82
83
        $items = $parent->Items()->sort('"ManyManyThroughListTest_JoinObject"."Sort" ASC');
84
        $this->assertListEquals(
85
            [
86
                ['Title' => 'item 1'],
87
                ['Title' => 'item 2'],
88
            ],
89
            $items
90
        );
91
        $items = $parent->Items()->sort('"ManyManyThroughListTest_JoinObject"."Title" DESC');
92
        $this->assertListEquals(
93
            [
94
                ['Title' => 'item 2'],
95
                ['Title' => 'item 1'],
96
            ],
97
            $items
98
        );
99
    }
100
101
    public function testAdd()
102
    {
103
        /** @var ManyManyThroughListTest\TestObject $parent */
104
        $parent = $this->objFromFixture(ManyManyThroughListTest\TestObject::class, 'parent1');
105
        $newItem = new ManyManyThroughListTest\Item();
106
        $newItem->Title = 'my new item';
107
        $newItem->write();
108
        $parent->Items()->add($newItem, ['Title' => 'new join record']);
109
110
        // Check select
111
        $newItem = $parent->Items()->filter(['Title' => 'my new item'])->first();
112
        $this->assertNotNull($newItem);
113
        $this->assertEquals('my new item', $newItem->Title);
114
        $this->assertInstanceOf(
115
            ManyManyThroughListTest\JoinObject::class,
116
            $newItem->getJoin()
117
        );
118
        $this->assertInstanceOf(
119
            ManyManyThroughListTest\JoinObject::class,
120
            $newItem->ManyManyThroughListTest_JoinObject
0 ignored issues
show
Bug Best Practice introduced by
The property ManyManyThroughListTest_JoinObject does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
121
        );
122
        $this->assertEquals('new join record', $newItem->ManyManyThroughListTest_JoinObject->Title);
123
    }
124
125
    public function testRemove()
126
    {
127
        /** @var ManyManyThroughListTest\TestObject $parent */
128
        $parent = $this->objFromFixture(ManyManyThroughListTest\TestObject::class, 'parent1');
129
        $this->assertListEquals(
130
            [
131
                ['Title' => 'item 1'],
132
                ['Title' => 'item 2']
133
            ],
134
            $parent->Items()
135
        );
136
        $item1 = $parent->Items()->filter(['Title' => 'item 1'])->first();
137
        $parent->Items()->remove($item1);
138
        $this->assertListEquals(
139
            [['Title' => 'item 2']],
140
            $parent->Items()
141
        );
142
    }
143
144
    /**
145
     * Test validation
146
     *
147
     * @expectedException \InvalidArgumentException
148
     */
149
    public function testValidateModelValidatesJoinType()
150
    {
151
        DataObject::reset();
152
        ManyManyThroughListTest\Item::config()->update(
153
            'db',
154
            [
155
            ManyManyThroughListTest\JoinObject::class => 'Text'
156
            ]
157
        );
158
159
        DataObject::getSchema()->manyManyComponent(ManyManyThroughListTest\TestObject::class, 'Items');
160
    }
161
162
    public function testRelationParsing()
163
    {
164
        $schema = DataObject::getSchema();
165
166
        // Parent components
167
        $this->assertEquals(
168
            [
169
                'relationClass' => ManyManyThroughList::class,
170
                'parentClass' => ManyManyThroughListTest\TestObject::class,
171
                'childClass' => ManyManyThroughListTest\Item::class,
172
                'parentField' => 'ParentID',
173
                'childField' => 'ChildID',
174
                'join' => ManyManyThroughListTest\JoinObject::class
175
            ],
176
            $schema->manyManyComponent(ManyManyThroughListTest\TestObject::class, 'Items')
177
        );
178
179
        // Belongs_many_many is the same, but with parent/child substituted
180
        $this->assertEquals(
181
            [
182
                'relationClass' => ManyManyThroughList::class,
183
                'parentClass' => ManyManyThroughListTest\Item::class,
184
                'childClass' => ManyManyThroughListTest\TestObject::class,
185
                'parentField' => 'ChildID',
186
                'childField' => 'ParentID',
187
                'join' => ManyManyThroughListTest\JoinObject::class
188
            ],
189
            $schema->manyManyComponent(ManyManyThroughListTest\Item::class, 'Objects')
190
        );
191
    }
192
193
    /**
194
     * Note: polymorphic many_many support is currently experimental
195
     */
196
    public function testPolymorphicManyMany()
197
    {
198
        /** @var ManyManyThroughListTest\PolyObjectA $objA1 */
199
        $objA1 = $this->objFromFixture(ManyManyThroughListTest\PolyObjectA::class, 'obja1');
200
        /** @var ManyManyThroughListTest\PolyObjectB $objB1 */
201
        $objB1 = $this->objFromFixture(ManyManyThroughListTest\PolyObjectB::class, 'objb1');
202
        /** @var ManyManyThroughListTest\PolyObjectB $objB2 */
203
        $objB2 = $this->objFromFixture(ManyManyThroughListTest\PolyObjectB::class, 'objb2');
204
205
        // Test various parent class queries
206
        $this->assertListEquals([
207
            ['Title' => 'item 1'],
208
            ['Title' => 'item 2'],
209
        ], $objA1->Items());
210
        $this->assertListEquals([
211
            ['Title' => 'item 2'],
212
        ], $objB1->Items());
213
        $this->assertListEquals([
214
            ['Title' => 'item 2'],
215
        ], $objB2->Items());
216
217
        // Test adding items
218
        $newItem = new PolyItem();
219
        $newItem->Title = 'New Item';
220
        $objA1->Items()->add($newItem);
221
        $objB2->Items()->add($newItem);
222
        $this->assertListEquals([
223
            ['Title' => 'item 1'],
224
            ['Title' => 'item 2'],
225
            ['Title' => 'New Item'],
226
        ], $objA1->Items());
227
        $this->assertListEquals([
228
            ['Title' => 'item 2'],
229
        ], $objB1->Items());
230
        $this->assertListEquals([
231
            ['Title' => 'item 2'],
232
            ['Title' => 'New Item'],
233
        ], $objB2->Items());
234
235
        // Test removing items
236
        $item2 = $this->objFromFixture(ManyManyThroughListTest\PolyItem::class, 'child2');
237
        $objA1->Items()->remove($item2);
238
        $objB1->Items()->remove($item2);
239
        $this->assertListEquals([
240
            ['Title' => 'item 1'],
241
            ['Title' => 'New Item'],
242
        ], $objA1->Items());
243
        $this->assertListEquals([], $objB1->Items());
244
        $this->assertListEquals([
245
            ['Title' => 'item 2'],
246
            ['Title' => 'New Item'],
247
        ], $objB2->Items());
248
249
        // Test set-by-id-list
250
        $objB2->Items()->setByIDList([
251
            $newItem->ID,
252
            $this->idFromFixture(ManyManyThroughListTest\PolyItem::class, 'child1'),
253
        ]);
254
        $this->assertListEquals([
255
            ['Title' => 'item 1'],
256
            ['Title' => 'New Item'],
257
        ], $objA1->Items());
258
        $this->assertListEquals([], $objB1->Items());
259
        $this->assertListEquals([
260
            ['Title' => 'item 1'],
261
            ['Title' => 'New Item'],
262
        ], $objB2->Items());
263
    }
264
}
265