Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix: change status code when ILC registry cannot render template #540

Merged
merged 2 commits into from
Oct 16, 2023
Merged
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 registry/server/templates/routes/getRenderedTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ async function getRenderedTemplate(req: Request<GetTemplateRenderedRequestParams
res.status(200).send(_.assign(template, renderedTemplate));
} catch (e) {
if (e instanceof errors.FetchIncludeError) {
res.status(503).send(e.message);
res.status(500).send(e.message);
noticeError(e, {
context: 'Error during fetch of the rendered template',
});
Expand Down
9 changes: 4 additions & 5 deletions registry/server/templates/services/renderTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,14 @@ type RenderTemplateResult = {
styleRefs: string[];
};

async function renderTemplate(template: string): Promise<RenderTemplateResult> {
if (!isTemplateValid(template)) {
async function renderTemplate(templateContent: string): Promise<RenderTemplateResult> {
if (!isTemplateValid(templateContent)) {
throw new Error('HTML template has invalid structure');
}

const includesAttributes = matchIncludesAttributes(template);

const includesAttributes = matchIncludesAttributes(templateContent);
const result: RenderTemplateResult = {
content: template,
content: templateContent,
styleRefs: [],
};

Expand Down
221 changes: 124 additions & 97 deletions registry/tests/templates.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ const example = {
'fr-CA': { content: '<html><head></head><body>Canada content</body></html>' },
},
}),
withInclude: Object.freeze({
name: 'ncTestTemplateNameWithInclude',
content:
'<html><head></head><body><include id="test-include" src="https://complete-random-ilc-include-test-domain.org.ote/include.html" timeout="100" />' +
'test content</body></html>',
}),
};

describe(`Tests ${example.url}`, () => {
Expand Down Expand Up @@ -170,103 +176,6 @@ describe(`Tests ${example.url}`, () => {
expect(response.body).deep.equal(example.correctLocalized);
});

it('should return a rendered template w/o authentication', async () => {
const includesHost = 'https://api.include.com';
const scope = nock(includesHost);

const includes = [
{
api: {
route: '/get/include/1',
delay: 0,
response: {
status: 200,
data: `
<div id="include-id-1">
This include has all necessary attributes
and a specified link header which is a stylesheet
</div>
`,
headers: {
'X-Powered-By': 'JS',
'X-My-Awesome-Header': 'Awesome',
Link: 'https://my.awesome.server/my-awesome-stylesheet.css;rel=stylesheet;loveyou=3000,https://my.awesome.server/my-awesome-script.js;rel=script;loveyou=3000',
},
},
},
attributes: {
id: 'include-id-1',
src: `${includesHost}/get/include/1`,
timeout: 1000,
},
},
];

const template = {
name: 'This template is for a render test',
content: `
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<include id="${includes[0].attributes.id}" src="${includes[0].attributes.src}" timeout="${includes[0].attributes.timeout}" />
<script>window.console.log('Something...')</script>
</head>
<body>
<div class="class-name-1">Something...</div>
<div id="div-id-1" class="class-name-2">Something...</div>
<div id="div-id-2" data-id="data-id-2" />
</body>
</html>
`,
};

includes.forEach(
({
api: {
route,
delay,
response: { status, data, headers },
},
}) => scope.persist().get(route).delay(delay).reply(status, data, headers),
);

try {
await req.post(example.url).send(template).expect(200);

const response = await reqWithAuth.get(example.url + template.name + '/rendered').expect(200);

expect(response.body).to.eql({
styleRefs: ['https://my.awesome.server/my-awesome-stylesheet.css'],
name: template.name,
content: `
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1"/>
${
`<!-- Template include "${includes[0].attributes.id}" START -->\n` +
'<link rel="stylesheet" href="https://my.awesome.server/my-awesome-stylesheet.css">\n' +
includes[0].api.response.data +
'\n' +
'<script src="https://my.awesome.server/my-awesome-script.js"></script>\n' +
`<!-- Template include "${includes[0].attributes.id}" END -->`
}
<script>window.console.log('Something...')</script>
</head>
<body>
<div class="class-name-1">Something...</div>
<div id="div-id-1" class="class-name-2">Something...</div>
<div id="div-id-2" data-id="data-id-2" />
</body>
</html>
`,
});
} finally {
await req.delete(example.url + template.name);
}
});

it('should return localized version of rendered template', async () => {
await withSetting(
SettingKeys.I18nSupportedLocales,
Expand Down Expand Up @@ -562,4 +471,122 @@ describe(`Tests ${example.url}`, () => {
});
});
});

describe('Rendered', () => {
it('should return HTTP 500 in case of inability to render template', async () => {
const setupIncludeResults = (delay: number) =>
nock('https://complete-random-ilc-include-test-domain.org.ote')
.get('/include.html')
.delay(delay)
.reply(200, '<div>test content</div>');
setupIncludeResults(10);
const creationResponse = await req.post(example.url).send(example.withInclude);
try {
expect(creationResponse.status).to.eq(200, creationResponse.text);
setupIncludeResults(1000); // should be bigger than timeout in HTML
const templateResponse = await req.get(example.url + example.withInclude.name + '/rendered');

expect(templateResponse.statusCode).to.equal(500);
} finally {
await req.delete(example.url + example.withInclude.name);
}
});

it('should return a rendered template w/o authentication', async () => {
const includesHost = 'https://api.include.com';
const scope = nock(includesHost);

const includes = [
{
api: {
route: '/get/include/1',
delay: 0,
response: {
status: 200,
data: `
<div id="include-id-1">
This include has all necessary attributes
and a specified link header which is a stylesheet
</div>
`,
headers: {
'X-Powered-By': 'JS',
'X-My-Awesome-Header': 'Awesome',
Link: 'https://my.awesome.server/my-awesome-stylesheet.css;rel=stylesheet;loveyou=3000,https://my.awesome.server/my-awesome-script.js;rel=script;loveyou=3000',
},
},
},
attributes: {
id: 'include-id-1',
src: `${includesHost}/get/include/1`,
timeout: 1000,
},
},
];

const template = {
name: 'This template is for a render test',
content: `
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<include id="${includes[0].attributes.id}" src="${includes[0].attributes.src}" timeout="${includes[0].attributes.timeout}" />
<script>window.console.log('Something...')</script>
</head>
<body>
<div class="class-name-1">Something...</div>
<div id="div-id-1" class="class-name-2">Something...</div>
<div id="div-id-2" data-id="data-id-2" />
</body>
</html>
`,
};

includes.forEach(
({
api: {
route,
delay,
response: { status, data, headers },
},
}) => scope.persist().get(route).delay(delay).reply(status, data, headers),
);

try {
await req.post(example.url).send(template).expect(200);

const response = await reqWithAuth.get(example.url + template.name + '/rendered').expect(200);

expect(response.body).to.eql({
styleRefs: ['https://my.awesome.server/my-awesome-stylesheet.css'],
name: template.name,
content: `
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1"/>
${
`<!-- Template include "${includes[0].attributes.id}" START -->\n` +
'<link rel="stylesheet" href="https://my.awesome.server/my-awesome-stylesheet.css">\n' +
includes[0].api.response.data +
'\n' +
'<script src="https://my.awesome.server/my-awesome-script.js"></script>\n' +
`<!-- Template include "${includes[0].attributes.id}" END -->`
}
<script>window.console.log('Something...')</script>
</head>
<body>
<div class="class-name-1">Something...</div>
<div id="div-id-1" class="class-name-2">Something...</div>
<div id="div-id-2" data-id="data-id-2" />
</body>
</html>
`,
});
} finally {
await req.delete(example.url + template.name);
}
});
});
});