Passed
Push — master ( 19e483...625e7f )
by Mathieu
04:13
created

JsonImporterTest::testImportNullRelation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 15
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace MathieuTu\JsonSyncer\Tests;
4
5
use MathieuTu\JsonSyncer\Exceptions\JsonDecodingException;
6
use MathieuTu\JsonSyncer\Exceptions\UnknownAttributeException;
7
use MathieuTu\JsonSyncer\Tests\Stubs\Bar;
8
use MathieuTu\JsonSyncer\Tests\Stubs\Baz;
9
use MathieuTu\JsonSyncer\Tests\Stubs\DoNotExport;
10
use MathieuTu\JsonSyncer\Tests\Stubs\Foo;
11
12
class JsonImporterTest extends TestCase
13
{
14
    public function testImportFromJson()
15
    {
16
        Foo::importFromJson(file_get_contents(__DIR__ . '/Stubs/import.json'));
17
        $this->assertAllImportedInDatabase();
18
    }
19
20
    protected function assertAllImportedInDatabase()
21
    {
22
        $this->assertFooIsImported();
23
        $this->assertBarsAreImported();
24
        $this->assertBazsAreImported();
25
        $this->assertEquals(0, DoNotExport::count());
26
    }
27
28
    protected function assertFooIsImported()
29
    {
30
        $this->assertEquals(1, Foo::count());
31
        $this->assertEquals(
32
            ['id' => 1, 'author' => 'Mathieu TUDISCO', 'username' => '@mathieutu'],
33
            Foo::first()->toArray()
34
        );
35
    }
36
37
    protected function assertBarsAreImported()
38
    {
39
        $this->assertEquals(2, Bar::count());
40
        $bars = Foo::first()->bars;
41
        $this->assertEquals([
42
            ['id' => 1, 'name' => 'bar1', 'foo_id' => 1],
43
            ['id' => 2, 'name' => 'bar2', 'foo_id' => 1],
44
        ], $bars->toArray());
45
    }
46
47
    protected function assertBazsAreImported()
48
    {
49
        $this->assertEquals(2, Baz::count());
50
        foreach (Foo::with('bars.baz')->first()->bars as $bar) {
51
            $baz = $bar->baz;
52
            $this->assertEquals(['id' => $baz->id, 'name' => $bar->name . '_baz', 'bar_id' => $bar->id], $baz->toArray());
53
        }
54
    }
55
56
    public function testImportWithoutRelation()
57
    {
58
        $import = $this->getImportArray();
59
60
        unset($import['bars'][1]['baz']);
61
62
        Foo::importFromJson($import);
63
64
        $this->assertFooIsImported();
65
        $this->assertBarsAreImported();
66
67
        $this->assertEquals(1, Baz::count());
68
        $baz = Foo::with('bars.baz')->first()->bars->pluck('baz');
69
        $this->assertEquals([['id' => 1, 'name' => 'bar1_baz', 'bar_id' => '1'], null], $baz->toArray());
70
    }
71
72
    private function getImportArray(): array
73
    {
74
        return json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true);
75
    }
76
77
    public function testImportWithAnEmptyRelation()
78
    {
79
        $import = $this->getImportArray();
80
81
        $import['bars'] = [];
82
83
        $import = json_encode($import);
84
85
        Foo::importFromJson($import);
86
87
        $this->assertEquals(1, Foo::count());
88
        $this->assertEquals(0, Bar::count());
89
        $this->assertEquals(0, Baz::count());
90
        $this->assertEquals(0, DoNotExport::count());
91
    }
92
93
    public function testImportSeveralTimesWillJustAdd()
94
    {
95
        $import = $this->getImportArray();
96
97
        Foo::importFromJson($import);
98
99
        $fooCount = Foo::count();
100
        $barCount = Bar::count();
101
        $bazCount = Baz::count();
102
        $doNotExportCount = DoNotExport::count();
103
104
        foreach (range(1, 3) as $time) {
105
            $this->assertEquals($time * $fooCount, Foo::count());
106
            $this->assertEquals($time * $barCount, Bar::count());
107
            $this->assertEquals($time * $bazCount, Baz::count());
108
            $this->assertEquals($time * $doNotExportCount, DoNotExport::count());
109
110
            Foo::importFromJson($import);
111
        }
112
    }
113
114
    public function testImportFromArray()
115
    {
116
        Foo::importFromJson($this->getImportArray());
117
118
        $this->assertAllImportedInDatabase();
119
    }
120
121
    public function testImportNullRelation()
122
    {
123
        $objects = $this->getImportArray();
124
        $objects['bars'] = null;
125
126
        Foo::importFromJson($objects);
127
128
        $this->assertFooIsImported();
129
130
        $this->assertEquals(0, Bar::count());
131
        $bars = Foo::first()->bars;
132
        $this->assertEquals([], $bars->toArray());
133
134
        $this->assertEquals(0, Baz::count());
135
        $this->assertEquals(0, DoNotExport::count());
136
    }
137
138
    public function testImportNullAttribute()
139
    {
140
        $objects = $this->getImportArray();
141
        $objects['author'] = null;
142
143
        Foo::importFromJson($objects);
144
145
        $this->assertEquals(1, Foo::count());
146
        $this->assertEquals(['id' => 1, 'author' => null, 'username' => '@mathieutu'], Foo::first()->toArray());
147
148
        $this->assertBarsAreImported();
149
        $this->assertBazsAreImported();
150
        $this->assertEquals(0, DoNotExport::count());
151
    }
152
153
    public function testImportBadJson()
154
    {
155
        $this->expectException(JsonDecodingException::class);
156
157
        Foo::importFromJson('badJson');
158
    }
159
160
    public function testImportUnWantedData()
161
    {
162
        $import = $this->getImportArray();
163
        $import['bad'] = 'attribute';
164
165
        Foo::importFromJson($import);
166
167
        $this->assertAllImportedInDatabase();
168
    }
169
170
    public function testImportNonRelationMethodWithDefaultRelations()
171
    {
172
        $import = $this->getImportArray();
173
        $import['otherMethod'] = ['Hello you!'];
174
175
        Foo::importFromJson($import);
176
177
        $this->assertAllImportedInDatabase();
178
    }
179
180
    public function testImportANonRelationMethodWithCustomRelations()
181
    {
182
        $this->expectException(UnknownAttributeException::class);
183
        $this->expectExceptionMessage("Unknown attribute or HasOneorMany relation 'otherMethod' in 'MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo'");
184
185
        $import = $this->getImportArray();
186
        $import['otherMethod'] = [];
187
188
        (new Foo)->setJsonImportableRelationsForTests(['bars', 'otherMethod'])
189
            ->instanceImportForTests($import);
190
    }
191
192
    public function testImportUnknownRelationWithCustomRelations()
193
    {
194
        $this->expectException(UnknownAttributeException::class);
195
        $this->expectExceptionMessage("Unknown attribute or HasOneorMany relation 'test' in 'MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo'.");
196
197
        $import = $this->getImportArray();
198
        $import['test'] = [];
199
200
        (new Foo)->setJsonImportableRelationsForTests(['bars', 'test'])
201
            ->instanceImportForTests($import);
202
    }
203
204
    public function testImportWithCustomRelationsAndAttributes()
205
    {
206
        $import = $this->getImportArray();
207
208
        (new Foo)->setJsonImportableRelationsForTests(['bars'])
209
            ->setJsonImportableAttributesForTests(['author'])
210
            ->instanceImportForTests($import);
211
212
        $this->assertEquals(['id' => 1, 'author' => 'Mathieu TUDISCO', 'username' => null], Foo::first()->toArray());
213
        $this->assertBarsAreImported();
214
        $this->assertBazsAreImported();
215
    }
216
217
    public function testIsImportingMethod()
218
    {
219
        $import = [
220
            'author' => 'Mathieu',
221
        ];
222
223
        $foo = new class extends Foo
224
        {
225
            protected $fillable = ['author'];
226
            protected $table = 'foos';
227
228
            public function setAuthorAttribute()
229
            {
230
                if ($this->isImporting()) {
231
                    throw new \Exception('Is importing ok !');
232
                }
233
234
                $this->attributes['author'] = 'not importing';
235
            }
236
        };
237
238
        $foo->author = 'test';
0 ignored issues
show
Bug introduced by
The property author does not seem to exist on anonymous//tests/JsonImporterTest.php$0. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
239
        $this->assertEquals('not importing', $foo->author);
240
241
        $this->expectExceptionMessage('Is importing ok !');
242
243
        $foo->setJsonImportableAttributesForTests(array_keys($import))
244
            ->instanceImportForTests($import);
245
    }
246
247
    public function testImportNonImportableObjects()
248
    {
249
        $baz = [
250
            'name' => 'baz_test',
251
            'doNots' => [
252
                'name' => 'Do not import !',
253
            ],
254
        ];
255
256
        Baz::importFromJson($baz);
257
        $this->assertEquals(1, Baz::count());
258
        $this->assertEquals(0, DoNotExport::count());
259
    }
260
}
261