mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
test: Use Components.js in SparqlStorage.
This commit is contained in:
@@ -1,66 +0,0 @@
|
||||
import type {
|
||||
DataAccessor,
|
||||
HttpHandler,
|
||||
ResourceStore,
|
||||
} from '../../src/index';
|
||||
import {
|
||||
AllowEverythingAuthorizer,
|
||||
AuthenticatedLdpHandler,
|
||||
EmptyCredentialsExtractor,
|
||||
MethodPermissionsExtractor,
|
||||
QuadToRdfConverter,
|
||||
RawBodyParser,
|
||||
RdfToQuadConverter,
|
||||
WaterfallHandler,
|
||||
} from '../../src/index';
|
||||
import type { ServerConfig } from './ServerConfig';
|
||||
import {
|
||||
getOperationHandler,
|
||||
getConvertingStore,
|
||||
getBasicRequestParser,
|
||||
getDataAccessorStore,
|
||||
getResponseWriter,
|
||||
} from './Util';
|
||||
|
||||
/**
|
||||
* DataAccessorBasedConfig works with
|
||||
* - an AllowEverythingAuthorizer (no acl)
|
||||
* - a DataAccessorBasedStore with a FileDataAccessor wrapped in a converting store (rdf to quad & quad to rdf)
|
||||
* - GET, POST, PUT & DELETE operation handlers
|
||||
*/
|
||||
export class DataAccessorBasedConfig implements ServerConfig {
|
||||
public store: ResourceStore;
|
||||
|
||||
public constructor(base: string, dataAccessor: DataAccessor, inType?: string) {
|
||||
this.store = getConvertingStore(
|
||||
getDataAccessorStore(base, dataAccessor),
|
||||
[ new QuadToRdfConverter(), new RdfToQuadConverter() ],
|
||||
inType,
|
||||
);
|
||||
}
|
||||
|
||||
public getHttpHandler(): HttpHandler {
|
||||
// This is for the sake of test coverage, as it could also be just getBasicRequestParser()
|
||||
const requestParser = getBasicRequestParser([ new RawBodyParser() ]);
|
||||
|
||||
const credentialsExtractor = new EmptyCredentialsExtractor();
|
||||
const permissionsExtractor = new WaterfallHandler([
|
||||
new MethodPermissionsExtractor(),
|
||||
]);
|
||||
const authorizer = new AllowEverythingAuthorizer();
|
||||
|
||||
const operationHandler = getOperationHandler(this.store);
|
||||
const responseWriter = getResponseWriter();
|
||||
|
||||
const handler = new AuthenticatedLdpHandler({
|
||||
requestParser,
|
||||
credentialsExtractor,
|
||||
permissionsExtractor,
|
||||
authorizer,
|
||||
operationHandler,
|
||||
responseWriter,
|
||||
});
|
||||
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import type { HttpHandler } from '../../src/server/HttpHandler';
|
||||
import type { ResourceStore } from '../../src/storage/ResourceStore';
|
||||
|
||||
export interface ServerConfig {
|
||||
store: ResourceStore;
|
||||
getHttpHandler: () => HttpHandler;
|
||||
}
|
||||
@@ -1,48 +1,6 @@
|
||||
import { join } from 'path';
|
||||
import * as Path from 'path';
|
||||
import { Loader } from 'componentsjs';
|
||||
import type {
|
||||
BodyParser,
|
||||
DataAccessor,
|
||||
Operation,
|
||||
RepresentationConverter,
|
||||
ResourceStore,
|
||||
ResponseDescription,
|
||||
HttpResponse,
|
||||
ResponseWriter,
|
||||
OperationHandler,
|
||||
} from '../../src/index';
|
||||
import {
|
||||
AcceptPreferenceParser,
|
||||
BasicMetadataExtractor,
|
||||
BasicRequestParser,
|
||||
BasicResponseWriter,
|
||||
BasicTargetExtractor,
|
||||
ContentTypeParser,
|
||||
DataAccessorBasedStore,
|
||||
DeleteOperationHandler,
|
||||
ErrorResponseWriter,
|
||||
GetOperationHandler,
|
||||
HeadOperationHandler,
|
||||
LinkRelMetadataWriter,
|
||||
LinkTypeParser,
|
||||
MappedMetadataWriter,
|
||||
PatchingStore,
|
||||
PatchOperationHandler,
|
||||
PostOperationHandler,
|
||||
PutOperationHandler,
|
||||
RawBodyParser,
|
||||
RepresentationConvertingStore,
|
||||
SequenceHandler,
|
||||
SingleRootIdentifierStrategy,
|
||||
SingleThreadedResourceLocker,
|
||||
SlugParser,
|
||||
SparqlUpdatePatchHandler,
|
||||
UrlBasedAclManager,
|
||||
WaterfallHandler,
|
||||
WebAclAuthorizer,
|
||||
} from '../../src/index';
|
||||
import { CONTENT_TYPE, HTTP, RDF } from '../../src/util/UriConstants';
|
||||
|
||||
export const BASE = 'http://test.com';
|
||||
|
||||
@@ -52,122 +10,6 @@ export const BASE = 'http://test.com';
|
||||
*/
|
||||
export const getRootFilePath = (subfolder: string): string => join(__dirname, '../testData', subfolder);
|
||||
|
||||
/**
|
||||
* Gives a data accessor store with the given data accessor.
|
||||
* @param base - Base URL.
|
||||
* @param dataAccessor - DataAccessor to use.
|
||||
*
|
||||
* @returns The data accessor based store.
|
||||
*/
|
||||
export const getDataAccessorStore = (base: string, dataAccessor: DataAccessor): DataAccessorBasedStore =>
|
||||
new DataAccessorBasedStore(dataAccessor, new SingleRootIdentifierStrategy(base));
|
||||
|
||||
/**
|
||||
* Gives a converting store given some converters.
|
||||
* @param store - Initial store.
|
||||
* @param converters - Converters to be used.
|
||||
*
|
||||
* @returns The converting store.
|
||||
*/
|
||||
export const getConvertingStore =
|
||||
(store: ResourceStore, converters: RepresentationConverter[], inType?: string):
|
||||
RepresentationConvertingStore =>
|
||||
new RepresentationConvertingStore(store, {
|
||||
inConverter: new WaterfallHandler(converters),
|
||||
outConverter: new WaterfallHandler(converters),
|
||||
inType,
|
||||
});
|
||||
|
||||
/**
|
||||
* Gives a patching store based on initial store.
|
||||
* @param store - Initial resource store.
|
||||
*
|
||||
* @returns The patching store.
|
||||
*/
|
||||
export const getPatchingStore = (store: ResourceStore): PatchingStore => {
|
||||
const locker = new SingleThreadedResourceLocker();
|
||||
const patcher = new SparqlUpdatePatchHandler(store, locker);
|
||||
return new PatchingStore(store, patcher);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives an operation handler given a store with all the common operation handlers.
|
||||
* @param store - Initial resource store.
|
||||
*
|
||||
* @returns The operation handler.
|
||||
*/
|
||||
export const getOperationHandler = (store: ResourceStore): OperationHandler => {
|
||||
const handlers = [
|
||||
new GetOperationHandler(store),
|
||||
new HeadOperationHandler(store),
|
||||
new PostOperationHandler(store),
|
||||
new PutOperationHandler(store),
|
||||
new PatchOperationHandler(store),
|
||||
new DeleteOperationHandler(store),
|
||||
];
|
||||
return new WaterfallHandler<Operation, ResponseDescription>(handlers);
|
||||
};
|
||||
|
||||
export const getResponseWriter = (): ResponseWriter => {
|
||||
const serializer = new SequenceHandler([
|
||||
new MappedMetadataWriter({
|
||||
[CONTENT_TYPE]: 'content-type',
|
||||
[HTTP.location]: 'location',
|
||||
}),
|
||||
new LinkRelMetadataWriter({
|
||||
[RDF.type]: 'type',
|
||||
}),
|
||||
]);
|
||||
|
||||
return new WaterfallHandler<{ response: HttpResponse; result: ResponseDescription | Error }, void>([
|
||||
new ErrorResponseWriter(),
|
||||
new BasicResponseWriter(serializer),
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a BasicMetadataExtractor with parsers for content-type, slugs and link types.
|
||||
*/
|
||||
export const getBasicMetadataExtractor = (): BasicMetadataExtractor => new BasicMetadataExtractor([
|
||||
new ContentTypeParser(),
|
||||
new SlugParser(),
|
||||
new LinkTypeParser(),
|
||||
]);
|
||||
|
||||
/**
|
||||
* Gives a basic request parser based on some body parses.
|
||||
* @param bodyParsers - Optional list of body parsers, default is RawBodyParser.
|
||||
*
|
||||
* @returns The request parser.
|
||||
*/
|
||||
export const getBasicRequestParser = (bodyParsers: BodyParser[] = []): BasicRequestParser => {
|
||||
let bodyParser: BodyParser;
|
||||
if (bodyParsers.length === 1) {
|
||||
bodyParser = bodyParsers[0];
|
||||
} else if (bodyParsers.length === 0) {
|
||||
// If no body parser is given (array is empty), default to RawBodyParser
|
||||
bodyParser = new RawBodyParser();
|
||||
} else {
|
||||
bodyParser = new WaterfallHandler(bodyParsers);
|
||||
}
|
||||
return new BasicRequestParser({
|
||||
targetExtractor: new BasicTargetExtractor(),
|
||||
preferenceParser: new AcceptPreferenceParser(),
|
||||
metadataExtractor: getBasicMetadataExtractor(),
|
||||
bodyParser,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Gives a web acl authorizer based on a (default) runtimeConfig.
|
||||
* @param store - Initial resource store.
|
||||
* @param aclManager - Optional acl manager, default is UrlBasedAclManager.
|
||||
*
|
||||
* @returns The acl authorizer.
|
||||
*/
|
||||
export const getWebAclAuthorizer = (store: ResourceStore, aclManager = new UrlBasedAclManager()): WebAclAuthorizer =>
|
||||
new WebAclAuthorizer(aclManager, store, new SingleRootIdentifierStrategy(BASE));
|
||||
|
||||
/**
|
||||
* Returns a component instantiated from a Components.js configuration.
|
||||
*/
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"files-scs:config/presets/representation-conversion.json",
|
||||
"files-scs:config/presets/storage/backend/storage-memory.json",
|
||||
"files-scs:config/presets/storage/backend/storage-filesystem.json",
|
||||
"files-scs:config/presets/storage/backend/storage-sparql-endpoint.json",
|
||||
"files-scs:config/presets/storage-wrapper.json",
|
||||
"files-scs:config/presets/cli-params.json"
|
||||
],
|
||||
@@ -23,7 +24,13 @@
|
||||
"RecordObject:_record": [
|
||||
{
|
||||
"RecordObject:_record_key": "initializer",
|
||||
"RecordObject:_record_value": { "@id": "urn:solid-server:default:AclInitializer" }
|
||||
"RecordObject:_record_value": {
|
||||
"@type": "SequenceHandler",
|
||||
"SequenceHandler:_handlers": [
|
||||
{ "@id": "urn:solid-server:default:RootContainerInitializer" },
|
||||
{ "@id": "urn:solid-server:default:AclInitializer" }
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"RecordObject:_record_key": "handler",
|
||||
|
||||
@@ -1,23 +1,37 @@
|
||||
import { RootContainerInitializer } from '../../src/init/RootContainerInitializer';
|
||||
import { SparqlDataAccessor } from '../../src/storage/accessors/SparqlDataAccessor';
|
||||
import { INTERNAL_QUADS } from '../../src/util/ContentTypes';
|
||||
import { SingleRootIdentifierStrategy } from '../../src/util/identifiers/SingleRootIdentifierStrategy';
|
||||
import { DataAccessorBasedConfig } from '../configs/DataAccessorBasedConfig';
|
||||
import { BASE } from '../configs/Util';
|
||||
import type { HttpHandler, Initializer, ResourceStore } from '../../src/';
|
||||
import { BASE, instantiateFromConfig } from '../configs/Util';
|
||||
import { describeIf, FileTestHelper } from '../util/TestHelpers';
|
||||
|
||||
describeIf('docker', 'a server with a SPARQL endpoint as storage', (): void => {
|
||||
describe('without acl', (): void => {
|
||||
const config = new DataAccessorBasedConfig(BASE,
|
||||
new SparqlDataAccessor('http://localhost:4000/sparql', new SingleRootIdentifierStrategy(BASE)),
|
||||
INTERNAL_QUADS);
|
||||
const handler = config.getHttpHandler();
|
||||
const fileHelper = new FileTestHelper(handler, new URL(BASE));
|
||||
let handler: HttpHandler;
|
||||
let fileHelper: FileTestHelper;
|
||||
|
||||
beforeAll(async(): Promise<void> => {
|
||||
// Initialize store
|
||||
const initializer = new RootContainerInitializer(BASE, config.store);
|
||||
// Set up the internal store
|
||||
const variables: Record<string, any> = {
|
||||
'urn:solid-server:default:variable:baseUrl': BASE,
|
||||
'urn:solid-server:default:variable:sparqlEndpoint': 'http://localhost:4000/sparql',
|
||||
};
|
||||
const internalStore = await instantiateFromConfig(
|
||||
'urn:solid-server:default:SparqlResourceStore',
|
||||
'auth-ldp-handler.json',
|
||||
variables,
|
||||
) as ResourceStore;
|
||||
variables['urn:solid-server:default:variable:store'] = internalStore;
|
||||
|
||||
// Create and initialize the HTTP handler and related components
|
||||
let initializer: Initializer;
|
||||
const instances = await instantiateFromConfig(
|
||||
'urn:solid-server:test:Instances',
|
||||
'auth-ldp-handler.json',
|
||||
variables,
|
||||
) as Record<string, any>;
|
||||
({ handler, initializer } = instances);
|
||||
await initializer.handleSafe();
|
||||
|
||||
// Create test helpers for manipulating the components
|
||||
fileHelper = new FileTestHelper(handler, new URL(BASE));
|
||||
});
|
||||
|
||||
it('can add a Turtle file to the store.', async():
|
||||
|
||||
Reference in New Issue
Block a user