Skip to content
This repository has been archived by the owner on Feb 18, 2023. It is now read-only.

User Registration endpoint #82

Merged
merged 8 commits into from
Jan 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,6 @@ jobs:
php artisan passport:keys
- name: Execute tests
run: vendor/bin/phpunit

- name: Test Code Style php-cs-fixer
run: PHP_CS_FIXER_IGNORE_ENV=true vendor/bin/php-cs-fixer fix --config=.php_cs.dist -v --dry-run --stop-on-violation --using-cache=no
33 changes: 33 additions & 0 deletions app/Http/Controllers/Api/Auth/RegisterController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace App\Http\Controllers\Api\Auth;

use App\Http\Controllers\Controller;
use App\Models\User;
use App\Transformers\Users\UserTransformer;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;

class RegisterController extends Controller
{
protected $model;

public function __construct(User $model)
{
$this->model = $model;
}

public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'email' => 'required|email|unique:users,email',
'password' => 'required|min:8|confirmed',
]);
$user = $this->model->create($request->all());
$user->assignRole('User');
event(new Registered($user));

return fractal($user, new UserTransformer())->respond(201);
}
}
1 change: 1 addition & 0 deletions database/seeders/Users/RoleTableSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class RoleTableSeeder extends Seeder
*/
public $roles = [
['name' => 'Administrator'],
['name' => 'User'],
];

/**
Expand Down
45 changes: 43 additions & 2 deletions docs/api/apiblueprint.apib
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,13 @@ The API uses conventional HTTP response codes to indicate the success or failure
# Data Structures

<!-- include(dataStructures/errors.apib) -->
<!-- include(dataStructures/auth.apib) -->
<!-- include(dataStructures/users.apib) -->
<!-- include(dataStructures/roles.apib) -->
<!-- include(dataStructures/permissions.apib) -->
<!-- include(dataStructures/assets.apib) -->

<!-- include(routes/auth.apib) -->
<!-- include(routes/users.apib) -->
<!-- include(routes/assets.apib) -->
### Asset Object (object)
Expand All @@ -59,7 +61,12 @@ The API uses conventional HTTP response codes to indicate the success or failure
+ full: `https://laravelapi.test/api/assets/0c244c51-0a3b-4b86-829a-ee161c2f966f/render` (string) - The asset link for render full size
+ thumb: `https://laravelapi.test/api/assets/0c244c51-0a3b-4b86-829a-ee161c2f966f/render?width=200&height=200` (string) - The asset link for render thumb size
+ created_at : `1997-07-16T19:20:30+01:00` (string) - Date in format iso 8601
## Error 404 (object)
### Registration input (object)
- name: `Jose Fonseca`(string, required) - The name of the user
- email: `[email protected]` (string, required) - The email of the user
- password: `Password123**` (string, required) - The password of the user
- password_confirmation: `Password123**` (string, required) - The password confirmation of the user
## Error 404 (object)
- message: `404 Not found` (string)
- status_code: 404 (number) `status code number`

Expand Down Expand Up @@ -216,7 +223,41 @@ In the body of the requests you can send the raw binary data in base 64 encoded
{
"code": 413,
"message": "The body is too large"
}
}# Group Auth

The auth API will allow you to work with the users registration and password management.

## Register [/api/register]
Use this endpoint to register a new user from the client consuming the API.

### Register user [POST]
This endpoint will allow you to handle the user registration in the API

+ Request (application/json)

+ Attributes (Registration input)

+ Response 201 (application/json)

+ Attributes
+ data (User Object)

+ Response 422 (application/json)

+ Attributes (Error 422)

+ Response 401 (application/json)

+ Attributes (Error 401)

+ Response 403 (application/json)

+ Attributes (Error 403)

+ Response 404 (application/json)

+ Attributes (Error 404)

## Permissions resource [/api/permissions]
It requires your user to have permissions to fetch, create, update or delete roles in the system depending on the request you want to make

Expand Down
2 changes: 2 additions & 0 deletions docs/api/blueprint/apidocs.apib
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@ The API uses conventional HTTP response codes to indicate the success or failure
# Data Structures

<!-- include(dataStructures/errors.apib) -->
<!-- include(dataStructures/auth.apib) -->
<!-- include(dataStructures/users.apib) -->
<!-- include(dataStructures/roles.apib) -->
<!-- include(dataStructures/permissions.apib) -->
<!-- include(dataStructures/assets.apib) -->

<!-- include(routes/auth.apib) -->
<!-- include(routes/users.apib) -->
<!-- include(routes/assets.apib) -->
5 changes: 5 additions & 0 deletions docs/api/blueprint/dataStructures/auth.apib
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Registration input (object)
- name: `Jose Fonseca`(string, required) - The name of the user
- email: `[email protected]` (string, required) - The email of the user
- password: `Password123**` (string, required) - The password of the user
- password_confirmation: `Password123**` (string, required) - The password confirmation of the user
34 changes: 34 additions & 0 deletions docs/api/blueprint/routes/auth.apib
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Group Auth

The auth API will allow you to work with the users registration and password management.

## Register [/api/register]
Use this endpoint to register a new user from the client consuming the API.

### Register user [POST]
This endpoint will allow you to handle the user registration in the API

+ Request (application/json)

+ Attributes (Registration input)

+ Response 201 (application/json)

+ Attributes
+ data (User Object)

+ Response 422 (application/json)

+ Attributes (Error 422)

+ Response 401 (application/json)

+ Attributes (Error 401)

+ Response 403 (application/json)

+ Attributes (Error 403)

+ Response 404 (application/json)

+ Attributes (Error 404)
196 changes: 193 additions & 3 deletions resources/views/apidocs.blade.php

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

Route::get('assets/{uuid}/render', 'Api\Assets\RenderFileController@show');

Route::post('register', 'Api\Auth\RegisterController@store');

Route::group(['middleware' => ['auth:api']], function () {
Route::group(['prefix' => 'users'], function () {
Route::get('/', 'Api\Users\UsersController@index');
Expand Down
74 changes: 74 additions & 0 deletions tests/Feature/Auth/RegisterTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Tests\Feature\Auth;

use App\Models\User;
use Illuminate\Auth\Events\Registered;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Event;
use Spatie\Permission\PermissionRegistrar;
use Tests\TestCase;

class RegisterTest extends TestCase
{
use RefreshDatabase;

public function setUp() : void
{
parent::setUp();
$this->seed();
$this->app->make(PermissionRegistrar::class)->registerPermissions();
}

public function test_it_register_user_with_role()
{
Event::fake([Registered::class]);
$response = $this->json('POST', 'api/register/', [
'name' => 'John Doe',
'email' => '[email protected]',
'password' => '12345678',
'password_confirmation' => '12345678',
]);
$response->assertStatus(201);
$this->assertDatabaseHas('users', [
'name' => 'John Doe',
'email' => '[email protected]',
]);
$user = User::where('email', '[email protected]')->first();
$this->assertTrue($user->hasRole('User'));
Event::assertDispatched(Registered::class, function ($event) use ($user) {
return $user->id === $event->user->id;
});
}

public function test_it_validates_input_for_registration()
{
Event::fake([Registered::class]);
$response = $this->json('POST', 'api/register', [
'name' => 'Some User',
'email' => '[email protected]',
'password' => '123456789qq',
]);
$response->assertStatus(422);
$this->assertDatabaseMissing('users', [
'name' => 'Some User',
'email' => '[email protected]',
]);
Event::assertNotDispatched(Registered::class);
}

public function test_it_returns_422_on_validation_error()
{
Event::fake([Registered::class]);
$response = $this->json('POST', 'api/register', [
'name' => 'Some User',
]);
$response->assertStatus(422);
$this->assertEquals('{"message":"The given data was invalid.","status_code":422,"errors":{"email":["The email field is required."],"password":["The password field is required."]}}', $response->getContent());
$this->assertDatabaseMissing('users', [
'name' => 'Some User',
'email' => '[email protected]',
]);
Event::assertNotDispatched(Registered::class);
}
}