feat: Create MetadataParser that detects JSON with Context link and throws an error

* feat: add PlainJsonLdFilter to reject JSON with context link

* refactor: abstract parseLinkHeader into HeaderUtils

* docs: typo in comment field

Co-authored-by: Ruben Verborgh <ruben@verborgh.org>

* refactor: Replace BadRequestHttpError with NotImplementedError

Co-authored-by: Ruben Verborgh <ruben@verborgh.org>

* refactor: incorporate requested changes

* refactor: requested changes incorporated

* refactor: remove obsolete code lines

Co-authored-by: Ruben Verborgh <ruben@verborgh.org>
This commit is contained in:
Thomas Dupont
2022-04-01 14:25:09 +02:00
committed by GitHub
parent 3685b7c659
commit 48efc6fae1
9 changed files with 323 additions and 28 deletions

View File

@@ -0,0 +1,63 @@
import { NotImplementedHttpError } from '../../../../../src';
import { PlainJsonLdFilter } from '../../../../../src/http/input/metadata/PlainJsonLdFilter';
import { RepresentationMetadata } from '../../../../../src/http/representation/RepresentationMetadata';
import type { HttpRequest } from '../../../../../src/server/HttpRequest';
describe('A PlainJsonLdFilter', (): void => {
const parser = new PlainJsonLdFilter();
let request: HttpRequest;
let metadata: RepresentationMetadata;
beforeEach(async(): Promise<void> => {
request = { headers: {}} as HttpRequest;
metadata = new RepresentationMetadata();
});
it('does nothing if there are no type headers.', async(): Promise<void> => {
await expect(parser.handle({ request, metadata })).resolves.toBeUndefined();
expect(metadata.quads()).toHaveLength(0);
});
it('does allow content-type application/json on its own.', async(): Promise<void> => {
request.headers['content-type'] = 'application/json';
await expect(parser.handle({ request, metadata })).resolves.toBeUndefined();
expect(metadata.quads()).toHaveLength(0);
});
it('does allow a correct content-type and link headers combination.', async(): Promise<void> => {
request.headers['content-type'] = 'application/json+ld';
request.headers.link = '<https://json-ld.org/contexts/person.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"';
await expect(parser.handle({ request, metadata })).resolves.toBeUndefined();
expect(metadata.quads()).toHaveLength(0);
});
it('throws error when content-type and link header are in conflict.', async(): Promise<void> => {
request.headers['content-type'] = 'application/json';
request.headers.link = '<https://json-ld.org/contexts/person.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"';
await expect(parser.handle({ request, metadata })).rejects.toThrow(NotImplementedHttpError);
expect(metadata.quads()).toHaveLength(0);
});
it('throws error when at least 1 content-type and link header are in conflict.', async(): Promise<void> => {
request.headers['content-type'] = 'application/json';
request.headers.link = [
'<http://test.com/type>; rel="type"',
'<https://json-ld.org/contexts/person.jsonld>; rel="http://www.w3.org/ns/json-ld#context"; type="application/ld+json"',
];
await expect(parser.handle({ request, metadata })).rejects.toThrow(NotImplementedHttpError);
expect(metadata.quads()).toHaveLength(0);
});
it('ignores invalid link headers.', async(): Promise<void> => {
request.headers['content-type'] = 'application/json';
request.headers.link = 'http://test.com/type;rel="type"';
await expect(parser.handle({ request, metadata })).resolves.toBeUndefined();
expect(metadata.quads()).toHaveLength(0);
});
it('ignores empty content-type headers.', async(): Promise<void> => {
request.headers.link = '<http://test.com/type>;rel="type"';
await expect(parser.handle({ request, metadata })).resolves.toBeUndefined();
expect(metadata.quads()).toHaveLength(0);
});
});