diff --git a/composer.json b/composer.json index 6b1363f..632a270 100644 --- a/composer.json +++ b/composer.json @@ -1,32 +1,33 @@ { - "name": "mathieutu/laravel-json-syncer", - "description": "Export and import your models to/from JSON", - "type": "package", - "require": { - "php": ">=7.0", - "illuminate/support": "^5.4", - "illuminate/database": "^5.4" - }, - "require-dev": { - "phpunit/phpunit": "~5.7", - "orchestra/testbench": "~3.0" - }, - "license": "MIT", - "authors": [ - { - "name": "Mathieu TUDISCO", - "email": "dev@mathieutu.ovh" - } - ], - "autoload": { - "psr-4": { - "MathieuTu\\JsonSyncer\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "MathieuTu\\JsonSyncer\\Tests\\": "tests/" - } - }, - "minimum-stability": "stable" + "name": "mathieutu/laravel-json-syncer", + "description": "Export and import your models to/from JSON", + "type": "package", + "require": { + "php": ">=7.0", + "illuminate/support": "^5.4", + "illuminate/database": "^5.4", + "ext-json": "*" + }, + "require-dev": { + "phpunit/phpunit": "~5.7", + "orchestra/testbench": "~3.0" + }, + "license": "MIT", + "authors": [ + { + "name": "Mathieu TUDISCO", + "email": "dev@mathieutu.ovh" + } + ], + "autoload": { + "psr-4": { + "MathieuTu\\JsonSyncer\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "MathieuTu\\JsonSyncer\\Tests\\": "tests/" + } + }, + "minimum-stability": "stable" } diff --git a/src/Helpers/JsonImporter.php b/src/Helpers/JsonImporter.php index 0b0c0fb..8a9e5e1 100644 --- a/src/Helpers/JsonImporter.php +++ b/src/Helpers/JsonImporter.php @@ -28,11 +28,8 @@ public function import($objects) { $objects = $this->convertObjectsToArray($objects); - $objects = $this->wrap($objects); - foreach ($objects as $attributes) { $object = $this->importAttributes($attributes); - $this->importRelations($object, $attributes); } } @@ -51,7 +48,7 @@ protected function convertObjectsToArray($objects): array $objects = $objects->toArray(); } - return (array) $objects; + return $this->wrap((array) $objects); } protected function wrap(array $objects): array @@ -71,7 +68,10 @@ protected function importRelations($object, $attributes) $relationsNames = array_intersect(array_keys($attributes), $this->importable->getJsonImportableRelations()); foreach ($relationsNames as $relationName) { - $this->importChildrenIfImportable($this->getRelationObject($object, $relationName), $this->wrap($attributes[$relationName])); + $children = $this->convertObjectsToArray($attributes[$relationName]); + $relation = $this->getRelationObject($object, $relationName); + + $this->importChildrenIfImportable($relation, $children); } } diff --git a/tests/JsonImporterTest.php b/tests/JsonImporterTest.php index ca156cd..85f50d1 100644 --- a/tests/JsonImporterTest.php +++ b/tests/JsonImporterTest.php @@ -22,12 +22,40 @@ protected function assertAllImportedInDatabase() $this->assertFooIsImported(); $this->assertBarsAreImported(); $this->assertBazsAreImported(); - $this->assertEquals(0, DoNotExport::query()->count()); + $this->assertEquals(0, DoNotExport::count()); + } + + protected function assertFooIsImported() + { + $this->assertEquals(1, Foo::count()); + $this->assertEquals( + ['id' => 1, 'author' => 'Mathieu TUDISCO', 'username' => '@mathieutu'], + Foo::first()->toArray() + ); + } + + protected function assertBarsAreImported() + { + $this->assertEquals(2, Bar::count()); + $bars = Foo::first()->bars; + $this->assertEquals([ + ['id' => 1, 'name' => 'bar1', 'foo_id' => 1], + ['id' => 2, 'name' => 'bar2', 'foo_id' => 1], + ], $bars->toArray()); + } + + protected function assertBazsAreImported() + { + $this->assertEquals(2, Baz::count()); + foreach (Foo::with('bars.baz')->first()->bars as $bar) { + $baz = $bar->baz; + $this->assertEquals(['id' => $baz->id, 'name' => $bar->name . '_baz', 'bar_id' => $bar->id], $baz->toArray()); + } } public function testImportWithoutRelation() { - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); unset($import['bars'][1]['baz']); @@ -36,14 +64,19 @@ public function testImportWithoutRelation() $this->assertFooIsImported(); $this->assertBarsAreImported(); - $this->assertEquals(1, Baz::query()->count()); + $this->assertEquals(1, Baz::count()); $baz = Foo::with('bars.baz')->first()->bars->pluck('baz'); $this->assertEquals([['id' => 1, 'name' => 'bar1_baz', 'bar_id' => '1'], null], $baz->toArray()); } + private function getImportArray(): array + { + return json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + } + public function testImportWithAnEmptyRelation() { - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); $import['bars'] = []; @@ -51,28 +84,28 @@ public function testImportWithAnEmptyRelation() Foo::importFromJson($import); - $this->assertEquals(1, Foo::query()->count()); - $this->assertEquals(0, Bar::query()->count()); - $this->assertEquals(0, Baz::query()->count()); - $this->assertEquals(0, DoNotExport::query()->count()); + $this->assertEquals(1, Foo::count()); + $this->assertEquals(0, Bar::count()); + $this->assertEquals(0, Baz::count()); + $this->assertEquals(0, DoNotExport::count()); } public function testImportSeveralTimesWillJustAdd() { - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); Foo::importFromJson($import); - $fooCount = Foo::query()->count(); - $barCount = Bar::query()->count(); - $bazCount = Baz::query()->count(); - $doNotExportCount = DoNotExport::query()->count(); + $fooCount = Foo::count(); + $barCount = Bar::count(); + $bazCount = Baz::count(); + $doNotExportCount = DoNotExport::count(); foreach (range(1, 3) as $time) { - $this->assertEquals($time * $fooCount, Foo::query()->count()); - $this->assertEquals($time * $barCount, Bar::query()->count()); - $this->assertEquals($time * $bazCount, Baz::query()->count()); - $this->assertEquals($time * $doNotExportCount, DoNotExport::query()->count()); + $this->assertEquals($time * $fooCount, Foo::count()); + $this->assertEquals($time * $barCount, Bar::count()); + $this->assertEquals($time * $bazCount, Baz::count()); + $this->assertEquals($time * $doNotExportCount, DoNotExport::count()); Foo::importFromJson($import); } @@ -80,11 +113,43 @@ public function testImportSeveralTimesWillJustAdd() public function testImportFromArray() { - Foo::importFromJson(json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true)); + Foo::importFromJson($this->getImportArray()); $this->assertAllImportedInDatabase(); } + public function testImportNullRelation() + { + $objects = $this->getImportArray(); + $objects['bars'] = null; + + Foo::importFromJson($objects); + + $this->assertFooIsImported(); + + $this->assertEquals(0, Bar::count()); + $bars = Foo::first()->bars; + $this->assertEquals([], $bars->toArray()); + + $this->assertEquals(0, Baz::count()); + $this->assertEquals(0, DoNotExport::count()); + } + + public function testImportNullAttribute() + { + $objects = $this->getImportArray(); + $objects['author'] = null; + + Foo::importFromJson($objects); + + $this->assertEquals(1, Foo::count()); + $this->assertEquals(['id' => 1, 'author' => null, 'username' => '@mathieutu'], Foo::first()->toArray()); + + $this->assertBarsAreImported(); + $this->assertBazsAreImported(); + $this->assertEquals(0, DoNotExport::count()); + } + public function testImportBadJson() { $this->expectException(JsonDecodingException::class); @@ -94,7 +159,7 @@ public function testImportBadJson() public function testImportUnWantedData() { - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); $import['bad'] = 'attribute'; Foo::importFromJson($import); @@ -104,7 +169,7 @@ public function testImportUnWantedData() public function testImportNonRelationMethodWithDefaultRelations() { - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); $import['otherMethod'] = ['Hello you!']; Foo::importFromJson($import); @@ -117,7 +182,7 @@ public function testImportANonRelationMethodWithCustomRelations() $this->expectException(UnknownAttributeException::class); $this->expectExceptionMessage('Unknown attribute or HasOneorMany relation "otherMethod" in "MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo".'); - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); $import['otherMethod'] = []; (new Foo)->setJsonImportableRelationsForTests(['bars', 'otherMethod']) @@ -129,7 +194,7 @@ public function testImportUnknownRelationWithCustomRelations() $this->expectException(UnknownAttributeException::class); $this->expectExceptionMessage('Unknown attribute or HasOneorMany relation "test" in "MathieuTu\\JsonSyncer\\Tests\\Stubs\\Foo".'); - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); $import['test'] = []; (new Foo)->setJsonImportableRelationsForTests(['bars', 'test']) @@ -138,7 +203,7 @@ public function testImportUnknownRelationWithCustomRelations() public function testImportWithCustomRelationsAndAttributes() { - $import = json_decode(file_get_contents(__DIR__ . '/Stubs/import.json'), true); + $import = $this->getImportArray(); (new Foo)->setJsonImportableRelationsForTests(['bars']) ->setJsonImportableAttributesForTests(['author']) @@ -155,7 +220,8 @@ public function testIsImportingMethod() 'author' => 'Mathieu', ]; - $foo = new class extends Foo { + $foo = new class extends Foo + { protected $fillable = ['author']; protected $table = 'foos'; @@ -188,32 +254,7 @@ public function testImportNonImportableObjects() ]; Baz::importFromJson($baz); - $this->assertEquals(1, Baz::query()->count()); - $this->assertEquals(0, DoNotExport::query()->count()); - } - - protected function assertBazsAreImported() - { - $this->assertEquals(2, Baz::query()->count()); - foreach (Foo::with('bars.baz')->first()->bars as $bar) { - $baz = $bar->baz; - $this->assertEquals(['id' => $baz->id, 'name' => $bar->name . '_baz', 'bar_id' => $bar->id], $baz->toArray()); - } - } - - protected function assertBarsAreImported() - { - $this->assertEquals(2, Bar::query()->count()); - $bars = Foo::query()->first()->bars; - $this->assertEquals([ - ['id' => 1, 'name' => 'bar1', 'foo_id' => 1], - ['id' => 2, 'name' => 'bar2', 'foo_id' => 1], - ], $bars->toArray()); - } - - protected function assertFooIsImported() - { - $this->assertEquals(1, Foo::query()->count()); - $this->assertEquals(['id' => 1, 'author' => 'Mathieu TUDISCO', 'username' => '@mathieutu'], Foo::query()->first()->toArray()); + $this->assertEquals(1, Baz::count()); + $this->assertEquals(0, DoNotExport::count()); } }