Skip to content

Commit

Permalink
chore: fix timeouts in e2e tests and use automatically fetched config…
Browse files Browse the repository at this point in the history
…uration (#877)

* chore: fix timeouts in e2e tests and use automatically fetched configuration

* chore: fix lint errors
  • Loading branch information
jeswr authored Dec 11, 2023
1 parent 5004931 commit 056c4ad
Showing 1 changed file with 81 additions and 73 deletions.
154 changes: 81 additions & 73 deletions e2e/node/e2e.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,15 @@
// FIXME: Remove when refactoring to test matrix
/* eslint-disable @typescript-eslint/no-non-null-assertion */

import { describe, it, expect, beforeEach, afterEach } from "@jest/globals";
import { describe, it, expect, beforeAll, afterAll } from "@jest/globals";
import type { Session } from "@inrupt/solid-client-authn-node";
import {
getNodeTestingEnvironment,
getAuthenticatedSession,
} from "@inrupt/internal-test-env";
import {
getVerifiableCredentialAllFromShape,
getVerifiableCredentialApiConfiguration,
issueVerifiableCredential,
revokeVerifiableCredential,
} from "../../src/index";
Expand All @@ -40,16 +41,21 @@ const validCredentialClaims = {
"https://schema.inrupt.com/credentials/v1.jsonld",
],
type: ["SolidAccessRequest"],
"http://example.org/my/filtering/property":
"http://example.org/my/filtering/object",
};
const validSubjectClaims = (options?: { resource?: string }) => ({
const validSubjectClaims = (options?: {
resource?: string;
purpose?: string;
}) => ({
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.inrupt.com/credentials/v1.jsonld",
],
hasConsent: {
mode: "Read",
forPersonalData: options?.resource ?? "https://example.org/ns/someData",
forPurpose: "https://example.org/ns/somePurpose",
forPurpose: options?.purpose ?? "https://example.org/ns/somePurpose",
hasStatus: "ConsentStatusRequested",
isConsentForDataSubject: "https://some.webid/resource-owner",
},
Expand Down Expand Up @@ -83,7 +89,12 @@ const env = getNodeTestingEnvironment({
describe("End-to-end verifiable credentials tests for environment", () => {
let vcSubject: string;
let session: Session;
beforeEach(async () => {
let issuerService: string;
let derivationService: string;
let statusService: string;
let verifierService: string;

beforeAll(async () => {
session = await getAuthenticatedSession(env);

if (!session.info.webId) {
Expand All @@ -92,18 +103,30 @@ describe("End-to-end verifiable credentials tests for environment", () => {
vcSubject = session.info.webId;
}

// The following code snippet doesn't work in Jest, probably because of
// https://github.com/standard-things/esm/issues/706 which seems to be
// related to https://github.com/facebook/jest/issues/9430. The JSON-LD
// module depends on @digitalbazaar/http-client, which uses esm, which
// looks like it confuses Jest. Working around this by hard-coding the
// endpoints IRIs.
// vcConfiguration = await getVerifiableCredentialApiConfiguration(
// vcProvider
// );
if (typeof env.vcProvider !== "string") {
throw new Error("vcProvider not available in context");
}

const vcConfiguration = await getVerifiableCredentialApiConfiguration(
env.vcProvider.toString(),
);

if (
typeof vcConfiguration.issuerService !== "string" ||
typeof vcConfiguration.derivationService !== "string" ||
typeof vcConfiguration.statusService !== "string" ||
typeof vcConfiguration.verifierService !== "string"
) {
throw new Error("A service endpoint is undefined");
}

issuerService = vcConfiguration.issuerService;
derivationService = vcConfiguration.derivationService;
statusService = vcConfiguration.statusService;
verifierService = vcConfiguration.verifierService;
});

afterEach(async () => {
afterAll(async () => {
// Making sure the session is logged out prevents tests from hanging due
// to the callback refreshing the access token.
await session.logout();
Expand All @@ -112,21 +135,17 @@ describe("End-to-end verifiable credentials tests for environment", () => {
describe("issue a VC", () => {
it("Successfully gets a VC from a valid issuer", async () => {
const credential = await issueVerifiableCredential(
new URL("issue", env.vcProvider).href,
issuerService,
validSubjectClaims(),
validCredentialClaims,
{
fetch: session.fetch,
},
);
expect(credential.credentialSubject.id).toBe(vcSubject);
await revokeVerifiableCredential(
new URL("status", env.vcProvider).href,
credential.id,
{
fetch: session.fetch,
},
);
await revokeVerifiableCredential(statusService, credential.id, {
fetch: session.fetch,
});
});

// FIXME: based on configuration, the server may have one of two behaviors
Expand All @@ -135,7 +154,7 @@ describe("End-to-end verifiable credentials tests for environment", () => {
// associated to the preconfigured shape.
it("throws if the issuer returns an error", async () => {
const vcPromise = issueVerifiableCredential(
new URL("issue", env.vcProvider).href,
issuerService,
invalidCredentialClaims,
undefined,
{
Expand All @@ -148,19 +167,24 @@ describe("End-to-end verifiable credentials tests for environment", () => {

describe("lookup VCs", () => {
it("returns all VC issued matching a given shape", async () => {
const purpose = `http://example.org/some/purpose/${Date.now()}`;
const [credential1, credential2] = await Promise.all([
issueVerifiableCredential(
new URL("issue", env.vcProvider).href,
validSubjectClaims({ resource: "https://example.org/some-resource" }),
issuerService,
validSubjectClaims({
resource: "https://example.org/some-resource",
purpose,
}),
validCredentialClaims,
{
fetch: session.fetch,
},
),
issueVerifiableCredential(
new URL("issue", env.vcProvider).href,
issuerService,
validSubjectClaims({
resource: "https://example.org/another-resource",
purpose,
}),
validCredentialClaims,
{
Expand All @@ -171,88 +195,72 @@ describe("End-to-end verifiable credentials tests for environment", () => {

await expect(
getVerifiableCredentialAllFromShape(
new URL("derive", env.vcProvider).href,
derivationService,
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://schema.inrupt.com/credentials/v1.jsonld",
],
type: ["VerifiableCredential"],
credentialSubject: {
id: vcSubject,
hasConsent: {
forPurpose: purpose,
},
},
},
{
fetch: session.fetch,
includeExpiredVc: false,
},
),
).resolves.not.toHaveLength(0);
).resolves.toHaveLength(2);

await expect(
getVerifiableCredentialAllFromShape(
new URL("derive", env.vcProvider).href,
credential1,
{
fetch: session.fetch,
},
),
getVerifiableCredentialAllFromShape(derivationService, credential1, {
fetch: session.fetch,
}),
).resolves.toHaveLength(1);

await expect(
getVerifiableCredentialAllFromShape(
new URL("derive", env.vcProvider).href,
credential2,
{
fetch: session.fetch,
},
),
getVerifiableCredentialAllFromShape(derivationService, credential2, {
fetch: session.fetch,
}),
).resolves.toHaveLength(1);

await Promise.all([
revokeVerifiableCredential(
new URL("status", env.vcProvider).href,
credential1.id,
{
fetch: session.fetch,
},
),
revokeVerifiableCredential(
new URL("status", env.vcProvider).href,
credential2.id,
{
fetch: session.fetch,
},
),
revokeVerifiableCredential(statusService, credential1.id, {
fetch: session.fetch,
}),
revokeVerifiableCredential(statusService, credential2.id, {
fetch: session.fetch,
}),
]);
});
});

describe("revoke VCs", () => {
it("can revoke a VC", async () => {
const credential = await issueVerifiableCredential(
new URL("issue", env.vcProvider).href,
issuerService,
validSubjectClaims(),
validCredentialClaims,
{
fetch: session.fetch,
},
);
await expect(
revokeVerifiableCredential(
new URL("status", env.vcProvider).href,
credential.id,
{
fetch: session.fetch,
},
),
revokeVerifiableCredential(statusService, credential.id, {
fetch: session.fetch,
}),
).resolves.not.toThrow();
const verificationResponse = await session.fetch(
new URL("verify", env.vcProvider).href,
{
method: "POST",
body: JSON.stringify({ verifiableCredential: credential }),
headers: {
"Content-Type": "application/json",
},
const verificationResponse = await session.fetch(verifierService, {
method: "POST",
body: JSON.stringify({ verifiableCredential: credential }),
headers: {
"Content-Type": "application/json",
},
);
});
const verification = await verificationResponse.json();
expect(verification.errors).toEqual([
"credentialStatus validation has failed: credential has been revoked",
Expand Down

1 comment on commit 056c4ad

@vercel
Copy link

@vercel vercel bot commented on 056c4ad Dec 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

solid-client-vc-js – ./

solid-client-vc-js-inrupt.vercel.app
solid-client-vc-js.vercel.app
solid-client-vc-js-git-main-inrupt.vercel.app

Please sign in to comment.