feat(mock-server): append /backend to domain-based URL when subpath access is enabled (#6448)

* feat: append /backend to domain-based mock server URL when subpath access enabled

* test: cover ENABLE_SUBPATH_BASED_ACCESS branch for domain-based mock server URL

Adds cast URL-generation tests asserting /backend is appended only when
ENABLE_SUBPATH_BASED_ACCESS is "true", covering the false/unset, https,
and null-wildcard cases.

* refactor: improve mock server URL generation with defensive guard and constants
This commit is contained in:
Mir Arif Hasan
2026-06-24 18:42:45 +06:00
committed by GitHub
parent 96b4d61d40
commit 00da4c33a7
2 changed files with 131 additions and 2 deletions
@@ -151,6 +151,123 @@ describe('MockServerService', () => {
});
});
describe('cast - server URL generation', () => {
test('should not append /backend to serverUrlDomainBased when ENABLE_SUBPATH_BASED_ACCESS is not set', async () => {
mockPrisma.mockServer.findMany.mockResolvedValue([dbMockServer]);
const result = await mockServerService.getUserMockServers(user.uid, {
take: 10,
skip: 0,
});
expect(result[0].serverUrlDomainBased).toBe(
'http://test-subdomain.mock.hopp.io',
);
});
test('should not append /backend to serverUrlDomainBased when ENABLE_SUBPATH_BASED_ACCESS is "false"', async () => {
mockConfigService.get.mockImplementation((key: string) => {
if (key === 'VITE_BACKEND_API_URL') return 'http://localhost:3170/v1';
if (key === 'INFRA.MOCK_SERVER_WILDCARD_DOMAIN')
return '*.mock.hopp.io';
if (key === 'INFRA.ALLOW_SECURE_COOKIES') return 'false';
if (key === 'ENABLE_SUBPATH_BASED_ACCESS') return 'false';
return undefined;
});
mockPrisma.mockServer.findMany.mockResolvedValue([dbMockServer]);
const result = await mockServerService.getUserMockServers(user.uid, {
take: 10,
skip: 0,
});
expect(result[0].serverUrlDomainBased).toBe(
'http://test-subdomain.mock.hopp.io',
);
});
test('should append /backend to serverUrlDomainBased when ENABLE_SUBPATH_BASED_ACCESS is "true"', async () => {
mockConfigService.get.mockImplementation((key: string) => {
if (key === 'VITE_BACKEND_API_URL') return 'http://localhost:3170/v1';
if (key === 'INFRA.MOCK_SERVER_WILDCARD_DOMAIN')
return '*.mock.hopp.io';
if (key === 'INFRA.ALLOW_SECURE_COOKIES') return 'false';
if (key === 'ENABLE_SUBPATH_BASED_ACCESS') return 'true';
return undefined;
});
mockPrisma.mockServer.findMany.mockResolvedValue([dbMockServer]);
const result = await mockServerService.getUserMockServers(user.uid, {
take: 10,
skip: 0,
});
expect(result[0].serverUrlDomainBased).toBe(
'http://test-subdomain.mock.hopp.io/backend',
);
});
test('should use https protocol and append /backend when secure cookies and subpath access are enabled', async () => {
mockConfigService.get.mockImplementation((key: string) => {
if (key === 'VITE_BACKEND_API_URL') return 'https://localhost:3170/v1';
if (key === 'INFRA.MOCK_SERVER_WILDCARD_DOMAIN')
return '*.mock.hopp.io';
if (key === 'INFRA.ALLOW_SECURE_COOKIES') return 'true';
if (key === 'ENABLE_SUBPATH_BASED_ACCESS') return 'true';
return undefined;
});
mockPrisma.mockServer.findMany.mockResolvedValue([dbMockServer]);
const result = await mockServerService.getUserMockServers(user.uid, {
take: 10,
skip: 0,
});
expect(result[0].serverUrlDomainBased).toBe(
'https://test-subdomain.mock.hopp.io/backend',
);
});
test('should leave serverUrlDomainBased null and not append /backend when wildcard domain is not configured', async () => {
mockConfigService.get.mockImplementation((key: string) => {
if (key === 'VITE_BACKEND_API_URL') return 'http://localhost:3170/v1';
if (key === 'INFRA.MOCK_SERVER_WILDCARD_DOMAIN') return undefined;
if (key === 'INFRA.ALLOW_SECURE_COOKIES') return 'false';
if (key === 'ENABLE_SUBPATH_BASED_ACCESS') return 'true';
return undefined;
});
mockPrisma.mockServer.findMany.mockResolvedValue([dbMockServer]);
const result = await mockServerService.getUserMockServers(user.uid, {
take: 10,
skip: 0,
});
expect(result[0].serverUrlDomainBased).toBeNull();
});
test('should strip trailing slashes from wildcard domain before appending subpath suffix', async () => {
mockConfigService.get.mockImplementation((key: string) => {
if (key === 'VITE_BACKEND_API_URL') return 'http://localhost:3170/v1';
if (key === 'INFRA.MOCK_SERVER_WILDCARD_DOMAIN')
return '*.mock.hopp.io/'; // Domain with trailing slash
if (key === 'INFRA.ALLOW_SECURE_COOKIES') return 'false';
if (key === 'ENABLE_SUBPATH_BASED_ACCESS') return 'true';
return undefined;
});
mockPrisma.mockServer.findMany.mockResolvedValue([dbMockServer]);
const result = await mockServerService.getUserMockServers(user.uid, {
take: 10,
skip: 0,
});
expect(result[0].serverUrlDomainBased).toBe(
'http://test-subdomain.mock.hopp.io/backend',
);
});
});
describe('getTeamMockServers', () => {
test('should return team mock servers with pagination', async () => {
const teamMockServer = {
@@ -64,8 +64,20 @@ export class MockServerService {
const isSecure =
this.configService.get<string>('INFRA.ALLOW_SECURE_COOKIES') === 'true';
const protocol = isSecure ? 'https://' : 'http://';
const serverUrlDomainBased = wildcardDomain
? protocol + dbMockServer.subdomain + wildcardDomain.substring(1)
// ENABLE_SUBPATH_BASED_ACCESS is a flat config key (no INFRA. prefix) to support flexible deployment strategies
const SUBPATH_BACKEND_SUFFIX = '/backend';
const subpathSuffix =
this.configService.get<string>('ENABLE_SUBPATH_BASED_ACCESS') === 'true'
? SUBPATH_BACKEND_SUFFIX
: '';
const domainPart = wildcardDomain
? dbMockServer.subdomain + wildcardDomain.substring(1)
: null;
const serverUrlDomainBased = domainPart
? `${protocol}${domainPart.replace(/\/+$/, '')}${subpathSuffix}`
: null;
return {