Files
L-Ami-Fiduciaire/tests/Feature/Team/ManageTeamTest.php

215 lines
6.6 KiB
PHP
Raw Normal View History

<?php
use App\Enums\Permission;
use App\Enums\WorkspaceUserRole;
use App\Mail\TeamInvitationMail;
use App\Models\TeamInvitation;
use App\Models\User;
use App\Models\Workspace;
use Illuminate\Support\Facades\Mail;
use Inertia\Testing\AssertableInertia as Assert;
function setupTeamUser(string $role, array $permissions = []): array
{
$user = User::factory()->create();
$workspace = Workspace::factory()->create();
$workspace->users()->attach($user->id, [
'role' => $role,
'permissions' => $permissions,
]);
session(['current_workspace_id' => $workspace->id]);
return [$user, $workspace];
}
// ── Team Index ──────────────────────────────────────────────
test('owner can view team index page', function () {
[$user, $workspace] = setupTeamUser(WorkspaceUserRole::Owner);
$response = $this->actingAs($user)->get(route('team.index'));
$response->assertOk();
$response->assertInertia(fn (Assert $page) => $page
->component('team/Index')
->has('members')
->has('pendingInvitations')
->where('canManageTeam', true)
->has('inviteUrl')
->has('roles')
);
});
test('manager with can_manage_team can view team index page', function () {
[$user] = setupTeamUser(WorkspaceUserRole::Manager, [
Permission::CanManageTeam => true,
]);
$response = $this->actingAs($user)->get(route('team.index'));
$response->assertOk();
$response->assertInertia(fn (Assert $page) => $page
->component('team/Index')
->where('canManageTeam', true)
);
});
test('manager without can_manage_team can view team index but canManageTeam is false', function () {
[$user] = setupTeamUser(WorkspaceUserRole::Manager, [
Permission::CanManageTeam => false,
]);
$response = $this->actingAs($user)->get(route('team.index'));
$response->assertOk();
$response->assertInertia(fn (Assert $page) => $page
->component('team/Index')
->where('canManageTeam', false)
);
});
test('worker receives 404 on team index', function () {
[$user] = setupTeamUser(WorkspaceUserRole::Worker);
$response = $this->actingAs($user)->get(route('team.index'));
$response->assertNotFound();
});
// ── Invite Member ───────────────────────────────────────────
test('owner can invite a new member', function () {
Mail::fake();
[$user, $workspace] = setupTeamUser(WorkspaceUserRole::Owner);
$response = $this->actingAs($user)->post(route('team.invite'), [
'email' => 'newmember@example.com',
'role' => 'worker',
]);
$response->assertRedirect();
$response->assertSessionHas('success', 'Invitation envoyée');
expect(TeamInvitation::where('workspace_id', $workspace->id)
->where('email', 'newmember@example.com')
->exists()
)->toBeTrue();
Mail::assertQueued(TeamInvitationMail::class, function ($mail) {
return $mail->hasTo('newmember@example.com');
});
});
test('manager with can_manage_team can invite a new member', function () {
Mail::fake();
[$user, $workspace] = setupTeamUser(WorkspaceUserRole::Manager, [
Permission::CanManageTeam => true,
]);
$response = $this->actingAs($user)->post(route('team.invite'), [
'email' => 'newmanager@example.com',
'role' => 'manager',
]);
$response->assertRedirect();
$response->assertSessionHas('success', 'Invitation envoyée');
expect(TeamInvitation::where('workspace_id', $workspace->id)
->where('email', 'newmanager@example.com')
->where('role', 'manager')
->exists()
)->toBeTrue();
});
test('manager without permission gets 404 on invite', function () {
[$user] = setupTeamUser(WorkspaceUserRole::Manager, [
Permission::CanManageTeam => false,
]);
$response = $this->actingAs($user)->post(route('team.invite'), [
'email' => 'blocked@example.com',
'role' => 'worker',
]);
$response->assertNotFound();
});
test('worker gets 404 on invite', function () {
[$user] = setupTeamUser(WorkspaceUserRole::Worker);
$response = $this->actingAs($user)->post(route('team.invite'), [
'email' => 'blocked@example.com',
'role' => 'worker',
]);
$response->assertNotFound();
});
test('cannot invite email already in workspace', function () {
[$user, $workspace] = setupTeamUser(WorkspaceUserRole::Owner);
$existingMember = User::factory()->create(['email' => 'existing@example.com']);
$workspace->users()->attach($existingMember->id, ['role' => 'worker']);
$response = $this->actingAs($user)->post(route('team.invite'), [
'email' => 'existing@example.com',
'role' => 'worker',
]);
$response->assertSessionHasErrors('email');
});
test('invitation creates team invitation record with correct data', function () {
Mail::fake();
[$user, $workspace] = setupTeamUser(WorkspaceUserRole::Owner);
$this->actingAs($user)->post(route('team.invite'), [
'email' => 'record@example.com',
'role' => 'manager',
]);
$invitation = TeamInvitation::where('email', 'record@example.com')->first();
expect($invitation)->not->toBeNull()
->and($invitation->workspace_id)->toBe($workspace->id)
->and($invitation->role)->toBe('manager')
->and($invitation->invited_by)->toBe($user->id)
->and($invitation->token)->not->toBeEmpty()
->and($invitation->expires_at)->not->toBeNull()
->and($invitation->accepted_at)->toBeNull();
});
test('invitation sends email', function () {
Mail::fake();
[$user] = setupTeamUser(WorkspaceUserRole::Owner);
$this->actingAs($user)->post(route('team.invite'), [
'email' => 'mailto@example.com',
'role' => 'worker',
]);
Mail::assertQueued(TeamInvitationMail::class, function ($mail) {
return $mail->hasTo('mailto@example.com');
});
});
test('cannot send duplicate active invitation to same email', function () {
Mail::fake();
[$user, $workspace] = setupTeamUser(WorkspaceUserRole::Owner);
// Create an existing active invitation
TeamInvitation::create([
'workspace_id' => $workspace->id,
'email' => 'duplicate@example.com',
'role' => 'worker',
'invited_by' => $user->id,
'expires_at' => now()->addDays(7),
]);
$response = $this->actingAs($user)->post(route('team.invite'), [
'email' => 'duplicate@example.com',
'role' => 'manager',
]);
$response->assertSessionHasErrors('email');
});