Skip to content

Commit e8753b5

Browse files
authored
Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a q… (laravel-portugal#49)
* Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Add new feature in CHANGELOG.md) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Refactoring) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Remove extra space) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Refactoring and remove ThrottleGuestMiddleware.php) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Refactoring and remove ThrottleGuestMiddleware.php) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Refactoring and remove ThrottleGuestMiddleware.php) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Refactoring and remove Test) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Refactoring and rename Test) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Resolve Trouble with Middleware) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Minor change) * Resolve laravel-portugal#48 - A guest or an authenticated user can see details of a question (Minor change)
1 parent abb432c commit e8753b5

File tree

5 files changed

+168
-1
lines changed

5 files changed

+168
-1
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ All notable changes to `laravel-portugal/api` will be documented in this file
66

77
### Added
88

9-
- N/A
9+
- A guest or an authenticated user can see details of a question (#48)
1010

1111
### Changed
1212

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
namespace Domains\Discussions\Controllers;
4+
5+
use App\Http\Controllers\Controller;
6+
use Domains\Discussions\Models\Question;
7+
use Domains\Discussions\Resources\QuestionResource;
8+
use Illuminate\Contracts\Auth\Factory as Auth;
9+
10+
class QuestionsViewController extends Controller
11+
{
12+
private Question $question;
13+
14+
public function __construct(Auth $auth, Question $question)
15+
{
16+
$this->question = $question;
17+
18+
if ($auth->guard()->guest()) {
19+
$this->middleware('throttle:30,1');
20+
}
21+
}
22+
23+
public function __invoke(int $questionId): QuestionResource
24+
{
25+
return QuestionResource::make($this->question->findOrFail($questionId));
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace Domains\Discussions\Resources;
4+
5+
use Domains\Accounts\Resources\UserResource;
6+
use Illuminate\Http\Resources\Json\JsonResource;
7+
8+
class QuestionResource extends JsonResource
9+
{
10+
public function toArray($request): array
11+
{
12+
return [
13+
'id' => $this->id,
14+
'title' => $this->title,
15+
'slug' => $this->slug,
16+
'description' => $this->description,
17+
'author' => UserResource::make($this->author),
18+
'created_at' => $this->created_at,
19+
'updated_at' => $this->updated_at,
20+
'deleted_at' => $this->deleted_at,
21+
];
22+
}
23+
}
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
3+
namespace Domains\Discussions\Tests\Feature;
4+
5+
use Domains\Accounts\Database\Factories\UserFactory;
6+
use Domains\Accounts\Models\User;
7+
use Domains\Discussions\Database\Factories\QuestionFactory;
8+
use Domains\Discussions\Models\Question;
9+
use Illuminate\Http\Response;
10+
use Laravel\Lumen\Testing\DatabaseMigrations;
11+
use Tests\TestCase;
12+
13+
class QuestionsViewTest extends TestCase
14+
{
15+
use DatabaseMigrations;
16+
17+
private User $user;
18+
private Question $question;
19+
20+
protected function setUp(): void
21+
{
22+
parent::setUp();
23+
24+
$this->user = UserFactory::new()->create();
25+
$this->question = QuestionFactory::new(['author_id' => $this->user->id])->create();
26+
}
27+
28+
/** @test */
29+
public function it_allow_guest_see_a_question(): void
30+
{
31+
$this->get(route('discussions.questions.view', ['questionId' => $this->question->id]))
32+
->seeJson([
33+
'data' => [
34+
'id' => $this->question->id,
35+
'title' => $this->question->title,
36+
'slug' => $this->question->slug,
37+
'description' => $this->question->description,
38+
'author' => [
39+
'id' => $this->user->id,
40+
'name' => $this->user->name,
41+
'email' => $this->user->email,
42+
'trusted' => $this->user->trusted ? "1" : "0",
43+
'created_at' => $this->user->created_at,
44+
'updated_at' => $this->user->updated_at,
45+
'deleted_at' => $this->user->deleted_at
46+
],
47+
'created_at' => $this->question->created_at,
48+
'updated_at' => $this->question->updated_at,
49+
'deleted_at' => $this->question->deleted_at
50+
]
51+
]);
52+
}
53+
54+
/** @test */
55+
public function it_allow_authenticated_user_see_a_question(): void
56+
{
57+
$this->actingAs($this->user);
58+
$this->get(route('discussions.questions.view', ['questionId' => $this->question->id]))
59+
->seeJsonStructure([
60+
'data' => [
61+
'id',
62+
'title',
63+
'slug',
64+
'description',
65+
'author',
66+
'created_at',
67+
'updated_at',
68+
'deleted_at'
69+
]
70+
]);
71+
}
72+
73+
/** @test */
74+
public function it_blocked_guest_for_many_attempts(): void
75+
{
76+
for ($attempt = 0; $attempt < 30; ++$attempt) {
77+
$this->get(route('discussions.questions.view', ['questionId' => $this->question->id]))
78+
->assertResponseStatus(Response::HTTP_OK);
79+
}
80+
81+
$this->get(route('discussions.questions.view', ['questionId' => $this->question->id]))
82+
->assertResponseStatus(Response::HTTP_TOO_MANY_REQUESTS);
83+
}
84+
85+
/** @test */
86+
public function it_not_blocked_authenticated_user_for_many_attempts(): void
87+
{
88+
$this->actingAs($this->user);
89+
90+
for ($attempt = 0; $attempt < 30; ++$attempt) {
91+
$this->get(route('discussions.questions.view', ['questionId' => $this->question->id]));
92+
}
93+
94+
$this->get(route('discussions.questions.view', ['questionId' => $this->question->id]))
95+
->assertResponseStatus(Response::HTTP_OK);
96+
}
97+
98+
/** @test */
99+
public function it_fails_on_invalid_question(): void
100+
{
101+
$this->get(route('discussions.questions.view', ['questionId' => 1000]))
102+
->assertResponseStatus(Response::HTTP_NOT_FOUND);
103+
}
104+
105+
/** @test */
106+
public function it_fails_on_view_a_deleted_question(): void
107+
{
108+
$this->question->delete();
109+
$this->get(route('discussions.questions.view', ['questionId' => $this->question->id]))
110+
->assertResponseStatus(Response::HTTP_NOT_FOUND);
111+
}
112+
}

domains/Discussions/routes.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use Domains\Discussions\Controllers\AnswersStoreController;
44
use Domains\Discussions\Controllers\QuestionsStoreController;
55
use Domains\Discussions\Controllers\QuestionsUpdateController;
6+
use Domains\Discussions\Controllers\QuestionsViewController;
67
use Illuminate\Support\Facades\Route;
78

89
Route::group(['middleware' => 'auth'], function () {
@@ -22,3 +23,7 @@
2223
]);
2324
});
2425

26+
Route::get('questions/{questionId}', [
27+
'as' => 'questions.view',
28+
'uses' => QuestionsViewController::class
29+
]);

0 commit comments

Comments
 (0)