From 6adbab541b282358ccc0d983d9086c7733f664b1 Mon Sep 17 00:00:00 2001 From: Seth Sharp Date: Sat, 10 Feb 2024 15:42:31 +1000 Subject: [PATCH] tests! --- app/Domain/File/Actions/StoreFileAction.php | 8 +- .../Dashboard/Blogs/StoreBlogController.php | 2 +- .../Blogs/StoreBlogImageController.php | 6 +- .../js/Components/Editor/Nodes/Image/View.vue | 1 - .../File/Actions/DestroyFileActionTest.php | 31 ++++ .../File/Actions/StoreFileActionTest.php | 4 +- .../Dashboard/Blogs/StoreBlogImageTest.php | 158 ++++++++++++++++++ tests/Http/Dashboard/Blogs/StoreBlogTest.php | 75 +++++++++ tests/Http/Dashboard/Blogs/UpdateBlogTest.php | 75 +++++++++ tests/TestCase.php | 1 + 10 files changed, 348 insertions(+), 13 deletions(-) create mode 100644 tests/Domain/File/Actions/DestroyFileActionTest.php create mode 100644 tests/Http/Dashboard/Blogs/StoreBlogImageTest.php diff --git a/app/Domain/File/Actions/StoreFileAction.php b/app/Domain/File/Actions/StoreFileAction.php index a39930b0..9b73a168 100644 --- a/app/Domain/File/Actions/StoreFileAction.php +++ b/app/Domain/File/Actions/StoreFileAction.php @@ -9,13 +9,11 @@ class StoreFileAction { public function __invoke(UploadedFile $file): string { - $structure = app()->environment('local') ? 'testing/' : 'production/'; + $structure = app()->environment('testing') || app()->environment('local') + ? 'testing/' : 'production/'; $dir = $structure . 'blogs'; - return Storage::disk(app()->environment('local') - ? 'public' - : config('filesystems.default')) - ->put($dir, $file); + return Storage::disk('s3')->put($dir, $file); } } diff --git a/app/Http/Controllers/Dashboard/Blogs/StoreBlogController.php b/app/Http/Controllers/Dashboard/Blogs/StoreBlogController.php index b5e160e8..1dccd190 100644 --- a/app/Http/Controllers/Dashboard/Blogs/StoreBlogController.php +++ b/app/Http/Controllers/Dashboard/Blogs/StoreBlogController.php @@ -16,7 +16,7 @@ public function __invoke(StoreBlogRequest $storeBlogRequest, StoreBlogAction $st $drafted = (bool)$storeBlogRequest->input('is_draft'); return redirect() - ->back() + ->route('dashboard.blogs.index') ->with('success', $blog->title . ' successfully ' . ($drafted ? 'drafted' : 'published')); } } diff --git a/app/Http/Controllers/Dashboard/Blogs/StoreBlogImageController.php b/app/Http/Controllers/Dashboard/Blogs/StoreBlogImageController.php index 7c38ac68..58c79167 100644 --- a/app/Http/Controllers/Dashboard/Blogs/StoreBlogImageController.php +++ b/app/Http/Controllers/Dashboard/Blogs/StoreBlogImageController.php @@ -5,19 +5,17 @@ use App\Domain\File\Models\File; use Illuminate\Http\JsonResponse; use App\Http\Controllers\Controller; +use Illuminate\Support\Facades\Storage; use App\Domain\File\Actions\StoreFileAction; use App\Domain\File\Actions\DestroyFileAction; use App\Http\Requests\Dashboard\Blogs\StoreBlogImageRequest; -use Illuminate\Support\Facades\Storage; class StoreBlogImageController extends Controller { public function __invoke(StoreBlogImageRequest $request, StoreFileAction $action): JsonResponse { $path = $action($request->file('file')); - $url = app()->environment('local') - ? $path - : Storage::url($path); + $url = Storage::disk('s3')->url($path); $fileId = intval($request->input('fileId')); $blogId = intval($request->input('blogId')) ?: null; diff --git a/resources/js/Components/Editor/Nodes/Image/View.vue b/resources/js/Components/Editor/Nodes/Image/View.vue index 0bacfb02..76b45adb 100644 --- a/resources/js/Components/Editor/Nodes/Image/View.vue +++ b/resources/js/Components/Editor/Nodes/Image/View.vue @@ -41,7 +41,6 @@ let { fileId, blogId, src, alt, height } = breakdownNodeViewProps(props)
- {{ src }}
diff --git a/tests/Domain/File/Actions/DestroyFileActionTest.php b/tests/Domain/File/Actions/DestroyFileActionTest.php new file mode 100644 index 00000000..8891e54e --- /dev/null +++ b/tests/Domain/File/Actions/DestroyFileActionTest.php @@ -0,0 +1,31 @@ +image('file.jpg'); + + $path = Storage::disk('s3')->put('testing', $uploadedFile); + + $file = File::create([ + 'path' => $path, + 'url' => 'some-url' + ]); + + app(DestroyFileAction::class)($file); + + Storage::assertMissing($uploadedFile->hashName('testing')); + } +} diff --git a/tests/Domain/File/Actions/StoreFileActionTest.php b/tests/Domain/File/Actions/StoreFileActionTest.php index b1fa346b..671cc630 100644 --- a/tests/Domain/File/Actions/StoreFileActionTest.php +++ b/tests/Domain/File/Actions/StoreFileActionTest.php @@ -12,12 +12,12 @@ class StoreFileActionTest extends TestCase /** @test */ public function can_store_file() { - Storage::fake(); + Storage::fake('s3'); $file = UploadedFile::fake()->image('file.jpg'); app(StoreFileAction::class)($file); - Storage::assertExists($file->hashName('testing/blogs')); + Storage::disk('s3')->assertExists($file->hashName('testing/blogs')); } } diff --git a/tests/Http/Dashboard/Blogs/StoreBlogImageTest.php b/tests/Http/Dashboard/Blogs/StoreBlogImageTest.php new file mode 100644 index 00000000..0d59f0d4 --- /dev/null +++ b/tests/Http/Dashboard/Blogs/StoreBlogImageTest.php @@ -0,0 +1,158 @@ +postJson(route('dashboard.blogs.store')) + ->assertStatus(401); + } + + /** @test */ + public function file_is_required() + { + $this->actingAs(User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.image.store'), [ + 'file' => null, + ]) + ->assertStatus(422) + ->assertJsonValidationErrors([ + 'file' => 'The file field is required' + ]); + } + + /** @test */ + public function file_must_be_an_image() + { + $this->actingAs(User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.image.store'), [ + 'file' => '1234', + ]) + ->assertStatus(422) + ->assertJsonValidationErrors([ + 'file' => 'The file must be an image' + ]); + } + + /** @test */ + public function fields_must_be_a_string() + { + $this->actingAs(User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.image.store'), [ + 'fileId' => 1234, + 'blogId' => 1234, + ]) + ->assertStatus(422) + ->assertJsonValidationErrors([ + 'fileId' => 'The file id must be a string', + 'blogId' => 'The blog id must be a string' + ]); + } + + /** @test */ + public function fields_are_not_required() + { + Storage::fake('s3'); + + $uploadedFile = UploadedFile::fake()->image('file.jpg'); + + $this->actingAs(User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.image.store'), [ + 'file' => $uploadedFile, + ]) + ->assertOk(); + } + + /** @test */ + public function file_info_is_replaced_with_new_info_if_id_is_provided() + { + Storage::fake('s3'); + + $this->storeFileAction = $this->mock(StoreFileAction::class); + app()->instance(StoreFileAction::class, $this->storeFileAction); + + $this->destroyFileAction = $this->mock(DestroyFileAction::class); + app()->instance(DestroyFileAction::class, $this->destroyFileAction); + + $uploadedFile = UploadedFile::fake()->image('file.jpg'); + + $file = File::create([ + 'path' => 'some-old-path', + 'url' => '/storage/some-old-path' + ]); + + $this->storeFileAction->shouldReceive('__invoke') + ->once() + ->withArgs(function ($uploadedFileInstance) { + return $uploadedFileInstance instanceof UploadedFile; + }) + ->andReturn('new-file-path'); + + $this->destroyFileAction->shouldReceive('__invoke') + ->once() + ->withArgs(function ($storedFileInstance) use ($file) { + return $storedFileInstance instanceof File + && $file->is($storedFileInstance); + }) + ->andReturn('new-file-path'); + + $this->actingAs(User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.image.store'), [ + 'file' => $uploadedFile, + 'fileId' => (string)$file->id + ]) + ->assertOk(); + + $this->assertDatabaseHas('files', [ + 'blog_id' => null, + 'path' => 'new-file-path', + 'url' => '/storage/new-file-path' + ]); + } + + /** @test */ + public function new_file_is_created_if_no_file_is_is_stored() + { + Storage::fake('s3'); + + $this->storeFileAction = $this->mock(StoreFileAction::class); + app()->instance(StoreFileAction::class, $this->storeFileAction); + + $file = UploadedFile::fake()->image('file.jpg'); + + $this->storeFileAction->shouldReceive('__invoke') + ->once() + ->withArgs(function ($uploadedFile) use ($file) { + return $uploadedFile instanceof UploadedFile; + }) + ->andReturn('some-random-path'); + + $this->actingAs(User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.image.store'), [ + 'file' => $file, + ]) + ->assertOk(); + + $this->assertDatabaseHas('files', [ + 'blog_id' => null, + 'path' => 'some-random-path', + 'url' => '/storage/some-random-path' + ]); + } +} diff --git a/tests/Http/Dashboard/Blogs/StoreBlogTest.php b/tests/Http/Dashboard/Blogs/StoreBlogTest.php index 54c8ce1e..e9e4882e 100644 --- a/tests/Http/Dashboard/Blogs/StoreBlogTest.php +++ b/tests/Http/Dashboard/Blogs/StoreBlogTest.php @@ -6,6 +6,7 @@ use App\Domain\Blog\Models\Tag; use App\Domain\Iam\Models\User; use App\Domain\Blog\Models\Blog; +use App\Domain\File\Models\File; class StoreBlogTest extends TestCase { @@ -253,4 +254,78 @@ public function tags_is_attached_to_blog() 'tag_id' => $tag->id, ]); } + + /** @test */ + public function will_replace_blog_id_in_content() + { + $tag = Tag::factory()->create(); + + $this->actingAs($user = User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.store'), [ + 'title' => 'Some Title', + 'slug' => 'some-slug', + 'tags' => [ + [ + 'id' => $tag->id, + 'name' => $tag->name + ] + ], + 'meta_title' => 'some title', + 'meta_tags' => 'some tag', + 'meta_description' => 'some description', + 'content' => ' ', + 'is_draft' => true + ]) + ->assertRedirect(route('dashboard.blogs.index')); + + $blog = Blog::first(); + + $this->assertDatabaseHas('blogs', [ + 'author_id' => $user->id, + 'is_draft' => 1, + 'title' => 'Some Title', + 'slug' => 'some-slug', + 'meta_title' => 'some title', + 'meta_tags' => 'some tag', + 'meta_description' => 'some description', + 'content' => "id\"> " + ]); + } + + /** @test */ + public function any_files_without_blog_id_will_be_assigned_recently_created_one() + { + File::create([ + 'path' => 'some-path', + 'url' => 'some-url' + ]); + + $tag = Tag::factory()->create(); + + $this->actingAs($user = User::factory()->author()->create()) + ->postJson(route('dashboard.blogs.store'), [ + 'title' => 'Some Title', + 'slug' => 'some-slug', + 'tags' => [ + [ + 'id' => $tag->id, + 'name' => $tag->name + ] + ], + 'meta_title' => 'some title', + 'meta_tags' => 'some tag', + 'meta_description' => 'some description', + 'content' => ' ', + 'is_draft' => true + ]) + ->assertRedirect(route('dashboard.blogs.index')); + + $blog = Blog::first(); + + $this->assertDatabaseHas('files', [ + 'blog_id' => $blog->id, + 'path' => 'some-path', + 'url' => 'some-url' + ]); + } } diff --git a/tests/Http/Dashboard/Blogs/UpdateBlogTest.php b/tests/Http/Dashboard/Blogs/UpdateBlogTest.php index 6038e55b..19bf5017 100644 --- a/tests/Http/Dashboard/Blogs/UpdateBlogTest.php +++ b/tests/Http/Dashboard/Blogs/UpdateBlogTest.php @@ -6,6 +6,7 @@ use App\Domain\Blog\Models\Tag; use App\Domain\Iam\Models\User; use App\Domain\Blog\Models\Blog; +use App\Domain\File\Models\File; class UpdateBlogTest extends TestCase { @@ -295,4 +296,78 @@ public function tags_is_attached_to_blog() 'tag_id' => $tag->id, ]); } + + /** @test */ + public function will_replace_blog_id_in_content() + { + $tag = Tag::factory()->create(); + + $this->actingAs($this->user) + ->putJson(route('dashboard.blogs.update', $this->blog), [ + 'title' => 'Some Title', + 'slug' => 'some-slug', + 'tags' => [ + [ + 'id' => $tag->id, + 'name' => $tag->name + ] + ], + 'meta_title' => 'some title', + 'meta_tags' => 'some tag', + 'meta_description' => 'some description', + 'content' => ' ', + 'is_draft' => true + ]) + ->assertRedirect(route('dashboard.blogs.index')); + + $blog = Blog::first(); + + $this->assertDatabaseHas('blogs', [ + 'author_id' => $this->user->id, + 'is_draft' => 1, + 'title' => 'Some Title', + 'slug' => 'some-slug', + 'meta_title' => 'some title', + 'meta_tags' => 'some tag', + 'meta_description' => 'some description', + 'content' => "id\"> " + ]); + } + + /** @test */ + public function any_files_without_blog_id_will_be_assigned_recently_created_one() + { + File::create([ + 'path' => 'some-path', + 'url' => 'some-url' + ]); + + $tag = Tag::factory()->create(); + + $this->actingAs($this->user) + ->putJson(route('dashboard.blogs.update', $this->blog), [ + 'title' => 'Some Title', + 'slug' => 'some-slug', + 'tags' => [ + [ + 'id' => $tag->id, + 'name' => $tag->name + ] + ], + 'meta_title' => 'some title', + 'meta_tags' => 'some tag', + 'meta_description' => 'some description', + 'content' => ' ', + 'is_draft' => true + ]) + ->assertRedirect(route('dashboard.blogs.index')); + + $blog = Blog::first(); + + $this->assertDatabaseHas('files', [ + 'blog_id' => $blog->id, + 'path' => 'some-path', + 'url' => 'some-url' + ]); + } } diff --git a/tests/TestCase.php b/tests/TestCase.php index aaaa5617..a07fd9f2 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -20,6 +20,7 @@ protected function setUp(): void $this->withoutVite(); $this->seedRoles(); + Carbon::setTestNow(now()); }