mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
fix: Support missing type preferences in ChainedConverter
This commit is contained in:
parent
d9b641c2b0
commit
52a3b84ee0
@ -32,8 +32,12 @@ export class AcceptPreferenceParser extends PreferenceParser {
|
||||
for (const { name, header, parse } of parsers) {
|
||||
const value = headers[header];
|
||||
if (typeof value === 'string') {
|
||||
preferences[name] = Object.fromEntries(parse(value)
|
||||
const result = Object.fromEntries(parse(value)
|
||||
.map(({ range, weight }): [string, number] => [ range, weight ]));
|
||||
// Interpret empty headers (or headers with no valid values) the same as missing headers
|
||||
if (Object.keys(result).length > 0) {
|
||||
preferences[name] = result;
|
||||
}
|
||||
}
|
||||
}
|
||||
return preferences;
|
||||
|
@ -174,15 +174,11 @@ export class ChainedConverter extends RepresentationConverter {
|
||||
if (!type) {
|
||||
throw new BadRequestHttpError('Missing Content-Type header.');
|
||||
}
|
||||
let preferences = input.preferences.type;
|
||||
if (!preferences) {
|
||||
throw new BadRequestHttpError('Missing type preferences.');
|
||||
}
|
||||
preferences = cleanPreferences(preferences);
|
||||
const preferences = cleanPreferences(input.preferences.type);
|
||||
|
||||
const weight = getTypeWeight(type, preferences);
|
||||
if (weight > 0) {
|
||||
this.logger.debug(`No conversion required: ${type} already matches ${Object.keys(input.preferences.type!)}`);
|
||||
this.logger.debug(`No conversion required: ${type} already matches ${Object.keys(preferences)}`);
|
||||
return { value: type, weight };
|
||||
}
|
||||
|
||||
|
@ -36,17 +36,50 @@ describe('A Solid server', (): void => {
|
||||
});
|
||||
});
|
||||
|
||||
it('can GET results from a container.', async(): Promise<void> => {
|
||||
it('can do a successful HEAD request to a container.', async(): Promise<void> => {
|
||||
const res = await fetch(baseUrl, { method: 'HEAD' });
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a successful HEAD request to a container without accept headers.', async(): Promise<void> => {
|
||||
const res = await fetch(baseUrl, { method: 'HEAD', headers: { accept: '' }});
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a successful HEAD request to a document.', async(): Promise<void> => {
|
||||
const url = `${baseUrl}.acl`;
|
||||
const res = await fetch(url, { method: 'HEAD' });
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a successful HEAD request to a document without accept headers.', async(): Promise<void> => {
|
||||
const url = `${baseUrl}.acl`;
|
||||
const res = await fetch(url, { method: 'HEAD', headers: { accept: '' }});
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a successful GET request to a container.', async(): Promise<void> => {
|
||||
const res = await fetch(baseUrl);
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can GET results from a resource.', async(): Promise<void> => {
|
||||
it('can do a successful GET request to a container without accept headers.', async(): Promise<void> => {
|
||||
const res = await fetch(baseUrl, { headers: { accept: '' }});
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a successful GET request to a document.', async(): Promise<void> => {
|
||||
const url = `${baseUrl}.acl`;
|
||||
const res = await fetch(url);
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can do a successful GET request to a document without accept headers.', async(): Promise<void> => {
|
||||
const url = `${baseUrl}.acl`;
|
||||
const res = await fetch(url, { headers: { accept: '' }});
|
||||
expect(res.status).toBe(200);
|
||||
});
|
||||
|
||||
it('can PUT to containers.', async(): Promise<void> => {
|
||||
const url = `${baseUrl}containerPUT/`;
|
||||
const res = await fetch(url, {
|
||||
@ -96,7 +129,7 @@ describe('A Solid server', (): void => {
|
||||
expect(res.headers.get('location')).toBe(`${baseUrl}containerPOST/`);
|
||||
});
|
||||
|
||||
it('can POST to create a resource.', async(): Promise<void> => {
|
||||
it('can POST to create a document.', async(): Promise<void> => {
|
||||
const res = await fetch(baseUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
@ -122,7 +155,7 @@ describe('A Solid server', (): void => {
|
||||
expect(res.status).toBe(205);
|
||||
});
|
||||
|
||||
it('can DELETE resources.', async(): Promise<void> => {
|
||||
it('can DELETE documents.', async(): Promise<void> => {
|
||||
const url = `${baseUrl}resourceDELETE`;
|
||||
await fetch(url, {
|
||||
method: 'PUT',
|
||||
@ -135,7 +168,7 @@ describe('A Solid server', (): void => {
|
||||
expect(res.status).toBe(205);
|
||||
});
|
||||
|
||||
it('can PATCH resources.', async(): Promise<void> => {
|
||||
it('can PATCH documents.', async(): Promise<void> => {
|
||||
const url = `${baseUrl}resourcePATCH`;
|
||||
await fetch(url, {
|
||||
method: 'PUT',
|
||||
|
@ -14,6 +14,9 @@ describe('An AcceptPreferenceParser', (): void => {
|
||||
|
||||
it('returns an empty result if there is no relevant input.', async(): Promise<void> => {
|
||||
await expect(preferenceParser.handle({ request })).resolves.toEqual({});
|
||||
|
||||
request.headers = { accept: '' };
|
||||
await expect(preferenceParser.handle({ request })).resolves.toEqual({});
|
||||
});
|
||||
|
||||
it('parses accept headers.', async(): Promise<void> => {
|
||||
|
@ -70,10 +70,6 @@ describe('A ChainedConverter', (): void => {
|
||||
const converters = [ new DummyConverter({ 'a/a': 1 }, { 'x/x': 1 }) ];
|
||||
const converter = new ChainedConverter(converters);
|
||||
await expect(converter.canHandle(args)).rejects.toThrow('Missing Content-Type header.');
|
||||
|
||||
args.representation.metadata.contentType = 'a/a';
|
||||
args.preferences = { };
|
||||
await expect(converter.canHandle(args)).rejects.toThrow('Missing type preferences.');
|
||||
});
|
||||
|
||||
it('errors if no path can be found.', async(): Promise<void> => {
|
||||
@ -95,6 +91,20 @@ describe('A ChainedConverter', (): void => {
|
||||
expect(result.metadata.contentType).toBe('b/b');
|
||||
});
|
||||
|
||||
it('interprets no preferences as */*.', async(): Promise<void> => {
|
||||
const converters = [ new DummyConverter({ 'a/a': 1 }, { 'x/x': 1 }) ];
|
||||
const converter = new ChainedConverter(converters);
|
||||
args.representation.metadata.contentType = 'b/b';
|
||||
args.preferences.type = undefined;
|
||||
|
||||
let result = await converter.handle(args);
|
||||
expect(result.metadata.contentType).toBe('b/b');
|
||||
|
||||
args.preferences.type = { };
|
||||
result = await converter.handle(args);
|
||||
expect(result.metadata.contentType).toBe('b/b');
|
||||
});
|
||||
|
||||
it('can find paths of length 1.', async(): Promise<void> => {
|
||||
const converters = [ new DummyConverter({ 'a/a': 1 }, { 'x/x': 1 }) ];
|
||||
const converter = new ChainedConverter(converters);
|
||||
|
Loading…
x
Reference in New Issue
Block a user