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 [
|
return [
|
||||||
'applications' => $applications->unique('id'),
|
'applications' => $applications->unique('id'),
|
||||||
'databases' => $databases->unique('id'),
|
'databases' => $databases->unique(fn ($database) => $database::class.':'.$database->id),
|
||||||
'services' => $services->unique('id'),
|
'services' => $services->unique('id'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,13 +166,13 @@ public function isEmpty()
|
||||||
public function databases(array $with = []): Collection
|
public function databases(array $with = []): Collection
|
||||||
{
|
{
|
||||||
return $this->postgresqls()->with($with)->get()
|
return $this->postgresqls()->with($with)->get()
|
||||||
->merge($this->redis()->with($with)->get())
|
->concat($this->redis()->with($with)->get())
|
||||||
->merge($this->mongodbs()->with($with)->get())
|
->concat($this->mongodbs()->with($with)->get())
|
||||||
->merge($this->mysqls()->with($with)->get())
|
->concat($this->mysqls()->with($with)->get())
|
||||||
->merge($this->mariadbs()->with($with)->get())
|
->concat($this->mariadbs()->with($with)->get())
|
||||||
->merge($this->keydbs()->with($with)->get())
|
->concat($this->keydbs()->with($with)->get())
|
||||||
->merge($this->dragonflies()->with($with)->get())
|
->concat($this->dragonflies()->with($with)->get())
|
||||||
->merge($this->clickhouses()->with($with)->get());
|
->concat($this->clickhouses()->with($with)->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function navigateTo()
|
public function navigateTo()
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ protected static function booted()
|
||||||
|
|
||||||
// Delete non-instance-wide sources owned by this team
|
// Delete non-instance-wide sources owned by this team
|
||||||
$teamSources = GithubApp::where('team_id', $team->id)->get()
|
$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) {
|
foreach ($teamSources as $source) {
|
||||||
$source->delete();
|
$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
|
<?php
|
||||||
|
|
||||||
use App\Livewire\Team\DangerZone;
|
use App\Livewire\Team\DangerZone;
|
||||||
|
use App\Models\GithubApp;
|
||||||
|
use App\Models\GitlabApp;
|
||||||
use App\Models\InstanceSettings;
|
use App\Models\InstanceSettings;
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
@ -52,3 +54,27 @@
|
||||||
|
|
||||||
expect(session('currentTeam'))->toBeNull();
|
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\Actions\User\DeleteUserResources;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use App\Models\StandaloneMariadb;
|
||||||
|
use App\Models\StandaloneRedis;
|
||||||
use App\Models\Team;
|
use App\Models\Team;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
|
|
||||||
|
|
@ -16,6 +18,38 @@
|
||||||
Mockery::close();
|
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 () {
|
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)
|
// Mock owned team where user is the ONLY member (will be deleted)
|
||||||
$ownedTeamPivot = (object) ['role' => 'owner'];
|
$ownedTeamPivot = (object) ['role' => 'owner'];
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue