mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Dynamically generate Allow and Accept-* headers
This commit is contained in:
115
test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts
Normal file
115
test/unit/http/output/metadata/AllowAcceptHeaderWriter.test.ts
Normal file
@@ -0,0 +1,115 @@
|
||||
import { createResponse } from 'node-mocks-http';
|
||||
import { AllowAcceptHeaderWriter } from '../../../../../src/http/output/metadata/AllowAcceptHeaderWriter';
|
||||
import type { MetadataRecord } from '../../../../../src/http/representation/RepresentationMetadata';
|
||||
import { RepresentationMetadata } from '../../../../../src/http/representation/RepresentationMetadata';
|
||||
import type { HttpResponse } from '../../../../../src/server/HttpResponse';
|
||||
import { MethodNotAllowedHttpError } from '../../../../../src/util/errors/MethodNotAllowedHttpError';
|
||||
import { NotFoundHttpError } from '../../../../../src/util/errors/NotFoundHttpError';
|
||||
import { UnsupportedMediaTypeHttpError } from '../../../../../src/util/errors/UnsupportedMediaTypeHttpError';
|
||||
import { LDP, PIM, RDF, SOLID_ERROR } from '../../../../../src/util/Vocabularies';
|
||||
|
||||
describe('An AllowAcceptHeaderWriter', (): void => {
|
||||
const document = new RepresentationMetadata({ path: 'http://example.com/foo/bar' },
|
||||
{ [RDF.type]: LDP.terms.Resource });
|
||||
const emptyContainer = new RepresentationMetadata({ path: 'http://example.com/foo/' },
|
||||
{ [RDF.type]: [ LDP.terms.Resource, LDP.terms.Container ]});
|
||||
const fullContainer = new RepresentationMetadata({ path: 'http://example.com/foo/' },
|
||||
{
|
||||
[RDF.type]: [ LDP.terms.Resource, LDP.terms.Container ],
|
||||
[LDP.contains]: [ document.identifier ],
|
||||
// Typescript doesn't find the correct constructor without the cast
|
||||
} as MetadataRecord);
|
||||
const storageContainer = new RepresentationMetadata({ path: 'http://example.com/foo/' },
|
||||
{ [RDF.type]: [ LDP.terms.Resource, LDP.terms.Container, PIM.terms.Storage ]});
|
||||
const error404 = new RepresentationMetadata({ [SOLID_ERROR.errorResponse]: NotFoundHttpError.uri });
|
||||
const error405 = new RepresentationMetadata(
|
||||
{ [SOLID_ERROR.errorResponse]: MethodNotAllowedHttpError.uri, [SOLID_ERROR.disallowedMethod]: 'PUT' },
|
||||
);
|
||||
const error415 = new RepresentationMetadata({ [SOLID_ERROR.errorResponse]: UnsupportedMediaTypeHttpError.uri });
|
||||
let response: HttpResponse;
|
||||
let writer: AllowAcceptHeaderWriter;
|
||||
|
||||
beforeEach(async(): Promise<void> => {
|
||||
response = createResponse();
|
||||
|
||||
writer = new AllowAcceptHeaderWriter(
|
||||
[ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'POST', 'PATCH', 'DELETE' ],
|
||||
{ patch: [ 'text/n3', 'application/sparql-update' ], post: [ '*/*' ], put: [ '*/*' ]},
|
||||
);
|
||||
});
|
||||
|
||||
it('returns all methods except POST for a document.', async(): Promise<void> => {
|
||||
await expect(writer.handleSafe({ response, metadata: document })).resolves.toBeUndefined();
|
||||
const headers = response.getHeaders();
|
||||
expect(typeof headers.allow).toBe('string');
|
||||
expect(new Set((headers.allow as string).split(', ')))
|
||||
.toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'PATCH', 'DELETE' ]));
|
||||
expect(headers['accept-patch']).toBe('text/n3, application/sparql-update');
|
||||
expect(headers['accept-put']).toBe('*/*');
|
||||
expect(headers['accept-post']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns all methods for an empty container.', async(): Promise<void> => {
|
||||
await expect(writer.handleSafe({ response, metadata: emptyContainer })).resolves.toBeUndefined();
|
||||
const headers = response.getHeaders();
|
||||
expect(typeof headers.allow).toBe('string');
|
||||
expect(new Set((headers.allow as string).split(', ')))
|
||||
.toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'POST', 'PATCH', 'DELETE' ]));
|
||||
expect(headers['accept-patch']).toBe('text/n3, application/sparql-update');
|
||||
expect(headers['accept-put']).toBe('*/*');
|
||||
expect(headers['accept-post']).toBe('*/*');
|
||||
});
|
||||
|
||||
it('returns all methods except DELETE for a non-empty container.', async(): Promise<void> => {
|
||||
await expect(writer.handleSafe({ response, metadata: fullContainer })).resolves.toBeUndefined();
|
||||
const headers = response.getHeaders();
|
||||
expect(typeof headers.allow).toBe('string');
|
||||
expect(new Set((headers.allow as string).split(', ')))
|
||||
.toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'POST', 'PATCH' ]));
|
||||
expect(headers['accept-patch']).toBe('text/n3, application/sparql-update');
|
||||
expect(headers['accept-put']).toBe('*/*');
|
||||
expect(headers['accept-post']).toBe('*/*');
|
||||
});
|
||||
|
||||
it('returns all methods except DELETE for a storage container.', async(): Promise<void> => {
|
||||
await expect(writer.handleSafe({ response, metadata: storageContainer })).resolves.toBeUndefined();
|
||||
const headers = response.getHeaders();
|
||||
expect(typeof headers.allow).toBe('string');
|
||||
expect(new Set((headers.allow as string).split(', ')))
|
||||
.toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'PUT', 'POST', 'PATCH' ]));
|
||||
expect(headers['accept-patch']).toBe('text/n3, application/sparql-update');
|
||||
expect(headers['accept-put']).toBe('*/*');
|
||||
expect(headers['accept-post']).toBe('*/*');
|
||||
});
|
||||
|
||||
it('returns PATCH and PUT if the target does not exist.', async(): Promise<void> => {
|
||||
await expect(writer.handleSafe({ response, metadata: error404 })).resolves.toBeUndefined();
|
||||
const headers = response.getHeaders();
|
||||
expect(typeof headers.allow).toBe('string');
|
||||
expect(new Set((headers.allow as string).split(', ')))
|
||||
.toEqual(new Set([ 'PUT', 'PATCH' ]));
|
||||
expect(headers['accept-patch']).toBe('text/n3, application/sparql-update');
|
||||
expect(headers['accept-put']).toBe('*/*');
|
||||
expect(headers['accept-post']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('removes methods that are not allowed by a 405 error.', async(): Promise<void> => {
|
||||
await expect(writer.handleSafe({ response, metadata: error405 })).resolves.toBeUndefined();
|
||||
const headers = response.getHeaders();
|
||||
expect(typeof headers.allow).toBe('string');
|
||||
expect(new Set((headers.allow as string).split(', ')))
|
||||
.toEqual(new Set([ 'OPTIONS', 'GET', 'HEAD', 'POST', 'PATCH', 'DELETE' ]));
|
||||
expect(headers['accept-patch']).toBe('text/n3, application/sparql-update');
|
||||
expect(headers['accept-put']).toBeUndefined();
|
||||
expect(headers['accept-post']).toBe('*/*');
|
||||
});
|
||||
|
||||
it('only returns Accept- headers in case of a 415.', async(): Promise<void> => {
|
||||
await expect(writer.handleSafe({ response, metadata: error415 })).resolves.toBeUndefined();
|
||||
const headers = response.getHeaders();
|
||||
expect(headers.allow).toBeUndefined();
|
||||
expect(headers['accept-patch']).toBe('text/n3, application/sparql-update');
|
||||
expect(headers['accept-put']).toBe('*/*');
|
||||
expect(headers['accept-post']).toBe('*/*');
|
||||
});
|
||||
});
|
||||
@@ -248,6 +248,13 @@ describe('A RepresentationMetadata', (): void => {
|
||||
);
|
||||
});
|
||||
|
||||
it('can check the existence of a triple.', async(): Promise<void> => {
|
||||
expect(metadata.has(namedNode('has'), literal('data'))).toBe(true);
|
||||
expect(metadata.has(namedNode('has'))).toBe(true);
|
||||
expect(metadata.has(undefined, literal('data'))).toBe(true);
|
||||
expect(metadata.has(namedNode('has'), literal('wrongData'))).toBe(false);
|
||||
});
|
||||
|
||||
it('can get all values for a predicate.', async(): Promise<void> => {
|
||||
expect(metadata.getAll(namedNode('has'))).toEqualRdfTermArray(
|
||||
[ literal('data'), literal('moreData'), literal('data') ],
|
||||
|
||||
Reference in New Issue
Block a user