mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Integrate PATCH functionality
This commit is contained in:
parent
04a12c723e
commit
0e486cf6a6
@ -2,21 +2,29 @@ import yargs from 'yargs';
|
|||||||
import {
|
import {
|
||||||
AcceptPreferenceParser,
|
AcceptPreferenceParser,
|
||||||
AuthenticatedLdpHandler,
|
AuthenticatedLdpHandler,
|
||||||
|
BodyParser,
|
||||||
CompositeAsyncHandler,
|
CompositeAsyncHandler,
|
||||||
ExpressHttpServer,
|
ExpressHttpServer,
|
||||||
|
HttpRequest,
|
||||||
Operation,
|
Operation,
|
||||||
|
PatchingStore,
|
||||||
|
Representation,
|
||||||
ResponseDescription,
|
ResponseDescription,
|
||||||
SimpleAuthorizer,
|
SimpleAuthorizer,
|
||||||
SimpleBodyParser,
|
SimpleBodyParser,
|
||||||
SimpleCredentialsExtractor,
|
SimpleCredentialsExtractor,
|
||||||
SimpleDeleteOperationHandler,
|
SimpleDeleteOperationHandler,
|
||||||
SimpleGetOperationHandler,
|
SimpleGetOperationHandler,
|
||||||
|
SimplePatchOperationHandler,
|
||||||
SimplePermissionsExtractor,
|
SimplePermissionsExtractor,
|
||||||
SimplePostOperationHandler,
|
SimplePostOperationHandler,
|
||||||
SimpleRequestParser,
|
SimpleRequestParser,
|
||||||
SimpleResourceStore,
|
SimpleResourceStore,
|
||||||
SimpleResponseWriter,
|
SimpleResponseWriter,
|
||||||
|
SimpleSparqlUpdateBodyParser,
|
||||||
|
SimpleSparqlUpdatePatchHandler,
|
||||||
SimpleTargetExtractor,
|
SimpleTargetExtractor,
|
||||||
|
SingleThreadedResourceLocker,
|
||||||
} from '..';
|
} from '..';
|
||||||
|
|
||||||
const { argv } = yargs
|
const { argv } = yargs
|
||||||
@ -29,10 +37,14 @@ const { argv } = yargs
|
|||||||
const { port } = argv;
|
const { port } = argv;
|
||||||
|
|
||||||
// This is instead of the dependency injection that still needs to be added
|
// This is instead of the dependency injection that still needs to be added
|
||||||
|
const bodyParser: BodyParser = new CompositeAsyncHandler<HttpRequest, Representation>([
|
||||||
|
new SimpleBodyParser(),
|
||||||
|
new SimpleSparqlUpdateBodyParser(),
|
||||||
|
]);
|
||||||
const requestParser = new SimpleRequestParser({
|
const requestParser = new SimpleRequestParser({
|
||||||
targetExtractor: new SimpleTargetExtractor(),
|
targetExtractor: new SimpleTargetExtractor(),
|
||||||
preferenceParser: new AcceptPreferenceParser(),
|
preferenceParser: new AcceptPreferenceParser(),
|
||||||
bodyParser: new SimpleBodyParser(),
|
bodyParser,
|
||||||
});
|
});
|
||||||
|
|
||||||
const credentialsExtractor = new SimpleCredentialsExtractor();
|
const credentialsExtractor = new SimpleCredentialsExtractor();
|
||||||
@ -41,10 +53,15 @@ const authorizer = new SimpleAuthorizer();
|
|||||||
|
|
||||||
// Will have to see how to best handle this
|
// Will have to see how to best handle this
|
||||||
const store = new SimpleResourceStore(`http://localhost:${port}/`);
|
const store = new SimpleResourceStore(`http://localhost:${port}/`);
|
||||||
|
const locker = new SingleThreadedResourceLocker();
|
||||||
|
const patcher = new SimpleSparqlUpdatePatchHandler(store, locker);
|
||||||
|
const patchingStore = new PatchingStore(store, patcher);
|
||||||
|
|
||||||
const operationHandler = new CompositeAsyncHandler<Operation, ResponseDescription>([
|
const operationHandler = new CompositeAsyncHandler<Operation, ResponseDescription>([
|
||||||
new SimpleGetOperationHandler(store),
|
new SimpleDeleteOperationHandler(patchingStore),
|
||||||
new SimplePostOperationHandler(store),
|
new SimpleGetOperationHandler(patchingStore),
|
||||||
new SimpleDeleteOperationHandler(store),
|
new SimplePatchOperationHandler(patchingStore),
|
||||||
|
new SimplePostOperationHandler(patchingStore),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const responseWriter = new SimpleResponseWriter();
|
const responseWriter = new SimpleResponseWriter();
|
||||||
|
8
index.ts
8
index.ts
@ -17,7 +17,9 @@ export * from './src/ldp/http/ResponseWriter';
|
|||||||
export * from './src/ldp/http/SimpleBodyParser';
|
export * from './src/ldp/http/SimpleBodyParser';
|
||||||
export * from './src/ldp/http/SimpleRequestParser';
|
export * from './src/ldp/http/SimpleRequestParser';
|
||||||
export * from './src/ldp/http/SimpleResponseWriter';
|
export * from './src/ldp/http/SimpleResponseWriter';
|
||||||
|
export * from './src/ldp/http/SimpleSparqlUpdateBodyParser';
|
||||||
export * from './src/ldp/http/SimpleTargetExtractor';
|
export * from './src/ldp/http/SimpleTargetExtractor';
|
||||||
|
export * from './src/ldp/http/SparqlUpdatePatch';
|
||||||
export * from './src/ldp/http/TargetExtractor';
|
export * from './src/ldp/http/TargetExtractor';
|
||||||
|
|
||||||
// LDP/Operations
|
// LDP/Operations
|
||||||
@ -26,6 +28,7 @@ export * from './src/ldp/operations/OperationHandler';
|
|||||||
export * from './src/ldp/operations/ResponseDescription';
|
export * from './src/ldp/operations/ResponseDescription';
|
||||||
export * from './src/ldp/operations/SimpleDeleteOperationHandler';
|
export * from './src/ldp/operations/SimpleDeleteOperationHandler';
|
||||||
export * from './src/ldp/operations/SimpleGetOperationHandler';
|
export * from './src/ldp/operations/SimpleGetOperationHandler';
|
||||||
|
export * from './src/ldp/operations/SimplePatchOperationHandler';
|
||||||
export * from './src/ldp/operations/SimplePostOperationHandler';
|
export * from './src/ldp/operations/SimplePostOperationHandler';
|
||||||
|
|
||||||
// LDP/Permissions
|
// LDP/Permissions
|
||||||
@ -52,11 +55,16 @@ export * from './src/server/HttpHandler';
|
|||||||
export * from './src/server/HttpRequest';
|
export * from './src/server/HttpRequest';
|
||||||
export * from './src/server/HttpResponse';
|
export * from './src/server/HttpResponse';
|
||||||
|
|
||||||
|
// Storage/Patch
|
||||||
|
export * from './src/storage/patch/PatchHandler';
|
||||||
|
export * from './src/storage/patch/SimpleSparqlUpdatePatchHandler';
|
||||||
|
|
||||||
// Storage
|
// Storage
|
||||||
export * from './src/storage/AtomicResourceStore';
|
export * from './src/storage/AtomicResourceStore';
|
||||||
export * from './src/storage/Conditions';
|
export * from './src/storage/Conditions';
|
||||||
export * from './src/storage/Lock';
|
export * from './src/storage/Lock';
|
||||||
export * from './src/storage/LockingResourceStore';
|
export * from './src/storage/LockingResourceStore';
|
||||||
|
export * from './src/storage/PatchingStore';
|
||||||
export * from './src/storage/RepresentationConverter';
|
export * from './src/storage/RepresentationConverter';
|
||||||
export * from './src/storage/ResourceLocker';
|
export * from './src/storage/ResourceLocker';
|
||||||
export * from './src/storage/ResourceMapper';
|
export * from './src/storage/ResourceMapper';
|
||||||
|
@ -27,7 +27,7 @@ export class SimpleSparqlUpdatePatchHandler extends PatchHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async canHandle(input: {identifier: ResourceIdentifier; patch: SparqlUpdatePatch}): Promise<void> {
|
public async canHandle(input: {identifier: ResourceIdentifier; patch: SparqlUpdatePatch}): Promise<void> {
|
||||||
if (input.patch.dataType !== 'algebra' || !input.patch.algebra) {
|
if (input.patch.dataType !== 'sparql-algebra' || !input.patch.algebra) {
|
||||||
throw new UnsupportedHttpError('Only SPARQL update patch requests are supported.');
|
throw new UnsupportedHttpError('Only SPARQL update patch requests are supported.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,59 @@
|
|||||||
import { AcceptPreferenceParser } from '../../src/ldp/http/AcceptPreferenceParser';
|
import { AcceptPreferenceParser } from '../../src/ldp/http/AcceptPreferenceParser';
|
||||||
import { AuthenticatedLdpHandler } from '../../src/ldp/AuthenticatedLdpHandler';
|
import { AuthenticatedLdpHandler } from '../../src/ldp/AuthenticatedLdpHandler';
|
||||||
|
import { BodyParser } from '../../src/ldp/http/BodyParser';
|
||||||
import { CompositeAsyncHandler } from '../../src/util/CompositeAsyncHandler';
|
import { CompositeAsyncHandler } from '../../src/util/CompositeAsyncHandler';
|
||||||
import { EventEmitter } from 'events';
|
import { EventEmitter } from 'events';
|
||||||
|
import { HttpHandler } from '../../src/server/HttpHandler';
|
||||||
import { HttpRequest } from '../../src/server/HttpRequest';
|
import { HttpRequest } from '../../src/server/HttpRequest';
|
||||||
|
import { IncomingHttpHeaders } from 'http';
|
||||||
import { Operation } from '../../src/ldp/operations/Operation';
|
import { Operation } from '../../src/ldp/operations/Operation';
|
||||||
|
import { Parser } from 'n3';
|
||||||
|
import { PatchingStore } from '../../src/storage/PatchingStore';
|
||||||
|
import { Representation } from '../../src/ldp/representation/Representation';
|
||||||
import { ResponseDescription } from '../../src/ldp/operations/ResponseDescription';
|
import { ResponseDescription } from '../../src/ldp/operations/ResponseDescription';
|
||||||
import { SimpleAuthorizer } from '../../src/authorization/SimpleAuthorizer';
|
import { SimpleAuthorizer } from '../../src/authorization/SimpleAuthorizer';
|
||||||
import { SimpleBodyParser } from '../../src/ldp/http/SimpleBodyParser';
|
import { SimpleBodyParser } from '../../src/ldp/http/SimpleBodyParser';
|
||||||
import { SimpleCredentialsExtractor } from '../../src/authentication/SimpleCredentialsExtractor';
|
import { SimpleCredentialsExtractor } from '../../src/authentication/SimpleCredentialsExtractor';
|
||||||
import { SimpleDeleteOperationHandler } from '../../src/ldp/operations/SimpleDeleteOperationHandler';
|
import { SimpleDeleteOperationHandler } from '../../src/ldp/operations/SimpleDeleteOperationHandler';
|
||||||
import { SimpleGetOperationHandler } from '../../src/ldp/operations/SimpleGetOperationHandler';
|
import { SimpleGetOperationHandler } from '../../src/ldp/operations/SimpleGetOperationHandler';
|
||||||
|
import { SimplePatchOperationHandler } from '../../src/ldp/operations/SimplePatchOperationHandler';
|
||||||
import { SimplePermissionsExtractor } from '../../src/ldp/permissions/SimplePermissionsExtractor';
|
import { SimplePermissionsExtractor } from '../../src/ldp/permissions/SimplePermissionsExtractor';
|
||||||
import { SimplePostOperationHandler } from '../../src/ldp/operations/SimplePostOperationHandler';
|
import { SimplePostOperationHandler } from '../../src/ldp/operations/SimplePostOperationHandler';
|
||||||
import { SimpleRequestParser } from '../../src/ldp/http/SimpleRequestParser';
|
import { SimpleRequestParser } from '../../src/ldp/http/SimpleRequestParser';
|
||||||
import { SimpleResourceStore } from '../../src/storage/SimpleResourceStore';
|
import { SimpleResourceStore } from '../../src/storage/SimpleResourceStore';
|
||||||
import { SimpleResponseWriter } from '../../src/ldp/http/SimpleResponseWriter';
|
import { SimpleResponseWriter } from '../../src/ldp/http/SimpleResponseWriter';
|
||||||
|
import { SimpleSparqlUpdateBodyParser } from '../../src/ldp/http/SimpleSparqlUpdateBodyParser';
|
||||||
|
import { SimpleSparqlUpdatePatchHandler } from '../../src/storage/patch/SimpleSparqlUpdatePatchHandler';
|
||||||
import { SimpleTargetExtractor } from '../../src/ldp/http/SimpleTargetExtractor';
|
import { SimpleTargetExtractor } from '../../src/ldp/http/SimpleTargetExtractor';
|
||||||
|
import { SingleThreadedResourceLocker } from '../../src/storage/SingleThreadedResourceLocker';
|
||||||
import streamifyArray from 'streamify-array';
|
import streamifyArray from 'streamify-array';
|
||||||
import { createResponse, MockResponse } from 'node-mocks-http';
|
import { createResponse, MockResponse } from 'node-mocks-http';
|
||||||
|
import { namedNode, quad } from '@rdfjs/data-model';
|
||||||
import * as url from 'url';
|
import * as url from 'url';
|
||||||
|
|
||||||
describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
|
const call = async(handler: HttpHandler, requestUrl: url.URL, method: string, headers: IncomingHttpHeaders, data: string[]): Promise<MockResponse<any>> => {
|
||||||
let handler: AuthenticatedLdpHandler;
|
const request = streamifyArray(data) as HttpRequest;
|
||||||
|
request.url = requestUrl.pathname;
|
||||||
|
request.method = method;
|
||||||
|
request.headers = headers;
|
||||||
|
request.headers.host = requestUrl.host;
|
||||||
|
const response: MockResponse<any> = createResponse({ eventEmitter: EventEmitter });
|
||||||
|
|
||||||
beforeEach(async(): Promise<void> => {
|
const endPromise = new Promise((resolve): void => {
|
||||||
|
response.on('end', (): void => {
|
||||||
|
expect(response._isEndCalled()).toBeTruthy();
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
await handler.handleSafe({ request, response });
|
||||||
|
await endPromise;
|
||||||
|
|
||||||
|
return response;
|
||||||
|
};
|
||||||
|
|
||||||
|
describe('An AuthenticatedLdpHandler', (): void => {
|
||||||
|
describe('with simple handlers', (): void => {
|
||||||
const requestParser = new SimpleRequestParser({
|
const requestParser = new SimpleRequestParser({
|
||||||
targetExtractor: new SimpleTargetExtractor(),
|
targetExtractor: new SimpleTargetExtractor(),
|
||||||
preferenceParser: new AcceptPreferenceParser(),
|
preferenceParser: new AcceptPreferenceParser(),
|
||||||
@ -43,7 +73,7 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
|
|||||||
|
|
||||||
const responseWriter = new SimpleResponseWriter();
|
const responseWriter = new SimpleResponseWriter();
|
||||||
|
|
||||||
handler = new AuthenticatedLdpHandler({
|
const handler = new AuthenticatedLdpHandler({
|
||||||
requestParser,
|
requestParser,
|
||||||
credentialsExtractor,
|
credentialsExtractor,
|
||||||
permissionsExtractor,
|
permissionsExtractor,
|
||||||
@ -51,101 +81,125 @@ describe('An AuthenticatedLdpHandler with instantiated handlers', (): void => {
|
|||||||
operationHandler,
|
operationHandler,
|
||||||
responseWriter,
|
responseWriter,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can add, read and delete data based on incoming requests.', async(): Promise<void> => {
|
||||||
|
// POST
|
||||||
|
let requestUrl = new url.URL('http://test.com/');
|
||||||
|
let response: MockResponse<any> = await call(
|
||||||
|
handler,
|
||||||
|
requestUrl,
|
||||||
|
'POST',
|
||||||
|
{ 'content-type': 'text/turtle' },
|
||||||
|
[ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ],
|
||||||
|
);
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(response._getData()).toHaveLength(0);
|
||||||
|
const id = response._getHeaders().location;
|
||||||
|
expect(id).toContain(url.format(requestUrl));
|
||||||
|
|
||||||
|
// GET
|
||||||
|
requestUrl = new url.URL(id);
|
||||||
|
response = await call(handler, requestUrl, 'GET', { accept: 'text/turtle' }, []);
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(response._getData()).toContain('<http://test.com/s> <http://test.com/p> <http://test.com/o>.');
|
||||||
|
expect(response._getHeaders().location).toBe(id);
|
||||||
|
|
||||||
|
// DELETE
|
||||||
|
response = await call(handler, requestUrl, 'DELETE', {}, []);
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(response._getData()).toHaveLength(0);
|
||||||
|
expect(response._getHeaders().location).toBe(url.format(requestUrl));
|
||||||
|
|
||||||
|
// GET
|
||||||
|
response = await call(handler, requestUrl, 'GET', { accept: 'text/turtle' }, []);
|
||||||
|
expect(response.statusCode).toBe(404);
|
||||||
|
expect(response._getData()).toContain('NotFoundHttpError');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('can add, read and delete data based on incoming requests.', async(): Promise<void> => {
|
describe('with simple PATCH handlers', (): void => {
|
||||||
// POST
|
const bodyParser: BodyParser = new CompositeAsyncHandler<HttpRequest, Representation>([
|
||||||
let requestUrl = new url.URL('http://test.com/');
|
new SimpleBodyParser(),
|
||||||
let request = streamifyArray([ '<http://test.com/s> <http://test.com/p> <http://test.com/o>.' ]) as HttpRequest;
|
new SimpleSparqlUpdateBodyParser(),
|
||||||
request.url = requestUrl.pathname;
|
]);
|
||||||
request.method = 'POST';
|
const requestParser = new SimpleRequestParser({
|
||||||
request.headers = {
|
targetExtractor: new SimpleTargetExtractor(),
|
||||||
'content-type': 'text/turtle',
|
preferenceParser: new AcceptPreferenceParser(),
|
||||||
host: requestUrl.host,
|
bodyParser,
|
||||||
};
|
|
||||||
let response: MockResponse<any> = createResponse({ eventEmitter: EventEmitter });
|
|
||||||
|
|
||||||
let id;
|
|
||||||
let endPromise = new Promise((resolve): void => {
|
|
||||||
response.on('end', (): void => {
|
|
||||||
expect(response._isEndCalled()).toBeTruthy();
|
|
||||||
expect(response.statusCode).toBe(200);
|
|
||||||
expect(response._getData()).toHaveLength(0);
|
|
||||||
id = response._getHeaders().location;
|
|
||||||
expect(id).toContain(url.format(requestUrl));
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await handler.handleSafe({ request, response });
|
const credentialsExtractor = new SimpleCredentialsExtractor();
|
||||||
await endPromise;
|
const permissionsExtractor = new SimplePermissionsExtractor();
|
||||||
|
const authorizer = new SimpleAuthorizer();
|
||||||
|
|
||||||
// GET
|
const store = new SimpleResourceStore('http://test.com/');
|
||||||
requestUrl = new url.URL(id);
|
const locker = new SingleThreadedResourceLocker();
|
||||||
request = {} as HttpRequest;
|
const patcher = new SimpleSparqlUpdatePatchHandler(store, locker);
|
||||||
request.url = requestUrl.pathname;
|
const patchingStore = new PatchingStore(store, patcher);
|
||||||
request.method = 'GET';
|
|
||||||
request.headers = {
|
|
||||||
accept: 'text/turtle',
|
|
||||||
host: requestUrl.host,
|
|
||||||
};
|
|
||||||
response = createResponse({ eventEmitter: EventEmitter });
|
|
||||||
|
|
||||||
endPromise = new Promise((resolve): void => {
|
const operationHandler = new CompositeAsyncHandler<Operation, ResponseDescription>([
|
||||||
response.on('end', (): void => {
|
new SimpleGetOperationHandler(patchingStore),
|
||||||
expect(response._isEndCalled()).toBeTruthy();
|
new SimplePostOperationHandler(patchingStore),
|
||||||
expect(response.statusCode).toBe(200);
|
new SimpleDeleteOperationHandler(patchingStore),
|
||||||
expect(response._getData()).toContain('<http://test.com/s> <http://test.com/p> <http://test.com/o>.');
|
new SimplePatchOperationHandler(patchingStore),
|
||||||
expect(response._getHeaders().location).toBe(url.format(requestUrl));
|
]);
|
||||||
resolve();
|
|
||||||
});
|
const responseWriter = new SimpleResponseWriter();
|
||||||
|
|
||||||
|
const handler = new AuthenticatedLdpHandler({
|
||||||
|
requestParser,
|
||||||
|
credentialsExtractor,
|
||||||
|
permissionsExtractor,
|
||||||
|
authorizer,
|
||||||
|
operationHandler,
|
||||||
|
responseWriter,
|
||||||
});
|
});
|
||||||
|
|
||||||
await handler.handleSafe({ request, response });
|
it('can handle simple SPARQL updates.', async(): Promise<void> => {
|
||||||
await endPromise;
|
// POST
|
||||||
|
let requestUrl = new url.URL('http://test.com/');
|
||||||
|
let response: MockResponse<any> = await call(
|
||||||
|
handler,
|
||||||
|
requestUrl,
|
||||||
|
'POST',
|
||||||
|
{ 'content-type': 'text/turtle' },
|
||||||
|
[ '<http://test.com/s1> <http://test.com/p1> <http://test.com/o1>.',
|
||||||
|
'<http://test.com/s2> <http://test.com/p2> <http://test.com/o2>.' ],
|
||||||
|
);
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(response._getData()).toHaveLength(0);
|
||||||
|
const id = response._getHeaders().location;
|
||||||
|
expect(id).toContain(url.format(requestUrl));
|
||||||
|
|
||||||
// DELETE
|
// PATCH
|
||||||
request = {} as HttpRequest;
|
requestUrl = new url.URL(id);
|
||||||
request.url = requestUrl.pathname;
|
response = await call(
|
||||||
request.method = 'DELETE';
|
handler,
|
||||||
request.headers = {
|
requestUrl,
|
||||||
host: requestUrl.host,
|
'PATCH',
|
||||||
};
|
{ 'content-type': 'application/sparql-update' },
|
||||||
response = createResponse({ eventEmitter: EventEmitter });
|
[ 'DELETE { <http://test.com/s1> <http://test.com/p1> <http://test.com/o1> }',
|
||||||
|
'INSERT {<http://test.com/s3> <http://test.com/p3> <http://test.com/o3>}',
|
||||||
|
'WHERE {}' ],
|
||||||
|
);
|
||||||
|
expect(response.statusCode).toBe(200);
|
||||||
|
expect(response._getData()).toHaveLength(0);
|
||||||
|
expect(response._getHeaders().location).toBe(id);
|
||||||
|
|
||||||
endPromise = new Promise((resolve): void => {
|
// GET
|
||||||
response.on('end', (): void => {
|
requestUrl = new url.URL(id);
|
||||||
expect(response._isEndCalled()).toBeTruthy();
|
response = await call(handler, requestUrl, 'GET', { accept: 'text/turtle' }, []);
|
||||||
expect(response.statusCode).toBe(200);
|
expect(response.statusCode).toBe(200);
|
||||||
expect(response._getData()).toHaveLength(0);
|
expect(response._getData()).toContain('<http://test.com/s2> <http://test.com/p2> <http://test.com/o2>.');
|
||||||
expect(response._getHeaders().location).toBe(url.format(requestUrl));
|
expect(response._getHeaders().location).toBe(id);
|
||||||
resolve();
|
const parser = new Parser();
|
||||||
});
|
const triples = parser.parse(response._getData());
|
||||||
|
expect(triples).toBeRdfIsomorphic(
|
||||||
|
[
|
||||||
|
quad(namedNode('http://test.com/s2'), namedNode('http://test.com/p2'), namedNode('http://test.com/o2')),
|
||||||
|
quad(namedNode('http://test.com/s3'), namedNode('http://test.com/p3'), namedNode('http://test.com/o3')),
|
||||||
|
],
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
await handler.handleSafe({ request, response });
|
|
||||||
await endPromise;
|
|
||||||
|
|
||||||
// GET
|
|
||||||
request = {} as HttpRequest;
|
|
||||||
request.url = requestUrl.pathname;
|
|
||||||
request.method = 'GET';
|
|
||||||
request.headers = {
|
|
||||||
accept: 'text/turtle',
|
|
||||||
host: requestUrl.host,
|
|
||||||
};
|
|
||||||
response = createResponse({ eventEmitter: EventEmitter });
|
|
||||||
|
|
||||||
endPromise = new Promise((resolve): void => {
|
|
||||||
response.on('end', (): void => {
|
|
||||||
expect(response._isEndCalled()).toBeTruthy();
|
|
||||||
expect(response.statusCode).toBe(404);
|
|
||||||
expect(response._getData()).toContain('NotFoundHttpError');
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
await handler.handleSafe({ request, response });
|
|
||||||
await endPromise;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -78,7 +78,7 @@ describe('A SimpleSparqlUpdatePatchHandler', (): void => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
it('only accepts SPARQL updates.', async(): Promise<void> => {
|
it('only accepts SPARQL updates.', async(): Promise<void> => {
|
||||||
const input = { identifier: { path: 'path' }, patch: { dataType: 'algebra', algebra: {}} as SparqlUpdatePatch };
|
const input = { identifier: { path: 'path' }, patch: { dataType: 'sparql-algebra', algebra: {}} as SparqlUpdatePatch };
|
||||||
await expect(handler.canHandle(input)).resolves.toBeUndefined();
|
await expect(handler.canHandle(input)).resolves.toBeUndefined();
|
||||||
input.patch.dataType = 'notAlgebra';
|
input.patch.dataType = 'notAlgebra';
|
||||||
await expect(handler.canHandle(input)).rejects.toThrow(UnsupportedHttpError);
|
await expect(handler.canHandle(input)).rejects.toThrow(UnsupportedHttpError);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user