mirror of
https://github.com/coollabsio/coolify.git
synced 2026-11-06 13:10:37 -04:00
test: cover OAuth redirect URI, multi-domain previews, server clones
- Add SettingsOauth tests that reject redirect URIs off the provider callback route and accept the callback route with or without a trailing slash - Add a compose preview test checking that every domain of a multi-domain service gets a PR-prefixed domain and its own Traefik Host rule - Add a clone test checking that cloning a service to another server keeps its generated database credentials and copies its volumes - Refresh template_last_updated_at timestamps in the service templates
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -194,3 +194,54 @@ test('cloning a cloned service replaces the clone suffix instead of adding anoth
|
||||
|
||||
expect($source->name)->toBe("Gitea Runner-clone-{$source->uuid}");
|
||||
});
|
||||
|
||||
test('cloning a service to another server keeps its generated database credentials and copies its volumes there', function () {
|
||||
$this->service->update(['docker_compose_raw' => <<<'YAML'
|
||||
services:
|
||||
freshrss:
|
||||
image: freshrss/freshrss:latest
|
||||
environment:
|
||||
- SERVICE_URL_FRESHRSS_80
|
||||
- MARIADB_USER=${SERVICE_USER_MARIADB}
|
||||
- MARIADB_PASSWORD=${SERVICE_PASSWORD_MARIADB}
|
||||
volumes:
|
||||
- freshrss-data:/var/www/FreshRSS/data
|
||||
freshrss-db:
|
||||
image: mariadb:11
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=$SERVICE_PASSWORD_ROOT
|
||||
- MYSQL_USER=${SERVICE_USER_MARIADB}
|
||||
- MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB}
|
||||
volumes:
|
||||
- mariadb-data:/var/lib/mysql
|
||||
YAML]);
|
||||
$this->service->parse();
|
||||
$sourceCredentials = $this->service->environment_variables()
|
||||
->whereIn('key', ['SERVICE_USER_MARIADB', 'SERVICE_PASSWORD_MARIADB', 'SERVICE_PASSWORD_ROOT'])
|
||||
->pluck('value', 'key')
|
||||
->all();
|
||||
expect($sourceCredentials)->toHaveCount(3);
|
||||
|
||||
$nodeB = Server::factory()->create(['team_id' => $this->team->id, 'private_key_id' => $this->service->server->private_key_id]);
|
||||
$nodeB->settings()->update(['is_reachable' => true, 'is_usable' => true]);
|
||||
$nodeBDestination = StandaloneDocker::where('server_id', $nodeB->id)->firstOrFail();
|
||||
|
||||
Livewire::test(ResourceOperations::class, ['resource' => $this->service])
|
||||
->set('cloneVolumeData', true)
|
||||
->call('cloneTo', $nodeBDestination->uuid)
|
||||
->assertHasNoErrors();
|
||||
|
||||
$clone = Service::query()->whereKeyNot($this->service->id)->sole();
|
||||
$cloneCredentials = $clone->environment_variables()
|
||||
->whereIn('key', array_keys($sourceCredentials))
|
||||
->pluck('value', 'key')
|
||||
->all();
|
||||
|
||||
expect($clone->server_id)->toBe($nodeB->id)
|
||||
->and($cloneCredentials)->toEqual($sourceCredentials)
|
||||
->and($clone->environment_variables()->where('key', 'SERVICE_PASSWORD_MARIADB')->count())->toBe(1)
|
||||
->and(chainedServiceVolumeClones())->toEqualCanonicalizing([
|
||||
["{$this->service->uuid}_freshrss-data", "{$clone->uuid}_freshrss-data"],
|
||||
["{$this->service->uuid}_mariadb-data", "{$clone->uuid}_mariadb-data"],
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -1205,3 +1205,33 @@ it('replaces a custom preview domain when the generate action runs', function ()
|
||||
|
||||
expect($preview->fresh()->fqdn)->toBe('https://6540.app.example.com');
|
||||
});
|
||||
|
||||
it('routes every generated compose preview domain when a service has more than one domain', function () {
|
||||
$this->application->update([
|
||||
'build_pack' => 'dockercompose',
|
||||
'compose_parsing_version' => '3',
|
||||
'preview_url_template' => '{{pr_id}}.{{domain}}',
|
||||
'docker_compose_raw' => "services:\n frontend:\n image: nginx:alpine\n",
|
||||
'fqdn' => null,
|
||||
'docker_compose_domains' => json_encode([
|
||||
'frontend' => ['domain' => 'https://dev.example.com,https://www.dev.example.com'],
|
||||
]),
|
||||
]);
|
||||
$preview = createPreviewForPortTests($this->application->fresh(), 92, [
|
||||
'docker_compose_domains' => $this->application->docker_compose_domains,
|
||||
]);
|
||||
|
||||
$preview->generate_preview_fqdn_compose();
|
||||
$preview->refresh();
|
||||
|
||||
expect(json_decode($preview->docker_compose_domains, true)['frontend']['domain'])
|
||||
->toBe('https://92.dev.example.com,https://92.www.dev.example.com');
|
||||
|
||||
$labels = collect(data_get(applicationParser($this->application->fresh(), 92, $preview->id), 'services.frontend-pr-92.labels'));
|
||||
$routerRules = $labels->filter(fn (string $label): bool => str_contains($label, '.rule='))->values();
|
||||
|
||||
expect($routerRules)->not->toBeEmpty()
|
||||
->and($routerRules->every(fn (string $label): bool => preg_match('/\.rule=Host\(`[a-z0-9.]+`\)( && PathPrefix\(`\/[^`]*`\))?$/', $label) === 1))->toBeTrue()
|
||||
->and($routerRules->contains(fn (string $label): bool => str_contains($label, 'Host(`92.dev.example.com`)')))->toBeTrue()
|
||||
->and($routerRules->contains(fn (string $label): bool => str_contains($label, 'Host(`92.www.dev.example.com`)')))->toBeTrue();
|
||||
});
|
||||
|
||||
@@ -184,6 +184,35 @@ it('validates oidc url fields before saving', function (string $field, string $v
|
||||
'non-http issuer url' => ['base_url', 'ftp://idp.example.com'],
|
||||
]);
|
||||
|
||||
it('rejects a redirect uri that does not point to the provider callback route', function (string $redirectUri) {
|
||||
actingAsInstanceAdmin();
|
||||
|
||||
Livewire::test(SettingsOauth::class, ['provider' => 'authentik'])
|
||||
->set('oauth_settings_map.authentik.redirect_uri', $redirectUri)
|
||||
->call('submit')
|
||||
->assertHasErrors(['oauth_settings_map.authentik.redirect_uri']);
|
||||
|
||||
expect(OauthSetting::where('provider', 'authentik')->first()->redirect_uri)->toBeNull();
|
||||
})->with([
|
||||
'swapped segments' => ['https://coolify.example.com/auth/callback/authentik'],
|
||||
'other provider' => ['https://coolify.example.com/auth/github/callback'],
|
||||
'no path' => ['https://coolify.example.com'],
|
||||
]);
|
||||
|
||||
it('accepts a redirect uri on the provider callback route', function (string $redirectUri) {
|
||||
actingAsInstanceAdmin();
|
||||
|
||||
Livewire::test(SettingsOauth::class, ['provider' => 'authentik'])
|
||||
->set('oauth_settings_map.authentik.redirect_uri', $redirectUri)
|
||||
->call('submit')
|
||||
->assertHasNoErrors();
|
||||
|
||||
expect(OauthSetting::where('provider', 'authentik')->first()->redirect_uri)->toBe($redirectUri);
|
||||
})->with([
|
||||
'callback route' => ['https://coolify.example.com/auth/authentik/callback'],
|
||||
'trailing slash' => ['https://coolify.example.com/auth/authentik/callback/'],
|
||||
]);
|
||||
|
||||
it('does not enable oidc without required fields', function () {
|
||||
actingAsInstanceAdmin();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user