From f5a1894c5a879dae3a840a4d38754a3175026320 Mon Sep 17 00:00:00 2001 From: fokosun Date: Mon, 21 Aug 2023 20:22:32 -0400 Subject: [PATCH] chore: improving test coverage --- app/Http/Controllers/RecipeController.php | 29 ++++- app/Models/Recipe.php | 1 + ...add_is_reported_field_to_recipes_table.php | 28 ++++ tests/Feature/RecipeTest.php | 123 +++++++++++++++++- 4 files changed, 171 insertions(+), 10 deletions(-) create mode 100644 database/migrations/2023_08_21_234409_add_is_reported_field_to_recipes_table.php diff --git a/app/Http/Controllers/RecipeController.php b/app/Http/Controllers/RecipeController.php index 21ea34a6..52d1413c 100755 --- a/app/Http/Controllers/RecipeController.php +++ b/app/Http/Controllers/RecipeController.php @@ -6,6 +6,7 @@ use App\Exceptions\CookbookModelNotFoundException; use App\Http\Requests\RecipeStoreRequest; +use App\Models\Recipe; use App\Services\RecipeService; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\Routing\ResponseFactory; @@ -13,6 +14,7 @@ use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Support\Facades\Log; +use PHPOpenSourceSaver\JWTAuth\Facades\JWTAuth; use Tymon\JWTAuth\Exceptions\JWTException; use Tymon\JWTAuth\JWT; @@ -157,14 +159,27 @@ public function destroy(Request $request, $recipeId, JWT $jwtAuth) ], Response::HTTP_UNAUTHORIZED); } - public function report(Request $request, JWT $jwtAuth) + public function report(Request $request) { - if ($jwtAuth->parseToken()->check()) { - return response()->json(['message' => 'feedback submitted.']); - } + if (JWTAuth::parseToken()->user()) { + $recipe = Recipe::find($request->get('recipe_id')); - return response()->json([ - 'error' => 'You are not authorized to perform this action.' - ], Response::HTTP_UNAUTHORIZED); + if ($recipe instanceof Recipe) { + $recipe->update(['is_reported' => 1]); + return response()->json(['message' => 'feedback submitted.']); + } + + Log::debug( + 'Error reporting recipe', + [ + 'message' => 'Invalid recipe id', + 'recipe_id' => $request->get('recipe_id') + ] + ); + + return $this->errorResponse([ + 'message' => 'There was an error processing this request. Please try again later.' + ]); + } } } diff --git a/app/Models/Recipe.php b/app/Models/Recipe.php index da0a20f2..5b441e44 100755 --- a/app/Models/Recipe.php +++ b/app/Models/Recipe.php @@ -36,6 +36,7 @@ class Recipe extends Model 'course', 'cuisine', 'nationality', + 'is_reported' ]; protected $hidden = ['user_id']; diff --git a/database/migrations/2023_08_21_234409_add_is_reported_field_to_recipes_table.php b/database/migrations/2023_08_21_234409_add_is_reported_field_to_recipes_table.php new file mode 100644 index 00000000..0511ddb6 --- /dev/null +++ b/database/migrations/2023_08_21_234409_add_is_reported_field_to_recipes_table.php @@ -0,0 +1,28 @@ +boolean('is_reported')->default(0); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('recipes', function (Blueprint $table) { + $table->dropColumn('is_reported'); + }); + } +}; diff --git a/tests/Feature/RecipeTest.php b/tests/Feature/RecipeTest.php index 9c831d09..fd54fd8f 100755 --- a/tests/Feature/RecipeTest.php +++ b/tests/Feature/RecipeTest.php @@ -7,14 +7,15 @@ use App\Models\Cookbook; use App\Models\Recipe; use App\Models\User; +use Illuminate\Hashing\BcryptHasher; use Illuminate\Http\Response; use Illuminate\Support\Facades\Auth; +use Illuminate\Support\Facades\Log; class RecipeTest extends \TestCase { /** * @test - * todo: service->validatePayload */ public function it_can_retrieve_all_recipes_and_respond_with_a_200_status_code() { @@ -163,11 +164,14 @@ public function it_cannot_clap_for_a_recipe_that_does_not_exist() ]); } + /** + * @test + */ public function it_can_show_my_recipes() { $user = User::factory()->make([ 'email' => 'evan.reid@123.com', - 'password' => 'pass123' + 'password' => (new BcryptHasher)->make('pass123'), ]); $user->save(); @@ -191,7 +195,7 @@ public function it_can_show_my_recipes() $recipe->save(); }); - $this->json( + $response = $this->json( 'GET', '/api/v1/my/recipes', [], @@ -199,5 +203,118 @@ public function it_can_show_my_recipes() 'Authorization' => 'Bearer ' . $token ] )->assertStatus(200); + + $decoded = json_decode($response->getContent(), true); + + $this->assertCount(3, $decoded['data']); + } + + /** + * @test + */ + public function it_can_report_a_recipe() + { + $user = User::factory()->make([ + 'email' => 'evan.reid@123.com', + 'password' => (new BcryptHasher)->make('pass123'), + ]); + $user->save(); + + $token = Auth::attempt([ + 'email' => 'evan.reid@123.com', + 'password' => 'pass123' + ]); + + $cookbook = Cookbook::factory()->make([ + 'user_id' => $user->getKey() + ]); + + $cookbook->save(); + + $recipe = Recipe::factory()->make([ + 'cookbook_id' => $cookbook->refresh()->getKey(), + 'user_id' => $user->getKey() + ]); + + $recipe->save(); + + $this->assertFalse((bool) $recipe->refresh()->is_reported); + + $this->json( + 'POST', + '/api/v1/report-recipe', + [ + 'recipe_id' => $recipe->refresh()->getKey() + ], + [ + 'Authorization' => 'Bearer ' . $token + ] + )->assertStatus(200) + ->assertExactJson([ + 'message' => 'feedback submitted.' + ]); + + $this->assertTrue((bool) $recipe->refresh()->is_reported); + } + + /** + * @test + */ + public function it_can_handle_error_reporting_recipe() + { + $user = User::factory()->make([ + 'email' => 'evan.reid@123.com', + 'password' => (new BcryptHasher)->make('pass123'), + ]); + $user->save(); + + $token = Auth::attempt([ + 'email' => 'evan.reid@123.com', + 'password' => 'pass123' + ]); + + Log::shouldReceive('debug') + ->once() + ->with( + 'Error reporting recipe', + [ + 'message' => 'Invalid recipe id', + 'recipe_id' => 1 + ] + ); + + $this->withoutExceptionHandling()->json( + 'POST', + '/api/v1/report-recipe', + [ + 'recipe_id' => 1 + ], + [ + 'Authorization' => 'Bearer ' . $token + ] + )->assertStatus(400) + ->assertExactJson([ + 'message' => 'There was an error processing this request. Please try again later.' + ]); + } + + /** + * @test + */ + public function it_allows_only_authorized_user_to_report_a_recipe() + { + $this->json( + 'POST', + '/api/v1/report-recipe', + [ + 'recipe_id' => 1 + ], + [ + 'Authorization' => 'Bearer invalid-token' + ] + )->assertStatus(401) + ->assertExactJson([ + 'error' => 'Your session has expired. Please login and try again.' + ]); } }