CommunitySolidServer/test/unit/storage/conversion/ConstantConverter.test.ts
2021-05-20 11:09:25 +02:00

113 lines
5.1 KiB
TypeScript

import fs from 'fs';
import arrayifyStream from 'arrayify-stream';
import { RepresentationMetadata } from '../../../../src/ldp/representation/RepresentationMetadata';
import type { ConstantConverterOptions } from '../../../../src/storage/conversion/ConstantConverter';
import { ConstantConverter } from '../../../../src/storage/conversion/ConstantConverter';
const createReadStream = jest.spyOn(fs, 'createReadStream').mockReturnValue('file contents' as any);
describe('A ConstantConverter', (): void => {
const identifier = { path: 'identifier' };
let options: ConstantConverterOptions;
let converter: ConstantConverter;
beforeEach(async(): Promise<void> => {
options = { container: true, document: true, minQuality: 1 };
converter = new ConstantConverter('abc/def/index.html', 'text/html', options);
});
it('does not support requests without content type preferences.', async(): Promise<void> => {
const preferences = {};
const representation = {} as any;
const args = { identifier, representation, preferences };
await expect(converter.canHandle(args)).rejects.toThrow('No content type preferences specified');
});
it('does not support requests targeting documents if disabled in the options.', async(): Promise<void> => {
const preferences = { type: { 'text/html': 1 }};
const representation = { metadata: new RepresentationMetadata() } as any;
const args = { identifier, representation, preferences };
converter = new ConstantConverter('abc/def/index.html', 'text/html', { document: false });
await expect(converter.canHandle(args)).rejects.toThrow('Documents are not supported');
});
it('does not support requests targeting containers if disabled in the options.', async(): Promise<void> => {
const preferences = { type: { 'text/html': 1 }};
const representation = { metadata: new RepresentationMetadata() } as any;
const args = { identifier: { path: 'container/' }, representation, preferences };
converter = new ConstantConverter('abc/def/index.html', 'text/html', { container: false });
await expect(converter.canHandle(args)).rejects.toThrow('Containers are not supported');
});
it('does not support requests without matching content type preference.', async(): Promise<void> => {
const preferences = { type: { 'text/turtle': 1 }};
const representation = {} as any;
const args = { identifier, representation, preferences };
await expect(converter.canHandle(args)).rejects.toThrow('No preference for text/html');
});
it('does not support requests not reaching the minimum preference quality.', async(): Promise<void> => {
const preferences = { type: { 'text/html': 0.9 }};
const representation = {} as any;
const args = { identifier, representation, preferences };
await expect(converter.canHandle(args)).rejects.toThrow('Preference is lower than the specified minimum quality');
});
it('does not support representations that are already in the right format.', async(): Promise<void> => {
const preferences = { type: { 'text/html': 1 }};
const metadata = new RepresentationMetadata({ contentType: 'text/html' });
const representation = { metadata } as any;
const args = { identifier, representation, preferences };
await expect(converter.canHandle(args)).rejects.toThrow('Representation is already text/html');
});
it('supports representations with an unknown content type.', async(): Promise<void> => {
const preferences = { type: { 'text/html': 1 }};
const metadata = new RepresentationMetadata();
const representation = { metadata } as any;
const args = { identifier, representation, preferences };
await expect(converter.canHandle(args)).resolves.toBeUndefined();
});
it('replaces the representation of a supported request.', async(): Promise<void> => {
const preferences = { type: { 'text/html': 1 }};
const metadata = new RepresentationMetadata({ contentType: 'text/turtle' });
const representation = { metadata, data: { destroy: jest.fn() }} as any;
const args = { identifier, representation, preferences };
await expect(converter.canHandle(args)).resolves.toBeUndefined();
const converted = await converter.handle(args);
expect(representation.data.destroy).toHaveBeenCalledTimes(1);
expect(createReadStream).toHaveBeenCalledTimes(1);
expect(createReadStream).toHaveBeenCalledWith('abc/def/index.html', 'utf8');
expect(converted.metadata.contentType).toBe('text/html');
expect(await arrayifyStream(converted.data)).toEqual([ 'file contents' ]);
});
it('defaults to the most permissive options.', async(): Promise<void> => {
const preferences = { type: { 'text/html': 0.1 }};
const metadata = new RepresentationMetadata();
const representation = { metadata } as any;
const args = { identifier, representation, preferences };
converter = new ConstantConverter('abc/def/index.html', 'text/html');
await expect(converter.canHandle(args)).resolves.toBeUndefined();
args.identifier = { path: 'container/' };
await expect(converter.canHandle(args)).resolves.toBeUndefined();
});
});