Merge branch 'main' into versions/3.0.0

# Conflicts:
#	package-lock.json
#	package.json
#	src/storage/patch/SparqlUpdatePatcher.ts
#	test/unit/init/AppRunner.test.ts
#	test/unit/util/QuadUtil.test.ts
This commit is contained in:
Joachim Van Herwegen 2022-02-11 15:30:45 +01:00
commit c5052625d1
28 changed files with 5464 additions and 6395 deletions

View File

@ -139,15 +139,15 @@ jobs:
github-token: ${{ secrets.github_token }}
parallel-finished: true
docker:
docker-main-branch:
needs:
- lint
- test-unit
- test-integration
- test-integration-windows
- validate-components
# Only run on tags starting with v prefix for now -- extra push need for triggering CI again
if: startsWith(github.ref, 'refs/tags/v')
# Only run on tag push events starting with v prefix for now OR main branch push events
if: startsWith(github.ref, 'refs/tags/v') || (github.ref == 'refs/heads/main')
runs-on: ubuntu-latest
steps:
- name: Checkout
@ -158,7 +158,9 @@ jobs:
with:
images: |
solidproject/community-server
# edge will always be executed (without latest tag), semver only on tag push events (with latest tag)
tags: |
type=edge
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
@ -178,6 +180,47 @@ jobs:
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
docker-versions-branch:
needs:
- lint
- test-unit
- test-integration
- test-integration-windows
- validate-components
# Only run on push events on a versions/* branch (ASSUMPTION: THERE SHOULD ONLY BE ONE THERE!)
if: startsWith(github.ref, 'refs/heads/versions/')
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: ${{ github.ref }}
- name: Docker meta
id: meta
uses: docker/metadata-action@v3
with:
images: |
solidproject/community-server
# Just one label: next (no latest here) for the last pushed commit on this branch
tags: |
type=raw,value=next
github-token: ${{ secrets.github_token }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
- name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
id: docker_build
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
docs:
runs-on: ubuntu-latest

View File

@ -28,11 +28,11 @@ jobs:
- name: Install dependencies and run build scripts
run: npm ci
- name: Start the server in the background
run: npm start &
run: npm start > server-output.log &
- name: Create the necessary folders
run: mkdir -p reports/css
- name: Pull the conformance harness docker
run: docker pull solidconformancetestbeta/conformance-test-harness
run: docker pull solidproject/conformance-test-harness
- name: Wait until the server has started
run: |
until $(curl --output /dev/null --silent --head --fail -k http://localhost:3000/); do
@ -47,3 +47,22 @@ jobs:
solidproject/conformance-test-harness
--output=/reports
--target=https://github.com/solid/conformance-test-harness/css
# Steps below use `always()` to make sure logs get uploaded in case the CTH errors
- name: Sanitize branch name for artifact upload
id: sanitize
if: always()
uses: yeouchien/sanitize-branch-name-action@v1
with:
branch-name: ${{ matrix.branch }}
- name: Save the reports
if: always()
uses: actions/upload-artifact@v2
with:
name: ${{ steps.sanitize.outputs.sanitized-branch-name }} reports
path: reports
- name: Save the server output
if: always()
uses: actions/upload-artifact@v2
with:
name: ${{ steps.sanitize.outputs.sanitized-branch-name }} server output
path: server-output.log

View File

@ -100,7 +100,7 @@ to some commonly used settings:
| parameter name | default value | description |
| -------------- | ------------- | ----------- |
| `--port, -p` | `3000` | The TCP port on which the server runs. |
| `--baseUrl. -b` | `http://localhost:$PORT/` | The public URL of your server. |
| `--baseUrl, -b` | `http://localhost:$PORT/` | The public URL of your server. |
| `--loggingLevel, -l` | `info` | The detail level of logging; useful for debugging problems. |
| `--config, -c` | `@css:config/default.json` | The configuration for the server. The default only stores data in memory; to persist to your filesystem, use `@css:config/file.json` |
| `--rootFilePath, -f` | `./` | Root folder of the server, when using a file-based configuration. |

11592
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -75,95 +75,94 @@
"templates"
],
"dependencies": {
"@comunica/actor-init-sparql": "^1.21.3",
"@rdfjs/data-model": "^1.2.0",
"@solid/access-token-verifier": "^1.1.2",
"@comunica/actor-init-sparql": "^1.22.3",
"@solid/access-token-verifier": "^1.1.3",
"@types/arrayify-stream": "^1.0.0",
"@types/async-lock": "^1.1.2",
"@types/async-lock": "^1.1.3",
"@types/bcrypt": "^5.0.0",
"@types/cors": "^2.8.10",
"@types/end-of-stream": "^1.4.0",
"@types/cors": "^2.8.12",
"@types/end-of-stream": "^1.4.1",
"@types/lodash.orderby": "^4.6.6",
"@types/marked": "^3.0.0",
"@types/mime-types": "^2.1.0",
"@types/n3": "^1.10.0",
"@types/marked": "^4.0.2",
"@types/mime-types": "^2.1.1",
"@types/n3": "^1.10.4",
"@types/node": "^14.18.0",
"@types/nodemailer": "^6.4.2",
"@types/nodemailer": "^6.4.4",
"@types/pump": "^1.1.1",
"@types/punycode": "^2.1.0",
"@types/redis": "^2.8.30",
"@types/redlock": "^4.0.1",
"@types/sparqljs": "^3.1.2",
"@types/url-join": "^4.0.0",
"@types/uuid": "^8.3.0",
"@types/ws": "^8.2.0",
"@types/sparqljs": "^3.1.3",
"@types/url-join": "^4.0.1",
"@types/uuid": "^8.3.4",
"@types/ws": "^8.2.2",
"@types/yargs": "^17.0.8",
"arrayify-stream": "^1.0.0",
"async-lock": "^1.3.0",
"bcrypt": "^5.0.1",
"componentsjs": "^4.4.1",
"componentsjs": "^4.5.0",
"cors": "^2.8.5",
"cross-fetch": "^3.1.4",
"cross-fetch": "^3.1.5",
"ejs": "^3.1.6",
"end-of-stream": "^1.4.4",
"escape-string-regexp": "^4.0.0",
"fetch-sparql-endpoint": "^2.0.1",
"fetch-sparql-endpoint": "^2.4.0",
"handlebars": "^4.7.7",
"jose": "^4.3.7",
"jose": "^4.4.0",
"lodash.orderby": "^4.6.0",
"marked": "^3.0.0",
"mime-types": "^2.1.32",
"n3": "^1.12.2",
"nodemailer": "^6.6.2",
"marked": "^4.0.12",
"mime-types": "^2.1.34",
"n3": "^1.13.0",
"nodemailer": "^6.7.2",
"oidc-provider": "^6.31.1",
"pump": "^3.0.0",
"punycode": "^2.1.1",
"rdf-parse": "^1.8.1",
"rdf-serialize": "^1.1.0",
"rdf-parse": "^1.9.1",
"rdf-serialize": "^1.2.0",
"rdf-terms": "^1.7.1",
"redis": "^3.1.2",
"redlock": "^4.2.0",
"sparqlalgebrajs": "^4.0.1",
"sparqljs": "^3.4.2",
"sparqlalgebrajs": "^4.0.2",
"sparqljs": "^3.5.1",
"url-join": "^4.0.1",
"uuid": "^8.3.2",
"winston": "^3.3.3",
"winston-transport": "^4.4.0",
"ws": "^8.2.3",
"yargs": "^17.0.1"
"winston": "^3.5.1",
"winston-transport": "^4.4.2",
"ws": "^8.4.2",
"yargs": "^17.3.1"
},
"devDependencies": {
"@inrupt/solid-client-authn-node": "^1.9.1",
"@inrupt/solid-client-authn-node": "^1.11.3",
"@microsoft/tsdoc-config": "^0.15.2",
"@tsconfig/node12": "^1.0.9",
"@types/cheerio": "^0.22.29",
"@types/ejs": "^3.0.6",
"@types/fs-extra": "^9.0.12",
"@types/jest": "^27.0.0",
"@types/set-cookie-parser": "^2.4.0",
"@types/cheerio": "^0.22.30",
"@types/ejs": "^3.1.0",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^27.4.0",
"@types/set-cookie-parser": "^2.4.2",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.3.0",
"@typescript-eslint/parser": "^5.3.0",
"cheerio": "^1.0.0-rc.10",
"componentsjs-generator": "^2.6.0",
"eslint": "^8.4.1",
"componentsjs-generator": "^2.6.1",
"eslint": "^8.8.0",
"eslint-config-es": "4.1.0",
"eslint-import-resolver-typescript": "^2.5.0",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-jest": "^25.3.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jest": "^26.0.0",
"eslint-plugin-tsdoc": "^0.2.14",
"eslint-plugin-unused-imports": "^2.0.0",
"fs-extra": "^10.0.0",
"husky": "^4.3.8",
"jest": "^27.0.6",
"jest-rdf": "^1.6.0",
"jest": "^27.4.7",
"jest-rdf": "^1.7.0",
"manual-git-changelog": "^1.0.1",
"node-mocks-http": "^1.10.1",
"nodemon": "^2.0.7",
"node-mocks-http": "^1.11.0",
"nodemon": "^2.0.15",
"set-cookie-parser": "^2.4.8",
"supertest": "^6.1.3",
"ts-jest": "^27.0.3",
"typedoc": "^0.22.0",
"typescript": "^4.3.4"
"supertest": "^6.2.2",
"ts-jest": "^27.1.3",
"typedoc": "^0.22.11",
"typescript": "^4.5.5"
}
}

View File

@ -1,4 +1,4 @@
import { namedNode } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import { SOLID_META } from '../../util/Vocabularies';
import type { RepresentationMetadata } from '../representation/RepresentationMetadata';
import type { AuxiliaryIdentifierStrategy } from './AuxiliaryIdentifierStrategy';
@ -24,7 +24,7 @@ export class LinkMetadataGenerator extends MetadataGenerator {
const identifier = { path: metadata.identifier.value };
if (!this.identifierStrategy.isAuxiliaryIdentifier(identifier)) {
metadata.add(this.link,
namedNode(this.identifierStrategy.getAuxiliaryIdentifier(identifier).path),
DataFactory.namedNode(this.identifierStrategy.getAuxiliaryIdentifier(identifier).path),
SOLID_META.terms.ResponseMetadata);
}
}

View File

@ -1,4 +1,4 @@
import marked from 'marked';
import { marked } from 'marked';
import { BasicRepresentation } from '../../http/representation/BasicRepresentation';
import type { Representation } from '../../http/representation/Representation';
import { TEXT_HTML, TEXT_MARKDOWN } from '../../util/ContentTypes';

View File

@ -2,8 +2,7 @@ import type { Readable } from 'stream';
import type { ActorInitSparql } from '@comunica/actor-init-sparql';
import { newEngine } from '@comunica/actor-init-sparql';
import type { IQueryResultUpdate } from '@comunica/actor-init-sparql/lib/ActorInitSparql-browser';
import { defaultGraph } from '@rdfjs/data-model';
import { Store } from 'n3';
import { DataFactory, Store } from 'n3';
import { Algebra } from 'sparqlalgebrajs';
import { BasicRepresentation } from '../../http/representation/BasicRepresentation';
import type { Patch } from '../../http/representation/Patch';
@ -89,7 +88,7 @@ export class SparqlUpdatePatcher extends RepresentationPatcher {
* This means: no GRAPH statements, no DELETE WHERE containing terms of type Variable.
*/
private validateDeleteInsert(op: Algebra.DeleteInsert): void {
const def = defaultGraph();
const def = DataFactory.defaultGraph();
const deletes = op.delete ?? [];
const inserts = op.insert ?? [];
if (!deletes.every((pattern): boolean => pattern.graph.equals(def))) {

View File

@ -1,5 +1,5 @@
/* eslint-disable function-paren-newline */
import { namedNode } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import type { NamedNode } from 'rdf-js';
type RecordOf<TKey extends any[], TValue> = Record<TKey[number], TValue>;
@ -41,7 +41,7 @@ Namespace<typeof localNames, string> {
*/
export function createTermNamespace<T extends string>(baseUri: string, ...localNames: T[]):
Namespace<typeof localNames, NamedNode> {
return createNamespace(baseUri, namedNode, ...localNames);
return createNamespace(baseUri, DataFactory.namedNode, ...localNames);
}
/**

View File

@ -9,3 +9,5 @@ USERS_BOB_PASSWORD=pass1234
RESOURCE_SERVER_ROOT=http://localhost:3000
TEST_CONTAINER=/alice/
quarkus.log.category."ResultLogger".level=INFO
quarkus.log.category."com.intuit.karate".level=DEBUG
MAXTHREADS=1

View File

@ -133,6 +133,10 @@ describe('A Solid server with IDP', (): void => {
});
});
afterAll(async(): Promise<void> => {
await state.session.logout();
});
it('initializes the session and logs in.', async(): Promise<void> => {
const url = await state.startSession();
const res = await state.fetchIdp(url);
@ -221,6 +225,10 @@ describe('A Solid server with IDP', (): void => {
state = new IdentityTestState(baseUrl, redirectUrl, oidcIssuer);
});
afterAll(async(): Promise<void> => {
await state.session.logout();
});
it('can not log in with the old password anymore.', async(): Promise<void> => {
const url = await state.startSession();
nextUrl = url;
@ -293,6 +301,10 @@ describe('A Solid server with IDP', (): void => {
email: newMail, password, confirmPassword: password, podName, createWebId: 'ok', register: 'ok', createPod: 'ok',
});
afterAll(async(): Promise<void> => {
await state.session.logout();
});
it('sends the form to create the WebID and register.', async(): Promise<void> => {
const res = await postForm(`${baseUrl}idp/register/`, formBody);
expect(res.status).toBe(200);

View File

@ -112,5 +112,7 @@ describe('A server with restricted IDP access', (): void => {
expect(res.status).toBe(200);
const body = await res.json();
expect(body.webId).toBe(joinUrl(baseUrl, 'bob/profile/card#me'));
await state.session.logout();
});
});

View File

@ -1,4 +1,4 @@
import { namedNode, quad } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import { CredentialGroup } from '../../../src/authentication/Credentials';
import type { CredentialSet } from '../../../src/authentication/Credentials';
import type { AccessChecker } from '../../../src/authorization/access/AccessChecker';
@ -15,7 +15,7 @@ import { NotFoundHttpError } from '../../../src/util/errors/NotFoundHttpError';
import { SingleRootIdentifierStrategy } from '../../../src/util/identifiers/SingleRootIdentifierStrategy';
import { guardedStreamFrom } from '../../../src/util/StreamUtil';
const nn = namedNode;
const { namedNode: nn, quad } = DataFactory;
const acl = 'http://www.w3.org/ns/auth/acl#';
const rdf = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#';

View File

@ -1,6 +1,6 @@
import 'jest-rdf';
import { namedNode, quad } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream';
import { DataFactory } from 'n3';
import { Algebra } from 'sparqlalgebrajs';
import * as algebra from 'sparqlalgebrajs';
import type { BodyParserArgs } from '../../../../../src/http/input/body/BodyParser';
@ -10,6 +10,7 @@ import type { HttpRequest } from '../../../../../src/server/HttpRequest';
import { BadRequestHttpError } from '../../../../../src/util/errors/BadRequestHttpError';
import { UnsupportedMediaTypeHttpError } from '../../../../../src/util/errors/UnsupportedMediaTypeHttpError';
import { guardedStreamFrom } from '../../../../../src/util/StreamUtil';
const { namedNode, quad } = DataFactory;
describe('A SparqlUpdateBodyParser', (): void => {
const bodyParser = new SparqlUpdateBodyParser();

View File

@ -1,12 +1,13 @@
import 'jest-rdf';
import { Readable } from 'stream';
import { namedNode } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream';
import { DataFactory } from 'n3';
import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation';
import { RepresentationMetadata } from '../../../../src/http/representation/RepresentationMetadata';
import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes';
import { guardedStreamFrom } from '../../../../src/util/StreamUtil';
import { CONTENT_TYPE } from '../../../../src/util/Vocabularies';
const { namedNode } = DataFactory;
describe('BasicRepresentation', (): void => {
it('creates a representation with (data, metadata, binary).', (): void => {

View File

@ -1,8 +1,9 @@
import 'jest-rdf';
import { defaultGraph, literal, namedNode, quad } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import type { NamedNode, Quad } from 'rdf-js';
import { RepresentationMetadata } from '../../../../src/http/representation/RepresentationMetadata';
import { CONTENT_TYPE } from '../../../../src/util/Vocabularies';
const { defaultGraph, literal, namedNode, quad } = DataFactory;
// Helper functions to filter quads
function getQuads(quads: Quad[], subject?: string, predicate?: string, object?: string, graph?: string): Quad[] {

View File

@ -66,7 +66,7 @@ describe('A TemplatedResourcesGenerator', (): void => {
expect(representation.binary).toBe(true);
expect(representation.metadata.contentType).toBe('text/turtle');
await expect(readableToString(representation.data)).resolves
.toEqual(`<${webId}> a <http://xmlns.com/foaf/0.1/Person>.`);
.toBe(`<${webId}> a <http://xmlns.com/foaf/0.1/Person>.`);
});
it('creates the necessary containers.', async(): Promise<void> => {
@ -83,7 +83,7 @@ describe('A TemplatedResourcesGenerator', (): void => {
const { representation } = result[3];
await expect(readableToString(representation.data)).resolves
.toEqual(`<${webId}> a <http://xmlns.com/foaf/0.1/Person>.`);
.toBe(`<${webId}> a <http://xmlns.com/foaf/0.1/Person>.`);
});
it('copies the file stream directly if no template extension is found.', async(): Promise<void> => {

View File

@ -209,7 +209,7 @@ describe('A DataAccessorBasedStore', (): void => {
const result = await store.getRepresentation(resourceID);
const contains = result.metadata.getAll(LDP.terms.contains);
expect(contains).toHaveLength(1);
expect(contains[0].value).toEqual(`${resourceID.path}resource`);
expect(contains[0].value).toBe(`${resourceID.path}resource`);
});
});

View File

@ -1,6 +1,6 @@
import 'jest-rdf';
import type { Readable } from 'stream';
import { namedNode } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import type { Representation } from '../../../../src/http/representation/Representation';
import { RepresentationMetadata } from '../../../../src/http/representation/RepresentationMetadata';
import { FileDataAccessor } from '../../../../src/storage/accessors/FileDataAccessor';
@ -277,7 +277,7 @@ describe('A FileDataAccessor', (): void => {
it('updates the filename if the content-type gets updated.', async(): Promise<void> => {
cache.data = { 'resource$.ttl': '<this> <is> <data>.', 'resource.meta': '<this> <is> <metadata>.' };
metadata.identifier = namedNode(`${base}resource`);
metadata.identifier = DataFactory.namedNode(`${base}resource`);
metadata.contentType = 'text/plain';
metadata.add('new', 'metadata');
await expect(accessor.writeDocument({ path: `${base}resource` }, data, metadata))
@ -289,7 +289,7 @@ describe('A FileDataAccessor', (): void => {
});
it('does not try to update the content-type if there is no original file.', async(): Promise<void> => {
metadata.identifier = namedNode(`${base}resource.txt`);
metadata.identifier = DataFactory.namedNode(`${base}resource.txt`);
metadata.contentType = 'text/turtle';
metadata.add('new', 'metadata');
await expect(accessor.writeDocument({ path: `${base}resource.txt` }, data, metadata))

View File

@ -96,8 +96,8 @@ describe('An InMemoryDataAccessor', (): void => {
children.push(child);
}
expect(children).toHaveLength(2);
expect(children[0].identifier.value).toEqual(`${base}container/resource`);
expect(children[1].identifier.value).toEqual(`${base}container/container2/`);
expect(children[0].identifier.value).toBe(`${base}container/resource`);
expect(children[1].identifier.value).toBe(`${base}container/container2/`);
});
it('adds stored metadata when requesting document metadata.', async(): Promise<void> => {
@ -148,7 +148,7 @@ describe('An InMemoryDataAccessor', (): void => {
children.push(child);
}
expect(children).toHaveLength(1);
expect(children[0].identifier.value).toEqual(`${base}container/resource`);
expect(children[0].identifier.value).toBe(`${base}container/resource`);
await expect(accessor.getMetadata({ path: `${base}container/resource` }))
.resolves.toBeInstanceOf(RepresentationMetadata);
@ -175,7 +175,7 @@ describe('An InMemoryDataAccessor', (): void => {
children.push(child);
}
expect(children).toHaveLength(1);
expect(children[0].identifier.value).toEqual(`${base}resource`);
expect(children[0].identifier.value).toBe(`${base}resource`);
await expect(accessor.getMetadata({ path: `${base}resource` }))
.resolves.toBeInstanceOf(RepresentationMetadata);

View File

@ -1,10 +1,11 @@
import { namedNode as nn, quad } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation';
import { ContainerToTemplateConverter } from '../../../../src/storage/conversion/ContainerToTemplateConverter';
import { SingleRootIdentifierStrategy } from '../../../../src/util/identifiers/SingleRootIdentifierStrategy';
import { readableToString } from '../../../../src/util/StreamUtil';
import type { TemplateEngine } from '../../../../src/util/templates/TemplateEngine';
import { LDP, RDF } from '../../../../src/util/Vocabularies';
const { namedNode: nn, quad } = DataFactory;
describe('A ContainerToTemplateConverter', (): void => {
const preferences = {};

View File

@ -1,4 +1,4 @@
import { namedNode, triple } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import rdfSerializer from 'rdf-serialize';
import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation';
import type { Representation } from '../../../../src/http/representation/Representation';
@ -9,6 +9,7 @@ import { QuadToRdfConverter } from '../../../../src/storage/conversion/QuadToRdf
import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes';
import { readableToString } from '../../../../src/util/StreamUtil';
import { DC, PREFERRED_PREFIX_TERM } from '../../../../src/util/Vocabularies';
const { namedNode, triple } = DataFactory;
describe('A QuadToRdfConverter', (): void => {
const converter = new QuadToRdfConverter();
@ -56,7 +57,7 @@ describe('A QuadToRdfConverter', (): void => {
metadata: expect.any(RepresentationMetadata),
});
expect(result.metadata.contentType).toBe('text/turtle');
await expect(readableToString(result.data)).resolves.toEqual(
await expect(readableToString(result.data)).resolves.toBe(
`<http://test.com/s> <http://test.com/p> <http://test.com/o>.
`,
);
@ -74,7 +75,7 @@ describe('A QuadToRdfConverter', (): void => {
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
const result = await converter.handle({ identifier, representation, preferences });
expect(result.metadata.contentType).toBe('text/turtle');
await expect(readableToString(result.data)).resolves.toEqual(
await expect(readableToString(result.data)).resolves.toBe(
`@prefix dc: <http://purl.org/dc/terms/>.
@prefix test: <http://test.com/>.
@ -93,7 +94,7 @@ test:s dc:modified test:o.
const preferences: RepresentationPreferences = { type: { 'text/turtle': 1 }};
const result = await converter.handle({ identifier, representation, preferences });
expect(result.metadata.contentType).toBe('text/turtle');
await expect(readableToString(result.data)).resolves.toEqual(
await expect(readableToString(result.data)).resolves.toBe(
`<> <#abc> <def/ghi>.
`,
);
@ -114,7 +115,7 @@ test:s dc:modified test:o.
metadata: expect.any(RepresentationMetadata),
});
expect(result.metadata.contentType).toBe('application/ld+json');
await expect(readableToString(result.data)).resolves.toEqual(
await expect(readableToString(result.data)).resolves.toBe(
`[
{
"@id": "http://test.com/s",

View File

@ -1,7 +1,7 @@
import 'jest-rdf';
import { Readable } from 'stream';
import { namedNode, triple } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream';
import { DataFactory } from 'n3';
import rdfParser from 'rdf-parse';
import { BasicRepresentation } from '../../../../src/http/representation/BasicRepresentation';
import type { Representation } from '../../../../src/http/representation/Representation';
@ -11,6 +11,7 @@ import type { ResourceIdentifier } from '../../../../src/http/representation/Res
import { RdfToQuadConverter } from '../../../../src/storage/conversion/RdfToQuadConverter';
import { INTERNAL_QUADS } from '../../../../src/util/ContentTypes';
import { BadRequestHttpError } from '../../../../src/util/errors/BadRequestHttpError';
const { namedNode, triple } = DataFactory;
describe('A RdfToQuadConverter', (): void => {
const converter = new RdfToQuadConverter();

View File

@ -1,6 +1,6 @@
import 'jest-rdf';
import { namedNode, quad } from '@rdfjs/data-model';
import arrayifyStream from 'arrayify-stream';
import { DataFactory } from 'n3';
import type { Quad } from 'rdf-js';
import type { Algebra } from 'sparqlalgebrajs';
import { translate } from 'sparqlalgebrajs';
@ -12,6 +12,7 @@ import type { RepresentationPatcherInput } from '../../../../src/storage/patch/R
import { SparqlUpdatePatcher } from '../../../../src/storage/patch/SparqlUpdatePatcher';
import { NotImplementedHttpError } from '../../../../src/util/errors/NotImplementedHttpError';
import { guardedStreamFrom } from '../../../../src/util/StreamUtil';
const { namedNode, quad } = DataFactory;
function getPatch(query: string): SparqlUpdatePatch {
const prefixedQuery = `prefix : <http://test.com/>\n${query}`;

View File

@ -39,7 +39,7 @@ describe('PathUtil', (): void => {
});
it('joins Windows paths.', async(): Promise<void> => {
expect(joinFilePath('c:\\foo\\bar\\', '..', '/baz')).toEqual(`c:/foo/baz`);
expect(joinFilePath('c:\\foo\\bar\\', '..', '/baz')).toBe(`c:/foo/baz`);
});
});

View File

@ -1,7 +1,8 @@
import 'jest-rdf';
import { literal, namedNode, quad } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import { parseQuads, serializeQuads, uniqueQuads } from '../../../src/util/QuadUtil';
import { guardedStreamFrom, readableToString } from '../../../src/util/StreamUtil';
const { literal, namedNode, quad } = DataFactory;
describe('QuadUtil', (): void => {
describe('#serializeQuads', (): void => {

View File

@ -1,5 +1,5 @@
import 'jest-rdf';
import { literal, namedNode } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import {
toCachedNamedNode,
toNamedTerm,
@ -9,6 +9,7 @@ import {
isTerm,
} from '../../../src/util/TermUtil';
import { CONTENT_TYPE_TERM, XSD } from '../../../src/util/Vocabularies';
const { literal, namedNode } = DataFactory;
describe('TermUtil', (): void => {
describe('isTerm function', (): void => {

View File

@ -1,4 +1,4 @@
import { namedNode } from '@rdfjs/data-model';
import { DataFactory } from 'n3';
import { LDP } from '../../../src/util/Vocabularies';
describe('Vocabularies', (): void => {
@ -8,7 +8,7 @@ describe('Vocabularies', (): void => {
});
it('contains its own URI as a term.', (): void => {
expect(LDP.terms.namespace).toEqual(namedNode('http://www.w3.org/ns/ldp#'));
expect(LDP.terms.namespace).toEqual(DataFactory.namedNode('http://www.w3.org/ns/ldp#'));
});
it('exposes ldp:contains.', (): void => {
@ -16,7 +16,7 @@ describe('Vocabularies', (): void => {
});
it('exposes ldp:contains as a term.', (): void => {
expect(LDP.terms.contains).toEqual(namedNode('http://www.w3.org/ns/ldp#contains'));
expect(LDP.terms.contains).toEqual(DataFactory.namedNode('http://www.w3.org/ns/ldp#contains'));
});
});
});