Skip to content

Commit ce8c7db

Browse files
committed
store properties requires authentication now
1 parent 2397bc6 commit ce8c7db

12 files changed

+74
-13
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Your local API Docs URL [here](http://localhost/docs/api#/)
1919

2020
## Test cases
2121

22-
![Properties API](/readme/testcases.png)
22+
![Properties API](/readme/tests.png)
2323

2424
## License
2525

app/Http/Controllers/Api/v1/PropertyController.php

+10-2
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,16 @@
1111
use Illuminate\Http\Request;
1212
use Illuminate\Http\Response;
1313
use Spatie\QueryBuilder\QueryBuilder;
14+
use App\Services\Properties\PropertyRepositoryService;
1415

1516
class PropertyController extends Controller
1617
{
18+
public function __construct()
19+
{
20+
//the user needs to be logged in for these methods to be accessed
21+
$this->middleware('auth:api')->only('store');
22+
}
23+
1724
/**
1825
* List properties
1926
*
@@ -95,9 +102,10 @@ public function index(GenericListingRequest $request)
95102
*
96103
* `slug` field is set automatically using the `name` field when the status is set to <b>active</b> (value 1). Once set it can't be changed.
97104
*/
98-
public function store(StorePropertyRequest $request)
105+
public function store(StorePropertyRequest $request, PropertyRepositoryService $propertyRepositoryService)
99106
{
100-
$property = Property::create($request->only('name', 'owner_id', 'status_id'));
107+
//store the new property
108+
$property = $propertyRepositoryService->authUserRequestCreateProperty();
101109

102110
return response()
103111
->json(['data' => [

app/Http/Controllers/Auth/AuthController.php

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ public function __construct()
2828
* Login
2929
*
3030
* Get a JWT via given credentials.
31+
*
32+
* @unauthenticated
3133
*/
3234
public function login(LoginRequest $request): JsonResponse
3335
{

app/Http/Controllers/Auth/PasswordResetLinkController.php

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class PasswordResetLinkController extends Controller
1919
* Handle an incoming password reset link request.
2020
*
2121
* @throws \Illuminate\Validation\ValidationException
22+
*
23+
* @unauthenticated
2224
*/
2325
public function store(Request $request): JsonResponse
2426
{

app/Http/Controllers/Auth/RegisteredUserController.php

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ class RegisteredUserController extends Controller
2222
* Handle an incoming registration request.
2323
*
2424
* @throws \Illuminate\Validation\ValidationException
25+
*
26+
* @unauthenticated
2527
*/
2628
public function register(Request $request): Response
2729
{

app/Http/Requests/v1/StorePropertyRequest.php

-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ public function rules(): array
2525
{
2626
return [
2727
'name' => 'required|string|min:3',
28-
'owner_id' => 'required|exists:users,id',
2928
'status_id' => ['required', Rule::enum(PropertyStatus::class)],
3029
];
3130
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace App\Services\Properties;
4+
5+
use App\Models\Property;
6+
7+
class PropertyRepositoryService
8+
{
9+
public function authUserRequestCreateProperty()
10+
{
11+
return Property::create([...request()->only('name', 'status_id'), ...['owner_id' => auth()->user()->id]]);
12+
}
13+
}

readme/api-docs.png

172 KB
Loading

readme/testcases.png

-459 KB
Binary file not shown.

readme/tests.png

436 KB
Loading

routes/api.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55

66
Route::prefix('v1')->name('api.v1.')->group(function () {
77
Route::apiResource('properties', PropertyController::class);
8-
})->name('v1');
8+
});

tests/Feature/Api/v1/PropertiesControllerTest.php

+43-8
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@
154154
]);
155155
});
156156

157-
it('stores a valid property', function (): void {
157+
it('fails to stores a valid property when unautenticated (unauthorized:401)', function (): void {
158158
$user = User::factory()->create();
159159

160160
// send request to create
@@ -165,6 +165,19 @@
165165
];
166166
$response = $this->postJson(route('api.v1.properties.store'), $recordData);
167167

168+
$response->assertUnauthorized();
169+
});
170+
171+
it('stores a valid property', function (): void {
172+
$user = User::factory()->create();
173+
174+
// send request to create
175+
$recordData = [
176+
'name' => 'Great Villa',
177+
'status_id' => fake()->randomElement(PropertyStatus::values()),
178+
];
179+
$response = $this->actingAs($user)->postJson(route('api.v1.properties.store'), $recordData);
180+
168181
$response->assertStatus(Response::HTTP_CREATED);
169182
$response->assertHeader('Content-Type', 'application/json');
170183
$response->assertJson([
@@ -176,39 +189,61 @@
176189
$this->assertDatabaseHas((new Property)->getTable(), $recordData);
177190
});
178191

192+
it('stores a valid property with the right user id even if different user id is sent', function (): void {
193+
$user = User::factory()->create();
194+
$testUser = User::factory()->create();
195+
196+
// send request to create
197+
$recordData = [
198+
'name' => 'Great Villa',
199+
'owner_id' => $testUser->id,
200+
'status_id' => fake()->randomElement(PropertyStatus::values()),
201+
];
202+
$response = $this->actingAs($user)->postJson(route('api.v1.properties.store'), $recordData);
203+
204+
$response->assertStatus(Response::HTTP_CREATED);
205+
$response->assertHeader('Content-Type', 'application/json');
206+
$response->assertJson([
207+
'data' => [
208+
'id' => 1,
209+
],
210+
]);
211+
212+
$this->assertDatabaseHas((new Property)->getTable(), [...$recordData, ...['owner_id' => $user->id]]);
213+
});
214+
179215
it('fails to store an empty property', function (): void {
216+
$user = User::factory()->create();
180217

181218
// send request to create
182-
$response = $this->postJson(route('api.v1.properties.store'), []);
219+
$response = $this->actingAs($user)->postJson(route('api.v1.properties.store'), []);
183220

184221
$response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
185222
$response->assertHeader('Content-Type', 'application/json');
186223
$response->assertJson([
187-
'message' => 'The name field is required. (and 2 more errors)',
224+
'message' => 'The name field is required. (and 1 more error)',
188225
'errors' => [
189226
'name' => ['The name field is required.'],
190-
'owner_id' => ['The owner id field is required.'],
191227
'status_id' => ['The status id field is required.'],
192228
],
193229
]);
194230
});
195231

196232
it('fails to store wrong values for a property', function (): void {
233+
$user = User::factory()->create();
197234

198235
// send request to create
199-
$response = $this->postJson(route('api.v1.properties.store'), [
236+
$response = $this->actingAs($user)->postJson(route('api.v1.properties.store'), [
200237
'name' => 'a',
201-
'owner_id' => 7,
202238
'status_id' => 91,
203239
]);
204240

205241
$response->assertStatus(Response::HTTP_UNPROCESSABLE_ENTITY);
206242
$response->assertHeader('Content-Type', 'application/json');
207243
$response->assertJson([
208-
'message' => 'The name field must be at least 3 characters. (and 2 more errors)',
244+
'message' => 'The name field must be at least 3 characters. (and 1 more error)',
209245
'errors' => [
210246
'name' => ['The name field must be at least 3 characters.'],
211-
'owner_id' => ['The selected owner id is invalid.'],
212247
'status_id' => ['The selected status id is invalid.'],
213248
],
214249
]);

0 commit comments

Comments
 (0)