0, 'disable_two_step_confirmation' => true, ]); $this->resourceTeam = Team::factory()->create(); $this->otherTeam = Team::factory()->create(); $this->user = User::factory()->create(); $this->resourceTeam->members()->attach($this->user, ['role' => 'admin']); $this->otherTeam->members()->attach($this->user, ['role' => 'owner']); $this->actingAs($this->user); session(['currentTeam' => $this->resourceTeam]); $this->server = Server::factory()->create(['team_id' => $this->resourceTeam->id]); $destination = StandaloneDocker::firstOrCreate( ['server_id' => $this->server->id, 'network' => 'coolify'], ['uuid' => (string) Str::uuid(), 'name' => 'docker'] ); $project = Project::factory()->create(['team_id' => $this->resourceTeam->id]); $environment = Environment::factory()->create(['project_id' => $project->id]); $this->database = StandalonePostgresql::create([ 'uuid' => (string) Str::uuid(), 'name' => 'db', 'postgres_user' => 'postgres', 'postgres_password' => 'password', 'postgres_db' => 'db', 'image' => 'postgres:17', 'status' => 'running', 'environment_id' => $environment->id, 'destination_id' => $destination->id, 'destination_type' => $destination->getMorphClass(), ]); $s3Attributes = ['region' => 'us-east-1', 'key' => 'key', 'secret' => 'secret', 'bucket' => 'backups', 'endpoint' => 'https://s3.example.com', 'is_usable' => true]; $this->resourceTeamStorage = S3Storage::create([...$s3Attributes, 'team_id' => $this->resourceTeam->id, 'name' => 'resource-team-s3']); $this->otherTeamStorage = S3Storage::create([...$s3Attributes, 'team_id' => $this->otherTeam->id, 'name' => 'other-team-s3']); }); class ImportFormResourceTeamTestComponent extends ImportForm { public function mount($database = null, $server = null): void { $this->resourceId = $database->id; $this->resourceType = $database::class; $this->serverId = $server->id; $this->container = $database->uuid; $this->resourceUuid = $database->uuid; $this->resourceStatus = $database->status ?? ''; $this->resourceDbType = $database->type(); $this->loadAvailableS3Storages(); } protected function serverFileExists(string $path): bool { return true; } public function render() { return view('livewire.project.database.import-form'); } } function importFormAfterTeamSwitch(): Testable { $component = Livewire::test(ImportFormResourceTeamTestComponent::class, [ 'database' => test()->database, 'server' => test()->server, ]); session(['currentTeam' => test()->otherTeam]); return $component; } function fakeStartedDatabaseImport(): Activity { return Activity::create([ 'log_name' => 'default', 'description' => 'queued', 'properties' => ['status' => 'queued'], ]); } test('a file import started after a session team switch runs for the database team', function () { StartDatabaseImport::shouldRun()->once() ->withArgs(fn ($resource, $source, int $teamId): bool => $teamId === $this->resourceTeam->id) ->andReturn(fakeStartedDatabaseImport()); importFormAfterTeamSwitch() ->set('customLocation', '/backups/backup.dump') ->call('checkFile') ->call('runImport') ->assertNotDispatched('error') ->assertDispatched('databaserestore'); }); test('an S3 restore started after a session team switch runs for the database team', function () { StartDatabaseImport::shouldRun()->once() ->withArgs(fn ($resource, $source, int $teamId): bool => $teamId === $this->resourceTeam->id && $source->s3StorageUuid === (string) $this->resourceTeamStorage->id) ->andReturn(fakeStartedDatabaseImport()); importFormAfterTeamSwitch() ->set('s3StorageId', $this->resourceTeamStorage->id) ->set('s3Path', '/backups/backup.dump') ->set('s3FileSize', 1024) ->call('restoreFromS3') ->assertNotDispatched('error') ->assertDispatched('databaserestore'); }); test('the S3 storage list contains only storages of the database team', function () { importFormAfterTeamSwitch() ->call('loadAvailableS3Storages') ->assertSet('availableS3Storages', fn (array $storages): bool => collect($storages)->pluck('id')->all() === [$this->resourceTeamStorage->id]); }); test('an S3 storage of another team cannot be checked for the database', function () { importFormAfterTeamSwitch() ->set('s3StorageId', $this->otherTeamStorage->id) ->set('s3Path', '/backups/backup.dump') ->call('checkS3File') ->assertNotFound(); }); test('a member of the database team cannot start an import after switching to a team they own', function () { $this->resourceTeam->members()->updateExistingPivot($this->user->id, ['role' => 'member']); $this->user->refresh(); StartDatabaseImport::shouldRun()->never(); importFormAfterTeamSwitch() ->set('filename', 'backup.dump') ->call('runImport') ->assertForbidden(); });