Complete main request tests

main
jaxoncreed 2 years ago
parent d11498aefb
commit c0d32e983f
  1. 112
      package-lock.json
  2. 8
      packages/solid/src/requester/requests/uploadResource.ts
  3. 280
      packages/solid/test/SolidLdoDataset.test.ts

112
package-lock.json generated

@ -11791,6 +11791,12 @@
"node": ">= 6"
}
},
"node_modules/blob-polyfill": {
"version": "7.0.20220408",
"resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-7.0.20220408.tgz",
"integrity": "sha512-oD8Ydw+5lNoqq+en24iuPt1QixdPpe/nUF8azTHnviCZYu9zUC+TwdzIp5orpblJosNlgNbVmmAb//c6d6ImUQ==",
"dev": true
},
"node_modules/bluebird": {
"version": "3.7.2",
"license": "MIT"
@ -14122,6 +14128,42 @@
"devOptional": true,
"license": "MIT"
},
"node_modules/cross-blob": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-3.0.2.tgz",
"integrity": "sha512-u+7xq68MAjIqvoEKrdgIEupKJNBeU8MSl/cpfPmJ3rm9yvxrgbMPr8TkZS9qnwCgiVC8BsEt9kDkeD7He2zmNA==",
"dev": true,
"dependencies": {
"blob-polyfill": "^7.0.20220408",
"fetch-blob": "^3.2.0"
},
"engines": {
"node": "^12.20 || >=14.13"
}
},
"node_modules/cross-blob/node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/cross-fetch": {
"version": "3.1.8",
"license": "MIT",
@ -23733,6 +23775,25 @@
"node": ">= 0.10.5"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "2.6.7",
"license": "MIT",
@ -31714,6 +31775,15 @@
"defaults": "^1.0.3"
}
},
"node_modules/web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
"dev": true,
"engines": {
"node": ">= 8"
}
},
"node_modules/web-streams-ponyfill": {
"version": "1.4.2",
"dev": true,
@ -34809,6 +34879,7 @@
"@rdfjs/types": "^1.0.1",
"@solid/community-server": "^6.0.2",
"@types/jest": "^29.0.3",
"cross-blob": "^3.0.2",
"dotenv": "^16.3.1",
"jest-rdf": "^1.8.0",
"ts-jest": "^29.0.2",
@ -44803,6 +44874,7 @@
"@solid/community-server": "^6.0.2",
"@types/jest": "^29.0.3",
"@types/parse-link-header": "^2.0.1",
"cross-blob": "*",
"cross-fetch": "^3.1.6",
"dotenv": "^16.3.1",
"http-link-header": "^1.1.1",
@ -50223,6 +50295,12 @@
}
}
},
"blob-polyfill": {
"version": "7.0.20220408",
"resolved": "https://registry.npmjs.org/blob-polyfill/-/blob-polyfill-7.0.20220408.tgz",
"integrity": "sha512-oD8Ydw+5lNoqq+en24iuPt1QixdPpe/nUF8azTHnviCZYu9zUC+TwdzIp5orpblJosNlgNbVmmAb//c6d6ImUQ==",
"dev": true
},
"bluebird": {
"version": "3.7.2"
},
@ -51762,6 +51840,28 @@
"version": "1.1.1",
"devOptional": true
},
"cross-blob": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/cross-blob/-/cross-blob-3.0.2.tgz",
"integrity": "sha512-u+7xq68MAjIqvoEKrdgIEupKJNBeU8MSl/cpfPmJ3rm9yvxrgbMPr8TkZS9qnwCgiVC8BsEt9kDkeD7He2zmNA==",
"dev": true,
"requires": {
"blob-polyfill": "^7.0.20220408",
"fetch-blob": "^3.2.0"
},
"dependencies": {
"fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"dev": true,
"requires": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
}
}
}
},
"cross-fetch": {
"version": "3.1.8",
"requires": {
@ -57863,6 +57963,12 @@
"minimatch": "^3.0.2"
}
},
"node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"dev": true
},
"node-fetch": {
"version": "2.6.7",
"requires": {
@ -62882,6 +62988,12 @@
"defaults": "^1.0.3"
}
},
"web-streams-polyfill": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
"dev": true
},
"web-streams-ponyfill": {
"version": "1.4.2",
"dev": true

@ -45,10 +45,12 @@ export async function uploadResource(
): Promise<LeafCreateIfAbsentResult | LeafCreateAndOverwriteResult> {
try {
const fetch = guaranteeFetch(options?.fetch);
let didOverwrite = false;
if (overwrite) {
const deleteResult = await deleteResource(uri, options);
// Return if it wasn't deleted
if (deleteResult.isError) return deleteResult;
didOverwrite = deleteResult.resourceExisted;
} else {
// Perform a read to check if it exists
const readResult = await readResource(uri, options);
@ -78,9 +80,11 @@ export async function uploadResource(
isError: false,
type: "createSuccess",
uri,
didOverwrite: !!overwrite,
didOverwrite,
};
} catch (err) {
return UnexpectedResourceError.fromThrown(uri, err);
const thing = UnexpectedResourceError.fromThrown(uri, err);
console.log(thing.message);
return thing;
}
}

@ -5,6 +5,7 @@ import type {
Leaf,
LeafUri,
SolidLdoDataset,
UpdateResultError,
} from "../src";
import { createSolidLdoDataset } from "../src";
import {
@ -12,8 +13,17 @@ import {
createApp,
getAuthenticatedFetch,
} from "./solidServer.helper";
import { namedNode, quad as createQuad } from "@rdfjs/data-model";
import { namedNode, quad as createQuad, literal } from "@rdfjs/data-model";
import type { CreateSuccess } from "../src/requester/results/success/CreateSuccess";
import type { DatasetChanges } from "@ldo/rdf-utils";
import { createDataset } from "@ldo/dataset";
import type { Quad } from "@rdfjs/types";
import type { AggregateSuccess } from "../src/requester/results/success/SuccessResult";
import type { UpdateSuccess } from "../src/requester/results/success/UpdateSuccess";
import type { ResourceSuccess } from "../src/resource/resourceResult/ResourceResult";
import type { AggregateError } from "../src/requester/results/error/ErrorResult";
import type { InvalidUriError } from "../src/requester/results/error/InvalidUriError";
import { Buffer } from "buffer";
const TEST_CONTAINER_SLUG = "test_ldo/";
const TEST_CONTAINER_URI =
@ -369,7 +379,9 @@ describe("SolidLdoDataset", () => {
});
/**
* Create Data Resource
* ===========================================================================
* Create
* ===========================================================================
*/
describe("createAndOverwrite", () => {
it("creates a document that doesn't exist", async () => {
@ -563,6 +575,9 @@ describe("SolidLdoDataset", () => {
});
});
/**
* Delete
*/
describe("deleteResource", () => {
it("returns an unexpected http error if an unexpected value is returned", async () => {
const resource = solidLdoDataset.getResource(SAMPLE_DATA_URI);
@ -586,4 +601,265 @@ describe("SolidLdoDataset", () => {
expect(result.type).toBe("unexpectedResourceError");
});
});
/**
* Update
*/
describe("updateDataResource", () => {
const changes: DatasetChanges<Quad> = {
added: createDataset([
createQuad(
namedNode("http://example.org/#green-goblin"),
namedNode("http://xmlns.com/foaf/0.1/name"),
literal("Norman Osborn"),
namedNode(SAMPLE_DATA_URI),
),
]),
removed: createDataset([
createQuad(
namedNode("http://example.org/#green-goblin"),
namedNode("http://xmlns.com/foaf/0.1/name"),
literal("Green Goblin"),
namedNode(SAMPLE_DATA_URI),
),
]),
};
it("applies changes to a Pod", async () => {
const result = await solidLdoDataset.commitChangesToPod(changes);
expect(result.type).toBe("aggregateSuccess");
const aggregateSuccess = result as AggregateSuccess<
ResourceSuccess<UpdateSuccess, Leaf>
>;
expect(aggregateSuccess.results.length).toBe(1);
expect(aggregateSuccess.results[0].type === "updateSuccess").toBe(true);
expect(
solidLdoDataset.has(
createQuad(
namedNode("http://example.org/#green-goblin"),
namedNode("http://xmlns.com/foaf/0.1/name"),
literal("Norman Osborn"),
namedNode(SAMPLE_DATA_URI),
),
),
);
});
it("handles an HTTP error", async () => {
fetchMock.mockResolvedValueOnce(new Response("Error", { status: 500 }));
const result = await solidLdoDataset.commitChangesToPod(changes);
expect(result.isError).toBe(true);
expect(result.type).toBe("aggregateError");
const aggregateError = result as AggregateError<
UpdateResultError | InvalidUriError
>;
expect(aggregateError.errors.length).toBe(1);
expect(aggregateError.errors[0].type).toBe("serverError");
});
it("handles an unknown request", async () => {
fetchMock.mockImplementationOnce(() => {
throw new Error("Some Error");
});
const result = await solidLdoDataset.commitChangesToPod(changes);
expect(result.isError).toBe(true);
expect(result.type).toBe("aggregateError");
const aggregateError = result as AggregateError<
UpdateResultError | InvalidUriError
>;
expect(aggregateError.errors.length).toBe(1);
expect(aggregateError.errors[0].type).toBe("unexpectedResourceError");
});
});
/**
* ===========================================================================
* Upload
* ===========================================================================
*/
describe("uploadAndOverwrite", () => {
it("uploads a document that doesn't exist", async () => {
const resource = solidLdoDataset.getResource(SAMPLE2_BINARY_URI);
const container = solidLdoDataset.getResource(TEST_CONTAINER_URI);
const result = await testRequestLoads(
() =>
resource.uploadAndOverwrite(
Buffer.from("some text.") as unknown as Blob,
"text/plain",
),
resource,
{
isLoading: true,
isUploading: true,
},
);
expect(result.type).toBe("createSuccess");
const createSuccess = result as CreateSuccess;
expect(createSuccess.didOverwrite).toBe(false);
expect(
solidLdoDataset.has(
createQuad(
namedNode(TEST_CONTAINER_URI),
namedNode("http://www.w3.org/ns/ldp#contains"),
namedNode(SAMPLE2_BINARY_URI),
namedNode(TEST_CONTAINER_URI),
),
),
).toBe(true);
expect(
container.children().some((child) => child.uri === SAMPLE2_BINARY_URI),
).toBe(true);
});
it("creates a binary resource that doesn't exist while overwriting", async () => {
const resource = solidLdoDataset.getResource(SAMPLE_BINARY_URI);
const container = solidLdoDataset.getResource(TEST_CONTAINER_URI);
const result = await testRequestLoads(
() =>
resource.uploadAndOverwrite(
Buffer.from("some text.") as unknown as Blob,
"text/plain",
),
resource,
{
isLoading: true,
isUploading: true,
},
);
expect(result.type).toBe("createSuccess");
const createSuccess = result as CreateSuccess;
expect(createSuccess.didOverwrite).toBe(true);
expect(
solidLdoDataset.has(
createQuad(
namedNode(TEST_CONTAINER_URI),
namedNode("http://www.w3.org/ns/ldp#contains"),
namedNode(SAMPLE_BINARY_URI),
namedNode(TEST_CONTAINER_URI),
),
),
).toBe(true);
expect(
container.children().some((child) => child.uri === SAMPLE_BINARY_URI),
).toBe(true);
});
it("returns a delete error if delete failed", async () => {
const resource = solidLdoDataset.getResource(SAMPLE_BINARY_URI);
fetchMock.mockResolvedValueOnce(
new Response(TEST_CONTAINER_TTL, {
status: 500,
}),
);
const result = await resource.uploadAndOverwrite(
Buffer.from("some text.") as unknown as Blob,
"text/plain",
);
expect(result.isError).toBe(true);
expect(result.type).toBe("serverError");
});
it("returns an error if the create fetch fails", async () => {
const resource = solidLdoDataset.getResource(SAMPLE_BINARY_URI);
fetchMock.mockImplementationOnce(async (...args) => {
return authFetch(...args);
});
fetchMock.mockResolvedValueOnce(
new Response(TEST_CONTAINER_TTL, {
status: 500,
}),
);
const result = await resource.uploadAndOverwrite(
Buffer.from("some text.") as unknown as Blob,
"text/plain",
);
expect(result.isError).toBe(true);
expect(result.type).toBe("serverError");
});
it("returns an unexpected error if some unknown error is triggered", async () => {
const resource = solidLdoDataset.getResource(SAMPLE_BINARY_URI);
fetchMock.mockImplementationOnce(async (...args) => {
return authFetch(...args);
});
fetchMock.mockImplementationOnce(async () => {
throw new Error("Some Unknown");
});
const result = await resource.uploadAndOverwrite(
Buffer.from("some text.") as unknown as Blob,
"text/plain",
);
expect(result.isError).toBe(true);
expect(result.type).toBe("unexpectedResourceError");
});
});
describe("uploadIfAbsent", () => {
it("creates a binary resource that doesn't exist", async () => {
const resource = solidLdoDataset.getResource(SAMPLE2_BINARY_URI);
const container = solidLdoDataset.getResource(TEST_CONTAINER_URI);
const result = await testRequestLoads(
() =>
resource.uploadIfAbsent(
Buffer.from("some text.") as unknown as Blob,
"text/plain",
),
resource,
{
isLoading: true,
isUploading: true,
},
);
expect(result.type).toBe("createSuccess");
const createSuccess = result as CreateSuccess;
expect(createSuccess.didOverwrite).toBe(false);
expect(
solidLdoDataset.has(
createQuad(
namedNode(TEST_CONTAINER_URI),
namedNode("http://www.w3.org/ns/ldp#contains"),
namedNode(SAMPLE2_BINARY_URI),
namedNode(TEST_CONTAINER_URI),
),
),
).toBe(true);
expect(
container.children().some((child) => child.uri === SAMPLE2_BINARY_URI),
).toBe(true);
});
it("doesn't overwrite a binary resource that does exist", async () => {
const resource = solidLdoDataset.getResource(SAMPLE_BINARY_URI);
const container = solidLdoDataset.getResource(TEST_CONTAINER_URI);
const result = await testRequestLoads(
() =>
resource.uploadIfAbsent(
Buffer.from("some text.") as unknown as Blob,
"text/plain",
),
resource,
{
isLoading: true,
isUploading: true,
},
);
expect(result.type).toBe("binaryReadSuccess");
expect(
solidLdoDataset.has(
createQuad(
namedNode(TEST_CONTAINER_URI),
namedNode("http://www.w3.org/ns/ldp#contains"),
namedNode(SAMPLE_BINARY_URI),
namedNode(TEST_CONTAINER_URI),
),
),
).toBe(true);
expect(
container.children().some((child) => child.uri === SAMPLE_BINARY_URI),
).toBe(true);
});
});
});

Loading…
Cancel
Save