Passed
Push — master ( 625e7f...d214cd )
by Mathieu
02:09
created

JsonImporterTest::testImportFromArrayable()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 5
rs 10
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 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(JsonDecodingException::class);
163
164
        Foo::importFromJson('badJson');
165
    }
166
167
    public function testImportUnWantedData()
168
    {
169
        $import = $this->getImportArray();
170
        $import['bad'] = 'attribute';
171
172
        Foo::importFromJson($import);
173
174
        $this->assertAllImportedInDatabase();
175
    }
176
177
    public function testImportNonRelationMethodWithDefaultRelations()
178
    {
179
        $import = $this->getImportArray();
180
        $import['otherMethod'] = ['Hello you!'];
181
182
        Foo::importFromJson($import);
183
184
        $this->assertAllImportedInDatabase();
185
    }
186
187
    public function testImportANonRelationMethodWithCustomRelations()
188
    {
189
        $this->expectException(UnknownAttributeException::class);
190
        $this->expectExceptionMessage("Unknown attribute or HasOneorMany relation 'otherMethod' in 'MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo'");
191
192
        $import = $this->getImportArray();
193
        $import['otherMethod'] = [];
194
195
        (new Foo)->setJsonImportableRelationsForTests(['bars', 'otherMethod'])
196
            ->instanceImportForTests($import);
197
    }
198
199
    public function testImportUnknownRelationWithCustomRelations()
200
    {
201
        $this->expectException(UnknownAttributeException::class);
202
        $this->expectExceptionMessage("Unknown attribute or HasOneorMany relation 'test' in 'MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo'.");
203
204
        $import = $this->getImportArray();
205
        $import['test'] = [];
206
207
        (new Foo)->setJsonImportableRelationsForTests(['bars', 'test'])
208
            ->instanceImportForTests($import);
209
    }
210
211
    public function testImportWithCustomRelationsAndAttributes()
212
    {
213
        $import = $this->getImportArray();
214
215
        (new Foo)->setJsonImportableRelationsForTests(['bars'])
216
            ->setJsonImportableAttributesForTests(['author'])
217
            ->instanceImportForTests($import);
218
219
        $this->assertEquals(['id' => 1, 'author' => 'Mathieu TUDISCO', 'username' => null], Foo::first()->toArray());
220
        $this->assertBarsAreImported();
221
        $this->assertBazsAreImported();
222
    }
223
224
    public function testIsImportingMethod()
225
    {
226
        $import = [
227
            'author' => 'Mathieu',
228
        ];
229
230
        $foo = new class extends Foo
231
        {
232
            protected $fillable = ['author'];
233
            protected $table = 'foos';
234
235
            public function setAuthorAttribute()
236
            {
237
                if ($this->isImporting()) {
238
                    throw new \Exception('Is importing ok !');
239
                }
240
241
                $this->attributes['author'] = 'not importing';
242
            }
243
        };
244
245
        $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...
246
        $this->assertEquals('not importing', $foo->author);
247
248
        $this->expectExceptionMessage('Is importing ok !');
249
250
        $foo->setJsonImportableAttributesForTests(array_keys($import))
251
            ->instanceImportForTests($import);
252
    }
253
254
    public function testImportNonImportableObjects()
255
    {
256
        $baz = [
257
            'name' => 'baz_test',
258
            'doNots' => [
259
                'name' => 'Do not import !',
260
            ],
261
        ];
262
263
        Baz::importFromJson($baz);
264
        $this->assertEquals(1, Baz::count());
265
        $this->assertEquals(0, DoNotExport::count());
266
    }
267
}
268