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 => { expect(cleanPreferences()).toEqual({ '*/*': 1, 'internal/*': 0 }); expect(cleanPreferences({})).toEqual(expect.objectContaining({ '*/*': 1, 'internal/*': 0 })); }); it('filters out internal types.', async(): Promise => { 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 => { 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 => { const preferences: ValuePreferences = { 'a/a': 0.8 }; expect(getTypeWeight('a/a', preferences)).toBe(0.8); }); it('returns the most specific weight.', async(): Promise => { 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 => { const preferences: ValuePreferences = { 'b/*': 0.5, 'c/c': 0.8 }; expect(getTypeWeight('a/a', preferences)).toBe(0); }); it('errors on invalid types.', async(): Promise => { 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 => { 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 => { 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 => { 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 => { 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 => { 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 => { 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 => { 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 => { 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 => { 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 => { 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 => { expect(matchesMediaPreferences('a/a')).toBe(true); }); it('does not match internal types if not in the preferences.', async(): Promise => { expect(matchesMediaPreferences('internal/b')).toBe(false); }); it('matches internal types if they are specifically requested.', async(): Promise => { 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 => { 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 => { expect(isInternalContentType('internal/quads')).toBeTruthy(); expect(isInternalContentType()).toBeFalsy(); expect(isInternalContentType('text/turtle')).toBeFalsy(); }); }); describe('#preferencesToString', (): void => { it('returns a string serialization.', async(): Promise => { 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'); }); }); });