Files
coolify/tests/Feature/ServiceTemplatesLastUpdatedHintTest.php
e3d4411ff2 chore: merge main into release/v4.5 (#12192)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Furox <177975472+Furox-Art@users.noreply.github.com>
Co-authored-by: johandenhollander <johan.den.hollander@finalist.nl>
Co-authored-by: João Cruz <161638790+SrJooJ@users.noreply.github.com>
Co-authored-by: Saim Hashmi <hashmisaim037@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-10-18 23:43:20 +02:00

165 lines
6.2 KiB
PHP

<?php
use App\Livewire\Project\New\Select;
use Carbon\CarbonImmutable;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\File;
beforeEach(function () {
Cache::flush();
});
it('returns the service templates bundle last updated timestamp', function () {
$component = new Select;
$templatePath = base_path('templates/'.config('constants.services.file_name'));
$resources = $component->loadServices();
expect($resources)
->toHaveKey('serviceTemplatesLastUpdated')
->and($resources['serviceTemplatesLastUpdated'])
->toBe(CarbonImmutable::createFromTimestamp(filemtime($templatePath))->timezone(config('app.timezone'))->format('M j, Y H:i'));
});
it('returns each service template last updated timestamp from the generated bundle', function () {
$component = new Select;
$templates = json_decode(file_get_contents(base_path('templates/'.config('constants.services.file_name'))), true);
$templateTimestamp = $templates['activepieces']['template_last_updated_at'];
$resources = $component->loadServices();
expect($resources['services']['activepieces'])
->toHaveKey('templateLastUpdated')
->and($resources['services']['activepieces']['templateLastUpdated'])
->toBe(CarbonImmutable::parse($templateTimestamp)->timezone(config('app.timezone'))->format('M j, Y H:i'));
});
it('returns local, CDN, and default logo fallbacks for every service', function () {
$services = (new Select)->loadServices()['services'];
expect($services['opnform']['logo'])->toBe(asset('svgs/opnform.svg'))
->and($services['pydio-cells']['logo'])->toBe(asset('svgs/cells.svg'))
->and($services['pydio-cells']['logo_cdn_url'])
->toBe('https://raw.githubusercontent.com/coollabsio/coolify/refs/heads/main/public/svgs/cells.svg')
->and($services['pydio-cells']['logo_default_url'])->toBe(asset('svgs/default.webp'));
});
it('uses resource tile icons for databases', function () {
$databases = collect((new Select)->loadServices()['databases'])->keyBy('id');
foreach (['keydb', 'dragonfly', 'clickhouse'] as $database) {
expect($databases[$database]['logo'])->toBe(resource_logo_url($database));
}
});
it('prefers embedded service template git timestamps from the templates bundle', function () {
$path = base_path('templates/'.config('constants.services.file_name'));
$payload = json_encode([
'activepieces' => [
'documentation' => 'https://coolify.io/docs',
'slogan' => 'Open source no-code business automation.',
'compose' => '',
'tags' => null,
'category' => 'automation',
'logo' => 'images/default.webp',
'minversion' => '0.0.0',
'template_last_updated_at' => '2026-05-31T12:34:56+00:00',
],
]);
File::partialMock()
->shouldReceive('exists')
->with($path)
->andReturn(true)
->shouldReceive('get')
->with($path)
->andReturn($payload);
$resources = (new Select)->loadServices();
expect($resources['services']['activepieces']['templateLastUpdated'])->toBe('May 31, 2026 12:34');
});
it('caches parsed local service templates by bundle mtime', function () {
Cache::flush();
$path = base_path('templates/'.config('constants.services.file_name'));
$json = file_get_contents($path);
File::partialMock()
->shouldReceive('get')
->once()
->with($path)
->andReturn($json);
$first = get_service_templates();
$second = get_service_templates();
expect($first->keys()->all())->toBe($second->keys()->all());
});
it('keeps service template keys for service selection and docs links', function () {
$path = base_path('templates/'.config('constants.services.file_name'));
File::partialMock()
->shouldReceive('exists')
->with($path)
->andReturn(true)
->shouldReceive('get')
->with($path)
->andReturn(json_encode([
'denoKV' => [
'documentation' => 'https://coolify.io/docs',
'slogan' => 'Deno KV.',
'compose' => '',
'tags' => null,
'category' => 'database',
'logo' => 'images/default.webp',
'minversion' => '0.0.0',
],
]));
$services = collect((new Select)->loadServices()['services']);
$denoKv = $services->firstWhere('id', 'denoKV');
expect($denoKv)
->not->toBeNull()
->and($denoKv['docsSlug'])->toBe('denokv');
});
it('preserves one click service key casing when selecting a service template', function () {
$component = new Select;
$component->servers = collect();
$component->allServers = collect();
$component->setType('one-click-service-denoKV');
expect($component->type)->toBe('one-click-service-denoKV');
});
it('links service websites to the project page instead of a shared host root', function () {
$path = base_path('templates/'.config('constants.services.file_name'));
$payload = json_encode([
'uptime-kuma' => ['documentation' => 'https://github.com/louislam/uptime-kuma?tab=readme-ov-file&utm_source=coolify.io'],
'alexandrie' => ['documentation' => 'https://www.github.com/Smaug6739/Alexandrie/tree/main/docs'],
'radarr' => ['documentation' => 'https://hub.docker.com/r/linuxserver/radarr?utm_source=coolify.io'],
'n8n' => ['documentation' => 'https://n8n.io/docs?utm_source=coolify.io'],
'broken' => ['documentation' => 'not a url'],
]);
File::partialMock()
->shouldReceive('exists')
->with($path)
->andReturn(true)
->shouldReceive('get')
->with($path)
->andReturn($payload);
$services = (new Select)->loadServices()['services'];
expect($services['uptime-kuma']['website'])->toBe('https://github.com/louislam/uptime-kuma')
->and($services['alexandrie']['website'])->toBe('https://www.github.com/Smaug6739/Alexandrie')
->and($services['radarr']['website'])->toBe('https://hub.docker.com/r/linuxserver/radarr')
->and($services['n8n']['website'])->toBe('https://n8n.io')
->and($services['broken']['website'])->toBeNull();
});