create([ 'name' => 'test-server', 'ip' => '127.0.0.1', ]); // Load Appwrite template $appwriteTemplate = file_get_contents(base_path('templates/compose/appwrite.yaml')); // Create Appwrite service $service = Service::factory()->create([ 'server_id' => $server->id, 'name' => 'appwrite-test', 'docker_compose_raw' => $appwriteTemplate, ]); // Create the appwrite-realtime service application $serviceApp = ServiceApplication::factory()->create([ 'service_id' => $service->id, 'name' => 'appwrite-realtime', 'fqdn' => 'https://test.abc/v1/realtime', ]); // Parse the service (simulates initial setup) $service->parse(); // Get environment variable $urlVar = $service->environment_variables() ->where('key', 'SERVICE_URL_APPWRITE') ->first(); // Initial setup should have path once expect($urlVar)->not->toBeNull() ->and($urlVar->value)->not->toContain('/v1/realtime/v1/realtime') ->and($urlVar->value)->toContain('/v1/realtime'); // Simulate user updating FQDN $serviceApp->fqdn = 'https://newdomain.com/v1/realtime'; $serviceApp->save(); // Call parse again (this is where the bug occurred) $service->parse(); // Check that path is not duplicated $urlVar = $service->environment_variables() ->where('key', 'SERVICE_URL_APPWRITE') ->first(); expect($urlVar)->not->toBeNull() ->and($urlVar->value)->not->toContain('/v1/realtime/v1/realtime') ->and($urlVar->value)->toContain('/v1/realtime'); })->skip('Requires database and Appwrite template - run in Docker'); test('Appwrite console service does not duplicate /console path', function () { $server = Server::factory()->create(); $appwriteTemplate = file_get_contents(base_path('templates/compose/appwrite.yaml')); $service = Service::factory()->create([ 'server_id' => $server->id, 'docker_compose_raw' => $appwriteTemplate, ]); $serviceApp = ServiceApplication::factory()->create([ 'service_id' => $service->id, 'name' => 'appwrite-console', 'fqdn' => 'https://test.abc/console', ]); // Parse service $service->parse(); // Update FQDN $serviceApp->fqdn = 'https://newdomain.com/console'; $serviceApp->save(); // Parse again $service->parse(); // Verify no duplication $urlVar = $service->environment_variables() ->where('key', 'SERVICE_URL_APPWRITE') ->first(); expect($urlVar)->not->toBeNull() ->and($urlVar->value)->not->toContain('/console/console') ->and($urlVar->value)->toContain('/console'); })->skip('Requires database and Appwrite template - run in Docker'); test('MindsDB service does not duplicate /api path', function () { $server = Server::factory()->create(); $mindsdbTemplate = file_get_contents(base_path('templates/compose/mindsdb.yaml')); $service = Service::factory()->create([ 'server_id' => $server->id, 'docker_compose_raw' => $mindsdbTemplate, ]); $serviceApp = ServiceApplication::factory()->create([ 'service_id' => $service->id, 'name' => 'mindsdb', 'fqdn' => 'https://test.abc/api', ]); // Parse service $service->parse(); // Update FQDN multiple times $serviceApp->fqdn = 'https://domain1.com/api'; $serviceApp->save(); $service->parse(); $serviceApp->fqdn = 'https://domain2.com/api'; $serviceApp->save(); $service->parse(); // Verify no duplication after multiple updates $urlVar = $service->environment_variables() ->where('key', 'SERVICE_URL_API') ->orWhere('key', 'LIKE', 'SERVICE_URL_%') ->first(); expect($urlVar)->not->toBeNull() ->and($urlVar->value)->not->toContain('/api/api'); })->skip('Requires database and MindsDB template - run in Docker'); test('service without path declaration is not affected', function () { $server = Server::factory()->create(); // Create a simple service without path in template $simpleTemplate = <<<'YAML' services: redis: image: redis:7 environment: - SERVICE_FQDN_REDIS YAML; $service = Service::factory()->create([ 'server_id' => $server->id, 'docker_compose_raw' => $simpleTemplate, ]); $serviceApp = ServiceApplication::factory()->create([ 'service_id' => $service->id, 'name' => 'redis', 'fqdn' => 'https://redis.test.abc', ]); // Parse service $service->parse(); $fqdnBefore = $service->environment_variables() ->where('key', 'SERVICE_FQDN_REDIS') ->first()?->value; // Update FQDN $serviceApp->fqdn = 'https://redis.newdomain.com'; $serviceApp->save(); // Parse again $service->parse(); $fqdnAfter = $service->environment_variables() ->where('key', 'SERVICE_FQDN_REDIS') ->first()?->value; // Should work normally without issues expect($fqdnAfter)->toBe('redis.newdomain.com') ->and($fqdnAfter)->not->toContain('//'); })->skip('Requires database - run in Docker'); test('multiple FQDN updates never cause path duplication', function () { $server = Server::factory()->create(); $appwriteTemplate = file_get_contents(base_path('templates/compose/appwrite.yaml')); $service = Service::factory()->create([ 'server_id' => $server->id, 'docker_compose_raw' => $appwriteTemplate, ]); $serviceApp = ServiceApplication::factory()->create([ 'service_id' => $service->id, 'name' => 'appwrite-realtime', 'fqdn' => 'https://test.abc/v1/realtime', ]); // Update FQDN 10 times and parse each time for ($i = 1; $i <= 10; $i++) { $serviceApp->fqdn = "https://domain{$i}.com/v1/realtime"; $serviceApp->save(); $service->parse(); // Check path is never duplicated $urlVar = $service->environment_variables() ->where('key', 'SERVICE_URL_APPWRITE') ->first(); expect($urlVar)->not->toBeNull() ->and($urlVar->value)->not->toContain('/v1/realtime/v1/realtime') ->and($urlVar->value)->toContain('/v1/realtime'); } })->skip('Requires database and Appwrite template - run in Docker');