mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Convert TemplateEngine to AsyncHandlers
This commit is contained in:
committed by
Joachim Van Herwegen
parent
a3c7baf6d3
commit
cf74ce3d2a
@@ -35,8 +35,8 @@ describe('An HtmlViewHandler', (): void => {
|
||||
};
|
||||
|
||||
templateEngine = {
|
||||
render: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
};
|
||||
handleSafe: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
} as any;
|
||||
|
||||
handler = new HtmlViewHandler(index, templateEngine, templates);
|
||||
});
|
||||
@@ -70,17 +70,23 @@ describe('An HtmlViewHandler', (): void => {
|
||||
const result = await handler.handle({ operation });
|
||||
expect(result.metadata.contentType).toBe(TEXT_HTML);
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render)
|
||||
.toHaveBeenLastCalledWith({ idpIndex, authenticating: false }, { templateFile: '/templates/login.html.ejs' });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe)
|
||||
.toHaveBeenLastCalledWith({
|
||||
contents: { idpIndex, authenticating: false },
|
||||
template: { templateFile: '/templates/login.html.ejs' },
|
||||
});
|
||||
});
|
||||
|
||||
it('sets authenticating to true if there is an active interaction.', async(): Promise<void> => {
|
||||
const result = await handler.handle({ operation, oidcInteraction: {} as any });
|
||||
expect(result.metadata.contentType).toBe(TEXT_HTML);
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render)
|
||||
.toHaveBeenLastCalledWith({ idpIndex, authenticating: true }, { templateFile: '/templates/login.html.ejs' });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe)
|
||||
.toHaveBeenLastCalledWith({
|
||||
contents: { idpIndex, authenticating: true },
|
||||
template: { templateFile: '/templates/login.html.ejs' },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,7 +28,7 @@ describe('A ForgotPasswordHandler', (): void => {
|
||||
} as any;
|
||||
|
||||
templateEngine = {
|
||||
render: jest.fn().mockResolvedValue(html),
|
||||
handleSafe: jest.fn().mockResolvedValue(html),
|
||||
} as any;
|
||||
|
||||
resetRoute = {
|
||||
|
||||
@@ -37,8 +37,8 @@ describe('A SetupHttpHandler', (): void => {
|
||||
};
|
||||
|
||||
templateEngine = {
|
||||
render: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
};
|
||||
handleSafe: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
} as any;
|
||||
|
||||
converter = {
|
||||
handleSafe: jest.fn((input: RepresentationConverterArgs): Representation => {
|
||||
|
||||
@@ -15,8 +15,8 @@ describe('A ContainerToTemplateConverter', (): void => {
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
templateEngine = {
|
||||
render: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
};
|
||||
handleSafe: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
} as any;
|
||||
converter = new ContainerToTemplateConverter(templateEngine, 'text/html', identifierStrategy);
|
||||
});
|
||||
|
||||
@@ -51,50 +51,52 @@ describe('A ContainerToTemplateConverter', (): void => {
|
||||
expect(converted.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(converted.data)).resolves.toBe('<html>');
|
||||
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render).toHaveBeenCalledWith({
|
||||
identifier: container.path,
|
||||
name: 'my-container',
|
||||
container: true,
|
||||
children: [
|
||||
{
|
||||
identifier: `${container.path}d/`,
|
||||
name: 'd',
|
||||
container: true,
|
||||
},
|
||||
{
|
||||
identifier: `${container.path}a`,
|
||||
name: 'a',
|
||||
container: false,
|
||||
},
|
||||
{
|
||||
identifier: `${container.path}b`,
|
||||
name: 'b',
|
||||
container: false,
|
||||
},
|
||||
{
|
||||
identifier: `${container.path}c%20c`,
|
||||
name: 'c c',
|
||||
container: false,
|
||||
},
|
||||
],
|
||||
parents: [
|
||||
{
|
||||
identifier: 'http://test.com/',
|
||||
name: 'test.com',
|
||||
container: true,
|
||||
},
|
||||
{
|
||||
identifier: 'http://test.com/foo/',
|
||||
name: 'foo',
|
||||
container: true,
|
||||
},
|
||||
{
|
||||
identifier: 'http://test.com/foo/bar/',
|
||||
name: 'bar',
|
||||
container: true,
|
||||
},
|
||||
],
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledWith({
|
||||
contents: {
|
||||
identifier: container.path,
|
||||
name: 'my-container',
|
||||
container: true,
|
||||
children: [
|
||||
{
|
||||
identifier: `${container.path}d/`,
|
||||
name: 'd',
|
||||
container: true,
|
||||
},
|
||||
{
|
||||
identifier: `${container.path}a`,
|
||||
name: 'a',
|
||||
container: false,
|
||||
},
|
||||
{
|
||||
identifier: `${container.path}b`,
|
||||
name: 'b',
|
||||
container: false,
|
||||
},
|
||||
{
|
||||
identifier: `${container.path}c%20c`,
|
||||
name: 'c c',
|
||||
container: false,
|
||||
},
|
||||
],
|
||||
parents: [
|
||||
{
|
||||
identifier: 'http://test.com/',
|
||||
name: 'test.com',
|
||||
container: true,
|
||||
},
|
||||
{
|
||||
identifier: 'http://test.com/foo/',
|
||||
name: 'foo',
|
||||
container: true,
|
||||
},
|
||||
{
|
||||
identifier: 'http://test.com/foo/bar/',
|
||||
name: 'bar',
|
||||
container: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -108,13 +110,15 @@ describe('A ContainerToTemplateConverter', (): void => {
|
||||
], 'internal/quads', false);
|
||||
await converter.handle({ identifier: container, representation, preferences });
|
||||
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render).toHaveBeenCalledWith({
|
||||
identifier: container.path,
|
||||
name: 'test.com',
|
||||
container: true,
|
||||
children: expect.objectContaining({ length: 3 }),
|
||||
parents: [],
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledWith({
|
||||
contents: {
|
||||
identifier: container.path,
|
||||
name: 'test.com',
|
||||
container: true,
|
||||
children: expect.objectContaining({ length: 3 }),
|
||||
parents: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -124,13 +128,15 @@ describe('A ContainerToTemplateConverter', (): void => {
|
||||
jest.spyOn(identifierStrategy, 'isRootContainer').mockReturnValueOnce(true);
|
||||
await converter.handle({ identifier: container, representation, preferences });
|
||||
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render).toHaveBeenCalledWith({
|
||||
identifier: container.path,
|
||||
name: container.path,
|
||||
container: true,
|
||||
children: [],
|
||||
parents: [],
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledWith({
|
||||
contents: {
|
||||
identifier: container.path,
|
||||
name: container.path,
|
||||
container: true,
|
||||
children: [],
|
||||
parents: [],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -33,8 +33,8 @@ describe('A DynamicJsonToTemplateConverter', (): void => {
|
||||
input = { identifier, representation, preferences };
|
||||
|
||||
templateEngine = {
|
||||
render: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
};
|
||||
handleSafe: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
} as any;
|
||||
converter = new DynamicJsonToTemplateConverter(templateEngine);
|
||||
});
|
||||
|
||||
@@ -63,8 +63,8 @@ describe('A DynamicJsonToTemplateConverter', (): void => {
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render).toHaveBeenLastCalledWith({ json: true }, { templateFile });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe).toHaveBeenLastCalledWith({ contents: { json: true }, template: { templateFile }});
|
||||
});
|
||||
|
||||
it('supports missing type preferences.', async(): Promise<void> => {
|
||||
|
||||
@@ -18,8 +18,8 @@ describe('An ErrorToTemplateConverter', (): void => {
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
templateEngine = {
|
||||
render: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
};
|
||||
handleSafe: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
} as any;
|
||||
converter = new ErrorToTemplateConverter(templateEngine,
|
||||
{ mainTemplatePath, codeTemplatesPath, extension, contentType });
|
||||
});
|
||||
@@ -38,31 +38,33 @@ describe('An ErrorToTemplateConverter', (): void => {
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render).toHaveBeenLastCalledWith(
|
||||
{ name: 'Error', message: 'error text', stack: error.stack },
|
||||
{ templateFile: mainTemplatePath },
|
||||
);
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe).toHaveBeenLastCalledWith({
|
||||
contents: { name: 'Error', message: 'error text', stack: error.stack },
|
||||
template: { templateFile: mainTemplatePath },
|
||||
});
|
||||
});
|
||||
|
||||
it('calls the template engine with all HTTP error fields.', async(): Promise<void> => {
|
||||
const error = new BadRequestHttpError('error text');
|
||||
const representation = new BasicRepresentation([ error ], 'internal/error', false);
|
||||
const prom = converter.handle({ identifier, representation, preferences });
|
||||
templateEngine.render.mockRejectedValueOnce(new Error('error-specific template not found'));
|
||||
templateEngine.handleSafe.mockRejectedValueOnce(new Error('error-specific template not found'));
|
||||
await expect(prom).resolves.toBeDefined();
|
||||
|
||||
const result = await prom;
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(1,
|
||||
{},
|
||||
{ templatePath: '/templates/codes', templateFile: 'H400.html' });
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(2,
|
||||
{ name: 'BadRequestHttpError', message: 'error text', stack: error.stack },
|
||||
{ templateFile: mainTemplatePath });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(1, {
|
||||
contents: {},
|
||||
template: { templatePath: '/templates/codes', templateFile: 'H400.html' },
|
||||
});
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(2, {
|
||||
contents: { name: 'BadRequestHttpError', message: 'error text', stack: error.stack },
|
||||
template: { templateFile: mainTemplatePath },
|
||||
});
|
||||
});
|
||||
|
||||
it('only adds stack if it is defined.', async(): Promise<void> => {
|
||||
@@ -70,20 +72,22 @@ describe('An ErrorToTemplateConverter', (): void => {
|
||||
delete error.stack;
|
||||
const representation = new BasicRepresentation([ error ], 'internal/error', false);
|
||||
const prom = converter.handle({ identifier, representation, preferences });
|
||||
templateEngine.render.mockRejectedValueOnce(new Error('error-specific template not found'));
|
||||
templateEngine.handleSafe.mockRejectedValueOnce(new Error('error-specific template not found'));
|
||||
await expect(prom).resolves.toBeDefined();
|
||||
|
||||
const result = await prom;
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(1,
|
||||
{},
|
||||
{ templatePath: '/templates/codes', templateFile: 'H400.html' });
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(2,
|
||||
{ name: 'BadRequestHttpError', message: 'error text' },
|
||||
{ templateFile: mainTemplatePath });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(1, {
|
||||
contents: {},
|
||||
template: { templatePath: '/templates/codes', templateFile: 'H400.html' },
|
||||
});
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(2, {
|
||||
contents: { name: 'BadRequestHttpError', message: 'error text' },
|
||||
template: { templateFile: mainTemplatePath },
|
||||
});
|
||||
});
|
||||
|
||||
it('adds additional information if an error code description is found.', async(): Promise<void> => {
|
||||
@@ -95,13 +99,15 @@ describe('An ErrorToTemplateConverter', (): void => {
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(1,
|
||||
{ key: 'val' },
|
||||
{ templatePath: '/templates/codes', templateFile: 'E0001.html' });
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(2,
|
||||
{ name: 'BadRequestHttpError', message: 'error text', stack: error.stack, description: '<html>' },
|
||||
{ templateFile: mainTemplatePath });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(1, {
|
||||
contents: { key: 'val' },
|
||||
template: { templatePath: '/templates/codes', templateFile: 'E0001.html' },
|
||||
});
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(2, {
|
||||
contents: { name: 'BadRequestHttpError', message: 'error text', stack: error.stack, description: '<html>' },
|
||||
template: { templateFile: mainTemplatePath },
|
||||
});
|
||||
});
|
||||
|
||||
it('sends an empty object for additional error code parameters if none are defined.', async(): Promise<void> => {
|
||||
@@ -114,33 +120,37 @@ describe('An ErrorToTemplateConverter', (): void => {
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(1,
|
||||
{},
|
||||
{ templatePath: '/templates/codes', templateFile: 'E0001.html' });
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(2,
|
||||
{ name: 'BadRequestHttpError', message: 'error text', stack: error.stack, description: '<html>' },
|
||||
{ templateFile: mainTemplatePath });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(1, {
|
||||
contents: {},
|
||||
template: { templatePath: '/templates/codes', templateFile: 'E0001.html' },
|
||||
});
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(2, {
|
||||
contents: { name: 'BadRequestHttpError', message: 'error text', stack: error.stack, description: '<html>' },
|
||||
template: { templateFile: mainTemplatePath },
|
||||
});
|
||||
});
|
||||
|
||||
it('converts errors with a code as usual if no corresponding template is found.', async(): Promise<void> => {
|
||||
const error = new BadRequestHttpError('error text', { errorCode: 'invalid' });
|
||||
const representation = new BasicRepresentation([ error ], 'internal/error', false);
|
||||
const prom = converter.handle({ identifier, representation, preferences });
|
||||
templateEngine.render.mockRejectedValueOnce(new Error('error-specific template not found'));
|
||||
templateEngine.handleSafe.mockRejectedValueOnce(new Error('error-specific template not found'));
|
||||
await expect(prom).resolves.toBeDefined();
|
||||
|
||||
const result = await prom;
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(1,
|
||||
{},
|
||||
{ templatePath: '/templates/codes', templateFile: 'invalid.html' });
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(2,
|
||||
{ name: 'BadRequestHttpError', message: 'error text', stack: error.stack },
|
||||
{ templateFile: mainTemplatePath });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(1, {
|
||||
contents: {},
|
||||
template: { templatePath: '/templates/codes', templateFile: 'invalid.html' },
|
||||
});
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(2, {
|
||||
contents: { name: 'BadRequestHttpError', message: 'error text', stack: error.stack },
|
||||
template: { templateFile: mainTemplatePath },
|
||||
});
|
||||
});
|
||||
|
||||
it('has default template options.', async(): Promise<void> => {
|
||||
@@ -153,12 +163,14 @@ describe('An ErrorToTemplateConverter', (): void => {
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/markdown');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(1,
|
||||
{ key: 'val' },
|
||||
{ templatePath: resolveModulePath('templates/error/descriptions/'), templateFile: 'E0001.md.hbs' });
|
||||
expect(templateEngine.render).toHaveBeenNthCalledWith(2,
|
||||
{ name: 'BadRequestHttpError', message: 'error text', stack: error.stack, description: '<html>' },
|
||||
{ templateFile: resolveModulePath('templates/error/main.md.hbs') });
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(2);
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(1, {
|
||||
contents: { key: 'val' },
|
||||
template: { templatePath: resolveModulePath('templates/error/descriptions/'), templateFile: 'E0001.md.hbs' },
|
||||
});
|
||||
expect(templateEngine.handleSafe).toHaveBeenNthCalledWith(2, {
|
||||
contents: { name: 'BadRequestHttpError', message: 'error text', stack: error.stack, description: '<html>' },
|
||||
template: { templateFile: resolveModulePath('templates/error/main.md.hbs') },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,8 +11,8 @@ describe('A MarkdownToHtmlConverter', (): void => {
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
templateEngine = {
|
||||
render: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
};
|
||||
handleSafe: jest.fn().mockReturnValue(Promise.resolve('<html>')),
|
||||
} as any;
|
||||
converter = new MarkdownToHtmlConverter(templateEngine);
|
||||
});
|
||||
|
||||
@@ -29,9 +29,9 @@ describe('A MarkdownToHtmlConverter', (): void => {
|
||||
expect(result.binary).toBe(true);
|
||||
expect(result.metadata.contentType).toBe('text/html');
|
||||
await expect(readableToString(result.data)).resolves.toBe('<html>');
|
||||
expect(templateEngine.render).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.render).toHaveBeenLastCalledWith(
|
||||
{ htmlBody: '<p>Text <code>code</code> more text.</p>\n' },
|
||||
expect(templateEngine.handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handleSafe).toHaveBeenLastCalledWith(
|
||||
{ contents: { htmlBody: '<p>Text <code>code</code> more text.</p>\n' }},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,13 +4,20 @@ import type { TemplateEngine } from '../../../../src/util/templates/TemplateEngi
|
||||
describe('A ChainedTemplateEngine', (): void => {
|
||||
const contents = { title: 'myTitle' };
|
||||
const template = { templateFile: '/template.tmpl' };
|
||||
const input = { contents, template };
|
||||
let engines: jest.Mocked<TemplateEngine>[];
|
||||
let engine: ChainedTemplateEngine;
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
engines = [
|
||||
{ render: jest.fn().mockResolvedValue('body1') },
|
||||
{ render: jest.fn().mockResolvedValue('body2') },
|
||||
{
|
||||
canHandle: jest.fn(),
|
||||
handle: jest.fn().mockResolvedValue('body1'),
|
||||
} as any,
|
||||
{
|
||||
canHandle: jest.fn(),
|
||||
handleSafe: jest.fn().mockResolvedValue('body2'),
|
||||
} as any,
|
||||
];
|
||||
|
||||
engine = new ChainedTemplateEngine(engines);
|
||||
@@ -21,19 +28,19 @@ describe('A ChainedTemplateEngine', (): void => {
|
||||
});
|
||||
|
||||
it('chains the engines.', async(): Promise<void> => {
|
||||
await expect(engine.render(contents, template)).resolves.toBe('body2');
|
||||
expect(engines[0].render).toHaveBeenCalledTimes(1);
|
||||
expect(engines[0].render).toHaveBeenLastCalledWith(contents, template);
|
||||
expect(engines[1].render).toHaveBeenCalledTimes(1);
|
||||
expect(engines[1].render).toHaveBeenLastCalledWith({ ...contents, body: 'body1' });
|
||||
await expect(engine.handleSafe(input)).resolves.toBe('body2');
|
||||
expect(engines[0].handle).toHaveBeenCalledTimes(1);
|
||||
expect(engines[0].handle).toHaveBeenLastCalledWith(input);
|
||||
expect(engines[1].handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(engines[1].handleSafe).toHaveBeenLastCalledWith({ contents: { ...contents, body: 'body1' }});
|
||||
});
|
||||
|
||||
it('can use a different field to pass along the body.', async(): Promise<void> => {
|
||||
engine = new ChainedTemplateEngine(engines, 'different');
|
||||
await expect(engine.render(contents, template)).resolves.toBe('body2');
|
||||
expect(engines[0].render).toHaveBeenCalledTimes(1);
|
||||
expect(engines[0].render).toHaveBeenLastCalledWith(contents, template);
|
||||
expect(engines[1].render).toHaveBeenCalledTimes(1);
|
||||
expect(engines[1].render).toHaveBeenLastCalledWith({ ...contents, different: 'body1' });
|
||||
await expect(engine.handleSafe(input)).resolves.toBe('body2');
|
||||
expect(engines[0].handle).toHaveBeenCalledTimes(1);
|
||||
expect(engines[0].handle).toHaveBeenLastCalledWith(input);
|
||||
expect(engines[1].handleSafe).toHaveBeenCalledTimes(1);
|
||||
expect(engines[1].handleSafe).toHaveBeenLastCalledWith({ contents: { ...contents, different: 'body1' }});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError';
|
||||
import { EjsTemplateEngine } from '../../../../src/util/templates/EjsTemplateEngine';
|
||||
|
||||
jest.mock('../../../../src/util/templates/TemplateEngine', (): any => ({
|
||||
getTemplateFilePath: jest.fn((): string => `filename`),
|
||||
readTemplate: jest.fn(async({ templateString }): Promise<string> => `${templateString}: <%= detail %>`),
|
||||
jest.mock('../../../../src/util/templates/TemplateUtil', (): any => ({
|
||||
getTemplateFilePath: jest.fn((template): string => template),
|
||||
readTemplate: jest.fn(async(): Promise<string> => `<%= detail %>`),
|
||||
}));
|
||||
|
||||
describe('A EjsTemplateEngine', (): void => {
|
||||
const defaultTemplate = { templateString: 'xyz' };
|
||||
const contents = { detail: 'a&b' };
|
||||
let templateEngine: EjsTemplateEngine;
|
||||
|
||||
beforeEach((): void => {
|
||||
templateEngine = new EjsTemplateEngine('http://localhost:3000', defaultTemplate);
|
||||
});
|
||||
|
||||
it('uses the default template when no template was passed.', async(): Promise<void> => {
|
||||
await expect(templateEngine.render(contents)).resolves.toBe('xyz: a&b');
|
||||
templateEngine = new EjsTemplateEngine('http://localhost:3000');
|
||||
});
|
||||
|
||||
it('uses the passed template.', async(): Promise<void> => {
|
||||
await expect(templateEngine.render(contents, { templateString: 'my' })).resolves.toBe('my: a&b');
|
||||
await expect(templateEngine.handleSafe({ contents, template: 'someTemplate.ejs' }))
|
||||
.resolves.toBe('a&b');
|
||||
});
|
||||
|
||||
it('throws an exception for unsupported template files.', async(): Promise<void> => {
|
||||
await expect(templateEngine.handleSafe({ contents, template: 'someTemplate.txt' }))
|
||||
.rejects.toThrow(NotImplementedHttpError);
|
||||
});
|
||||
|
||||
it('throws an exception if no template was passed.', async(): Promise<void> => {
|
||||
await expect(templateEngine.handleSafe({ contents }))
|
||||
.rejects.toThrow(NotImplementedHttpError);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,23 +1,31 @@
|
||||
import { NotImplementedHttpError } from '../../../../src';
|
||||
import { HandlebarsTemplateEngine } from '../../../../src/util/templates/HandlebarsTemplateEngine';
|
||||
|
||||
jest.mock('../../../../src/util/templates/TemplateEngine', (): any => ({
|
||||
readTemplate: jest.fn(async({ templateString }): Promise<string> => `${templateString}: {{detail}}`),
|
||||
jest.mock('../../../../src/util/templates/TemplateUtil', (): any => ({
|
||||
getTemplateFilePath: jest.fn((template): string => template),
|
||||
readTemplate: jest.fn(async(): Promise<string> => `{{detail}}`),
|
||||
}));
|
||||
|
||||
describe('A HandlebarsTemplateEngine', (): void => {
|
||||
const template = { templateString: 'xyz' };
|
||||
const contents = { detail: 'a&b' };
|
||||
let templateEngine: HandlebarsTemplateEngine;
|
||||
|
||||
beforeEach((): void => {
|
||||
templateEngine = new HandlebarsTemplateEngine('http://localhost:3000/', template);
|
||||
});
|
||||
|
||||
it('uses the default template when no template was passed.', async(): Promise<void> => {
|
||||
await expect(templateEngine.render(contents)).resolves.toBe('xyz: a&b');
|
||||
templateEngine = new HandlebarsTemplateEngine('http://localhost:3000/');
|
||||
});
|
||||
|
||||
it('uses the passed template.', async(): Promise<void> => {
|
||||
await expect(templateEngine.render(contents, { templateString: 'my' })).resolves.toBe('my: a&b');
|
||||
await expect(templateEngine.handleSafe({ contents, template: 'someTemplate.hbs' }))
|
||||
.resolves.toBe('a&b');
|
||||
});
|
||||
|
||||
it('throws an exception for unsupported template files.', async(): Promise<void> => {
|
||||
await expect(templateEngine.handleSafe({ contents, template: 'someTemplate.txt' }))
|
||||
.rejects.toThrow(NotImplementedHttpError);
|
||||
});
|
||||
|
||||
it('throws an exception if no template was passed.', async(): Promise<void> => {
|
||||
await expect(templateEngine.handleSafe({ contents }))
|
||||
.rejects.toThrow(NotImplementedHttpError);
|
||||
});
|
||||
});
|
||||
|
||||
47
test/unit/util/templates/StaticTemplateEngine.test.ts
Normal file
47
test/unit/util/templates/StaticTemplateEngine.test.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import { StaticTemplateEngine, NotFoundHttpError } from '../../../../src';
|
||||
import type { AsyncHandler, TemplateEngineInput } from '../../../../src';
|
||||
import Dict = NodeJS.Dict;
|
||||
|
||||
describe('A StaticTemplateEngine', (): void => {
|
||||
let templateEngine: jest.Mocked<AsyncHandler<TemplateEngineInput<Dict<any>>, string>>;
|
||||
|
||||
it('forwards calls to the handle method of the provided templateEngine, adding the template as an argument.',
|
||||
async(): Promise<void> => {
|
||||
templateEngine = {
|
||||
canHandle: jest.fn(),
|
||||
handle: jest.fn().mockResolvedValue(''),
|
||||
} as any;
|
||||
const input = { contents: {}};
|
||||
const engine = new StaticTemplateEngine(templateEngine, 'template');
|
||||
await expect(engine.handleSafe(input)).resolves.toBe('');
|
||||
expect(templateEngine.canHandle).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.canHandle).toHaveBeenLastCalledWith({ contents: {}, template: 'template' });
|
||||
expect(templateEngine.handle).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handle).toHaveBeenLastCalledWith({ contents: {}, template: 'template' });
|
||||
});
|
||||
|
||||
it('propagates errors that occur in the handle method of the provided handler.', async(): Promise<void> => {
|
||||
templateEngine = {
|
||||
canHandle: jest.fn(),
|
||||
handle: jest.fn().mockRejectedValue(new NotFoundHttpError()),
|
||||
} as any;
|
||||
const input = { contents: {}};
|
||||
const engine = new StaticTemplateEngine(templateEngine, 'template');
|
||||
await expect(engine.handleSafe(input)).rejects.toThrow(NotFoundHttpError);
|
||||
expect(templateEngine.canHandle).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.canHandle).toHaveBeenLastCalledWith({ contents: input.contents, template: 'template' });
|
||||
expect(templateEngine.handle).toHaveBeenCalledTimes(1);
|
||||
expect(templateEngine.handle).toHaveBeenLastCalledWith({ contents: input.contents, template: 'template' });
|
||||
});
|
||||
|
||||
it('results in an error when calling handle with template defined.', async(): Promise<void> => {
|
||||
templateEngine = {
|
||||
canHandle: jest.fn(),
|
||||
handle: jest.fn().mockResolvedValue(''),
|
||||
} as any;
|
||||
const input = { contents: {}, template: 'template2' };
|
||||
const engine = new StaticTemplateEngine(templateEngine, 'template1');
|
||||
await expect(engine.handleSafe(input)).rejects
|
||||
.toThrow('StaticTemplateEngine does not support template as handle input');
|
||||
});
|
||||
});
|
||||
@@ -1,10 +1,10 @@
|
||||
import { resolveAssetPath } from '../../../../src/util/PathUtil';
|
||||
import { getTemplateFilePath, readTemplate } from '../../../../src/util/templates/TemplateEngine';
|
||||
import { getTemplateFilePath, readTemplate } from '../../../../src/util/templates/TemplateUtil';
|
||||
import { mockFileSystem } from '../../../util/Util';
|
||||
|
||||
jest.mock('fs');
|
||||
|
||||
describe('TemplateEngine', (): void => {
|
||||
describe('TemplateUtil', (): void => {
|
||||
describe('#getTemplateFilePath', (): void => {
|
||||
const templateFile = 'template.xyz';
|
||||
const templatePath = 'other';
|
||||
Reference in New Issue
Block a user