create([ 'email' => 'manager@test.com', 'password' => bcrypt('password123'), 'role' => 'manager', 'active' => true, ]); $response = $this->postJson('/api/auth/login', [ 'email' => 'manager@test.com', 'password' => 'password123', ]); return $response->json('access_token'); } public function test_create_allocation_accepts_null_team_member_id(): void { $token = $this->loginAsManager(); $project = Project::factory()->create(); $response = $this->withHeader('Authorization', "Bearer {$token}") ->postJson('/api/allocations', [ 'project_id' => $project->id, 'team_member_id' => null, 'month' => '2026-02', 'allocated_hours' => 40, ]); $response->assertStatus(201); $this->assertDatabaseHas('allocations', [ 'project_id' => $project->id, 'team_member_id' => null, 'allocated_hours' => 40, ]); } public function test_bulk_create_accepts_mixed_tracked_and_untracked(): void { $token = $this->loginAsManager(); $project = Project::factory()->create(); $role = Role::factory()->create(); $teamMember = TeamMember::factory()->create(['role_id' => $role->id, 'active' => true]); $response = $this->withHeader('Authorization', "Bearer {$token}") ->postJson('/api/allocations/bulk', [ 'allocations' => [ [ 'project_id' => $project->id, 'team_member_id' => $teamMember->id, 'month' => '2026-02', 'allocated_hours' => 40, ], [ 'project_id' => $project->id, 'team_member_id' => null, 'month' => '2026-02', 'allocated_hours' => 30, ], ], ]); $response->assertStatus(201); $this->assertDatabaseCount('allocations', 2); } public function test_partial_bulk_persists_valid_rows(): void { $token = $this->loginAsManager(); $project = Project::factory()->create(); $role = Role::factory()->create(); $teamMember = TeamMember::factory()->create(['role_id' => $role->id, 'active' => true]); $response = $this->withHeader('Authorization', "Bearer {$token}") ->postJson('/api/allocations/bulk', [ 'allocations' => [ [ 'project_id' => $project->id, 'team_member_id' => $teamMember->id, 'month' => '2026-02', 'allocated_hours' => 40, ], [ 'project_id' => 'invalid-uuid', 'team_member_id' => $teamMember->id, 'month' => '2026-02', 'allocated_hours' => 20, ], ], ]); $response->assertStatus(201); $response->assertJsonPath('summary.created', 1); $response->assertJsonPath('summary.failed', 1); $this->assertDatabaseCount('allocations', 1); } }