create([ 'workspace_id' => $tenantA->workspace_id, ]); createUserWithTenant(tenant: $tenantB, user: $user, role: 'manager'); BackupSchedule::query()->create([ 'tenant_id' => $tenantA->id, 'name' => 'Tenant A schedule', 'is_enabled' => true, 'timezone' => 'UTC', 'frequency' => 'daily', 'time_of_day' => '01:00:00', 'days_of_week' => null, 'policy_types' => [ 'deviceConfiguration', 'groupPolicyConfiguration', 'settingsCatalogPolicy', ], 'include_foundations' => true, 'retention_keep_last' => 30, ]); BackupSchedule::query()->create([ 'tenant_id' => $tenantB->id, 'name' => 'Tenant B schedule', 'is_enabled' => true, 'timezone' => 'UTC', 'frequency' => 'daily', 'time_of_day' => '02:00:00', 'days_of_week' => null, 'policy_types' => ['deviceCompliancePolicy'], 'include_foundations' => true, 'retention_keep_last' => 30, ]); $this->actingAs($user); // createUserWithTenant() may be called multiple times in this test; ensure the current // workspace matches the tenant we are about to access. session()->put(\App\Support\Workspaces\WorkspaceContext::SESSION_KEY, (int) $tenantA->workspace_id); $this->get(route('filament.admin.resources.backup-schedules.index', filamentTenantRouteParams($tenantA))) ->assertOk() ->assertSee('Tenant A schedule') ->assertSee('Device Configuration') ->assertSee('more') ->assertDontSee('Tenant B schedule'); }); test('backup schedules listing shows next run in schedule timezone', function () { [$user, $tenant] = createUserWithTenant(role: 'manager'); BackupSchedule::query()->create([ 'tenant_id' => $tenant->id, 'name' => 'Berlin schedule', 'is_enabled' => true, 'timezone' => 'Europe/Berlin', 'frequency' => 'daily', 'time_of_day' => '10:17:00', 'days_of_week' => null, 'policy_types' => ['deviceConfiguration'], 'include_foundations' => true, 'retention_keep_last' => 30, 'next_run_at' => CarbonImmutable::create(2026, 1, 5, 9, 17, 0, 'UTC'), ]); $this->actingAs($user); $this->get(route('filament.admin.resources.backup-schedules.index', filamentTenantRouteParams($tenant))) ->assertOk() ->assertSee('Jan 5, 2026 10:17:00'); }); test('backup schedules pages return 404 for unauthorized tenant', function () { [$user] = createUserWithTenant(role: 'manager'); $unauthorizedTenant = Tenant::factory()->create(); $this->actingAs($user) ->get(route('filament.admin.resources.backup-schedules.index', filamentTenantRouteParams($unauthorizedTenant))) ->assertNotFound(); }); test('manager can create and edit backup schedules via filament', function () { [$user, $tenant] = createUserWithTenant(role: 'manager'); $this->actingAs($user); Filament::setTenant($tenant, true); Livewire::test(CreateBackupSchedule::class) ->fillForm([ 'name' => 'Daily at 10', 'is_enabled' => true, 'timezone' => 'UTC', 'frequency' => 'daily', 'time_of_day' => '10:00', 'policy_types' => ['deviceConfiguration'], 'include_foundations' => true, 'retention_keep_last' => 30, ]) ->call('create') ->assertHasNoFormErrors(); $schedule = BackupSchedule::query()->where('tenant_id', $tenant->id)->first(); expect($schedule)->not->toBeNull(); expect($schedule->next_run_at)->not->toBeNull(); Livewire::test(EditBackupSchedule::class, ['record' => $schedule->getRouteKey()]) ->fillForm([ 'name' => 'Daily at 11', ]) ->call('save') ->assertHasNoFormErrors(); $schedule->refresh(); expect($schedule->name)->toBe('Daily at 11'); });