2022-03-29 14:52:36 +02:00

129 lines
4.4 KiB
TypeScript

import 'jest-rdf';
import type { Response } from 'cross-fetch';
import fetch from 'cross-fetch';
import type { Quad } from 'n3';
import { Parser } from 'n3';
import { isContainerPath } from '../../src/util/PathUtil';
import { LDP } from '../../src/util/Vocabularies';
/**
* This is specifically for GET requests which are expected to succeed.
*/
export async function getResource(url: string,
options?: { accept?: string },
expected?: { contentType?: string }): Promise<Response> {
const isContainer = isContainerPath(url);
const response = await fetch(url, { headers: options });
expect(response.status).toBe(200);
expect(response.headers.get('link')).toContain(`<${LDP.Resource}>; rel="type"`);
expect(response.headers.get('link')).toContain(`<${url}.acl>; rel="acl"`);
expect(response.headers.get('accept-patch')).toBe('text/n3, application/sparql-update');
expect(response.headers.get('ms-author-via')).toBe('SPARQL');
if (isContainer) {
expect(response.headers.get('link')).toContain(`<${LDP.Container}>; rel="type"`);
expect(response.headers.get('link')).toContain(`<${LDP.BasicContainer}>; rel="type"`);
}
if (expected?.contentType) {
expect(response.headers.get('content-type')).toBe(expected.contentType);
} else if (isContainer) {
expect(response.headers.get('content-type')).toBe('text/turtle');
}
return response;
}
/**
* This is specifically for PUT requests which are expected to succeed.
*/
export async function putResource(url: string, options: { contentType: string; body?: string; exists?: boolean }):
Promise<Response> {
const init: RequestInit = {
method: 'PUT',
headers: { 'content-type': options.contentType },
body: options.body,
};
if (isContainerPath(url)) {
(init.headers as Record<string, string>).link = '<http://www.w3.org/ns/ldp#Container>; rel="type"';
}
const response = await fetch(url, init);
expect(response.status).toBe(options.exists ? 205 : 201);
if (!options.exists) {
expect(response.headers.get('location')).toBe(url);
}
await expect(response.text()).resolves.toHaveLength(0);
return response;
}
export type CreateOptions = {
contentType: string;
isContainer?: boolean;
slug?: string;
body?: string;
};
/**
* This is specifically for POST requests which are expected to succeed.
*/
export async function postResource(container: string, options: CreateOptions): Promise<Response> {
const init: RequestInit = {
method: 'POST',
headers: { 'content-type': options.contentType },
body: options.body,
};
if (options.isContainer) {
(init.headers as Record<string, string>).link = '<http://www.w3.org/ns/ldp#Container>; rel="type"';
}
if (options.slug) {
(init.headers as Record<string, string>).slug = options.slug;
}
const response = await fetch(container, init);
await expect(response.text()).resolves.toHaveLength(0);
expect(response.status).toBe(201);
const regex = new RegExp(`^${container}[^/]+${options.isContainer ? '/' : ''}`, 'u');
expect(response.headers.get('location')).toMatch(regex);
return response;
}
/**
* This is specifically for PATCH requests which are expected to succeed.
*/
export async function patchResource(url: string, query: string, exists?: boolean): Promise<Response> {
const response = await fetch(url, {
method: 'PATCH',
headers: {
'content-type': 'application/sparql-update',
},
body: query,
});
await expect(response.text()).resolves.toHaveLength(0);
expect(response.status).toBe(exists ? 205 : 201);
if (!exists) {
expect(response.headers.get('location')).toBe(url);
}
return response;
}
export async function deleteResource(url: string): Promise<void> {
let response = await fetch(url, { method: 'DELETE' });
expect(response.status).toBe(205);
response = await fetch(url);
expect(response.status).toBe(404);
}
/**
* Verifies if the body of the given Response contains the expected Quads.
* If `exact` is true, a 1-to-1 match is expected, if not, the expected quads should be a subset of the body.
*/
export async function expectQuads(response: Response, expected: Quad[], exact?: boolean): Promise<void> {
const parser = new Parser({ baseIRI: response.url });
const quads = parser.parse(await response.text());
if (exact) {
expect(quads).toBeRdfIsomorphic(expected);
} else {
for (const expectedQuad of expected) {
expect(quads.some((entry): boolean => entry.equals(expectedQuad))).toBe(true);
}
}
}