Passed
Push — 4 ( d1e890...251093 )
by Damian
06:37 queued 10s
created

ManyManyThroughListTest::testGetJoinTable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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