Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion browser-tests/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ COPY ./browser-tests/snapshot-tests ./snapshot-tests
COPY ./browser-tests/playwright.config.ts ./
COPY ./browser-tests/tsconfig.json ./
COPY ../views/ipv/page ../views/ipv/page
COPY ../src/test-utils/pages-and-contexts.ts ../src/test-utils/pages-and-contexts.ts
COPY ../src/config/pages-and-contexts.ts ../src/config/pages-and-contexts.ts

CMD ["npm run test"]
2 changes: 1 addition & 1 deletion browser-tests/data/pagesAndContexts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {pagesAndContexts} from "../../src/test-utils/pages-and-contexts";
import {pagesAndContexts} from "../../src/config/pages-and-contexts";

type TestFn = (pageName: string, context: string | undefined, language: string, url: string) => void;

Expand Down
2 changes: 1 addition & 1 deletion browser-tests/snapshot-tests/snapshot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import fs from "fs";
import {
iteratePagesAndContexts
} from "../data/pagesAndContexts";
import { pagesAndContexts } from "../../src/test-utils/pages-and-contexts";
import { pagesAndContexts } from "../../src/config/pages-and-contexts";

test.describe.parallel("Snapshot tests", () => {
test.setTimeout(120000);
Expand Down
8 changes: 6 additions & 2 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import config from "./config/config";
import { setLocals } from "./lib/locals";
import { loggerMiddleware, logger } from "./lib/logger";
import { i18nextConfigurationOptions } from "./config/i18next";
import { configureNunjucks } from "./config/nunjucks";
import { configureNunjucks, preloadTemplates } from "./config/nunjucks";
import serverErrorHandler from "./handlers/internal-server-error-handler";
import journeyEventErrorHandler from "./handlers/journey-event-error-handler";
import pageNotFoundHandler from "./handlers/page-not-found-handler";
Expand Down Expand Up @@ -110,7 +110,9 @@ app.get("/healthcheck", (req, res) => {

app.use(setLocals);
app.use(cspHandler);
app.set("view engine", configureNunjucks(app, APP_VIEWS));

const nunjucksEnv = configureNunjucks(app, APP_VIEWS);
app.set("view engine", nunjucksEnv);

i18next
.use(Backend)
Expand All @@ -121,6 +123,8 @@ i18next

app.use(i18nextMiddleware.handle(i18next));

preloadTemplates(nunjucksEnv); // Must come after nunjucks and i18n

app.use(cookieParser());

// Generate a new session ID asynchronously if no session cookie
Expand Down
2 changes: 1 addition & 1 deletion src/app/development/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const pagesAndContextsStub = {
},
};
const middleware = proxyquire("./middleware", {
"../../test-utils/pages-and-contexts": pagesAndContextsStub,
"../../config/pages-and-contexts": pagesAndContextsStub,
"fs/promises": fsReadDirStub,
});

Expand Down
2 changes: 1 addition & 1 deletion src/app/development/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { generateQrCodeImageData } from "../shared/qrCodeHelper";
import { getAppStoreRedirectUrl } from "../shared/appDownloadHelper";
import PAGES from "../../constants/ipv-pages";
import { getIpvPageTemplatePath, getTemplatePath } from "../../lib/paths";
import { pagesAndContexts } from "../../test-utils/pages-and-contexts";
import { pagesAndContexts } from "../../config/pages-and-contexts";

interface RadioOption {
text: string;
Expand Down
21 changes: 21 additions & 0 deletions src/config/nunjucks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import i18next from "i18next";
import nunjucks, { Environment } from "nunjucks";
import { kebabCaseToPascalCase } from "../app/shared/stringHelper";
import config from "./config";
import { logger } from "../lib/logger";
import { getIpvPageTemplatePath } from "../lib/paths";
import { pagesAndContexts } from "./pages-and-contexts";

interface FilterContext {
ctx: {
Expand Down Expand Up @@ -85,3 +88,21 @@ export const configureNunjucks = (
nunjucksEnv.addGlobal("addLanguageParam", addLanguageParam);
return nunjucksEnv;
};

// Usually nunjucks will load templates on-demand (and are then cached indefinitely).
// However, this can trigger overload-protection as it's a synchronous blocking call.
// By pre-rendering each template once, we can force all the templates to be loaded at startup.
export const preloadTemplates = (nunjucksEnv: Environment): void => {
if (config.TEMPLATE_CACHING) {
logger.info("Preloading templates");
const dummyContext = {
i18n: {
language: "en",
},
};

Object.keys(pagesAndContexts).forEach((pageId) => {
nunjucksEnv.render(getIpvPageTemplatePath(pageId), dummyContext);
});
}
};