fix(resources): preserve records sharing IDs across model types (#11300)
This commit is contained in:
parent
bb9f5e5768
commit
1440d35750
6 changed files with 109 additions and 9 deletions
|
|
@ -70,7 +70,7 @@ public function getResourcesPreview(): array
|
|||
|
||||
return [
|
||||
'applications' => $applications->unique('id'),
|
||||
'databases' => $databases->unique('id'),
|
||||
'databases' => $databases->unique(fn ($database) => $database::class.':'.$database->id),
|
||||
'services' => $services->unique('id'),
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -166,13 +166,13 @@ public function isEmpty()
|
|||
public function databases(array $with = []): Collection
|
||||
{
|
||||
return $this->postgresqls()->with($with)->get()
|
||||
->merge($this->redis()->with($with)->get())
|
||||
->merge($this->mongodbs()->with($with)->get())
|
||||
->merge($this->mysqls()->with($with)->get())
|
||||
->merge($this->mariadbs()->with($with)->get())
|
||||
->merge($this->keydbs()->with($with)->get())
|
||||
->merge($this->dragonflies()->with($with)->get())
|
||||
->merge($this->clickhouses()->with($with)->get());
|
||||
->concat($this->redis()->with($with)->get())
|
||||
->concat($this->mongodbs()->with($with)->get())
|
||||
->concat($this->mysqls()->with($with)->get())
|
||||
->concat($this->mariadbs()->with($with)->get())
|
||||
->concat($this->keydbs()->with($with)->get())
|
||||
->concat($this->dragonflies()->with($with)->get())
|
||||
->concat($this->clickhouses()->with($with)->get());
|
||||
}
|
||||
|
||||
public function navigateTo()
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@ protected static function booted()
|
|||
|
||||
// Delete non-instance-wide sources owned by this team
|
||||
$teamSources = GithubApp::where('team_id', $team->id)->get()
|
||||
->merge(GitlabApp::where('team_id', $team->id)->get());
|
||||
->concat(GitlabApp::where('team_id', $team->id)->get());
|
||||
foreach ($teamSources as $source) {
|
||||
$source->delete();
|
||||
}
|
||||
|
|
|
|||
40
tests/Feature/ProjectDatabasesTest.php
Normal file
40
tests/Feature/ProjectDatabasesTest.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
use App\Models\Project;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\StandaloneMariadb;
|
||||
use App\Models\StandaloneRedis;
|
||||
use App\Models\Team;
|
||||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||||
|
||||
uses(RefreshDatabase::class);
|
||||
|
||||
test('databases includes different database types with the same primary key', function () {
|
||||
$team = Team::factory()->create();
|
||||
$server = Server::factory()->create(['team_id' => $team->id]);
|
||||
$destination = StandaloneDocker::where('server_id', $server->id)->firstOrFail();
|
||||
$project = Project::factory()->create(['team_id' => $team->id]);
|
||||
$environment = $project->environments()->firstOrFail();
|
||||
|
||||
StandaloneRedis::forceCreate([
|
||||
'id' => 42,
|
||||
'name' => 'redis',
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
StandaloneMariadb::forceCreate([
|
||||
'id' => 42,
|
||||
'name' => 'mariadb',
|
||||
'mariadb_root_password' => 'password',
|
||||
'mariadb_password' => 'password',
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination->getMorphClass(),
|
||||
]);
|
||||
|
||||
expect($project->redis()->count())->toBe(1)
|
||||
->and($project->mariadbs()->count())->toBe(1)
|
||||
->and($project->databases())->toHaveCount(2);
|
||||
});
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
<?php
|
||||
|
||||
use App\Livewire\Team\DangerZone;
|
||||
use App\Models\GithubApp;
|
||||
use App\Models\GitlabApp;
|
||||
use App\Models\InstanceSettings;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
|
|
@ -52,3 +54,27 @@
|
|||
|
||||
expect(session('currentTeam'))->toBeNull();
|
||||
});
|
||||
|
||||
test('deleting a team deletes github and gitlab sources with the same primary key', function () {
|
||||
$githubApp = GithubApp::forceCreate([
|
||||
'id' => 42,
|
||||
'name' => 'GitHub source',
|
||||
'team_id' => $this->teamToDelete->id,
|
||||
'api_url' => 'https://api.github.com',
|
||||
'html_url' => 'https://github.com',
|
||||
'is_public' => false,
|
||||
]);
|
||||
$gitlabApp = GitlabApp::forceCreate([
|
||||
'id' => 42,
|
||||
'name' => 'GitLab source',
|
||||
'team_id' => $this->teamToDelete->id,
|
||||
'api_url' => 'https://gitlab.com/api/v4',
|
||||
'html_url' => 'https://gitlab.com',
|
||||
'is_public' => false,
|
||||
]);
|
||||
|
||||
$this->teamToDelete->delete();
|
||||
|
||||
expect(GithubApp::find($githubApp->id))->toBeNull()
|
||||
->and(GitlabApp::find($gitlabApp->id))->toBeNull();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
use App\Actions\User\DeleteUserResources;
|
||||
use App\Models\Server;
|
||||
use App\Models\StandaloneMariadb;
|
||||
use App\Models\StandaloneRedis;
|
||||
use App\Models\Team;
|
||||
use App\Models\User;
|
||||
|
||||
|
|
@ -16,6 +18,38 @@
|
|||
Mockery::close();
|
||||
});
|
||||
|
||||
it('keeps different database types with the same primary key in the preview', function () {
|
||||
$teamPivot = (object) ['role' => 'owner'];
|
||||
$team = Mockery::mock(Team::class);
|
||||
$team->shouldReceive('getAttribute')->with('pivot')->andReturn($teamPivot);
|
||||
$team->shouldReceive('getAttribute')->with('members')->andReturn(collect([$this->user]));
|
||||
$team->shouldReceive('setAttribute')->andReturnSelf();
|
||||
$team->pivot = $teamPivot;
|
||||
$team->members = collect([$this->user]);
|
||||
|
||||
$redis = new StandaloneRedis;
|
||||
$redis->id = 42;
|
||||
$mariadb = new StandaloneMariadb;
|
||||
$mariadb->id = 42;
|
||||
|
||||
$server = Mockery::mock(Server::class);
|
||||
$server->shouldReceive('applications')->andReturn(collect());
|
||||
$server->shouldReceive('databases')->andReturn(collect([$redis, $mariadb]));
|
||||
$server->shouldReceive('services->get')->andReturn(collect());
|
||||
|
||||
$teamsRelation = Mockery::mock();
|
||||
$teamsRelation->shouldReceive('get')->andReturn(collect([$team]));
|
||||
$this->user->shouldReceive('teams')->andReturn($teamsRelation);
|
||||
|
||||
$serversRelation = Mockery::mock();
|
||||
$serversRelation->shouldReceive('get')->andReturn(collect([$server]));
|
||||
$team->shouldReceive('servers')->andReturn($serversRelation);
|
||||
|
||||
$preview = (new DeleteUserResources($this->user, true))->getResourcesPreview();
|
||||
|
||||
expect($preview['databases'])->toHaveCount(2);
|
||||
});
|
||||
|
||||
it('only collects resources from teams where user is the sole member', function () {
|
||||
// Mock owned team where user is the ONLY member (will be deleted)
|
||||
$ownedTeamPivot = (object) ['role' => 'owner'];
|
||||
|
|
|
|||
Loading…
Reference in a new issue