Skip to content

Commit de82ecf

Browse files
committed
1 parent 794c2a5 commit de82ecf

File tree

8 files changed

+194
-55
lines changed

8 files changed

+194
-55
lines changed
Lines changed: 153 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,189 @@
11
import { getAuthUrl } from '@utils/get-auth-url';
22

33
describe('getAuthUrl', () => {
4-
const originalEnv = process.env;
5-
6-
beforeEach(() => {
7-
jest.resetModules();
8-
process.env = { ...originalEnv };
9-
});
4+
const originalWindow = { ...global.window };
5+
const originalEnv = { ...process.env };
106

117
afterAll(() => {
12-
process.env = originalEnv;
8+
Object.defineProperty(process, 'env', {
9+
value: originalEnv,
10+
configurable: true,
11+
});
12+
13+
Object.defineProperty(global, 'window', {
14+
value: originalWindow,
15+
configurable: true,
16+
});
1317
});
1418

15-
describe('in production', () => {
19+
describe('client side (when window is available)', () => {
1620
beforeEach(() => {
17-
Object.defineProperty(process.env, 'NODE_ENV', {
18-
value: 'production',
21+
Object.defineProperty(global, 'window', {
22+
value: {
23+
location: {
24+
protocol: 'https:',
25+
host: 'nhsnotify.national.nhs.uk',
26+
},
27+
},
1928
configurable: true,
2029
});
21-
process.env.NOTIFY_DOMAIN_NAME = 'nhsnotify.nhs.uk';
2230
});
2331

24-
it('should use https protocol', () => {
25-
const result = getAuthUrl('/auth');
26-
expect(result).toBe('https://nhsnotify.nhs.uk/auth');
32+
afterAll(() => {
33+
Object.defineProperty(global, 'window', {
34+
value: originalWindow,
35+
configurable: true,
36+
});
2737
});
2838

29-
it('should not include basePath for auth app URLs', () => {
30-
const result = getAuthUrl('/auth/signout');
31-
expect(result).toBe('https://nhsnotify.nhs.uk/auth/signout');
39+
it('should construct URL', () => {
40+
const result = getAuthUrl('/auth');
41+
expect(result).toBe('https://nhsnotify.national.nhs.uk/auth');
3242
});
3343

3444
it('should handle query parameters', () => {
3545
const result = getAuthUrl('/auth?redirect=%2Ftemplates%2Fcreate');
46+
3647
expect(result).toBe(
37-
'https://nhsnotify.nhs.uk/auth?redirect=%2Ftemplates%2Fcreate'
48+
'https://nhsnotify.national.nhs.uk/auth?redirect=%2Ftemplates%2Fcreate'
3849
);
3950
});
4051

41-
it('should fallback to localhost when NOTIFY_DOMAIN_NAME is not set', () => {
42-
delete process.env.NOTIFY_DOMAIN_NAME;
43-
const result = getAuthUrl('/auth');
44-
expect(result).toBe('https://localhost:3000/auth');
52+
describe('in development env', () => {
53+
beforeEach(() => {
54+
Object.defineProperty(process.env, 'NODE_ENV', {
55+
value: 'development',
56+
configurable: true,
57+
});
58+
});
59+
60+
afterAll(() => {
61+
Object.defineProperty(process.env, 'NODE_ENV', {
62+
value: originalEnv,
63+
configurable: true,
64+
});
65+
});
66+
67+
it('should include the base path set', () => {
68+
process.env.NEXT_PUBLIC_BASE_PATH = '/base-path';
69+
70+
const result = getAuthUrl('/auth');
71+
expect(result).toBe('https://nhsnotify.national.nhs.uk/base-path/auth');
72+
});
73+
74+
it('should fallback to templates when no base path environment variable provided', () => {
75+
delete process.env.NEXT_PUBLIC_BASE_PATH;
76+
77+
const result = getAuthUrl('/auth');
78+
expect(result).toBe('https://nhsnotify.national.nhs.uk/templates/auth');
79+
});
4580
});
4681
});
4782

48-
describe('in development', () => {
83+
describe('when window is not available', () => {
4984
beforeEach(() => {
50-
Object.defineProperty(process.env, 'NODE_ENV', {
51-
value: 'development',
52-
configurable: true,
53-
});
85+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
86+
delete (global as any).window;
5487
});
5588

56-
it('should use http protocol', () => {
57-
const result = getAuthUrl('/auth');
58-
expect(result).toBe('http://localhost:3000/templates/auth');
89+
afterAll(() => {
90+
global.window = originalWindow;
5991
});
6092

61-
it('should include basePath to hit local auth pages', () => {
62-
process.env.NEXT_PUBLIC_BASE_PATH = '/templates';
63-
const result = getAuthUrl('/auth');
64-
expect(result).toBe('http://localhost:3000/templates/auth');
65-
});
93+
describe('when gateway URL environment variable is available', () => {
94+
beforeEach(() => {
95+
process.env.NEXT_PUBLIC_GATEWAY_URL =
96+
'https://dev.web-gateway.nhsnotify.national.nhs.uk';
97+
});
6698

67-
it('should fallback to /templates basePath when NEXT_PUBLIC_BASE_PATH is undefined', () => {
68-
delete process.env.NEXT_PUBLIC_BASE_PATH;
69-
const result = getAuthUrl('/auth');
70-
expect(result).toBe('http://localhost:3000/templates/auth');
99+
it('should use NEXT_PUBLIC_GATEWAY_URL', () => {
100+
const result = getAuthUrl('/auth');
101+
expect(result).toBe(
102+
'https://dev.web-gateway.nhsnotify.national.nhs.uk/auth'
103+
);
104+
});
105+
106+
it('should handle query parameters', () => {
107+
const result = getAuthUrl('/auth?redirect=%2Ftemplates%2Fcreate');
108+
expect(result).toBe(
109+
'https://dev.web-gateway.nhsnotify.national.nhs.uk/auth?redirect=%2Ftemplates%2Fcreate'
110+
);
111+
});
112+
113+
describe('in development env', () => {
114+
beforeEach(() => {
115+
Object.defineProperty(process.env, 'NODE_ENV', {
116+
value: 'development',
117+
configurable: true,
118+
});
119+
});
120+
121+
afterAll(() => {
122+
Object.defineProperty(process.env, 'NODE_ENV', {
123+
value: originalEnv,
124+
configurable: true,
125+
});
126+
});
127+
128+
it('should include the base path set', () => {
129+
process.env.NEXT_PUBLIC_BASE_PATH = '/base-path';
130+
131+
const result = getAuthUrl('/auth');
132+
expect(result).toBe(
133+
'https://dev.web-gateway.nhsnotify.national.nhs.uk/base-path/auth'
134+
);
135+
});
136+
137+
it('should fallback to templates when no base path environment variable provided', () => {
138+
delete process.env.NEXT_PUBLIC_BASE_PATH;
139+
140+
const result = getAuthUrl('/auth');
141+
expect(result).toBe(
142+
'https://dev.web-gateway.nhsnotify.national.nhs.uk/templates/auth'
143+
);
144+
});
145+
});
71146
});
72147

73-
it('should handle query parameters with basePath', () => {
74-
const result = getAuthUrl('/auth?redirect=%2Ftemplates%2Fcreate');
75-
expect(result).toBe(
76-
'http://localhost:3000/templates/auth?redirect=%2Ftemplates%2Fcreate'
77-
);
148+
describe('when no gateway URL environment variable is available', () => {
149+
beforeEach(() => {
150+
delete process.env.NEXT_PUBLIC_GATEWAY_URL;
151+
});
152+
153+
it('should fallback to localhost:3000', () => {
154+
const result = getAuthUrl('/auth');
155+
expect(result).toBe('http://localhost:3000/auth');
156+
});
157+
158+
describe('in development env', () => {
159+
beforeEach(() => {
160+
Object.defineProperty(process.env, 'NODE_ENV', {
161+
value: 'development',
162+
configurable: true,
163+
});
164+
});
165+
166+
afterAll(() => {
167+
Object.defineProperty(process.env, 'NODE_ENV', {
168+
value: originalEnv,
169+
configurable: true,
170+
});
171+
});
172+
173+
it('should include the base path set', () => {
174+
process.env.NEXT_PUBLIC_BASE_PATH = '/base-path';
175+
176+
const result = getAuthUrl('/auth');
177+
expect(result).toBe('http://localhost:3000/base-path/auth');
178+
});
179+
180+
it('should fallback to templates when no base path environment variable provided', () => {
181+
delete process.env.NEXT_PUBLIC_BASE_PATH;
182+
183+
const result = getAuthUrl('/auth');
184+
expect(result).toBe('http://localhost:3000/templates/auth');
185+
});
186+
});
78187
});
79188
});
80189
});

frontend/src/utils/get-auth-url.ts

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1+
function getBasePath(): string {
2+
return process.env.NODE_ENV === 'development'
3+
? (process.env.NEXT_PUBLIC_BASE_PATH ?? '/templates')
4+
: '';
5+
}
6+
17
export function getAuthUrl(path: string): string {
2-
const protocol = process.env.NODE_ENV === 'production' ? 'https:' : 'http:';
3-
const domain = process.env.NOTIFY_DOMAIN_NAME ?? 'localhost:3000';
8+
const basePath = getBasePath();
9+
10+
if (typeof window !== 'undefined') {
11+
return `${window.location.protocol}//${window.location.host}${basePath}${path}`;
12+
}
413

5-
const basePath =
6-
process.env.NODE_ENV === 'development'
7-
? (process.env.NEXT_PUBLIC_BASE_PATH ?? '/templates')
8-
: '';
14+
const gatewayUrl = process.env.NEXT_PUBLIC_GATEWAY_URL;
15+
if (gatewayUrl) {
16+
return `${gatewayUrl}${basePath}${path}`;
17+
}
918

10-
return `${protocol}//${domain}${basePath}${path}`;
19+
return `http://localhost:3000${basePath}${path}`;
1120
}

infrastructure/terraform/components/app/amplify_app.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ resource "aws_amplify_app" "main" {
3232
AMPLIFY_MONOREPO_APP_ROOT = "frontend"
3333
API_BASE_URL = module.backend_api.api_base_url
3434
CSRF_SECRET = aws_ssm_parameter.csrf_secret.value
35+
NEXT_PUBLIC_GATEWAY_URL = local.gateway_url
3536
NEXT_PUBLIC_PROMPT_SECONDS_BEFORE_LOGOUT = 120
3637
NEXT_PUBLIC_TIME_TILL_LOGOUT_SECONDS = 900
3738
NOTIFY_DOMAIN_NAME = local.root_domain_name

infrastructure/terraform/components/app/locals.tf

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,9 @@ locals {
33
root_domain_name = "${var.environment}.${local.acct.dns_zone["name"]}"
44
lambdas_source_code_dir = "../../../../lambdas"
55
log_destination_arn = "arn:aws:logs:${var.region}:${var.observability_account_id}:destination:nhs-main-obs-firehose-logs"
6+
gateway_url = var.gateway_domain != null ? (
7+
var.use_environment_specific_gateway_domain
8+
? "https://${var.environment}.${var.gateway_domain}"
9+
: "https://${var.gateway_domain}"
10+
) : "https://${aws_amplify_app.main.default_domain}"
611
}

infrastructure/terraform/components/app/module_amplify_branch.tf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ module "amplify_branch" {
1616
enable_auto_build = false
1717

1818
environment_variables = {
19-
NOTIFY_SUBDOMAIN = var.environment
20-
NEXT_PUBLIC_BASE_PATH = "/templates"
19+
NOTIFY_SUBDOMAIN = var.environment
20+
NEXT_PUBLIC_BASE_PATH = "/templates"
21+
NEXT_PUBLIC_GATEWAY_URL = local.gateway_url
2122
}
2223
}

infrastructure/terraform/components/app/outputs.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ output "amplify" {
33
id = aws_amplify_app.main.id
44
domain_name = local.root_domain_name
55
branch_name = var.branch_name
6+
gateway_url = local.gateway_url
67
}
78
}
89

infrastructure/terraform/components/app/variables.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,3 +212,15 @@ variable "external_email_domain" {
212212
default = null
213213
description = "Externally managed domain used to create an SES identity for sending emails from. Validation DNS records will need to be manually configured in the DNS provider."
214214
}
215+
216+
variable "gateway_domain" {
217+
type = string
218+
description = "The web gateway domain (e.g., notify.nhs.uk or web-gateway.nhsnotify.national.nhs.uk)"
219+
default = ""
220+
}
221+
222+
variable "use_environment_specific_gateway_domain" {
223+
type = bool
224+
description = "Whether to prefix the gateway domain with the environment name"
225+
default = false
226+
}

infrastructure/terraform/components/branch/module_amplify_branch.tf

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ module "amplify_branch" {
1818
enable_auto_build = true
1919

2020
environment_variables = {
21-
NOTIFY_SUBDOMAIN = var.environment
22-
NEXT_PUBLIC_BASE_PATH = "/templates~${local.normalised_branch_name}"
21+
NOTIFY_SUBDOMAIN = var.environment
22+
NEXT_PUBLIC_BASE_PATH = "/templates~${local.normalised_branch_name}"
23+
NEXT_PUBLIC_GATEWAY_URL = local.app.amplify["gateway_url"]
2324
}
2425
}

0 commit comments

Comments
 (0)