mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Sort preferences by descending weight.
This commit is contained in:
parent
de939ac7ba
commit
98bf8c199d
@ -84,16 +84,19 @@ export class RepresentationConvertingStore<T extends ResourceStore = ResourceSto
|
|||||||
* Helper function that converts a Representation using the given args and converter,
|
* Helper function that converts a Representation using the given args and converter,
|
||||||
* if the conversion is necessary and there is a converter.
|
* if the conversion is necessary and there is a converter.
|
||||||
*/
|
*/
|
||||||
private async convertRepresentation(args: RepresentationConverterArgs, converter?: RepresentationConverter):
|
private async convertRepresentation(input: RepresentationConverterArgs, converter?: RepresentationConverter):
|
||||||
Promise<Representation> {
|
Promise<Representation> {
|
||||||
if (!converter || !args.preferences.type || this.matchesPreferences(args.representation, args.preferences)) {
|
if (!converter || !input.preferences.type || this.matchesPreferences(input.representation, input.preferences)) {
|
||||||
return args.representation;
|
return input.representation;
|
||||||
}
|
}
|
||||||
|
this.logger.debug(`Conversion needed for ${input.identifier
|
||||||
|
.path} from ${input.representation.metadata.contentType} to satisfy ${input.preferences.type
|
||||||
|
.map((pref): string => `${pref.value};q=${pref.weight}`).join(', ')}`);
|
||||||
|
|
||||||
const typeStr = args.preferences.type.map((pref): string => `${pref.value};q=${pref.weight}`).join(', ');
|
const converted = await converter.handleSafe(input);
|
||||||
this.logger.info(`Convert ${args.identifier.path} from ${args.representation.metadata.contentType} to ${typeStr}`);
|
this.logger.info(`Converted representation for ${input.identifier
|
||||||
|
.path} from ${input.representation.metadata.contentType} to ${converted.metadata.contentType}`);
|
||||||
return converter.handleSafe(args);
|
return converted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,7 +54,10 @@ RepresentationPreference[] => {
|
|||||||
return { value: type, weight };
|
return { value: type, weight };
|
||||||
});
|
});
|
||||||
|
|
||||||
return weightedSupported.filter((preference): boolean => preference.weight !== 0);
|
// Return all non-zero preferences in descending order of weight
|
||||||
|
return weightedSupported
|
||||||
|
.filter((pref): boolean => pref.weight !== 0)
|
||||||
|
.sort((prefA, prefB): number => prefB.weight - prefA.weight);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -11,6 +11,8 @@ describe('A RepresentationConvertingStore', (): void => {
|
|||||||
let source: ResourceStore;
|
let source: ResourceStore;
|
||||||
let inConverter: RepresentationConverter;
|
let inConverter: RepresentationConverter;
|
||||||
let outConverter: RepresentationConverter;
|
let outConverter: RepresentationConverter;
|
||||||
|
const convertedIn = { metadata: {}};
|
||||||
|
const convertedOut = { metadata: {}};
|
||||||
const inType = 'text/turtle';
|
const inType = 'text/turtle';
|
||||||
const metadata = new RepresentationMetadata({ [CONTENT_TYPE]: 'text/turtle' });
|
const metadata = new RepresentationMetadata({ [CONTENT_TYPE]: 'text/turtle' });
|
||||||
let representation: Representation;
|
let representation: Representation;
|
||||||
@ -22,8 +24,8 @@ describe('A RepresentationConvertingStore', (): void => {
|
|||||||
setRepresentation: jest.fn(),
|
setRepresentation: jest.fn(),
|
||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
inConverter = { handleSafe: jest.fn(async(): Promise<any> => 'inConvert') } as any;
|
inConverter = { handleSafe: jest.fn(async(): Promise<any> => convertedIn) } as any;
|
||||||
outConverter = { handleSafe: jest.fn(async(): Promise<any> => 'outConvert') } as any;
|
outConverter = { handleSafe: jest.fn(async(): Promise<any> => convertedOut) } as any;
|
||||||
|
|
||||||
store = new RepresentationConvertingStore(source, { inType, inConverter, outConverter });
|
store = new RepresentationConvertingStore(source, { inType, inConverter, outConverter });
|
||||||
representation = { binary: true, data: 'data', metadata } as any;
|
representation = { binary: true, data: 'data', metadata } as any;
|
||||||
@ -64,7 +66,7 @@ describe('A RepresentationConvertingStore', (): void => {
|
|||||||
it('calls the converter if another output is preferred.', async(): Promise<void> => {
|
it('calls the converter if another output is preferred.', async(): Promise<void> => {
|
||||||
await expect(store.getRepresentation({ path: 'path' }, { type: [
|
await expect(store.getRepresentation({ path: 'path' }, { type: [
|
||||||
{ value: 'text/plain', weight: 1 }, { value: 'text/turtle', weight: 0 },
|
{ value: 'text/plain', weight: 1 }, { value: 'text/turtle', weight: 0 },
|
||||||
]})).resolves.toEqual('outConvert');
|
]})).resolves.toEqual(convertedOut);
|
||||||
expect(source.getRepresentation).toHaveBeenCalledTimes(1);
|
expect(source.getRepresentation).toHaveBeenCalledTimes(1);
|
||||||
expect(outConverter.handleSafe).toHaveBeenCalledTimes(1);
|
expect(outConverter.handleSafe).toHaveBeenCalledTimes(1);
|
||||||
expect(outConverter.handleSafe).toHaveBeenLastCalledWith({
|
expect(outConverter.handleSafe).toHaveBeenLastCalledWith({
|
||||||
@ -95,11 +97,11 @@ describe('A RepresentationConvertingStore', (): void => {
|
|||||||
|
|
||||||
await expect(store.addResource(id, representation, 'conditions' as any)).resolves.toBeUndefined();
|
await expect(store.addResource(id, representation, 'conditions' as any)).resolves.toBeUndefined();
|
||||||
expect(inConverter.handleSafe).toHaveBeenCalledTimes(1);
|
expect(inConverter.handleSafe).toHaveBeenCalledTimes(1);
|
||||||
expect(source.addResource).toHaveBeenLastCalledWith(id, 'inConvert', 'conditions');
|
expect(source.addResource).toHaveBeenLastCalledWith(id, convertedIn, 'conditions');
|
||||||
|
|
||||||
await expect(store.setRepresentation(id, representation, 'conditions' as any)).resolves.toBeUndefined();
|
await expect(store.setRepresentation(id, representation, 'conditions' as any)).resolves.toBeUndefined();
|
||||||
expect(inConverter.handleSafe).toHaveBeenCalledTimes(2);
|
expect(inConverter.handleSafe).toHaveBeenCalledTimes(2);
|
||||||
expect(source.setRepresentation).toHaveBeenLastCalledWith(id, 'inConvert', 'conditions');
|
expect(source.setRepresentation).toHaveBeenLastCalledWith(id, convertedIn, 'conditions');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws an error if no content-type is provided.', async(): Promise<void> => {
|
it('throws an error if no content-type is provided.', async(): Promise<void> => {
|
||||||
|
@ -62,6 +62,13 @@ describe('ConversionUtil', (): void => {
|
|||||||
expect(matchingMediaTypes(preferences, [ 'b/x', 'c/x' ])).toEqual([{ value: 'b/x', weight: 0.5 }]);
|
expect(matchingMediaTypes(preferences, [ 'b/x', 'c/x' ])).toEqual([{ value: 'b/x', weight: 0.5 }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('sorts by descending weight.', async(): Promise<void> => {
|
||||||
|
const preferences: RepresentationPreferences = { type:
|
||||||
|
[{ value: 'a/x', weight: 1 }, { value: 'b/x', weight: 0.5 }, { value: 'c/x', weight: 0.8 }]};
|
||||||
|
expect(matchingMediaTypes(preferences, [ 'a/x', 'b/x', 'c/x' ]))
|
||||||
|
.toEqual([{ value: 'a/x', weight: 1 }, { value: 'c/x', weight: 0.8 }, { value: 'b/x', weight: 0.5 }]);
|
||||||
|
});
|
||||||
|
|
||||||
it('errors if there are duplicate preferences.', async(): Promise<void> => {
|
it('errors if there are duplicate preferences.', async(): Promise<void> => {
|
||||||
const preferences: RepresentationPreferences =
|
const preferences: RepresentationPreferences =
|
||||||
{ type: [{ value: 'b/x', weight: 1 }, { value: 'b/x', weight: 0 }]};
|
{ type: [{ value: 'b/x', weight: 1 }, { value: 'b/x', weight: 0 }]};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user