Complete TP7 TP8 authentication authorization and classic CSS
This commit is contained in:
@@ -4,6 +4,7 @@ namespace Tests\Feature;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Product;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -13,6 +14,8 @@ class CrudTest extends TestCase
|
||||
|
||||
public function test_client_crud_is_available(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->admin()->create());
|
||||
|
||||
$this->get(route('clients.index'))->assertOk();
|
||||
$this->get(route('clients.create'))->assertOk();
|
||||
|
||||
@@ -39,6 +42,8 @@ class CrudTest extends TestCase
|
||||
|
||||
public function test_product_crud_is_available(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->admin()->create());
|
||||
|
||||
$this->get(route('products.index'))->assertOk();
|
||||
$this->get(route('products.create'))->assertOk();
|
||||
|
||||
|
||||
@@ -2,18 +2,12 @@
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
// use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class ExampleTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* A basic test example.
|
||||
*/
|
||||
public function test_the_application_returns_a_successful_response(): void
|
||||
public function test_the_login_page_is_public(): void
|
||||
{
|
||||
$response = $this->get('/');
|
||||
|
||||
$response->assertStatus(200);
|
||||
$this->get(route('login'))->assertOk();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Tests\Feature;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Product;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -13,6 +14,8 @@ class Tp6SearchPaginationTest extends TestCase
|
||||
|
||||
public function test_client_search_checks_name_email_and_city(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
Client::create(['name' => 'Jean Dupont', 'email' => 'jean@example.test', 'city' => 'Paris']);
|
||||
Client::create(['name' => 'Marie Martin', 'email' => 'marie@gmail.test', 'city' => 'Lyon']);
|
||||
Client::create(['name' => 'Paul Durand', 'email' => 'paul@example.test', 'city' => 'Bordeaux']);
|
||||
@@ -29,6 +32,8 @@ class Tp6SearchPaginationTest extends TestCase
|
||||
|
||||
public function test_client_pagination_keeps_the_search_on_page_two(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
for ($number = 1; $number <= 12; $number++) {
|
||||
Client::create([
|
||||
'name' => sprintf('Jean %02d', $number),
|
||||
@@ -51,6 +56,8 @@ class Tp6SearchPaginationTest extends TestCase
|
||||
|
||||
public function test_product_search_by_name_or_price_is_paginated(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
for ($number = 1; $number <= 12; $number++) {
|
||||
Product::create(['name' => sprintf('Clavier %02d', $number), 'price' => 50, 'stock' => 10]);
|
||||
}
|
||||
@@ -70,6 +77,8 @@ class Tp6SearchPaginationTest extends TestCase
|
||||
|
||||
public function test_form_requests_keep_tp5_validation_and_messages(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
$this->post(route('clients.store'), ['name' => '', 'email' => 'bonjour'])
|
||||
->assertSessionHasErrors(['name', 'email']);
|
||||
$this->post(route('products.store'), ['name' => 'Clavier', 'price' => -2, 'stock' => 1])
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
class Tp7AuthenticationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_guest_is_redirected_from_the_mini_crm_to_login(): void
|
||||
{
|
||||
$this->get(route('clients.index'))->assertRedirect(route('login'));
|
||||
$this->get(route('products.index'))->assertRedirect(route('login'));
|
||||
$this->get(route('dashboard'))->assertRedirect(route('login'));
|
||||
}
|
||||
|
||||
public function test_user_can_log_in_with_valid_credentials(): void
|
||||
{
|
||||
$user = User::factory()->create([
|
||||
'email' => 'jean@example.com',
|
||||
'password' => 'password123',
|
||||
]);
|
||||
|
||||
$this->post(route('login.store'), [
|
||||
'email' => 'jean@example.com',
|
||||
'password' => 'password123',
|
||||
])->assertRedirect(route('dashboard'));
|
||||
|
||||
$this->assertAuthenticatedAs($user);
|
||||
}
|
||||
|
||||
public function test_invalid_credentials_are_rejected_and_email_is_kept(): void
|
||||
{
|
||||
User::factory()->create([
|
||||
'email' => 'jean@example.com',
|
||||
'password' => 'password123',
|
||||
]);
|
||||
|
||||
$this->from(route('login'))->post(route('login.store'), [
|
||||
'email' => 'jean@example.com',
|
||||
'password' => 'incorrect',
|
||||
])->assertRedirect(route('login'))
|
||||
->assertSessionHasErrors(['email' => 'Les identifiants sont incorrects.'])
|
||||
->assertSessionHasInput('email', 'jean@example.com');
|
||||
|
||||
$this->assertGuest();
|
||||
}
|
||||
|
||||
public function test_authenticated_user_can_log_out(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
|
||||
$this->actingAs($user)
|
||||
->post(route('logout'))
|
||||
->assertRedirect(route('login'));
|
||||
|
||||
$this->assertGuest();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Product;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Illuminate\Support\Facades\Gate;
|
||||
use Tests\TestCase;
|
||||
|
||||
class Tp8AuthorizationTest extends TestCase
|
||||
{
|
||||
use RefreshDatabase;
|
||||
|
||||
public function test_client_policy_permission_matrix_matches_the_tp(): void
|
||||
{
|
||||
$admin = User::factory()->admin()->create();
|
||||
$user = User::factory()->create();
|
||||
$client = Client::create(['name' => 'Jean Client', 'email' => 'client@example.com']);
|
||||
|
||||
$this->assertTrue(Gate::forUser($admin)->allows('view', $client));
|
||||
$this->assertTrue(Gate::forUser($admin)->allows('create', Client::class));
|
||||
$this->assertTrue(Gate::forUser($admin)->allows('update', $client));
|
||||
$this->assertTrue(Gate::forUser($admin)->allows('delete', $client));
|
||||
$this->assertTrue(Gate::forUser($user)->allows('view', $client));
|
||||
$this->assertTrue(Gate::forUser($user)->allows('create', Client::class));
|
||||
$this->assertTrue(Gate::forUser($user)->allows('update', $client));
|
||||
$this->assertFalse(Gate::forUser($user)->allows('delete', $client));
|
||||
}
|
||||
|
||||
public function test_standard_user_cannot_delete_client_or_product(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$client = Client::create(['name' => 'Client protégé', 'email' => 'client@example.com']);
|
||||
$product = Product::create(['name' => 'Produit protégé', 'price' => 25, 'stock' => 5]);
|
||||
|
||||
$this->actingAs($user)->delete(route('clients.destroy', $client))->assertForbidden();
|
||||
$this->actingAs($user)->delete(route('products.destroy', $product))->assertForbidden();
|
||||
|
||||
$this->assertModelExists($client);
|
||||
$this->assertModelExists($product);
|
||||
}
|
||||
|
||||
public function test_administrator_can_delete_client_and_product(): void
|
||||
{
|
||||
$admin = User::factory()->admin()->create();
|
||||
$client = Client::create(['name' => 'Client à supprimer', 'email' => 'delete@example.com']);
|
||||
$product = Product::create(['name' => 'Produit à supprimer', 'price' => 25, 'stock' => 5]);
|
||||
|
||||
$this->actingAs($admin)
|
||||
->delete(route('clients.destroy', $client))
|
||||
->assertRedirect(route('clients.index'));
|
||||
$this->actingAs($admin)
|
||||
->delete(route('products.destroy', $product))
|
||||
->assertRedirect(route('products.index'));
|
||||
|
||||
$this->assertModelMissing($client);
|
||||
$this->assertModelMissing($product);
|
||||
}
|
||||
|
||||
public function test_delete_buttons_are_hidden_from_standard_user(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
Client::create(['name' => 'Client visible', 'email' => 'visible@example.com']);
|
||||
Product::create(['name' => 'Produit visible', 'price' => 25, 'stock' => 5]);
|
||||
|
||||
$this->actingAs($user)->get(route('clients.index'))
|
||||
->assertSee('Client visible')
|
||||
->assertDontSee('Supprimer');
|
||||
$this->actingAs($user)->get(route('products.index'))
|
||||
->assertSee('Produit visible')
|
||||
->assertDontSee('Supprimer');
|
||||
}
|
||||
|
||||
public function test_admin_page_is_restricted_to_administrators(): void
|
||||
{
|
||||
$user = User::factory()->create();
|
||||
$admin = User::factory()->admin()->create();
|
||||
|
||||
$this->actingAs($user)->get(route('admin'))->assertForbidden();
|
||||
$this->actingAs($admin)->get(route('admin'))->assertSee('Administration');
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ namespace Tests\Feature;
|
||||
|
||||
use App\Models\Client;
|
||||
use App\Models\Product;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
use Tests\TestCase;
|
||||
|
||||
@@ -13,6 +14,8 @@ class ValidationTp5Test extends TestCase
|
||||
|
||||
public function test_client_creation_rejects_invalid_values_and_keeps_old_input(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
$this->from(route('clients.create'))->post(route('clients.store'), [
|
||||
'name' => '',
|
||||
'email' => 'bonjour',
|
||||
@@ -35,6 +38,8 @@ class ValidationTp5Test extends TestCase
|
||||
|
||||
public function test_client_limits_optional_fields_and_update_validation(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
$valid = ['name' => 'Jean Dupont', 'email' => 'jean@example.test'];
|
||||
$this->post(route('clients.store'), $valid)->assertRedirect(route('clients.index'));
|
||||
$client = Client::firstOrFail();
|
||||
@@ -76,6 +81,8 @@ class ValidationTp5Test extends TestCase
|
||||
|
||||
public function test_product_creation_and_update_reject_invalid_values(): void
|
||||
{
|
||||
$this->actingAs(User::factory()->create());
|
||||
|
||||
foreach ([
|
||||
['name' => '', 'price' => 15, 'stock' => 10, 'field' => 'name'],
|
||||
['name' => 'Clavier', 'price' => -10, 'stock' => 10, 'field' => 'price'],
|
||||
|
||||
Reference in New Issue
Block a user