From b82f34ed4d3299dcdd3b91cbbc51729b4bfadeae Mon Sep 17 00:00:00 2001 From: Peter Papp Date: Sun, 28 Feb 2021 16:45:34 +0100 Subject: [PATCH] added ShareTest test methods --- .../FileFunctions/ShareController.php | 46 ++-- .../Sharing/FileSharingController.php | 15 +- .../Requests/Share/CreateShareRequest.php | 3 +- app/Http/Resources/ShareResource.php | 18 +- app/Models/Folder.php | 2 +- .../2020_04_20_071047_create_shares_table.php | 2 +- routes/api.php | 6 +- tests/Feature/ShareTest.php | 205 +++++++++++++++++- 8 files changed, 246 insertions(+), 51 deletions(-) diff --git a/app/Http/Controllers/FileFunctions/ShareController.php b/app/Http/Controllers/FileFunctions/ShareController.php index d132dbe3..68f57127 100644 --- a/app/Http/Controllers/FileFunctions/ShareController.php +++ b/app/Http/Controllers/FileFunctions/ShareController.php @@ -5,8 +5,9 @@ namespace App\Http\Controllers\FileFunctions; use App\Http\Requests\Share\CreateShareRequest; use App\Http\Requests\Share\UpdateShareRequest; use App\Http\Resources\ShareResource; +use App\Models\Share; +use App\Models\Zip; use App\Notifications\SharedSendViaEmail; -use App\Zip; use Illuminate\Contracts\Routing\ResponseFactory; use App\Http\Controllers\Controller; use Illuminate\Http\Request; @@ -15,7 +16,6 @@ use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Notification; use Illuminate\Support\Str; -use App\Share; use Validator; class ShareController extends Controller @@ -38,40 +38,43 @@ class ShareController extends Controller * Generate file share link * * @param CreateShareRequest $request + * @param $id * @return ShareResource */ - public function store(CreateShareRequest $request) + public function store(CreateShareRequest $request, $id) { + // TODO: poriesit binarny string do { // Generate unique token $token = Str::random(16); - } while (Share::where(DB::raw('BINARY `token`'), $token)->exists()); + } while (Share::where('token', $token)->exists()); // Create shared options $options = [ - 'password' => $request->has('password') ? Hash::make($request->password) : null, - 'type' => $request->type === 'folder' ? 'folder' : 'file', - 'protected' => $request->isPassword, - 'permission' => $request->permission, - 'item_id' => $request->unique_id, - 'expire_in' => $request->expiration, - 'user_id' => Auth::id(), - 'token' => $token, + 'password' => $request->has('password') ? Hash::make($request->password) : null, + 'type' => $request->type === 'folder' ? 'folder' : 'file', + 'is_protected' => $request->isPassword, + 'permission' => $request->permission ?? null, + 'item_id' => $id, + 'expire_in' => $request->expiration ?? null, + 'user_id' => Auth::id(), + 'token' => $token, ]; - // Return created shared record - $share = new ShareResource(Share::create($options)); - // Send shared link via email if ($request->has('emails')) { foreach ($request->emails as $email) { - Notification::route('mail', $email)->notify(new SharedSendViaEmail($token)); + + Notification::route('mail', $email)->notify( + new SharedSendViaEmail($token) + ); } } - return $share; + // Return created shared record + return new ShareResource(Share::create($options)); } /** @@ -137,8 +140,9 @@ class ShareController extends Controller * @param $token * @param $request */ - public function shared_send_via_email(Request $request, $token) + public function send_to_emails_recipients(Request $request, $token) { + // TODO: pridat validation request // Make validation of array of emails $validator = Validator::make($request->all(), [ 'emails.*' => 'required|email', @@ -148,9 +152,11 @@ class ShareController extends Controller if ($validator->fails()) abort(400, 'Bad email input'); // Send shared link via email - if($request->has('emails')) { + if ($request->has('emails')) { + foreach ($request->emails as $email) { - Notification::route('mail', $email)->notify(new SharedSendViaEmail($token)); + Notification::route('mail', $email) + ->notify(new SharedSendViaEmail($token)); } } diff --git a/app/Http/Controllers/Sharing/FileSharingController.php b/app/Http/Controllers/Sharing/FileSharingController.php index 4571b200..07c4d1b1 100644 --- a/app/Http/Controllers/Sharing/FileSharingController.php +++ b/app/Http/Controllers/Sharing/FileSharingController.php @@ -6,8 +6,8 @@ use App\Http\Controllers\Controller; use App\Http\Requests\Share\AuthenticateShareRequest; use App\Http\Resources\ShareResource; use App\Http\Tools\Guardian; -use App\Setting; -use http\Env\Response; +use App\Models\Share; +use App\Models\Setting; use Illuminate\Contracts\View\Factory; use Illuminate\Support\Facades\Cookie; use Illuminate\Support\Facades\DB; @@ -15,10 +15,9 @@ use Illuminate\Support\Facades\Hash; use Illuminate\Support\Collection; use Illuminate\Http\Request; use Illuminate\Support\Arr; -use App\Folder; -use App\File; -use App\User; -use App\Share; +use App\Models\Folder; +use App\Models\File; +use App\Models\User; use Illuminate\Support\Facades\Storage; class FileSharingController extends Controller @@ -43,14 +42,14 @@ class FileSharingController extends Controller Cookie::queue('shared_access_token', '', -1); // Set cookies - if ((int) $shared->protected) { + if ((int) $shared->is_protected) { // Set shared token Cookie::queue('shared_token', $token, 43200); } // Check if shared is image file and then show it - if ($shared->type === 'file' && ! (int) $shared->protected) { + if ($shared->type === 'file' && ! (int) $shared->is_protected) { $image = File::where('user_id', $shared->user_id) ->where('type', 'image') diff --git a/app/Http/Requests/Share/CreateShareRequest.php b/app/Http/Requests/Share/CreateShareRequest.php index b3e18f49..40d0bedb 100644 --- a/app/Http/Requests/Share/CreateShareRequest.php +++ b/app/Http/Requests/Share/CreateShareRequest.php @@ -26,12 +26,11 @@ class CreateShareRequest extends FormRequest { return [ 'isPassword' => 'required|boolean', - 'unique_id' => 'required|integer', 'type' => 'required|string', 'expiration' => 'integer|nullable', 'permission' => 'string', 'password' => 'string', - 'emails.*' => 'email' + 'emails.*' => 'email' ]; } } diff --git a/app/Http/Resources/ShareResource.php b/app/Http/Resources/ShareResource.php index 3f37d5ae..fdd89e37 100644 --- a/app/Http/Resources/ShareResource.php +++ b/app/Http/Resources/ShareResource.php @@ -19,15 +19,15 @@ class ShareResource extends JsonResource 'id' => (string)$this->id, 'type' => 'shares', 'attributes' => [ - 'permission' => $this->permission, - 'protected' => (int) $this->protected, - 'item_id' => (int) $this->item_id, - 'expire_in' => (int) $this->expire_in, - 'token' => $this->token, - 'link' => $this->link, - 'type' => $this->type, - 'created_at' => $this->created_at, - 'updated_at' => $this->updated_at, + 'permission' => $this->permission, + 'is_protected' => $this->is_protected, + 'item_id' => $this->item_id, + 'expire_in' => (int)$this->expire_in, + 'token' => $this->token, + 'link' => $this->link, + 'type' => $this->type, + 'created_at' => $this->created_at, + 'updated_at' => $this->updated_at, ] ] ]; diff --git a/app/Models/Folder.php b/app/Models/Folder.php index a660c57a..666d58f1 100644 --- a/app/Models/Folder.php +++ b/app/Models/Folder.php @@ -188,7 +188,7 @@ class Folder extends Model */ public function shared() { - return $this->hasOne(Share::class, 'item_id', 'unique_id'); + return $this->hasOne(Share::class, 'item_id', 'id'); } // Delete all folder children diff --git a/database/migrations/2020_04_20_071047_create_shares_table.php b/database/migrations/2020_04_20_071047_create_shares_table.php index 713586e2..110dd75f 100644 --- a/database/migrations/2020_04_20_071047_create_shares_table.php +++ b/database/migrations/2020_04_20_071047_create_shares_table.php @@ -16,8 +16,8 @@ class CreateSharesTable extends Migration Schema::create('shares', function (Blueprint $table) { $table->uuid('id')->primary(); $table->uuid('user_id'); - $table->string('token', 16)->unique(); $table->uuid('item_id'); + $table->string('token', 16)->unique(); $table->enum('type', ['file', 'folder']); $table->enum('permission', ['visitor', 'editor'])->nullable(); $table->boolean('is_protected')->default(0); diff --git a/routes/api.php b/routes/api.php index b41d8926..13f5b63e 100644 --- a/routes/api.php +++ b/routes/api.php @@ -70,10 +70,10 @@ Route::group(['middleware' => ['auth:sanctum']], function () { // Share Route::group(['prefix' => 'share'], function () { - Route::post('/{token}/send-email', [ShareController::class, 'shared_send_via_email']); - Route::post('/cancel', [ShareController::class, 'destroy']); + Route::post('/{token}/email', [ShareController::class, 'send_to_emails_recipients']); + Route::delete('/revoke', [ShareController::class, 'destroy']); Route::patch('/{token}', [ShareController::class, 'update']); - Route::post('/', [ShareController::class, 'store']); + Route::post('/{id}', [ShareController::class, 'store']); }); }); diff --git a/tests/Feature/ShareTest.php b/tests/Feature/ShareTest.php index 9dbcabef..4917ac5d 100644 --- a/tests/Feature/ShareTest.php +++ b/tests/Feature/ShareTest.php @@ -2,47 +2,238 @@ namespace Tests\Feature; +use App\Models\File; +use App\Models\Folder; +use App\Models\Share; +use App\Models\User; +use App\Notifications\SharedSendViaEmail; use Illuminate\Foundation\Testing\DatabaseMigrations; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithFaker; +use Illuminate\Support\Facades\Notification; +use Laravel\Sanctum\Sanctum; use Tests\TestCase; class ShareTest extends TestCase { use DatabaseMigrations; + /** + * @test + */ + public function it_share_single_file_without_password() + { + $file = File::factory(File::class) + ->create(); + + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $this->postJson("/api/share/$file->id", [ + 'isPassword' => false, + 'permission' => 'editor', + 'type' => 'file', + ])->assertStatus(201)->assertJsonFragment([ + 'item_id' => $file->id, + 'type' => 'file', + ]); + + $this->assertDatabaseHas('shares', [ + 'user_id' => $user->id, + 'item_id' => $file->id, + 'type' => 'file', + 'is_protected' => false, + 'password' => null, + 'expire_in' => null, + ]); + } + + /** + * @test + */ public function it_share_folder_without_password() { + $folder = Folder::factory(Folder::class) + ->create(); + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $this->postJson("/api/share/$folder->id", [ + 'isPassword' => false, + 'permission' => 'editor', + 'type' => 'folder', + ])->assertStatus(201)->assertJsonFragment([ + 'item_id' => $folder->id, + 'type' => 'folder', + ]); + + $this->assertDatabaseHas('shares', [ + 'user_id' => $user->id, + 'item_id' => $folder->id, + 'type' => 'folder', + 'is_protected' => false, + 'password' => null, + 'expire_in' => null, + ]); } + /** + * @test + */ public function it_share_folder_with_password() { + $folder = Folder::factory(Folder::class) + ->create(); + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $this->postJson("/api/share/$folder->id", [ + 'isPassword' => true, + 'password' => 'secret', + 'permission' => 'editor', + 'type' => 'folder', + ]) + ->assertStatus(201) + ->assertJsonFragment([ + 'item_id' => $folder->id, + 'type' => 'folder', + ]); + + $this->assertDatabaseHas('shares', [ + 'user_id' => $user->id, + 'item_id' => $folder->id, + 'type' => 'folder', + 'is_protected' => true, + ]); + + $this->assertDatabaseMissing('shares', [ + 'item_id' => $folder->id, + 'password' => null, + ]); } + /** + * @test + */ public function it_share_folder_with_expiration_time() { + $folder = Folder::factory(Folder::class) + ->create(); + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $this->postJson("/api/share/$folder->id", [ + 'isPassword' => false, + 'permission' => 'editor', + 'type' => 'folder', + 'expiration' => 12, + ]) + ->assertStatus(201) + ->assertJsonFragment([ + 'item_id' => $folder->id, + 'expire_in' => 12, + ]); } - public function it_share_folder_for_single_email() - { - - } - + /** + * @test + */ public function it_share_folder_for_multiple_email() { + Notification::fake(); + $folder = Folder::factory(Folder::class) + ->create(); + + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $this->postJson("/api/share/$folder->id", [ + 'isPassword' => false, + 'permission' => 'editor', + 'type' => 'folder', + 'emails' => [ + 'john@doe.com', + 'jane@doe.com', + ], + ])->assertStatus(201); + + Notification::assertTimesSent(2, SharedSendViaEmail::class); } - public function it_cancel_single_sharing() + /** + * @test + */ + public function it_send_existing_shared_folder_for_multiple_email_once_again() { + Notification::fake(); + $folder = Folder::factory(Folder::class) + ->create(); + + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $this->postJson("/api/share/$folder->id", [ + 'isPassword' => false, + 'permission' => 'editor', + 'type' => 'folder', + ])->assertStatus(201); + + $this->postJson("/api/share/$folder->id/email", [ + 'emails' => [ + 'john@doe.com', + 'jane@doe.com', + ], + ])->assertStatus(204); + + Notification::assertTimesSent(2, SharedSendViaEmail::class); } - public function it_cancel_multiple_sharing() + /** + * @test + * + * TODO: pridat test na zmazanie zip + */ + public function it_revoke_single_sharing() { + $folder = Folder::factory(Folder::class) + ->create(); + $user = User::factory(User::class) + ->create(); + + Sanctum::actingAs($user); + + $this->postJson("/api/share/$folder->id", [ + 'isPassword' => false, + 'permission' => 'editor', + 'type' => 'folder', + ])->assertStatus(201); + + $this->deleteJson("/api/share/revoke", [ + 'tokens' => [ + $folder->shared->token + ], + ])->assertStatus(204); + + $this->assertDatabaseMissing('shares', [ + 'item_id' => $folder->id + ]); } }