diff --git a/.env.test b/.env.test new file mode 100644 index 0000000..ed80fcd --- /dev/null +++ b/.env.test @@ -0,0 +1,64 @@ +APP_NAME="Open Sketch" +APP_ENV=local +APP_KEY=base64:CtMJILvYQpvcoSlICeIOJZggQgmNOemBJNs8Sn8Rzz0= +APP_DEBUG=true +APP_URL=opensketch:// + +LOG_CHANNEL=stack +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=sqlite +DB_DATABASE=database/open_sketch_test.sqlite + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DISK=local +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +MEMCACHED_HOST=127.0.0.1 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailpit +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="hello@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_HOST= +PUSHER_PORT=443 +PUSHER_SCHEME=https +PUSHER_APP_CLUSTER=mt1 + +VITE_APP_NAME="${APP_NAME}" +VITE_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +VITE_PUSHER_HOST="${PUSHER_HOST}" +VITE_PUSHER_PORT="${PUSHER_PORT}" +VITE_PUSHER_SCHEME="${PUSHER_SCHEME}" +VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" + +NATIVEPHP_APP_ID="OpenSketch" +NATIVEPHP_APP_VERSION="0.5.0" +NATIVEPHP_DEEPLINK_SCHEME=opensketch +NATIVEPHP_DOCUMENTS_PATH="/home/${USER}/Documents" + +GITHUB_REPO=open-sketch +GITHUB_OWNER=kpicaza +GITHUB_TOKEN= diff --git a/README.md b/README.md index cb89ad5..91f6a26 100644 --- a/README.md +++ b/README.md @@ -29,13 +29,11 @@ provides the tools you need. * [x] Open New Sketch Books * [x] Open Existing Sketch Books +* [x] Portable Sketch Book format ### Simple Paint * [x] Static size painting canvas -* [x] Default "Pen" Brush -* [x] Brush Color -* [x] Brush Size ### Drawing Palette diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index e6b9960..3a1ebcc 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -7,6 +7,10 @@ class Kernel extends ConsoleKernel { + protected $commands = [ + \Native\Laravel\Commands\LoadStartupConfigurationCommand::class, + ]; + /** * Define the application's command schedule. */ diff --git a/app/Listeners/OpenDocumentWindow.php b/app/Listeners/OpenDocumentWindow.php index a3f5d95..ac76d74 100644 --- a/app/Listeners/OpenDocumentWindow.php +++ b/app/Listeners/OpenDocumentWindow.php @@ -6,17 +6,22 @@ use Illuminate\Support\Facades\Storage; use Native\Laravel\Dialog; use Native\Laravel\Facades\Window; +use OpenSketch\SketchBook\Domain\Command\ResetSketchBookLocationCommand; +use OpenSketch\SketchBook\Domain\Handler\ResetSketchBookLocation; class OpenDocumentWindow { + public function __construct( + private ResetSketchBookLocation $resetSketchBookLocation + ) { + } + public function handle(DocumentOpened $event): void { $storagePath = Storage::disk('user_documents')->path('OpenSketch'); - /** @var \Native\Laravel\Windows\WindowManager $window */ - $window = Window::getFacadeRoot(); $path = Dialog::new() ->title('Open Sketch Book') - ->asSheet() + ->asSheet('welcome') ->defaultPath($storagePath) ->open(); @@ -24,18 +29,28 @@ public function handle(DocumentOpened $event): void return; } + $sketchBookData = json_decode( + Storage::get(str_replace( + storage_path('app'), + '', + $path + )), + true + ); + $command = ResetSketchBookLocationCommand::withIdAndPath( + $sketchBookData['id'], + $path + ); + + $sketchBookId = $this->resetSketchBookLocation->handle($command); + + /** @var \Native\Laravel\Windows\WindowManager $window */ + $window = Window::getFacadeRoot(); Window::open('welcome'); Window::close('sketch-book'); Window::open('sketch-book') ->hideMenu(false) - ->route('sketch-book', json_decode( - Storage::get(str_replace( - storage_path('app'), - '', - $path - )), - true - )) + ->route('sketch-book', ['id' => $sketchBookId]) ; $window->maximize('sketch-book'); diff --git a/app/Listeners/StoreDocument.php b/app/Listeners/StoreDocument.php index b307b37..5b7b51b 100644 --- a/app/Listeners/StoreDocument.php +++ b/app/Listeners/StoreDocument.php @@ -9,12 +9,16 @@ use Illuminate\Support\Facades\Storage; use Native\Laravel\Dialog; use Native\Laravel\Facades\Window; +use OpenSketch\SketchBook\Domain\Command\CreateNewSketchBookCommand; +use OpenSketch\SketchBook\Domain\Handler\CreateNewSketchBook; +use OpenSketch\SketchBook\Domain\SketchBookRepository; use Ramsey\Uuid\Uuid; class StoreDocument { - public function __construct() - { + public function __construct( + private CreateNewSketchBook $createNewSketchBook + ) { } public function handle(DocumentSaved $event): void @@ -22,7 +26,7 @@ public function handle(DocumentSaved $event): void $storagePath = Storage::disk('user_documents')->path('OpenSketch'); $path = Dialog::new() ->title('Save Sketch Book') - ->asSheet() + ->asSheet('welcome') ->defaultPath($storagePath) ->save(); @@ -30,21 +34,22 @@ public function handle(DocumentSaved $event): void return; } - $id = Uuid::uuid4(); - $routeParams = [ - 'id' => $id->toString(), - ]; + $command = CreateNewSketchBookCommand::withIdAndPath( + Uuid::uuid4()->toString(), + $path + ); - Storage::put($path . '.json', json_encode($routeParams, JSON_THROW_ON_ERROR)); + $this->createNewSketchBook->handle($command); /** @var \Native\Laravel\Windows\WindowManager $window */ $window = Window::getFacadeRoot(); - Window::open('welcome'); Window::close('sketch-book'); Window::open('sketch-book') ->hideMenu(false) - ->route('sketch-book', $routeParams) + ->route('sketch-book', [ + 'id' => $command->sketchBookId, + ]) ; $window->maximize('sketch-book'); diff --git a/app/Models/SketchBookReference.php b/app/Models/SketchBookReference.php new file mode 100644 index 0000000..0519591 --- /dev/null +++ b/app/Models/SketchBookReference.php @@ -0,0 +1,19 @@ +app->bind( SketchBookRepository::class, - EloquentSketchBookRepository::class + FileSystemSketchBookRepository::class ); - $this->app->bind( - PutSketchBook::class, - fn(Application $app) => new PutSketchBook( - $this->app->make(SketchBookRepository::class) - ) - ); - $this->app->bind( - GetSketchBook::class, - fn(Application $app) => new GetSketchBook( - $this->app->make(SketchBookRepository::class) - ) - ); + $this->app->bind(PutSketchBook::class); + $this->app->bind(GetSketchBook::class); } /** diff --git a/composer.json b/composer.json index 43b08a0..8573912 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "laravel/sail": "^1.18", "mockery/mockery": "^1.4.4", "nunomaduro/collision": "^7.0", - "phpunit/phpunit": "^10.1", + "phpunit/phpunit": "^10.4", "spatie/laravel-ignition": "^2.0" }, "autoload": { diff --git a/composer.lock b/composer.lock index 8c3ee25..9ff340c 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "18ef1cd5f923083214897f2ce0b0ab6b", + "content-hash": "b974fb29a1ec432124d378e98186cf27", "packages": [ { "name": "brick/math", diff --git a/config/nativephp.php b/config/nativephp.php index c2de8d1..014fb5a 100644 --- a/config/nativephp.php +++ b/config/nativephp.php @@ -51,7 +51,8 @@ 'NATIVEPHP_APPLE_ID', 'NATIVEPHP_APPLE_ID_PASS', 'NATIVEPHP_APPLE_TEAM_ID', - ], + 'GITHUB_*', + ], /** * The NativePHP updater configuration. @@ -71,6 +72,16 @@ 'default' => env('NATIVEPHP_UPDATER_PROVIDER', 'spaces'), 'providers' => [ + 'github' => [ + 'driver' => 'github', + 'repo' => env('GITHUB_REPO'), + 'owner' => env('GITHUB_OWNER'), + 'token' => env('GITHUB_TOKEN'), + 'vPrefixedTagName' => env('GITHUB_V_PREFIXED_TAG_NAME', true), + 'private' => env('GITHUB_PRIVATE', false), + 'channel' => env('GITHUB_CHANNEL', 'latest'), + 'releaseType' => env('GITHUB_RELEASE_TYPE', 'draft'), + ], 's3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), diff --git a/database/migrations/2023_10_13_190014_create_sketch_books_reference_table.php b/database/migrations/2023_10_13_190014_create_sketch_books_reference_table.php new file mode 100644 index 0000000..2a9c209 --- /dev/null +++ b/database/migrations/2023_10_13_190014_create_sketch_books_reference_table.php @@ -0,0 +1,27 @@ +uuid('id'); + $table->string('storage_path'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('sketch_books_reference'); + } +}; diff --git a/phpunit.xml b/phpunit.xml index f112c0c..39cf846 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -22,7 +22,7 @@ - + diff --git a/src/SketchBook/Domain/Command/CreateNewSketchBookCommand.php b/src/SketchBook/Domain/Command/CreateNewSketchBookCommand.php new file mode 100644 index 0000000..8774bd4 --- /dev/null +++ b/src/SketchBook/Domain/Command/CreateNewSketchBookCommand.php @@ -0,0 +1,19 @@ +sketchBookId, + $command->storagePath, + [] + ); + + $this->repository->save($sketchBook); + } +} diff --git a/src/SketchBook/Domain/Handler/ResetSketchBookLocation.php b/src/SketchBook/Domain/Handler/ResetSketchBookLocation.php new file mode 100644 index 0000000..0704589 --- /dev/null +++ b/src/SketchBook/Domain/Handler/ResetSketchBookLocation.php @@ -0,0 +1,27 @@ +repository->get($command->sketchBookId); + + $sketchBook = $sketchBook->updateStoragePath($command->storagePath); + + $this->repository->save($sketchBook); + + return $sketchBook->id; + } +} diff --git a/src/SketchBook/Domain/Handler/SaveSketchBook.php b/src/SketchBook/Domain/Handler/SaveSketchBook.php new file mode 100644 index 0000000..16a216f --- /dev/null +++ b/src/SketchBook/Domain/Handler/SaveSketchBook.php @@ -0,0 +1,30 @@ +repository->get($command->sketchBookId); + + $sketchBook->updateSketches(array_map( + fn(array $sketch) => new Sketch((int)$sketch['id'], $sketch['image']), + $command->sketches + )); + + $this->repository->save($sketchBook); + + } +} diff --git a/src/SketchBook/Domain/Model/Sketch.php b/src/SketchBook/Domain/Model/Sketch.php index 299ade2..b6539bd 100644 --- a/src/SketchBook/Domain/Model/Sketch.php +++ b/src/SketchBook/Domain/Model/Sketch.php @@ -4,11 +4,11 @@ namespace OpenSketch\SketchBook\Domain\Model; -class Sketch +final readonly class Sketch { public function __construct( - public readonly int $id, - public readonly string $image + public int $id, + public string $image ) { } } diff --git a/src/SketchBook/Domain/Model/SketchBook.php b/src/SketchBook/Domain/Model/SketchBook.php index 4a22fd8..f340e65 100644 --- a/src/SketchBook/Domain/Model/SketchBook.php +++ b/src/SketchBook/Domain/Model/SketchBook.php @@ -5,12 +5,15 @@ namespace OpenSketch\SketchBook\Domain\Model; use JsonSerializable; +use OpenSketch\SketchBook\Domain\Exception\StoragePathChanged; +use Ramsey\Uuid\Uuid; -class SketchBook implements JsonSerializable +final class SketchBook implements JsonSerializable { /** @param Sketch[] $sketches */ public function __construct( - private string $id, + public readonly string $id, + private string $storagePath, private array $sketches ) { if ([] === $this->sketches) { @@ -21,21 +24,46 @@ public function __construct( } } + private function openedInNewLocation(string $id, string $storagePath): self + { + return new self( + $id, + $storagePath, + $this->sketches + ); + } + + public function storagePath(): string + { + return $this->storagePath; + } + /** @return Sketch[] */ public function sketches(): array { return $this->sketches; } - public function id(): string + /** @param array $sketches */ + public function updateSketches(array $sketches): void { - return $this->id; + $this->sketches = $sketches; + } + + public function updateStoragePath(string $storagePath): self + { + if ($storagePath === $this->storagePath) { + return $this; + } + + return $this->openedInNewLocation(Uuid::uuid4()->toString(), $storagePath); } public function jsonSerialize(): mixed { return [ 'id' => $this->id, + 'storage_path' => $this->storagePath, 'sketches' => $this->sketches, ]; } diff --git a/src/SketchBook/Infrastructure/Http/GetSketchBook.php b/src/SketchBook/Infrastructure/Http/GetSketchBook.php index a67778c..87d738b 100644 --- a/src/SketchBook/Infrastructure/Http/GetSketchBook.php +++ b/src/SketchBook/Infrastructure/Http/GetSketchBook.php @@ -7,10 +7,10 @@ use Illuminate\Http\JsonResponse; use OpenSketch\SketchBook\Domain\SketchBookRepository; -class GetSketchBook +final readonly class GetSketchBook { public function __construct( - private readonly SketchBookRepository $sketchBookRepository + private SketchBookRepository $sketchBookRepository ) { } diff --git a/src/SketchBook/Infrastructure/Http/PutSketchBook.php b/src/SketchBook/Infrastructure/Http/PutSketchBook.php index 19f33bb..90a11f6 100644 --- a/src/SketchBook/Infrastructure/Http/PutSketchBook.php +++ b/src/SketchBook/Infrastructure/Http/PutSketchBook.php @@ -6,14 +6,16 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; +use OpenSketch\SketchBook\Domain\Command\SaveSketchBookCommand; +use OpenSketch\SketchBook\Domain\Handler\SaveSketchBook; use OpenSketch\SketchBook\Domain\Model\Sketch; use OpenSketch\SketchBook\Domain\Model\SketchBook; use OpenSketch\SketchBook\Domain\SketchBookRepository; -class PutSketchBook +final readonly class PutSketchBook { public function __construct( - private readonly SketchBookRepository $sketchBookRepository + private SaveSketchBook $saveSketchBook ) { } @@ -21,15 +23,10 @@ public function handle(Request $request): Response { $sketchBookData = $request->json()->all(); - $sketchBook = new SketchBook( + $this->saveSketchBook->handle(SaveSketchBookCommand::withIdAndSketches( $sketchBookData['id'], - array_map( - fn(array $sketch) => new Sketch((int)$sketch['id'], $sketch['image']), - $sketchBookData['sketches'] - ) - ); - - $this->sketchBookRepository->save($sketchBook); + $sketchBookData['sketches'], + )); return new Response(null, 200); } diff --git a/src/SketchBook/Infrastructure/Persistence/EloquentSketchBookRepository.php b/src/SketchBook/Infrastructure/Persistence/EloquentSketchBookRepository.php deleted file mode 100644 index fd16429..0000000 --- a/src/SketchBook/Infrastructure/Persistence/EloquentSketchBookRepository.php +++ /dev/null @@ -1,41 +0,0 @@ - $sketchBook->id(), - ]); - - $persistentSketchBook->sketches = $sketchBook->sketches(); - $persistentSketchBook->save(); - } - - public function get(string $sketchBookId): SketchBook - { - $persistentSketchBook = PersistentSketchBook::firstOrNew([ - 'id' => $sketchBookId, - ]); - if (null === $persistentSketchBook) { - throw new \Exception('Sketch Book not found.'); - } - - return new SketchBook( - $persistentSketchBook->id, - array_map( - static fn(array $sketch) => new Sketch($sketch['id'], $sketch['image']), - $persistentSketchBook->sketches?->toArray() ?? [] - ) - ); - } -} diff --git a/src/SketchBook/Infrastructure/Persistence/FileSystemSketchBookRepository.php b/src/SketchBook/Infrastructure/Persistence/FileSystemSketchBookRepository.php new file mode 100644 index 0000000..4cbdfff --- /dev/null +++ b/src/SketchBook/Infrastructure/Persistence/FileSystemSketchBookRepository.php @@ -0,0 +1,50 @@ +storagePath()) . '.json'; + SketchBookReference::firstOrNew([ + 'id' => $sketchBook->id, + 'storage_path' => $path, + ])->save(); + + Storage::put($path, json_encode($sketchBook, JSON_THROW_ON_ERROR)); + } + + public function get(string $sketchBookId): SketchBook + { + $sketchBookReference = SketchBookReference::firstOrNew([ + 'id' => $sketchBookId, + ]); + + if (null === $sketchBookReference->storage_path) { + throw new \Exception('Sketch Book not found.'); + } + + $content = Storage::get($sketchBookReference->storage_path) ?? '[]'; + $sketchBookSerialized = json_decode($content, true, 512, JSON_THROW_ON_ERROR); + + + return new SketchBook( + $sketchBookReference->id, + $sketchBookReference->storage_path, + array_map( + static fn(array $sketch) => new Sketch($sketch['id'], $sketch['image']), + $sketchBookSerialized['sketches'] ?? [] + ) + ); + } +} diff --git a/tests/Feature/CreateNewSketchBookTest.php b/tests/Feature/CreateNewSketchBookTest.php new file mode 100644 index 0000000..4dca062 --- /dev/null +++ b/tests/Feature/CreateNewSketchBookTest.php @@ -0,0 +1,23 @@ +set('nativephp-internal.api_url', 'https://jsonplaceholder.typicode.com/todos/1'); + Storage::fake(); + $response = $this->post('/api/sketch-books/save'); + + $response->assertStatus(201); + } +} diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php deleted file mode 100644 index 8364a84..0000000 --- a/tests/Feature/ExampleTest.php +++ /dev/null @@ -1,19 +0,0 @@ -get('/'); - - $response->assertStatus(200); - } -} diff --git a/tests/Feature/GetSketchBookTest.php b/tests/Feature/GetSketchBookTest.php new file mode 100644 index 0000000..971705c --- /dev/null +++ b/tests/Feature/GetSketchBookTest.php @@ -0,0 +1,56 @@ +set('nativephp-internal.api_url', 'https://jsonplaceholder.typicode.com/todos/1'); + Storage::fake(); + + $sketchBookId = Uuid::uuid4()->toString(); + $sketches = [ + [ + 'id' => 1, + 'image' => 'data:,' + ] + ]; + + Storage::put('/home/fake/sketch-book.json', json_encode([ + 'id' => $sketchBookId, + 'storage_path' => '/home/fake/sketch-book.json', + 'sketches' => $sketches + ])); + + SketchBookReference::firstOrNew([ + 'id' => $sketchBookId, + 'storage_path' => 'home/fake/sketch-book.json', + ])->save(); + + $response = $this->json('GET', '/api/sketch-books/' . $sketchBookId); + + $response->assertStatus(200); + $this->assertSame($response->json(), [ + "id" => $sketchBookId, + "storage_path" => "home/fake/sketch-book.json", + "sketches" => [ + 0 => [ + "id" => 1, + "image" => "data:," + ] + ] + ]); + } +} diff --git a/tests/Feature/OpenExistingSketchBookTest.php b/tests/Feature/OpenExistingSketchBookTest.php new file mode 100644 index 0000000..b3b300d --- /dev/null +++ b/tests/Feature/OpenExistingSketchBookTest.php @@ -0,0 +1,23 @@ +set('nativephp-internal.api_url', 'https://jsonplaceholder.typicode.com/todos/1'); + Storage::fake(); + $response = $this->post('/api/sketch-books/open'); + + $response->assertStatus(201); + } +} diff --git a/tests/Feature/SaveSketchBookTest.php b/tests/Feature/SaveSketchBookTest.php new file mode 100644 index 0000000..59476ba --- /dev/null +++ b/tests/Feature/SaveSketchBookTest.php @@ -0,0 +1,48 @@ +set('nativephp-internal.api_url', 'https://jsonplaceholder.typicode.com/todos/1'); + Storage::fake(); + + $sketchBookId = Uuid::uuid4()->toString(); + $sketches = [ + [ + 'id' => 1, + 'image' => 'data:,' + ] + ]; + + Storage::put('/home/fake/sketch-book.json', json_encode([ + 'id' => $sketchBookId, + 'storage_path' => '/home/fake/sketch-book.json', + 'sketches' => $sketches + ])); + + SketchBookReference::firstOrNew([ + 'id' => $sketchBookId, + 'storage_path' => 'home/fake/sketch-book.json', + ])->save(); + + $response = $this->json('PUT', '/api/sketch-books', [ + 'id' => $sketchBookId, + 'sketches' => $sketches + ]); + + $response->assertStatus(200); + } +} diff --git a/tests/Unit/CreateNewSketchBookTest.php b/tests/Unit/CreateNewSketchBookTest.php new file mode 100644 index 0000000..cd0b559 --- /dev/null +++ b/tests/Unit/CreateNewSketchBookTest.php @@ -0,0 +1,27 @@ +createMock(SketchBookRepository::class); + $repository->expects($this->once()) + ->method('save'); + $createNeSketchBook = new CreateNewSketchBook( + $repository + ); + + $createNeSketchBook->handle(CreateNewSketchBookCommand::withIdAndPath( + Uuid::uuid4(), + '/home/kpicaza/OpenSketch' + )); + } +} diff --git a/tests/Unit/ExampleTest.php b/tests/Unit/ExampleTest.php deleted file mode 100644 index 5773b0c..0000000 --- a/tests/Unit/ExampleTest.php +++ /dev/null @@ -1,16 +0,0 @@ -assertTrue(true); - } -} diff --git a/tests/Unit/ResetSketchBookLocationTest.php b/tests/Unit/ResetSketchBookLocationTest.php new file mode 100644 index 0000000..ce88c68 --- /dev/null +++ b/tests/Unit/ResetSketchBookLocationTest.php @@ -0,0 +1,74 @@ +toString(); + $repository = $this->createMock(SketchBookRepository::class); + $repository->expects($this->once()) + ->method('get') + ->with($sketchBookId) + ->willReturn(new SketchBook( + $sketchBookId, + '/home/fake/old-location.json', + [ + new Sketch(1, 'data:,') + ] + )) + ; + $repository->expects($this->once()) + ->method('save'); + + $createNeSketchBook = new ResetSketchBookLocation( + $repository + ); + + $newSketchBookId = $createNeSketchBook->handle(ResetSketchBookLocationCommand::withIdAndPath( + $sketchBookId, + '/home/fake/new-location.json', + )); + + $this->assertNotEquals($newSketchBookId, $sketchBookId); + } + + public function testDoNotUpdateSketchBookLocationBeforeOpenWhenExist(): void + { + $sketchBookId = Uuid::uuid4()->toString(); + $repository = $this->createMock(SketchBookRepository::class); + $repository->expects($this->once()) + ->method('get') + ->with($sketchBookId) + ->willReturn(new SketchBook( + $sketchBookId, + '/home/fake/location.json', + [ + new Sketch(1, 'data:,') + ] + )) + ; + $repository->expects($this->once()) + ->method('save'); + + $createNeSketchBook = new ResetSketchBookLocation( + $repository + ); + + $newSketchBookId = $createNeSketchBook->handle(ResetSketchBookLocationCommand::withIdAndPath( + $sketchBookId, + '/home/fake/location.json', + )); + + $this->assertSame($newSketchBookId, $sketchBookId); + } +} diff --git a/tests/Unit/SaveSketchBookTest.php b/tests/Unit/SaveSketchBookTest.php new file mode 100644 index 0000000..3c81792 --- /dev/null +++ b/tests/Unit/SaveSketchBookTest.php @@ -0,0 +1,55 @@ +toString(); + $repository = $this->createMock(SketchBookRepository::class); + $repository->expects($this->once()) + ->method('get') + ->with($sketchBookId) + ->willReturn(new SketchBook( + $sketchBookId, + '/home/fake/old-location.json', + [ + new Sketch(1, 'data:,') + ] + )) + ; + $repository->expects($this->once()) + ->method('save') + ->with(new SketchBook( + $sketchBookId, + '/home/fake/old-location.json', + [ + new Sketch(1, 'data:1'), + new Sketch(2, 'data:2'), + new Sketch(3, 'data:3'), + ] + )); + + $createNeSketchBook = new SaveSketchBook( + $repository + ); + + $createNeSketchBook->handle(SaveSketchBookCommand::withIdAndSketches( + $sketchBookId, + [ + ['id' => 1, 'image' => 'data:1'], + ['id' => 2, 'image' => 'data:2'], + ['id' => 3, 'image' => 'data:3'], + ] + )); + } +}