create(); $workspace = Workspace::factory()->create(); $workspace->users()->attach($user->id, [ 'role' => $role, 'permissions' => $permissions, ]); session(['current_workspace_id' => $workspace->id]); return [$user, $workspace]; } // AC #2: Worker sees only assigned declarations in index test('worker sees only assigned declarations in index', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $assignedDeclaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, 'assigned_to' => $worker->id, ]); $unassignedDeclaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, 'assigned_to' => null, ]); $otherUser = User::factory()->create(); $otherAssignedDeclaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, 'assigned_to' => $otherUser->id, ]); $response = $this->actingAs($worker)->get(route('declarations.index')); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->component('declarations/Index') ->has('declarations.data', 1) ->where('declarations.data.0.id', $assignedDeclaration->id) ); }); // AC #3: Owner sees all declarations test('owner sees all declarations in index', function () { [$owner, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Owner); $client = Client::factory()->create(['workspace_id' => $workspace->id]); Declaration::factory()->count(5)->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); $response = $this->actingAs($owner)->get(route('declarations.index')); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->component('declarations/Index') ->has('declarations.data', 5) ); }); // AC #3: Manager sees all declarations test('manager sees all declarations in index', function () { [$manager, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Manager); $client = Client::factory()->create(['workspace_id' => $workspace->id]); Declaration::factory()->count(3)->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); $response = $this->actingAs($manager)->get(route('declarations.index')); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->component('declarations/Index') ->has('declarations.data', 3) ); }); // AC #4: Worker gets 404 accessing unassigned declaration via direct URL test('worker gets 404 accessing unassigned declaration via direct URL', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, 'assigned_to' => null, ]); $response = $this->actingAs($worker)->get(route('declarations.show', $declaration)); $response->assertNotFound(); }); // Worker can access assigned declaration show test('worker can access assigned declaration show', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, 'assigned_to' => $worker->id, ]); $response = $this->actingAs($worker)->get(route('declarations.show', $declaration)); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->component('declarations/Show') ); }); // AC #6: Worker gets 404 on create test('worker gets 404 on declaration create', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $response = $this->actingAs($worker)->get(route('declarations.create')); $response->assertNotFound(); }); // Worker gets 404 on store test('worker gets 404 on declaration store', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $response = $this->actingAs($worker)->post(route('declarations.store'), [ 'title' => 'Test', 'type' => 'vat_monthly', 'client_id' => $client->id, 'period_year' => 2026, 'period_month' => 1, ]); $response->assertNotFound(); }); // Worker gets 404 on edit test('worker gets 404 on declaration edit', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); $response = $this->actingAs($worker)->get(route('declarations.edit', $declaration)); $response->assertNotFound(); }); // Worker gets 404 on update test('worker gets 404 on declaration update', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); $response = $this->actingAs($worker)->put(route('declarations.update', $declaration), [ 'title' => 'Updated', 'type' => 'vat_monthly', 'client_id' => $client->id, 'period_year' => 2026, 'period_month' => 1, ]); $response->assertNotFound(); }); // Worker gets 404 on destroy test('worker gets 404 on declaration destroy', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); $response = $this->actingAs($worker)->delete(route('declarations.destroy', $declaration)); $response->assertNotFound(); }); // Manager can access all CRUD operations test('manager can access all declaration CRUD operations', function () { [$manager, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Manager); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); // Index $this->actingAs($manager)->get(route('declarations.index'))->assertOk(); // Show $this->actingAs($manager)->get(route('declarations.show', $declaration))->assertOk(); // Create page $this->actingAs($manager)->get(route('declarations.create'))->assertOk(); // Edit page $this->actingAs($manager)->get(route('declarations.edit', $declaration))->assertOk(); }); // Owner can access all CRUD operations test('owner can access all declaration CRUD operations', function () { [$owner, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Owner); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); // Index $this->actingAs($owner)->get(route('declarations.index'))->assertOk(); // Show $this->actingAs($owner)->get(route('declarations.show', $declaration))->assertOk(); // Create page $this->actingAs($owner)->get(route('declarations.create'))->assertOk(); // Edit page $this->actingAs($owner)->get(route('declarations.edit', $declaration))->assertOk(); }); // AC #10: canCreate/canEdit/canDelete props false for Workers test('worker gets canCreate canEdit canDelete as false in declarations index', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $response = $this->actingAs($worker)->get(route('declarations.index')); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->where('canCreate', false) ->where('canEdit', false) ->where('canDelete', false) ); }); // AC #10: canCreate/canEdit/canDelete props true for Owners test('owner gets canCreate canEdit canDelete as true in declarations index', function () { [$owner, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Owner); $response = $this->actingAs($owner)->get(route('declarations.index')); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->where('canCreate', true) ->where('canEdit', true) ->where('canDelete', true) ); }); // AC #9: auth.workspaceRole is shared correctly test('auth.workspaceRole is shared correctly for each role', function () { // Test Owner [$owner, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Owner); $response = $this->actingAs($owner)->get(route('declarations.index')); $response->assertInertia(fn (Assert $page) => $page ->where('auth.workspaceRole', 'owner') ); // Test Manager [$manager, $workspace2] = setupDeclarationTestUser(WorkspaceUserRole::Manager); $response = $this->actingAs($manager)->get(route('declarations.index')); $response->assertInertia(fn (Assert $page) => $page ->where('auth.workspaceRole', 'manager') ); // Test Worker [$worker, $workspace3] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $response = $this->actingAs($worker)->get(route('declarations.index')); $response->assertInertia(fn (Assert $page) => $page ->where('auth.workspaceRole', 'worker') ); }); // AC #11: Cross-workspace isolation test('worker in workspace A cannot see declarations in workspace B', function () { [$worker, $workspaceA] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $workspaceB = Workspace::factory()->create(); $clientB = Client::factory()->create(['workspace_id' => $workspaceB->id]); $declarationInB = Declaration::factory()->create([ 'workspace_id' => $workspaceB->id, 'client_id' => $clientB->id, 'assigned_to' => $worker->id, ]); // Worker should not see workspace B declarations in their index $response = $this->actingAs($worker)->get(route('declarations.index')); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->has('declarations.data', 0) ); // Worker should get 404 trying to access workspace B declaration directly $response = $this->actingAs($worker)->get(route('declarations.show', $declarationInB)); $response->assertNotFound(); }); // canMention is false for workers in declaration show test('worker gets canMention as false in declaration show', function () { [$worker, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Worker); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, 'assigned_to' => $worker->id, ]); $response = $this->actingAs($worker)->get(route('declarations.show', $declaration)); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->where('canMention', false) ->where('canEdit', false) ->where('canDelete', false) ); }); // canMention is true for owners/managers in declaration show test('owner gets canMention as true in declaration show', function () { [$owner, $workspace] = setupDeclarationTestUser(WorkspaceUserRole::Owner); $client = Client::factory()->create(['workspace_id' => $workspace->id]); $declaration = Declaration::factory()->create([ 'workspace_id' => $workspace->id, 'client_id' => $client->id, ]); $response = $this->actingAs($owner)->get(route('declarations.show', $declaration)); $response->assertOk(); $response->assertInertia(fn (Assert $page) => $page ->where('canMention', true) ->where('canEdit', true) ->where('canDelete', true) ); });