Passed
Push — pulls/manymanylist-add-callbac... ( aed064...34c05d )
by Ingo
13:26
created

HasManyListTest::testRemoveCallbackOnRemoveById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 14
rs 10
1
<?php
2
3
namespace SilverStripe\ORM\Tests;
4
5
use SilverStripe\Dev\SapphireTest;
6
use SilverStripe\ORM\Tests\DataObjectTest\Player;
7
use SilverStripe\ORM\Tests\DataObjectTest\Team;
8
use SilverStripe\ORM\Tests\HasManyListTest\Company;
9
use SilverStripe\ORM\Tests\HasManyListTest\CompanyCar;
10
use SilverStripe\ORM\Tests\HasManyListTest\Employee;
11
12
class HasManyListTest extends SapphireTest
13
{
14
15
    protected static $fixture_file = [
16
        'DataObjectTest.yml', // Borrow the model from DataObjectTest
17
        'HasManyListTest.yml',
18
    ];
19
20
    public static $extra_data_objects = [
21
        Company::class,
22
        Employee::class,
23
        CompanyCar::class,
24
    ];
25
26
    public static function getExtraDataObjects()
27
    {
28
        return array_merge(
29
            DataObjectTest::$extra_data_objects,
30
            ManyManyListTest::$extra_data_objects,
31
            static::$extra_data_objects
32
        );
33
    }
34
35
    public function testRelationshipEmptyOnNewRecords()
36
    {
37
        // Relies on the fact that (unrelated) comments exist in the fixture file already
38
        $newTeam = new Team(); // has_many Comments
39
        $this->assertEquals([], $newTeam->Comments()->column('ID'));
40
    }
41
42
    /**
43
     * Test that related objects can be removed from a relation
44
     */
45
    public function testRemoveRelation()
46
    {
47
48
        // Check that expected teams exist
49
        $list = Team::get();
50
        $this->assertEquals(
51
            ['Subteam 1', 'Subteam 2', 'Subteam 3', 'Team 1', 'Team 2', 'Team 3'],
52
            $list->sort('Title')->column('Title')
53
        );
54
55
        // Test that each team has the correct fans
56
        $team1 = $this->objFromFixture(DataObjectTest\Team::class, 'team1');
57
        $team2 = $this->objFromFixture(DataObjectTest\Team::class, 'team2');
58
        $this->assertEquals(['Bob', 'Joe'], $team1->Comments()->sort('Name')->column('Name'));
0 ignored issues
show
Bug introduced by
The method Comments() does not exist on SilverStripe\ORM\DataObject. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

58
        $this->assertEquals(['Bob', 'Joe'], $team1->/** @scrutinizer ignore-call */ Comments()->sort('Name')->column('Name'));
Loading history...
59
        $this->assertEquals(['Phil'], $team2->Comments()->sort('Name')->column('Name'));
60
61
        // Test that removing comments from unrelated team has no effect
62
        $team1comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment1');
63
        $team2comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment3');
64
        $team1->Comments()->remove($team2comment);
65
        $team2->Comments()->remove($team1comment);
66
        $this->assertEquals(['Bob', 'Joe'], $team1->Comments()->sort('Name')->column('Name'));
67
        $this->assertEquals(['Phil'], $team2->Comments()->sort('Name')->column('Name'));
68
        $this->assertEquals($team1->ID, $team1comment->TeamID);
0 ignored issues
show
Bug Best Practice introduced by
The property TeamID does not exist on SilverStripe\ORM\DataObject. Since you implemented __get, consider adding a @property annotation.
Loading history...
69
        $this->assertEquals($team2->ID, $team2comment->TeamID);
70
71
        // Test that removing items from the related team resets the has_one relations on the fan
72
        $team1comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment1');
73
        $team2comment = $this->objFromFixture(DataObjectTest\TeamComment::class, 'comment3');
74
        $team1->Comments()->remove($team1comment);
75
        $team2->Comments()->remove($team2comment);
76
        $this->assertEquals(['Bob'], $team1->Comments()->sort('Name')->column('Name'));
77
        $this->assertEquals([], $team2->Comments()->sort('Name')->column('Name'));
78
        $this->assertEmpty($team1comment->TeamID);
79
        $this->assertEmpty($team2comment->TeamID);
80
    }
81
82
    public function testDefaultSortIsUsedOnList()
83
    {
84
        /** @var Company $company */
85
        $company = $this->objFromFixture(Company::class, 'silverstripe');
86
87
        $this->assertListEquals([
88
            ['Make' => 'Ferrari'],
89
            ['Make' => 'Jaguar'],
90
            ['Make' => 'Lamborghini'],
91
        ], $company->CompanyCars());
0 ignored issues
show
Bug introduced by
The method CompanyCars() does not exist on SilverStripe\ORM\Tests\HasManyListTest\Company. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

91
        ], $company->/** @scrutinizer ignore-call */ CompanyCars());
Loading history...
92
    }
93
94
    public function testCanBeSortedDescending()
95
    {
96
        /** @var Company $company */
97
        $company = $this->objFromFixture(Company::class, 'silverstripe');
98
99
        $this->assertListEquals([
100
            ['Make' => 'Lamborghini'],
101
            ['Make' => 'Jaguar'],
102
            ['Make' => 'Ferrari'],
103
        ], $company->CompanyCars()->sort('"Make" DESC'));
104
    }
105
106
    public function testSortByModel()
107
    {
108
        /** @var Company $company */
109
        $company = $this->objFromFixture(Company::class, 'silverstripe');
110
111
        $this->assertListEquals([
112
            ['Model' => 'Countach'],
113
            ['Model' => 'E Type'],
114
            ['Model' => 'F40'],
115
        ], $company->CompanyCars()->sort('"Model" ASC'));
116
    }
117
118
    public function testCallbackOnSetById()
119
    {
120
        $addedIds = [];
121
        $removedIds = [];
122
123
        $base = $this->objFromFixture(Company::class, 'silverstripe');
124
        $relation = $base->Employees();
0 ignored issues
show
Bug introduced by
The method Employees() does not exist on SilverStripe\ORM\DataObject. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

124
        /** @scrutinizer ignore-call */ 
125
        $relation = $base->Employees();
Loading history...
125
        $remove = $relation->First();
126
        $add = new Employee();
127
        $add->write();
128
129
        $relation->addCallbacks()->add(function ($list, $item) use (&$addedIds) {
130
            $addedIds[] = $item;
131
        });
132
133
        $relation->removeCallbacks()->add(function ($list, $ids) use (&$removedIds) {
134
            $removedIds = $ids;
135
        });
136
137
        $relation->setByIDList(array_merge(
138
            $base->Employees()->exclude('ID', $remove->ID)->column('ID'),
139
            [$add->ID]
140
        ));
141
        $this->assertEquals([$remove->ID], $removedIds);
142
    }
143
144
    public function testAddCallback()
145
    {
146
        $added = [];
147
148
        $base = $this->objFromFixture(Company::class, 'silverstripe');
149
        $relation = $base->Employees();
150
        $add = new Employee();
151
        $add->write();
152
153
        $relation->addCallbacks()->add(function ($list, $item) use (&$added) {
154
            $added[] = $item;
155
        });
156
157
        $relation->add($add);
158
        $this->assertEquals([$add], $added);
159
    }
160
161
    public function testRemoveCallbackOnRemove()
162
    {
163
        $removedIds = [];
164
165
        $base = $this->objFromFixture(Company::class, 'silverstripe');
166
        $relation = $base->Employees();
167
        $remove = $relation->First();
168
169
        $relation->removeCallbacks()->add(function ($list, $ids) use (&$removedIds) {
170
            $removedIds = $ids;
171
        });
172
173
        $relation->remove($remove);
174
        $this->assertEquals([$remove->ID], $removedIds);
175
    }
176
177
    public function testRemoveCallbackOnRemoveById()
178
    {
179
        $removedIds = [];
180
181
        $base = $this->objFromFixture(Company::class, 'silverstripe');
182
        $relation = $base->Employees();
183
        $remove = $relation->First();
184
185
        $relation->removeCallbacks()->add(function ($list, $ids) use (&$removedIds) {
186
            $removedIds = $ids;
187
        });
188
189
        $relation->removeByID($remove->ID);
190
        $this->assertEquals([$remove->ID], $removedIds);
191
    }
192
}
193