Tutorial Laravel Rest API - #5 - Membuat Module Profile

Artikel ini merupakan series dari Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing, disini kita belajar membuat module profile selain membuat rest api kita juga menuliskan sebuah unit test untuk module tersebut.

Rafi Taufiqurrahman
Dipublish 20/10/2024

Pendahuluan

Pada artikel kali ini, kita akan sama - sama membuat sebuah module profile yang kita bagi menjadi beberapa langkah diatanya sebagai berikut :

  1. Membuat Controller Profile
  2. Membuat Route Profile
  3. Membuat Test Profile
  4. Uji Coba Restapi Profile

Membuat Controller Profile

Silahkan teman - teman buka terminal-nya, kemudian jalankan perintah berikut ini :

Terminal
php artisan make:controller Api/ProfileController -i

Jika perintah diatas berhasil dijalankan, maka kita akan mendapatkan sebuah file yang terletak di app/Http/Controllers/Api dengan nama ProfileController.php, selanjutnya silahkan buka file tersebut kemudian tambahkan kodenya menjadi seperti berikut ini.

ProfileController.php
<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class ProfileController extends Controller
{
    /**
     * Display the authenticated user's profile information.
     *
     */
    public function show(Request $request)
    {
        // return response json
        return response()->json([
            'user' => $request->user(),
        ]);
    }

    /**
     * Update the user's profile information.
     *
     */
    public function update(Request $request)
    {
        // get current user
        $user = $request->user();

        // validate request
        $validatedData = $request->validate([
            'name' => 'required|string|max:255',
            'email' => 'required|string|email|max:255|unique:users,email,' . $user->id,
        ]);

        // update user data
        $user->update($validatedData);

        // return response json
        return response()->json([
            'message' => 'Profile updated successfully',
            'user' => $user
        ]);
    }
}

Didalam class ProfileController, kita membuat 2 buah method baru diantaranya sebagai berikut :

  1. show
  2. update

Method Show

Method ini kita gunakan untuk mendapatkan informasi data user yang sedang login.

ProfileController.php
/**
 * Display the authenticated user's profile information.
 *
 */
public function show(Request $request)
{
    // return response json
    return response()->json([
        'user' => $request->user(),
    ]);
}

Disini kita hanya mengembalikan data user dalam bentuk format Json.

ProfileController.php
// return response json
return response()->json([
    'user' => $request->user(),
]);

Method Update

Method ini kita gunakan untuk melakukan update data user yang sedang login.

ProfileController.php
/**
 * Update the user's profile information.
 *
 */
public function update(Request $request)
{
    // get current user
    $user = $request->user();

    // validate request
    $validatedData = $request->validate([
        'name' => 'required|string|max:255',
        'email' => 'required|string|email|max:255|unique:users,email,' . $user->id,
    ]);

    // update user data
    $user->update($validatedData);

    // return response json
    return response()->json([
        'message' => 'Profile updated successfully',
        'user' => $user
    ]);
}

Pertama - tama kita tampung data user yang sedang login kedalam variabel $user.

ProfileController.php
// get current user
$user = $request->user();

Kemudian kita membuat validasi data terlebih dahulu, sebelum melakukan update data user menggunakan method validate.

ProfileController.php
// validate request
$validatedData = $request->validate([
    'name' => 'required|string|max:255',
    'email' => 'required|string|email|max:255|unique:users,email,' . $user->id,
]);

Selanjutnya jika request yang kita kirimkan sudah sesuai dengan kriteria validasi yang kita definisikan, maka kita akan melakukan proses update data menggunakan method update.

ProfileController.php
// update user data
$user->update($validatedData);

Terakhir, kita kembalikan datanya dalam bentuk format Json.

ProfileController.php
// return response json
return response()->json([
    'message' => 'Profile updated successfully',
    'user' => $user
]);

Membuat Route Profile

Setelah berhasil membuat sebuah controller Profile, sekarang kita akan lanjutkan untuk pembuatan route-nya, silahkan teman - teman buka file routes/api.php, kemudian ubah kode-nya menjadi seperti berikut ini.

api.php
<?php

use App\Http\Controllers\Api\LoginController;
use App\Http\Controllers\Api\ProfileController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\RegisterController;

Route::post('/register', RegisterController::class);
Route::post('/login', LoginController::class);

Route::controller(ProfileController::class)->middleware('auth:sanctum')->group(function(){
    Route::get('/profile', 'show');
    Route::put('/profile', 'update');
});

Pada kode diatas, kita menambahkan sebuah route baru dengan method get dan put yang kita arahkan ke url api/profile, untuk memastikan route yang kita buat telah berfungsi, teman - teman bisa jalankan perintah berikut ini pada terminal-nya.

Terminal
php artisan r:l

Setelah perintah artisan diatas dijalankan, maka kita akan mendapatkan output, kurang lebih seperti berikut ini.

Terminal
GET|HEAD  / ............................................................................................................................. 
POST      api/login ................................................................................................. Api\LoginController
GET|HEAD  api/profile ........................................................................................ Api\ProfileController@show
PUT       api/profile ...................................................................................... Api\ProfileController@update
POST      api/register ........................................................................................... Api\RegisterController
GET|HEAD  sanctum/csrf-cookie ......................................... sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
GET|HEAD  storage/{path} .................................................................................................. storage.local
GET|HEAD  up ............................................................................................................................ 

Membuat Test Profile

Setelah berhasil membuat route Profile, sekarang kita akan lanjutkan untuk pembuatan test-nya, disini kita akan menggunakan PHPUnit untuk membuat test-nya. Silahkan teman - teman buka terminal-nya, kemudian jalankan perintah berikut ini :

Terminal
php artisan make:test ProfileControllerTest

Jika perintah diatas berhasil dijalankan, maka kita akan mendapatkan sebuah file yang terletak di tests/Feature dengan nama ProfileControllerTest, selanjutnya silahkan buka file tersebut kemudian tambahkan kodenya menjadi seperti berikut ini.

ProfileControllerTest.php
<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;

class ProfileControllerTest extends TestCase
{
    use RefreshDatabase;

    public function test_unauthenticated_user_cannot_access_profile()
    {
        // send json get request to view profile
        $response = $this->getJson('/api/profile');

        // assert that the response is a 401
        $response->assertStatus(401);
    }

    public function test_user_can_view_their_profile()
    {
        // create a user with factory
        $user = User::factory()->create();

        // send json get request to view profile
        $response = $this->actingAs($user)
            ->getJson('/api/profile');

        // assert that the response is a 200 with a json structure containing the user's id, name, and email
        $response->assertStatus(200)
            ->assertJson([
                'user' => [
                    'id' => $user->id,
                    'name' => $user->name,
                    'email' => $user->email,
                ]
            ]);
    }

    public function test_user_can_update_their_profile()
    {
        // create a user with factory
        $user = User::factory()->create();

        // send json put request to update profile
        $response = $this->actingAs($user)
            ->putJson('/api/profile', [
                'name' => 'Raf',
                'email' => 'raf@example.com'
            ]);

        // assert that the response is a 200 with a json structure containing the updated user's id, name, and email
        $response->assertStatus(200)
            ->assertJson([
                'message' => 'Profile updated successfully',
                'user' => [
                    'id' => $user->id,
                    'name' => 'Raf',
                    'email' => 'raf@example.com',
                ]
            ]);

        // assert that the user was updated in the database
        $this->assertDatabaseHas('users', [
            'name' => 'Raf',
            'email' => 'raf@example.com',
        ]);
    }
}

Didalam class ProfileControllerTest, kita membuat 3 buah method baru diantaranya sebagai berikut :

  1. test_unauthenticated_user_cannot_access_profile
  2. test_user_can_view_their_profile
  3. test_user_can_update_their_profile

Dari kode diatas, pertama kita lakukan import model user.

ProfileControllerTest.php
use App\Models\User;

Selanjutnya kita import juga sebuah trait yang akan kita gunakan, disini kita menggunakan trait RefreshDatabase;.

ProfileControllerTest.php
use Illuminate\Foundation\Testing\RefreshDatabase;

untuk penggunaan trait tersebut kita menggunakan method use.

ProfileControllerTest.php
use RefreshDatabase;

Method test_unauthenticated_user_cannot_access_profile

Method ini kita gunakan untuk memastikan bahwa user yang belum login tidak dapat mengakses halaman profile.

ProfileControllerTest.php
public function test_unauthenticated_user_cannot_access_profile()
{
    // send json get request to view profile
    $response = $this->getJson('/api/profile');

    // assert that the response is a 401
    $response->assertStatus(401);
}

Pada kode di atas, kita menggunakan method getJson untuk melakukan request dengan method GET ke route /api/profile, tanpa menyertakan token atau kredensial apapun.

ProfileControllerTest.php
// send json get request to view profile
$response = $this->getJson('/api/profile');

Setelah request dikirim, kita menggunakan method assertStatus untuk memastikan bahwa respons dari request tersebut memiliki status kode 401. Status kode ini berarti Unauthorized, yang menunjukkan bahwa user tidak memiliki izin untuk mengakses halaman profil karena belum terautentikasi.

ProfileControllerTest.php
// assert that the response is a 401
$response->assertStatus(401);

Method test_user_can_view_their_profile

Method ini digunakan untuk memastikan bahwa user yang telah terautentikasi bisa melihat profil mereka sendiri.

ProfileControllerTest.php
public function test_user_can_view_their_profile()
{
    // create a user with factory
    $user = User::factory()->create();

    // send json get request to view profile
    $response = $this->actingAs($user)
        ->getJson('/api/profile');

    // assert that the response is a 200 with a json structure containing the user's id, name, and email
    $response->assertStatus(200)
        ->assertJson([
            'user' => [
                'id' => $user->id,
                'name' => $user->name,
                'email' => $user->email,
            ]
        ]);
}

Pada kode diatas, pertama - tama kita mendaftarkan user baru dengan sebuah factory yang telah disediakan oleh laravel.

ProfileControllerTest.php
// create a user with factory
$user = User::factory()->create();

Setelah user dibuat, kita menggunakan method actingAs untuk melakukan login menggunakan user yang baru saja kita buat. Kemudian, kita mengirimkan request GET ke route /api/profile menggunakan method getJson.

ProfileControllerTest.php
// send json get request to view profile
$response = $this->actingAs($user)
    ->getJson('/api/profile');

Setelah request dikirim, kita menggunakan method assertStatus untuk memastikan bahwa respons dari request tersebut memiliki status kode 200, yang berarti request tersebut berhasil dilakukan. Selain itu, kita juga menggunakan method assertJson untuk memverifikasi bahwa respons Json yang diterima dalam respons mengembalikan sebuah key id, name, dan email dari user yang sedang login.

ProfileControllerTest.php
// assert that the response is a 200 with a json structure containing the user's id, name, and email
$response->assertStatus(200)
    ->assertJson([
        'user' => [
            'id' => $user->id,
            'name' => $user->name,
            'email' => $user->email,
        ]
    ]);

Method test_user_can_update_their_profile

Method ini digunakan untuk memastikan bahwa user yang telah berhasil login bisa memperbarui profile mereka.

ProfileControllerTest.php
public function test_user_can_update_their_profile()
{
    // create a user with factory
    $user = User::factory()->create();

    // send json put request to update profile
    $response = $this->actingAs($user)
        ->putJson('/api/profile', [
            'name' => 'Raf',
            'email' => 'raf@example.com'
        ]);

    // assert that the response is a 200 with a json structure containing the updated user's id, name, and email
    $response->assertStatus(200)
        ->assertJson([
            'message' => 'Profile updated successfully',
            'user' => [
                'id' => $user->id,
                'name' => 'Raf',
                'email' => 'raf@example.com',
            ]
        ]);

    // assert that the user was updated in the database
    $this->assertDatabaseHas('users', [
        'name' => 'Raf',
        'email' => 'raf@example.com',
    ]);
}

Pada kode diatas, pertama - tama kita mendaftarkan user baru dengan sebuah factory yang telah disediakan oleh laravel.

ProfileControllerTest.php
// create a user with factory
$user = User::factory()->create();

Setelah user dibuat, kita menggunakan method actingAs untuk melakukan login menggunakan user yang baru saja kita buat. Kemudian, kita mengirimkan request put ke route /api/profile menggunakan method putJson dengan body name dan email.

ProfileControllerTest.php
// send json put request to update profile
$response = $this->actingAs($user)
    ->putJson('/api/profile', [
        'name' => 'Raf',
        'email' => 'raf@example.com'
    ]);

Setelah request dikirim, kita menggunakan method assertStatus untuk memastikan bahwa respons dari request tersebut memiliki status kode200, yang berarti request berhasil dilakukan. Selain itu, kita juga menggunakan method assertJson untuk memverifikasi bahwa respons Json menampilkan message serta data user yang telah diperbarui, termasuk id, name, dan email dengan nilai yang baru.

ProfileControllerTest.php
// assert that the response is a 200 with a json structure containing the updated user's id, name, and email
$response->assertStatus(200)
    ->assertJson([
        'message' => 'Profile updated successfully',
        'user' => [
            'id' => $user->id,
            'name' => 'Raf',
            'email' => 'raf@example.com',
        ]
    ]);

Terakhir, kita menggunakan method assertDatabaseHas untuk memastikan bahwa user dengan name raf dan email raf@example.com benar-benar telah tersimpan di tabel users .

ProfileControllerTest.php
// assert that the user was updated in the database
$this->assertDatabaseHas('users', [
    'name' => 'Raf',
    'email' => 'raf@example.com',
]);

Menjalankan Test

Setelah berhasil menuliskan Unit Test, disini kitakan akan menjalankan test yang telah kita tulis. Silahkan teman - teman buka terminal-nya, kemudian jalankan perintah berikut ini:

Terminal
php artisan test tests/Feature/ProfileControllerTest.php

Pada kode diatas, kita menjalankan sebuah test secara spesifik dengan memasukan nama file beserta foldernya.

Terminal
tests/Feature/ProfileControllerTest.php

jika perintah diatas, berhasil dijalankan kita akan menerima output kurang lebih berikut ini, yang menandakan semua test yang kita buat berhasil tanpa ada error.

Terminal
PASS  Tests\Feature\ProfileControllerTest
✓ unauthenticated user cannot access profile                                                                                        0.35s  
✓ user can view their profile                                                                                                       0.04s  
✓ user can update their profile                                                                                                     0.02s  

Tests:    3 passed (6 assertions)
Duration: 0.48s

Uji Coba Rest Api Profile

Setelah berhasil membuat test dan menjalankannya, disini kita akan lanjutkan melakukan uji coba rest api tersebut menggunakan Postman. Silahkan teman - teman buka aplikasi Postman, kemudian masukan url http://localhost:8000/api/profile dan method-nya silahkan di set menjadi GET.

profile-request

Kemudian silahkan teman - teman masuk tab Authorization dan pilih Bearer Token pada Auth Type, silahkan masukan token sesuai user yang sedang login saat ini. Selanjutnya, silahkan teman - teman klik tombol send, jika request berhasil dilakukan maka kita akan mendapatkan response seperti berikut ini.

Postman
{
    "user": {
        "id": 3,
        "name": "rafi",
        "email": "raf@dev.com",
        "email_verified_at": null,
        "created_at": "2024-10-20T13:11:44.000000Z",
        "updated_at": "2024-10-20T13:29:39.000000Z"
    }
}

profile-success

Selanjutnya kita akan coba melakukan update profile kita, silahkan teman - teman buat request baru dengan url yang sama yaitu http://localhost:8000/api/profile dan method-nya silahkan di set menjadi POST, tidak lupa kita set juga Authorization menggunakan Bearer Token dengan value token user yang sedang login saat ini.

profile-update-request

Kemudian pada tab headers masukan beberapa key dan value seperti contoh berikut ini.

Key Value
Accept application/json
Content-Type application/json

Selanjutnya silahkan teman - teman buka tab body dan masukan beberapa key dan value seperti berikut ini.

Key Value
name Rafi Taufiqurrahman
email raf.taufiqurrahman@gmail.com
_method put

Terakhir silahkan, teman - teman klik tombol send, jika request berhasil dilakukan maka kita akan mendapatkan response seperti berikut ini.

Postman
{
    "message": "Profile updated successfully",
    "user": {
        "id": 3,
        "name": "Rafi Taufiqurrahman",
        "email": "raf.taufiqurrahman@gmail.com",
        "email_verified_at": null,
        "created_at": "2024-10-20T13:11:44.000000Z",
        "updated_at": "2024-10-20T13:40:29.000000Z"
    }
}

profile-update-success

Penutup

Pada artikel kali ini kita telah berhasil menyelesaikan pembuatan module profile, dan ini merupakan artikel terakhir dari series Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing, saya ucapkan banyak terimakasih kepada teman - teman yang sudah mengikuti seri ini dari awal sampai akhir, jika ada pertanyaan bisa langsung ke telegram saya Rafi Taufiqurrahman, dan jika ada salah kata maupun ada kekurangan mohon dimaklumi, nantikan seri - seri selanjutnya dari saya, semoga bermanfaat terimakasih : )

Series Artikel

Berikut ini daftar series artikel dari Tutorial Authentication Dengan Laravel Sanctum dan Unit Testing

JurnalKoding

Mulai asah skill dengan berbagai macam teknologi - teknologi terbaru seperti Laravel, React, Vue, Inertia, Tailwind CSS, dan masih banyak lagi.

© 2024 JurnalKoding, Inc. All rights reserved.