refactor: Remove RuntimeConfig in favor of config variables, Closes #106

This commit is contained in:
Ruben Taelman 2020-09-11 10:18:53 +02:00 committed by Joachim Van Herwegen
parent b1991cb08a
commit 1dd140ab61
25 changed files with 116 additions and 199 deletions

View File

@ -10,6 +10,7 @@
"files-scs:config/presets/ldp/request-parser.json",
"files-scs:config/presets/setup.json",
"files-scs:config/presets/storage.json",
"files-scs:config/presets/storage_wrapper.json"
"files-scs:config/presets/storage_wrapper.json",
"files-scs:config/presets/cli-params.json"
]
}

View File

@ -0,0 +1,17 @@
{
"@context": "https://linkedsoftwaredependencies.org/bundles/npm/@solid/community-server/^1.0.0/components/context.jsonld",
"@graph": [
{
"@id": "urn:solid-server:default:variable:port",
"@type": "Variable"
},
{
"@id": "urn:solid-server:default:variable:base",
"@type": "Variable"
},
{
"@id": "urn:solid-server:default:variable:rootFilePath",
"@type": "Variable"
}
]
}

View File

@ -13,10 +13,11 @@
"Setup:_aclManager": {
"@id": "urn:solid-server:default:AclManager"
},
"Setup:_runtimeConfig": {
"@id": "urn:solid-server:default:RuntimeConfig",
"@type": "RuntimeConfig",
"RuntimeConfigData:_port": 3000
"Setup:_base": {
"@id": "urn:solid-server:default:variable:base"
},
"Setup:_port": {
"@id": "urn:solid-server:default:variable:port"
}
}
]

View File

@ -4,8 +4,8 @@
{
"@id": "urn:solid-server:default:ResourceStore",
"@type": "InMemoryResourceStore",
"InMemoryResourceStore:_runtimeConfig": {
"@id": "urn:solid-server:default:RuntimeConfig"
"InMemoryResourceStore:_base": {
"@id": "urn:solid-server:default:variable:base"
}
}
]

View File

@ -72,8 +72,8 @@
{
"@id": "urn:solid-server:default:UrlContainerManager",
"@type": "UrlContainerManager",
"UrlContainerManager:_runtimeConfig": {
"@id": "urn:solid-server:default:RuntimeConfig"
"UrlContainerManager:_base": {
"@id": "urn:solid-server:default:variable:base"
}
}
]

View File

@ -12,7 +12,6 @@ export * from './src/authorization/WebAclAuthorizer';
// Init
export * from './src/init/CliRunner';
export * from './src/init/RuntimeConfig';
export * from './src/init/Setup';
// LDP/HTTP

6
package-lock.json generated
View File

@ -2519,9 +2519,9 @@
}
},
"componentsjs": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/componentsjs/-/componentsjs-3.4.2.tgz",
"integrity": "sha512-ICaSvvxY/CvWwFt0lLsoRL/DHY09akoI6x9WakQQ9g4GYHVaZumWSAdOrzM/htjGpBumpVh1C/4hk0/ghh9jXA==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/componentsjs/-/componentsjs-3.6.0.tgz",
"integrity": "sha512-G3lMrIbE7iiZpERoPXnxM0aDopq9q1s1C5aIUrnHW3rcRDa3kcCytc4ASt5aFRjNiwBubivcMfJsvF2ihXg7jQ==",
"requires": {
"@types/lodash": "^4.14.56",
"@types/minimist": "^1.2.0",

View File

@ -42,7 +42,7 @@
"prepare": "npm run build",
"start": "node ./bin/server.js -p 3000",
"test": "jest",
"validate": "componentsjs-compile-config urn:solid-server:default -c config/config-default.json > /dev/null",
"validate": "componentsjs-compile-config urn:solid-server:default -c config/config-default.json -f > /dev/null",
"version": "manual-git-changelog onversion",
"watch": "nodemon --watch \"src/**/*.js\" --watch \"bin/**/*.js\" --exec npm start"
},
@ -76,7 +76,7 @@
"@types/yargs": "^15.0.5",
"arrayify-stream": "^1.0.0",
"async-lock": "^1.2.4",
"componentsjs": "^3.4.2",
"componentsjs": "^3.6.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"mime-types": "^2.1.27",

View File

@ -2,7 +2,6 @@ import * as Path from 'path';
import { ReadStream, WriteStream } from 'tty';
import { Loader, LoaderProperties } from 'componentsjs';
import yargs from 'yargs';
import { RuntimeConfig } from './RuntimeConfig';
import { Setup } from './Setup';
/**
@ -23,12 +22,12 @@ export const runCustom = function(
const { argv } = yargs
.usage('node ./bin/server.js [args]')
.options({
port: { type: 'number', alias: 'p' },
port: { type: 'number', alias: 'p', default: 3000 },
config: { type: 'string', alias: 'c' },
})
.help();
new Promise<RuntimeConfig>(async(resolve): Promise<void> => {
(async(): Promise<string> => {
// Load provided or default config file
const configPath = argv.config ?
Path.join(process.cwd(), argv.config) :
@ -38,10 +37,16 @@ export const runCustom = function(
const loader = new Loader(properties);
await loader.registerAvailableModuleResources();
const setup: Setup = await loader
.instantiateFromUrl('urn:solid-server:default', configPath);
resolve(await setup.setup({ port: argv.port }));
}).then((runtimeConfig: RuntimeConfig): void => {
stdout.write(`Running at ${runtimeConfig.base}\n`);
.instantiateFromUrl('urn:solid-server:default', configPath, undefined, {
variables: {
'urn:solid-server:default:variable:port': argv.port,
'urn:solid-server:default:variable:base': `http://localhost:${argv.port}/`,
'urn:solid-server:default:variable:rootFilePath': process.cwd(),
},
});
return await setup.setup();
})().then((base: string): void => {
stdout.write(`Running at ${base}\n`);
}).catch((error): void => {
stderr.write(`${error}\n`);
});

View File

@ -1,43 +0,0 @@
import { ensureTrailingSlash } from '../util/Util';
/**
* This class holds all configuration options that can be defined by the user via the command line.
*
* Concretely, this contains data that is only relevant *after* dependency injection.
*/
export class RuntimeConfig implements RuntimeConfigData {
private pport!: number;
private pbase!: string;
private prootFilepath!: string;
public constructor(data: RuntimeConfigData = {}) {
this.reset(data);
}
public reset(data: RuntimeConfigData): void {
this.pport = data.port ?? 3000;
this.pbase = ensureTrailingSlash(data.base ?? `http://localhost:${this.port}/`);
this.prootFilepath = data.rootFilepath ?? process.cwd();
}
/**
* The returned URL is ensured to have a trailing slash.
*/
public get base(): string {
return this.pbase;
}
public get port(): number {
return this.pport;
}
public get rootFilepath(): string {
return this.prootFilepath;
}
}
export interface RuntimeConfigData {
port?: number;
base?: string;
rootFilepath?: string;
}

View File

@ -3,7 +3,6 @@ import { AclManager } from '../authorization/AclManager';
import { ExpressHttpServer } from '../server/ExpressHttpServer';
import { ResourceStore } from '../storage/ResourceStore';
import { TEXT_TURTLE } from '../util/ContentTypes';
import { RuntimeConfig, RuntimeConfigData } from './RuntimeConfig';
/**
* Invokes all logic to setup a server.
@ -12,27 +11,27 @@ export class Setup {
private readonly httpServer: ExpressHttpServer;
private readonly store: ResourceStore;
private readonly aclManager: AclManager;
private readonly runtimeConfig: RuntimeConfig;
private readonly base: string;
private readonly port: number;
public constructor(
httpServer: ExpressHttpServer,
store: ResourceStore,
aclManager: AclManager,
runtimeConfig: RuntimeConfig,
base: string,
port: number,
) {
this.httpServer = httpServer;
this.store = store;
this.aclManager = aclManager;
this.runtimeConfig = runtimeConfig;
this.base = base;
this.port = port;
}
/**
* Set up a server at the given port and base URL.
* @param data - Runtime config data.
* Set up a server.
*/
public async setup(data: RuntimeConfigData = {}): Promise<RuntimeConfig> {
this.runtimeConfig.reset(data);
public async setup(): Promise<string> {
// Set up acl so everything can still be done by default
// Note that this will need to be adapted to go through all the correct channels later on
const aclSetup = async(): Promise<void> => {
@ -47,10 +46,10 @@ export class Setup {
acl:mode acl:Append;
acl:mode acl:Delete;
acl:mode acl:Control;
acl:accessTo <${this.runtimeConfig.base}>;
acl:default <${this.runtimeConfig.base}>.`;
acl:accessTo <${this.base}>;
acl:default <${this.base}>.`;
await this.store.setRepresentation(
await this.aclManager.getAcl({ path: this.runtimeConfig.base }),
await this.aclManager.getAcl({ path: this.base }),
{
binary: true,
data: streamifyArray([ acl ]),
@ -64,8 +63,8 @@ export class Setup {
};
await aclSetup();
this.httpServer.listen(this.runtimeConfig.port);
this.httpServer.listen(this.port);
return this.runtimeConfig;
return this.base;
}
}

View File

@ -1,6 +1,5 @@
import { posix } from 'path';
import { types } from 'mime-types';
import { RuntimeConfig } from '../init/RuntimeConfig';
import { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import { APPLICATION_OCTET_STREAM, TEXT_TURTLE } from '../util/ContentTypes';
import { ConflictHttpError } from '../util/errors/ConflictHttpError';
@ -24,22 +23,22 @@ export interface ResourcePath {
}
export class ExtensionBasedMapper implements FileIdentifierMapper {
private readonly runtimeConfig: RuntimeConfig;
private readonly base: string;
private readonly prootFilepath: string;
private readonly types: Record<string, any>;
public constructor(runtimeConfig: RuntimeConfig, overrideTypes = { acl: TEXT_TURTLE, metadata: TEXT_TURTLE }) {
this.runtimeConfig = runtimeConfig;
public constructor(base: string, rootFilepath: string, overrideTypes = { acl: TEXT_TURTLE, metadata: TEXT_TURTLE }) {
this.base = base;
this.prootFilepath = rootFilepath;
this.types = { ...types, ...overrideTypes };
}
// Using getters because the values of runtimeConfig get filled in at runtime (so they are still empty at
// construction time until issue #106 gets resolved.)
public get baseRequestURI(): string {
return trimTrailingSlashes(this.runtimeConfig.base);
return trimTrailingSlashes(this.base);
}
public get rootFilepath(): string {
return trimTrailingSlashes(this.runtimeConfig.rootFilepath);
return trimTrailingSlashes(this.prootFilepath);
}
/**

View File

@ -1,7 +1,6 @@
import { PassThrough } from 'stream';
import arrayifyStream from 'arrayify-stream';
import streamifyArray from 'streamify-array';
import { RuntimeConfig } from '../init/RuntimeConfig';
import { Representation } from '../ldp/representation/Representation';
import { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import { TEXT_TURTLE } from '../util/ContentTypes';
@ -15,15 +14,15 @@ import { ResourceStore } from './ResourceStore';
*/
export class InMemoryResourceStore implements ResourceStore {
private readonly store: { [id: string]: Representation };
private readonly runtimeConfig: RuntimeConfig;
private readonly base: string;
private index = 0;
/**
* @param runtimeConfig - Config containing base that will be stripped of all incoming URIs
* and added to all outgoing ones to find the relative path.
* @param base - Base that will be stripped of all incoming URIs
* and added to all outgoing ones to find the relative path.
*/
public constructor(runtimeConfig: RuntimeConfig) {
this.runtimeConfig = runtimeConfig;
public constructor(base: string) {
this.base = ensureTrailingSlash(base);
this.store = {
// Default root entry (what you get when the identifier is equal to the base)
@ -105,8 +104,8 @@ export class InMemoryResourceStore implements ResourceStore {
* @returns A string representing the relative path.
*/
private parseIdentifier(identifier: ResourceIdentifier): string {
const path = identifier.path.slice(this.runtimeConfig.base.length);
if (!identifier.path.startsWith(this.runtimeConfig.base)) {
const path = identifier.path.slice(this.base.length);
if (!identifier.path.startsWith(this.base)) {
throw new NotFoundHttpError();
}
return path;

View File

@ -1,4 +1,3 @@
import { RuntimeConfig } from '../init/RuntimeConfig';
import { ResourceIdentifier } from '../ldp/representation/ResourceIdentifier';
import { ensureTrailingSlash } from '../util/Util';
import { ContainerManager } from './ContainerManager';
@ -7,15 +6,15 @@ import { ContainerManager } from './ContainerManager';
* Determines containers based on URL decomposition.
*/
export class UrlContainerManager implements ContainerManager {
private readonly runtimeConfig: RuntimeConfig;
private readonly base: string;
public constructor(runtimeConfig: RuntimeConfig) {
this.runtimeConfig = runtimeConfig;
public constructor(base: string) {
this.base = base;
}
public async getContainer(id: ResourceIdentifier): Promise<ResourceIdentifier> {
const path = this.canonicalUrl(id.path);
if (this.runtimeConfig.base === path) {
if (this.base === path) {
throw new Error('Root does not have a container.');
}

View File

@ -8,7 +8,6 @@ import {
ResourceStore,
UnsecureWebIdExtractor,
QuadToRdfConverter,
RuntimeConfig,
} from '../../index';
import { ServerConfig } from './ServerConfig';
import {
@ -27,13 +26,13 @@ import {
*/
export class AuthenticatedFileResourceStoreConfig implements ServerConfig {
private readonly runtimeConfig: RuntimeConfig;
public base: string;
public store: ResourceStore;
public constructor(runtimeConfig: RuntimeConfig) {
this.runtimeConfig = runtimeConfig;
public constructor(base: string, rootFilepath: string) {
this.base = base;
this.store = getConvertingStore(
getFileResourceStore(runtimeConfig),
getFileResourceStore(base, rootFilepath),
[ new QuadToRdfConverter(),
new RdfToQuadConverter() ],
);
@ -50,7 +49,7 @@ export class AuthenticatedFileResourceStoreConfig implements ServerConfig {
const operationHandler = getOperationHandler(this.store);
const responseWriter = new BasicResponseWriter();
const authorizer = getWebAclAuthorizer(this.store, this.runtimeConfig.base);
const authorizer = getWebAclAuthorizer(this.store, this.base);
const handler = new AuthenticatedLdpHandler({
requestParser,

View File

@ -9,7 +9,6 @@ import {
RawBodyParser,
RdfToQuadConverter,
ResourceStore,
RuntimeConfig,
UnsecureWebIdExtractor,
} from '../../index';
import { ServerConfig } from './ServerConfig';
@ -25,9 +24,9 @@ import { getFileResourceStore, getOperationHandler, getConvertingStore, getBasic
export class FileResourceStoreConfig implements ServerConfig {
public store: ResourceStore;
public constructor(runtimeConfig: RuntimeConfig) {
public constructor(base: string, rootFilepath: string) {
this.store = getConvertingStore(
getFileResourceStore(runtimeConfig),
getFileResourceStore(base, rootFilepath),
[ new QuadToRdfConverter(), new RdfToQuadConverter() ],
);
}

View File

@ -23,7 +23,6 @@ import {
RepresentationConvertingStore,
ResourceStore,
ResponseDescription,
RuntimeConfig,
SingleThreadedResourceLocker,
SparqlUpdatePatchHandler,
UrlBasedAclManager,
@ -32,26 +31,24 @@ import {
} from '../../index';
import { ExtensionBasedMapper } from '../../src/storage/ExtensionBasedMapper';
const BASE = 'http://test.com';
export const BASE = 'http://test.com';
/**
* Creates a RuntimeConfig with its rootFilePath set based on the given subfolder.
* @param subfolder - Folder to use in the global testData folder.
*/
export const getRuntimeConfig = (subfolder: string): RuntimeConfig => new RuntimeConfig({
base: BASE,
rootFilepath: join(__dirname, '../testData', subfolder),
});
export const getRootFilePath = (subfolder: string): string => join(__dirname, '../testData', subfolder);
/**
* Gives a file resource store based on (default) runtime config.
* @param runtimeConfig - Optional runtime config.
* @param base - Base URL.
* @param rootFilepath - The root file path.
*
* @returns The file resource store.
*/
export const getFileResourceStore = (runtimeConfig: RuntimeConfig): FileResourceStore =>
export const getFileResourceStore = (base: string, rootFilepath: string): FileResourceStore =>
new FileResourceStore(
new ExtensionBasedMapper(runtimeConfig),
new ExtensionBasedMapper(base, rootFilepath),
new InteractionController(),
new MetadataController(),
);
@ -63,7 +60,7 @@ export const getFileResourceStore = (runtimeConfig: RuntimeConfig): FileResource
* @returns The in memory resource store.
*/
export const getInMemoryResourceStore = (base = BASE): InMemoryResourceStore =>
new InMemoryResourceStore(new RuntimeConfig({ base }));
new InMemoryResourceStore(base);
/**
* Gives a converting store given some converters.
@ -138,6 +135,6 @@ export const getBasicRequestParser = (bodyParsers: BodyParser[] = []): BasicRequ
*/
export const getWebAclAuthorizer =
(store: ResourceStore, base = BASE, aclManager = new UrlBasedAclManager()): WebAclAuthorizer => {
const containerManager = new UrlContainerManager(new RuntimeConfig({ base }));
const containerManager = new UrlContainerManager(base);
return new WebAclAuthorizer(aclManager, containerManager, store);
};

View File

@ -1,9 +1,10 @@
import { copyFileSync, mkdirSync } from 'fs';
import { join } from 'path';
import * as rimraf from 'rimraf';
import { HttpHandler, ResourceStore, RuntimeConfig } from '../../index';
import { HttpHandler, ResourceStore } from '../../index';
import { ensureTrailingSlash } from '../../src/util/Util';
import { AuthenticatedFileResourceStoreConfig } from '../configs/AuthenticatedFileResourceStoreConfig';
import { getRuntimeConfig } from '../configs/Util';
import { BASE, getRootFilePath } from '../configs/Util';
import { AclTestHelper, FileTestHelper } from '../util/TestHelpers';
describe('A server using a AuthenticatedFileResourceStore', (): void => {
@ -12,24 +13,23 @@ describe('A server using a AuthenticatedFileResourceStore', (): void => {
let store: ResourceStore;
let aclHelper: AclTestHelper;
let fileHelper: FileTestHelper;
let runtimeConfig: RuntimeConfig;
let rootFilePath: string;
beforeAll(async(): Promise<void> => {
runtimeConfig = getRuntimeConfig('AuthenticatedFileResourceStore');
config = new AuthenticatedFileResourceStoreConfig(runtimeConfig);
const { base, rootFilepath } = runtimeConfig;
rootFilePath = getRootFilePath('AuthenticatedFileResourceStore');
config = new AuthenticatedFileResourceStoreConfig(BASE, rootFilePath);
handler = config.getHttpHandler();
({ store } = config);
aclHelper = new AclTestHelper(store, base);
fileHelper = new FileTestHelper(handler, new URL('http://test.com/'));
aclHelper = new AclTestHelper(store, ensureTrailingSlash(BASE));
fileHelper = new FileTestHelper(handler, new URL(ensureTrailingSlash(BASE)));
// Make sure the root directory exists
mkdirSync(rootFilepath, { recursive: true });
copyFileSync(join(__dirname, '../assets/permanent.txt'), `${rootFilepath}/permanent.txt`);
mkdirSync(rootFilePath, { recursive: true });
copyFileSync(join(__dirname, '../assets/permanent.txt'), `${rootFilePath}/permanent.txt`);
});
afterAll(async(): Promise<void> => {
rimraf.sync(runtimeConfig.rootFilepath, { glob: false });
rimraf.sync(rootFilePath, { glob: false });
});
describe('with acl', (): void => {

View File

@ -1,26 +1,25 @@
import * as rimraf from 'rimraf';
import { RuntimeConfig } from '../../src/init/RuntimeConfig';
import { HttpHandler } from '../../src/server/HttpHandler';
import { FileResourceStoreConfig } from '../configs/FileResourceStoreConfig';
import { getRuntimeConfig } from '../configs/Util';
import { BASE, getRootFilePath } from '../configs/Util';
import { FileTestHelper } from '../util/TestHelpers';
describe('A server using a FileResourceStore', (): void => {
describe('without acl', (): void => {
let rootFilePath: string;
let config: FileResourceStoreConfig;
let handler: HttpHandler;
let fileHelper: FileTestHelper;
let runtimeConfig: RuntimeConfig;
beforeAll(async(): Promise<void> => {
runtimeConfig = getRuntimeConfig('FileResourceStore');
config = new FileResourceStoreConfig(runtimeConfig);
rootFilePath = getRootFilePath('FileResourceStore');
config = new FileResourceStoreConfig(BASE, rootFilePath);
handler = config.getHttpHandler();
fileHelper = new FileTestHelper(handler, new URL(runtimeConfig.base));
fileHelper = new FileTestHelper(handler, new URL(BASE));
});
afterAll(async(): Promise<void> => {
rimraf.sync(runtimeConfig.rootFilepath, { glob: false });
rimraf.sync(rootFilePath, { glob: false });
});
it('can add a file to the store, read it and delete it.', async():

View File

@ -1,48 +0,0 @@
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
describe('RuntimeConfig', (): void => {
it('handles undefined args.', async(): Promise<void> => {
const config = new RuntimeConfig();
expect(config.port).toEqual(3000);
expect(config.base).toEqual('http://localhost:3000/');
});
it('handles empty args.', async(): Promise<void> => {
const config = new RuntimeConfig({});
expect(config.port).toEqual(3000);
expect(config.base).toEqual('http://localhost:3000/');
});
it('handles args with port.', async(): Promise<void> => {
const config = new RuntimeConfig({ port: 1234 });
expect(config.port).toEqual(1234);
expect(config.base).toEqual('http://localhost:1234/');
});
it('handles args with base.', async(): Promise<void> => {
const config = new RuntimeConfig({ base: 'http://example.org/' });
expect(config.port).toEqual(3000);
expect(config.base).toEqual('http://example.org/');
});
it('handles args with port and base.', async(): Promise<void> => {
const config = new RuntimeConfig({ port: 1234, base: 'http://example.org/' });
expect(config.port).toEqual(1234);
expect(config.base).toEqual('http://example.org/');
});
it('handles resetting data.', async(): Promise<void> => {
const config = new RuntimeConfig({});
expect(config.port).toEqual(3000);
expect(config.base).toEqual('http://localhost:3000/');
config.reset({ port: 1234, base: 'http://example.org/' });
expect(config.port).toEqual(1234);
expect(config.base).toEqual('http://example.org/');
});
it('ensures trailing slash in base.', async(): Promise<void> => {
const config = new RuntimeConfig({ base: 'http://example.org' });
expect(config.base).toEqual('http://example.org/');
});
});

View File

@ -1,4 +1,3 @@
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
import { Setup } from '../../../src/init/Setup';
describe('Setup', (): void => {
@ -16,7 +15,7 @@ describe('Setup', (): void => {
httpServer = {
listen: jest.fn(),
};
setup = new Setup(httpServer, store, aclManager, new RuntimeConfig());
setup = new Setup(httpServer, store, aclManager, 'http://localhost:3000/', 3000);
});
it('starts an HTTP server.', async(): Promise<void> => {

View File

@ -1,10 +1,9 @@
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
import { ExtensionBasedMapper } from '../../../src/storage/ExtensionBasedMapper';
describe('An ExtensionBasedMapper', (): void => {
const base = 'http://test.com/';
const rootFilepath = 'uploads/';
const resourceMapper = new ExtensionBasedMapper(new RuntimeConfig({ base, rootFilepath }));
const resourceMapper = new ExtensionBasedMapper(base, rootFilepath);
it('returns the correct url of a file.', async(): Promise<void> => {
let result = resourceMapper.mapFilePathToUrl(`${rootFilepath}test.txt`);

View File

@ -5,7 +5,6 @@ import { literal, namedNode, quad as quadRDF, triple } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream';
import { DataFactory } from 'n3';
import streamifyArray from 'streamify-array';
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
import { Representation } from '../../../src/ldp/representation/Representation';
import { RepresentationMetadata } from '../../../src/ldp/representation/RepresentationMetadata';
import { ExtensionBasedMapper } from '../../../src/storage/ExtensionBasedMapper';
@ -55,7 +54,7 @@ describe('A FileResourceStore', (): void => {
jest.clearAllMocks();
store = new FileResourceStore(
new ExtensionBasedMapper(new RuntimeConfig({ base, rootFilepath })),
new ExtensionBasedMapper(base, rootFilepath),
new InteractionController(),
new MetadataController(),
);

View File

@ -1,6 +1,5 @@
import { Readable } from 'stream';
import streamifyArray from 'streamify-array';
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
import { Representation } from '../../../src/ldp/representation/Representation';
import { RepresentationMetadata } from '../../../src/ldp/representation/RepresentationMetadata';
import { InMemoryResourceStore } from '../../../src/storage/InMemoryResourceStore';
@ -15,7 +14,7 @@ describe('A InMemoryResourceStore', (): void => {
const dataString = '<http://test.com/s> <http://test.com/p> <http://test.com/o>.';
beforeEach(async(): Promise<void> => {
store = new InMemoryResourceStore(new RuntimeConfig({ base }));
store = new InMemoryResourceStore(base);
representation = {
binary: true,

View File

@ -1,9 +1,8 @@
import { RuntimeConfig } from '../../../src/init/RuntimeConfig';
import { UrlContainerManager } from '../../../src/storage/UrlContainerManager';
describe('An UrlContainerManager', (): void => {
it('returns the parent URl for a single call.', async(): Promise<void> => {
const manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo/' }));
const manager = new UrlContainerManager('http://test.com/foo/');
await expect(manager.getContainer({ path: 'http://test.com/foo/bar' }))
.resolves.toEqual({ path: 'http://test.com/foo/' });
await expect(manager.getContainer({ path: 'http://test.com/foo/bar/' }))
@ -11,13 +10,13 @@ describe('An UrlContainerManager', (): void => {
});
it('errors when getting the container of root.', async(): Promise<void> => {
let manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo/' }));
let manager = new UrlContainerManager('http://test.com/foo/');
await expect(manager.getContainer({ path: 'http://test.com/foo/' }))
.rejects.toThrow('Root does not have a container.');
await expect(manager.getContainer({ path: 'http://test.com/foo' }))
.rejects.toThrow('Root does not have a container.');
manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo' }));
manager = new UrlContainerManager('http://test.com/foo/');
await expect(manager.getContainer({ path: 'http://test.com/foo/' }))
.rejects.toThrow('Root does not have a container.');
await expect(manager.getContainer({ path: 'http://test.com/foo' }))
@ -25,7 +24,7 @@ describe('An UrlContainerManager', (): void => {
});
it('errors when the root of an URl is reached that does not match the input root.', async(): Promise<void> => {
const manager = new UrlContainerManager(new RuntimeConfig({ base: 'http://test.com/foo/' }));
const manager = new UrlContainerManager('http://test.com/foo/');
await expect(manager.getContainer({ path: 'http://test.com/' }))
.rejects.toThrow('URL root reached.');
});