Joachim Van Herwegen 90a6460c8d Merge branch 'main' into versions/3.0.0
# Conflicts:
#	package-lock.json
#	test/integration/Identity.test.ts
#	test/integration/RepresentationConverter.test.ts
2022-01-25 11:44:24 +01:00

164 lines
7.1 KiB
TypeScript

import type { ValuePreferences } from '../../../../src/http/representation/RepresentationPreferences';
import {
cleanPreferences,
getBestPreference,
getConversionTarget,
getTypeWeight,
getWeightedPreferences, isInternalContentType,
matchesMediaPreferences,
matchesMediaType, preferencesToString,
} from '../../../../src/storage/conversion/ConversionUtil';
import { InternalServerError } from '../../../../src/util/errors/InternalServerError';
describe('ConversionUtil', (): void => {
describe('#cleanPreferences', (): void => {
it('supports all types for empty preferences.', async(): Promise<void> => {
expect(cleanPreferences()).toEqual({ '*/*': 1, 'internal/*': 0 });
expect(cleanPreferences({})).toEqual(expect.objectContaining({ '*/*': 1, 'internal/*': 0 }));
});
it('filters out internal types.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/a': 1 };
expect(cleanPreferences(preferences)).toEqual({ 'a/a': 1, 'internal/*': 0 });
});
it('keeps internal types that are specifically requested.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/a': 1, 'internal/*': 0.5 };
expect(cleanPreferences(preferences)).toEqual({ 'a/a': 1, 'internal/*': 0.5 });
});
});
describe('#getTypeWeight', (): void => {
it('returns the matching weight from the preferences.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/a': 0.8 };
expect(getTypeWeight('a/a', preferences)).toBe(0.8);
});
it('returns the most specific weight.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/*': 0.5, '*/*': 0.8 };
expect(getTypeWeight('a/a', preferences)).toBe(0.5);
});
it('returns 0 if no match is possible.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'b/*': 0.5, 'c/c': 0.8 };
expect(getTypeWeight('a/a', preferences)).toBe(0);
});
it('errors on invalid types.', async(): Promise<void> => {
expect((): any => getTypeWeight('unknown', {})).toThrow(InternalServerError);
expect((): any => getTypeWeight('unknown', {})).toThrow('Unexpected media type: unknown.');
});
});
describe('#getWeightedPreferences', (): void => {
it('returns all weights in a sorted list.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'b/b': 1, 'c/c': 0.8 };
const preferences: ValuePreferences = { 'a/*': 1, 'c/c': 0.8 };
expect(getWeightedPreferences(types, preferences)).toEqual([
{ value: 'c/c', weight: 0.8 * 0.8 },
{ value: 'a/a', weight: 0.5 },
{ value: 'b/b', weight: 0 },
]);
});
});
describe('#getBestPreference', (): void => {
it('returns the best match.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'b/b': 1, 'c/c': 0.8 };
const preferences: ValuePreferences = { 'a/*': 1, 'c/c': 0.8 };
expect(getBestPreference(types, preferences)).toEqual({ value: 'c/c', weight: 0.8 * 0.8 });
});
it('returns undefined if there is no match.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'b/b': 1, 'c/c': 0.8 };
const preferences: ValuePreferences = { 'd/*': 1, 'e/e': 0.8 };
expect(getBestPreference(types, preferences)).toBeUndefined();
});
});
describe('#getConversionTarget', (): void => {
it('returns the best match.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'b/b': 1, 'c/c': 0.8 };
const preferences: ValuePreferences = { 'a/*': 1, 'c/c': 0.8 };
expect(getConversionTarget(types, preferences)).toBe('c/c');
});
it('matches anything if there are no preferences.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'b/b': 1, 'c/c': 0.8 };
expect(getConversionTarget(types)).toBe('b/b');
});
it('returns undefined if there is no match.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'b/b': 1, 'c/c': 0.8 };
const preferences: ValuePreferences = { 'd/*': 1, 'e/e': 0.8 };
expect(getConversionTarget(types, preferences)).toBeUndefined();
});
it('does not match internal types if not in the preferences.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'internal/b': 1, 'c/c': 0.8 };
expect(getConversionTarget(types)).toBe('c/c');
});
it('matches internal types if they are specifically requested.', async(): Promise<void> => {
const types: ValuePreferences = { 'a/a': 0.5, 'internal/b': 1, 'c/c': 0.8 };
const preferences: ValuePreferences = { 'a/*': 1, 'internal/b': 1, 'c/c': 0.8 };
expect(getConversionTarget(types, preferences)).toBe('internal/b');
});
});
describe('#matchesMediaPreferences', (): void => {
it('returns false if there are no matches.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/x': 1, 'b/x': 0.5, 'c/x': 0 };
expect(matchesMediaPreferences('c/x', preferences)).toBe(false);
});
it('returns true if there are matches.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/x': 1, 'b/x': 0.5, 'c/x': 0 };
expect(matchesMediaPreferences('b/x', preferences)).toBe(true);
});
it('matches anything if there are no preferences.', async(): Promise<void> => {
expect(matchesMediaPreferences('a/a')).toBe(true);
});
it('does not match internal types if not in the preferences.', async(): Promise<void> => {
expect(matchesMediaPreferences('internal/b')).toBe(false);
});
it('matches internal types if they are specifically requested.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/*': 1, 'internal/b': 1, 'c/c': 0.8 };
expect(matchesMediaPreferences('internal/b', preferences)).toBe(true);
});
});
describe('#matchesMediaType', (): void => {
it('matches all possible media types.', async(): Promise<void> => {
expect(matchesMediaType('*/*', 'text/turtle')).toBeTruthy();
expect(matchesMediaType('text/*', '*/*')).toBeTruthy();
expect(matchesMediaType('text/*', 'text/turtle')).toBeTruthy();
expect(matchesMediaType('text/plain', 'text/*')).toBeTruthy();
expect(matchesMediaType('text/turtle', 'text/turtle')).toBeTruthy();
expect(matchesMediaType('text/*', 'application/*')).toBeFalsy();
expect(matchesMediaType('text/plain', 'application/*')).toBeFalsy();
expect(matchesMediaType('text/plain', 'text/turtle')).toBeFalsy();
});
});
describe('#isInternalContentType', (): void => {
it('only returns true on internal types.', async(): Promise<void> => {
expect(isInternalContentType('internal/quads')).toBeTruthy();
expect(isInternalContentType()).toBeFalsy();
expect(isInternalContentType('text/turtle')).toBeFalsy();
});
});
describe('#preferencesToString', (): void => {
it('returns a string serialization.', async(): Promise<void> => {
const preferences: ValuePreferences = { 'a/*': 1, 'b/b': 0.8, 'c/c': 0 };
expect(preferencesToString(preferences)).toBe('a/*:1,b/b:0.8,c/c:0');
});
});
});