mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Make internal/quads unacceptable output
This commit is contained in:
parent
69ed2e069f
commit
715ba126f9
@ -1,5 +1,6 @@
|
||||
import type { RepresentationPreference } from '../../ldp/representation/RepresentationPreference';
|
||||
import type { RepresentationPreferences } from '../../ldp/representation/RepresentationPreferences';
|
||||
import { INTERNAL_ALL } from '../../util/ContentTypes';
|
||||
import { InternalServerError } from '../../util/errors/InternalServerError';
|
||||
import { UnsupportedHttpError } from '../../util/errors/UnsupportedHttpError';
|
||||
import { matchingMediaType } from '../../util/Util';
|
||||
@ -8,6 +9,9 @@ import type { RepresentationConverterArgs } from './RepresentationConverter';
|
||||
/**
|
||||
* Filters media types based on the given preferences.
|
||||
* Based on RFC 7231 - Content negotiation.
|
||||
* Will add a default `internal/*;q=0` to the preferences to prevent accidental use of internal types.
|
||||
* Since more specific media ranges override less specific ones,
|
||||
* this will be ignored if there is a specific internal type preference.
|
||||
*
|
||||
* @param preferences - Preferences for output type.
|
||||
* @param types - Media types to compare to the preferences.
|
||||
@ -31,6 +35,11 @@ RepresentationPreference[] => {
|
||||
return map;
|
||||
}, {});
|
||||
|
||||
// Prevent accidental use of internal types
|
||||
if (!prefMap[INTERNAL_ALL]) {
|
||||
prefMap[INTERNAL_ALL] = 0;
|
||||
}
|
||||
|
||||
// RFC 7231
|
||||
// Media ranges can be overridden by more specific media ranges or
|
||||
// specific media types. If more than one media range applies to a
|
||||
|
@ -4,4 +4,5 @@ export const APPLICATION_OCTET_STREAM = 'application/octet-stream';
|
||||
export const APPLICATION_SPARQL_UPDATE = 'application/sparql-update';
|
||||
|
||||
// Internal (non-exposed) content types
|
||||
export const INTERNAL_ALL = 'internal/*';
|
||||
export const INTERNAL_QUADS = 'internal/quads';
|
||||
|
@ -19,22 +19,22 @@ describe('A ConversionUtil', (): void => {
|
||||
describe('#checkRequest', (): void => {
|
||||
it('requires an input type.', async(): Promise<void> => {
|
||||
const preferences: RepresentationPreferences = {};
|
||||
expect((): any => checkRequest({ identifier, representation, preferences }, [ '*/*' ], [ '*/*' ]))
|
||||
expect((): any => checkRequest({ identifier, representation, preferences }, [ 'a/x' ], [ 'a/x' ]))
|
||||
.toThrow('Input type required for conversion.');
|
||||
});
|
||||
|
||||
it('requires a matching input type.', async(): Promise<void> => {
|
||||
metadata.contentType = 'a/x';
|
||||
const preferences: RepresentationPreferences = { type: [{ value: 'b/x', weight: 1 }]};
|
||||
expect((): any => checkRequest({ identifier, representation, preferences }, [ 'c/x' ], [ '*/*' ]))
|
||||
.toThrow('Can only convert from c/x to */*.');
|
||||
expect((): any => checkRequest({ identifier, representation, preferences }, [ 'c/x' ], [ 'a/x' ]))
|
||||
.toThrow('Can only convert from c/x to a/x.');
|
||||
});
|
||||
|
||||
it('requires a matching output type.', async(): Promise<void> => {
|
||||
metadata.contentType = 'a/x';
|
||||
const preferences: RepresentationPreferences = { type: [{ value: 'b/x', weight: 1 }]};
|
||||
expect((): any => checkRequest({ identifier, representation, preferences }, [ '*/*' ], [ 'c/x' ]))
|
||||
.toThrow('Can only convert from */* to c/x.');
|
||||
expect((): any => checkRequest({ identifier, representation, preferences }, [ 'a/x' ], [ 'c/x' ]))
|
||||
.toThrow('Can only convert from a/x to c/x.');
|
||||
});
|
||||
|
||||
it('succeeds with a valid input and output type.', async(): Promise<void> => {
|
||||
@ -48,7 +48,7 @@ describe('A ConversionUtil', (): void => {
|
||||
describe('#matchingTypes', (): void => {
|
||||
it('requires type preferences.', async(): Promise<void> => {
|
||||
const preferences: RepresentationPreferences = {};
|
||||
expect((): any => matchingTypes(preferences, [ '*/*' ]))
|
||||
expect((): any => matchingTypes(preferences, [ 'a/b' ]))
|
||||
.toThrow('Output type required for conversion.');
|
||||
});
|
||||
|
||||
@ -71,5 +71,24 @@ describe('A ConversionUtil', (): void => {
|
||||
expect((): any => matchingTypes(preferences, [ 'noType' ]))
|
||||
.toThrow(new InternalServerError(`Unexpected type preference: noType`));
|
||||
});
|
||||
|
||||
it('filters out internal types.', async(): Promise<void> => {
|
||||
const preferences: RepresentationPreferences = { type: [{ value: '*/*', weight: 1 }]};
|
||||
expect(matchingTypes(preferences, [ 'a/x', 'internal/quads' ])).toEqual([{ value: 'a/x', weight: 1 }]);
|
||||
});
|
||||
|
||||
it('keeps internal types that are specifically requested.', async(): Promise<void> => {
|
||||
const preferences: RepresentationPreferences =
|
||||
{ type: [{ value: '*/*', weight: 1 }, { value: 'internal/*', weight: 0.5 }]};
|
||||
expect(matchingTypes(preferences, [ 'a/x', 'internal/quads' ]))
|
||||
.toEqual([{ value: 'a/x', weight: 1 }, { value: 'internal/quads', weight: 0.5 }]);
|
||||
});
|
||||
|
||||
it('takes the most relevant weight for a type.', async(): Promise<void> => {
|
||||
const preferences: RepresentationPreferences =
|
||||
{ type: [{ value: '*/*', weight: 1 }, { value: 'internal/quads', weight: 0.5 }]};
|
||||
expect(matchingTypes(preferences, [ 'a/x', 'internal/quads' ]))
|
||||
.toEqual([{ value: 'a/x', weight: 1 }, { value: 'internal/quads', weight: 0.5 }]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user