Skip to content

Commit 168923d

Browse files
committed
wip getting the Storage driver to work for remote json files
1 parent cd3adf1 commit 168923d

File tree

2 files changed

+207
-14
lines changed

2 files changed

+207
-14
lines changed

src/Updater.php

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace nullthoughts\LaravelDataSync;
44

5+
use Illuminate\Support\Facades\Storage;
56
use nullthoughts\LaravelDataSync\Exceptions\ErrorUpdatingModelException;
67
use nullthoughts\LaravelDataSync\Exceptions\FileDirectoryNotFoundException;
78
use nullthoughts\LaravelDataSync\Exceptions\NoCriteriaException;
@@ -13,18 +14,44 @@
1314

1415
class Updater
1516
{
17+
/**
18+
* @var string
19+
*/
20+
private $directory;
21+
22+
/**
23+
* @var \Illuminate\Support\Collection
24+
*/
25+
private $files;
26+
27+
/**
28+
* @var bool
29+
*/
30+
private $remote;
31+
32+
/**
33+
* @var string
34+
*/
35+
private $disk;
36+
1637
/**
1738
* Get files in sync directory.
1839
*
19-
* @param string|null $path
20-
* @param string|null $model
40+
* @param string|null $path
41+
* @param string|null $model
42+
*
43+
* @param bool $remote
44+
* @param string $disk
2145
*
2246
* @throws \nullthoughts\LaravelDataSync\Exceptions\FileDirectoryNotFoundException
2347
*/
24-
public function __construct($path = null, $model = null)
48+
public function __construct($path = null, $model = null, $remote = false, $disk = 's3')
2549
{
26-
$directory = $this->getDirectory($path);
27-
$this->files = $this->getFiles($directory, $model);
50+
$this->remote = $remote;
51+
$this->disk = $disk;
52+
53+
$this->directory = $this->getDirectory($path);
54+
$this->files = $this->getFiles($this->directory, $model);
2855
}
2956

3057
/**
@@ -50,11 +77,11 @@ public function run()
5077
/**
5178
* Parse each record for criteria/values and update/create model.
5279
*
53-
* @param string $file
54-
*
55-
* @throws \nullthoughts\LaravelDataSync\Exceptions\NoRecordsInvalidJSONException
80+
* @param string $file
5681
*
5782
* @return \Illuminate\Support\Collection
83+
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
84+
* @throws \nullthoughts\LaravelDataSync\Exceptions\NoRecordsInvalidJSONException
5885
*/
5986
protected function syncModel(string $file)
6087
{
@@ -89,7 +116,7 @@ protected function getDirectory($path)
89116
{
90117
$directory = $path ?? config('data-sync.path', base_path('sync'));
91118

92-
if (!file_exists($directory)) {
119+
if (!file_exists($directory) && !$this->remote) {
93120
throw new FileDirectoryNotFoundException();
94121
}
95122

@@ -110,10 +137,17 @@ protected function getFiles(string $directory, $model = null)
110137
return Collection::wrap($directory.'/'.$model.'.json');
111138
}
112139

113-
return collect(File::files($directory))
140+
$files = ($this->remote) ? Storage::disk($this->disk)->files($directory) : File::files($directory);
141+
142+
return collect($files)
114143
->filter(function ($file) {
115144
return pathinfo($file, PATHINFO_EXTENSION) == 'json';
116145
})->map(function ($path) {
146+
147+
if (is_string($path)) {
148+
return $path;
149+
}
150+
117151
return $path->getPathname();
118152
});
119153
}
@@ -204,15 +238,17 @@ protected function getModel(string $name)
204238
/**
205239
* Parses JSON from file and returns collection.
206240
*
207-
* @param string $file
208-
*
209-
* @throws \nullthoughts\LaravelDataSync\Exceptions\NoRecordsInvalidJSONException
241+
* @param string $file
210242
*
211243
* @return \Illuminate\Support\Collection
244+
* @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
245+
* @throws \nullthoughts\LaravelDataSync\Exceptions\NoRecordsInvalidJSONException
212246
*/
213247
protected function getRecords(string $file)
214248
{
215-
$records = collect(json_decode(File::get($file)));
249+
$fetchedFile = ($this->remote) ? Storage::disk($this->disk)->get($file) : File::get($file);
250+
251+
$records = collect(json_decode($fetchedFile));
216252

217253
if ($records->isEmpty()) {
218254
throw new NoRecordsInvalidJSONException($file);

tests/Unit/UpdaterRemoteTest.php

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
namespace nullthoughts\LaravelDataSync\Tests;
4+
5+
use Illuminate\Support\Facades\File;
6+
use Illuminate\Support\Facades\Storage;
7+
use nullthoughts\LaravelDataSync\Exceptions\ErrorUpdatingModelException;
8+
use nullthoughts\LaravelDataSync\Tests\fakes\UpdaterFake;
9+
use Exception;
10+
11+
class UpdaterRemoteTest extends TestCase
12+
{
13+
protected function setUp(): void
14+
{
15+
parent::setUp();
16+
17+
Storage::fake('s3');
18+
Storage::disk('s3')->put('test-data/roles.json', File::get(__DIR__.'/../test-data/roles.json'));
19+
foreach (File::directories(__DIR__.'/../test-data/') as $directory) {
20+
$files = File::files($directory);
21+
22+
foreach ($files as $file) {
23+
Storage::disk('s3')->put('test-data/'.basename($directory).'/'.$file->getRelativePathname(), File::get($file->getPathname()));
24+
}
25+
}
26+
}
27+
28+
/** @test @group current */
29+
public function it_adds_roles_to_the_database()
30+
{
31+
$updater = new UpdaterFake('/test-data', 'roles', true, 's3');
32+
33+
$updater->run();
34+
35+
$this->assertDatabaseHas('roles', ['slug' => 'update-student-records']);
36+
$this->assertDatabaseHas('roles', ['slug' => 'borrow-ferrari']);
37+
$this->assertDatabaseHas('roles', ['slug' => 'destroy-ferrari']);
38+
}
39+
40+
/** @test */
41+
public function it_can_default_to_configuration()
42+
{
43+
config()->set('data-sync.path', 'test-data');
44+
45+
$updater = new UpdaterFake(null, null, true, 's3');
46+
47+
$updater->run();
48+
49+
$this->assertDatabaseHas('roles', ['slug' => 'update-student-records']);
50+
$this->assertDatabaseHas('roles', ['slug' => 'borrow-ferrari']);
51+
$this->assertDatabaseHas('roles', ['slug' => 'destroy-ferrari']);
52+
}
53+
54+
/** @test */
55+
public function it_can_update_an_existing_record()
56+
{
57+
config()->set('data-sync.path', 'test-data');
58+
(new UpdaterFake(null, null, true, 's3'))->run();
59+
60+
config()->set('data-sync.path', 'test-data/valid');
61+
(new UpdaterFake(null, null, true, 's3'))->run();
62+
63+
$this->assertDatabaseHas('roles', ['category' => 'changed']);
64+
$this->assertDatabaseHas('roles', ['category' => 'changed']);
65+
$this->assertDatabaseHas('roles', ['category' => 'changed']);
66+
}
67+
68+
/** @test */
69+
public function it_can_update_the_relationship()
70+
{
71+
$supervisor = Supervisor::create([
72+
'name' => 'CEO',
73+
]);
74+
75+
config()->set('data-sync.path', 'test-data/relationship');
76+
(new UpdaterFake(null, null, true, 's3'))->run();
77+
78+
$this->assertEquals($supervisor->id, Roles::first()->supervisor_id);
79+
$this->assertTrue($supervisor->is(Roles::first()->supervisor));
80+
}
81+
82+
/** @test */
83+
public function exception_is_thrown_if_the_directory_does_not_exists()
84+
{
85+
try {
86+
new UpdaterFake(null, null, true, 's3');
87+
88+
$this->fail('exception was thrown');
89+
} catch (Exception $e) {
90+
$this->assertEquals('Specified sync file directory does not exist', $e->getMessage());
91+
}
92+
}
93+
//
94+
// /** @test */
95+
// public function invalid_json_throws_an_exception()
96+
// {
97+
// try {
98+
// $updater = new UpdaterFake(__DIR__.'/../test-data/invalid-json');
99+
// $updater->run();
100+
//
101+
// $this->fail('exception was thrown');
102+
// } catch (Exception $e) {
103+
// $this->assertStringContainsString('No records or invalid JSON for', $e->getMessage());
104+
// }
105+
// }
106+
//
107+
// /** @test */
108+
// public function the_json_must_contain_a_key_with_an_underscore()
109+
// {
110+
// try {
111+
// $updater = new UpdaterFake(__DIR__.'/../test-data/no-criteria');
112+
// $updater->run();
113+
//
114+
// $this->fail('exception was thrown');
115+
// } catch (Exception $e) {
116+
// $this->assertEquals('No criteria/attributes detected', $e->getMessage());
117+
// }
118+
// }
119+
//
120+
// /** @test */
121+
// public function order_of_imports_can_be_defined_in_config()
122+
// {
123+
// config()->set('data-sync.order', [
124+
// 'Supervisor',
125+
// 'Roles',
126+
// ]);
127+
//
128+
// $updater = new UpdaterFake(__DIR__.'/../test-data/ordered');
129+
// $updater->run();
130+
//
131+
// $this->assertDatabaseHas('roles', ['slug' => 'update-student-records']);
132+
// $this->assertDatabaseHas('supervisors', ['name' => 'CEO']);
133+
// }
134+
//
135+
// /** @test */
136+
// public function exception_is_thrown_if_imports_are_in_incorrect_order()
137+
// {
138+
// config()->set('data-sync.order', [
139+
// 'Roles',
140+
// 'Supervisor',
141+
// ]);
142+
//
143+
// $this->expectException(ErrorUpdatingModelException::class);
144+
//
145+
// $updater = new UpdaterFake(__DIR__.'/../test-data/ordered');
146+
// $updater->run();
147+
// }
148+
//
149+
// /** @test */
150+
// public function it_ignores_non_json_files()
151+
// {
152+
// $updater = new UpdaterFake(__DIR__.'/../test-data/not-json');
153+
// $updater->run();
154+
//
155+
// $this->assertDatabaseMissing('roles', ['slug' => 'update-student-records']);
156+
// }
157+
}

0 commit comments

Comments
 (0)