JsonImporterTest::testImportNullRelation()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 15
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 9
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 15
rs 9.9666
1
<?php
2
3
namespace MathieuTu\JsonSyncer\Tests;
4
5
use JsonException;
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 testImportFromArrayable()
122
    {
123
        Foo::importFromJson(collect($this->getImportArray()));
124
125
        $this->assertAllImportedInDatabase();
126
    }
127
128
    public function testImportNullRelation()
129
    {
130
        $objects = $this->getImportArray();
131
        $objects['bars'] = null;
132
133
        Foo::importFromJson($objects);
134
135
        $this->assertFooIsImported();
136
137
        $this->assertEquals(0, Bar::count());
138
        $bars = Foo::first()->bars;
139
        $this->assertEquals([], $bars->toArray());
140
141
        $this->assertEquals(0, Baz::count());
142
        $this->assertEquals(0, DoNotExport::count());
143
    }
144
145
    public function testImportNullAttribute()
146
    {
147
        $objects = $this->getImportArray();
148
        $objects['author'] = null;
149
150
        Foo::importFromJson($objects);
151
152
        $this->assertEquals(1, Foo::count());
153
        $this->assertEquals(['id' => 1, 'author' => null, 'username' => '@mathieutu'], Foo::first()->toArray());
154
155
        $this->assertBarsAreImported();
156
        $this->assertBazsAreImported();
157
        $this->assertEquals(0, DoNotExport::count());
158
    }
159
160
    public function testImportBadJson()
161
    {
162
        $this->expectException(JsonException::class);
163
        $this->expectExceptionMessage('Syntax error');
164
165
        Foo::importFromJson('badJson');
166
    }
167
168
    public function testImportUnWantedData()
169
    {
170
        $import = $this->getImportArray();
171
        $import['bad'] = 'attribute';
172
173
        Foo::importFromJson($import);
174
175
        $this->assertAllImportedInDatabase();
176
    }
177
178
    public function testImportNonRelationMethodWithDefaultRelations()
179
    {
180
        $import = $this->getImportArray();
181
        $import['otherMethod'] = ['Hello you!'];
182
183
        Foo::importFromJson($import);
184
185
        $this->assertAllImportedInDatabase();
186
    }
187
188
    public function testImportANonRelationMethodWithCustomRelations()
189
    {
190
        $this->expectException(UnknownAttributeException::class);
191
        $this->expectExceptionMessage("Unknown attribute or HasOneorMany relation 'otherMethod' in 'MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo'");
192
193
        $import = $this->getImportArray();
194
        $import['otherMethod'] = [];
195
196
        (new Foo)->setJsonImportableRelationsForTests(['bars', 'otherMethod'])
197
            ->instanceImportForTests($import);
198
    }
199
200
    public function testImportUnknownRelationWithCustomRelations()
201
    {
202
        $this->expectException(UnknownAttributeException::class);
203
        $this->expectExceptionMessage("Unknown attribute or HasOneorMany relation 'test' in 'MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo'.");
204
205
        $import = $this->getImportArray();
206
        $import['test'] = [];
207
208
        (new Foo)->setJsonImportableRelationsForTests(['bars', 'test'])
209
            ->instanceImportForTests($import);
210
    }
211
212
    public function testImportWithCustomRelationsAndAttributes()
213
    {
214
        $import = $this->getImportArray();
215
216
        (new Foo)->setJsonImportableRelationsForTests(['bars'])
217
            ->setJsonImportableAttributesForTests(['author'])
218
            ->instanceImportForTests($import);
219
220
        $this->assertEquals(['id' => 1, 'author' => 'Mathieu TUDISCO', 'username' => null], Foo::first()->toArray());
221
        $this->assertBarsAreImported();
222
        $this->assertBazsAreImported();
223
    }
224
225
    public function testIsImportingMethod()
226
    {
227
        $import = [
228
            'author' => 'Mathieu',
229
        ];
230
231
        $foo = new class extends Foo
232
        {
233
            protected $fillable = ['author'];
234
            protected $table = 'foos';
235
236
            public function setAuthorAttribute()
237
            {
238
                if ($this->isImporting()) {
239
                    throw new \Exception('Is importing ok !');
240
                }
241
242
                $this->attributes['author'] = 'not importing';
243
            }
244
        };
245
246
        $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...
247
        $this->assertEquals('not importing', $foo->author);
248
249
        $this->expectExceptionMessage('Is importing ok !');
250
251
        $foo->setJsonImportableAttributesForTests(array_keys($import))
252
            ->instanceImportForTests($import);
253
    }
254
255
    public function testImportNonImportableObjects()
256
    {
257
        $baz = [
258
            'name' => 'baz_test',
259
            'doNots' => [
260
                'name' => 'Do not import !',
261
            ],
262
        ];
263
264
        Baz::importFromJson($baz);
265
        $this->assertEquals(1, Baz::count());
266
        $this->assertEquals(0, DoNotExport::count());
267
    }
268
}
269