Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom fields browser-based tests #1189

Merged
merged 7 commits into from
Dec 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 140 additions & 12 deletions e2e/browser/test-app/components/accessGrants/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,89 @@
//

import { getDefaultSession } from "@inrupt/solid-client-authn-browser";
import type { AccessGrant } from "@inrupt/solid-client-access-grants";
import type {
AccessGrant,
DatasetWithId,
} from "@inrupt/solid-client-access-grants";
import {
issueAccessRequest,
redirectToAccessManagementUi,
getAccessGrant,
cancelAccessRequest,
getCustomFields,
getResourceOwner,
getResources,
getAccessModes,
} from "@inrupt/solid-client-access-grants";

Check warning on line 36 in e2e/browser/test-app/components/accessGrants/index.tsx

View workflow job for this annotation

GitHub Actions / lint / lint

Unable to resolve path to module '@inrupt/solid-client-access-grants'
import {
getPodUrlAll,
saveFileInContainer,
getSourceUrl,
deleteFile,
} from "@inrupt/solid-client";
import React, { useState } from "react";

Check warning on line 43 in e2e/browser/test-app/components/accessGrants/index.tsx

View workflow job for this annotation

GitHub Actions / lint / lint

Unable to resolve path to module 'react'
import { useRouter } from "next/router";

Check warning on line 44 in e2e/browser/test-app/components/accessGrants/index.tsx

View workflow job for this annotation

GitHub Actions / lint / lint

Unable to resolve path to module 'next/router'

const session = getDefaultSession();
const SHARED_FILE_CONTENT = "Some content.\n";

function AccessCredential({
vc,
testId,
}: {
vc: DatasetWithId | undefined;
testId: "access-request" | "access-grant";
}) {
if (vc === undefined) {
return undefined;
}
return (
<div data-testid={testId}>
<p>
Resource owner:{" "}
<span data-testid="credential-owner">{getResourceOwner(vc)}</span>
</p>
<p>
Requested resources:{" "}
<span data-testid="credential-resources">{getResources(vc)}</span>
</p>
<p>
Requested modes:{" "}
<span data-testid="credential-modes">
{JSON.stringify(getAccessModes(vc))}
</span>
</p>
<p>
Custom fields:{" "}
<span data-testid="credential-custom">
{JSON.stringify(getCustomFields(vc))}
</span>
</p>
</div>
);
}

export default function AccessController({
setErrorMessage,
}: {
setErrorMessage: (msg: string) => void;
}) {
const [accessGrant, setAccessGrant] = useState<AccessGrant>();
const [accessRequest, setAccessRequest] = useState<string>();
const [accessRequestUrl, setAccessRequestUrl] = useState<string>();
const [accessRequest, setAccessRequest] = useState<DatasetWithId>();
const [sharedResourceIri, setSharedResourceIri] = useState<string>();
const [customInt, setCustomInt] = useState<number>();
const [customIntUrl, setCustomIntUrl] = useState<string>(
"https://example.org/my-int",
);
const [customStr, setCustomStr] = useState<string>();
const [customStrUrl, setCustomStrUrl] = useState<string>(
"https://example.org/my-string",
);
const [customBoolean, setCustomBoolean] = useState<boolean>();
const [customBooleanUrl, setCustomBooleanUrl] = useState<string>(
"https://example.org/my-boolean",
);
const router = useRouter();

const handleCreate = async () => {
Expand Down Expand Up @@ -103,9 +159,25 @@
},
{
fetch: session.fetch,
returnLegacyJsonld: false,
customFields: new Set([
{
key: new URL(customIntUrl),
value: customInt!,
},
{
key: new URL(customStrUrl),
value: customStr!,
},
{
key: new URL(customBooleanUrl),
value: customBoolean!,
},
]),
},
);
setAccessRequest(accessRequestReturned);
setAccessRequestUrl(accessRequestReturned.id);
};

const handleRevoke = async () => {
Expand All @@ -117,6 +189,7 @@
fetch: session.fetch,
});
setAccessRequest(undefined);
setAccessRequestUrl(undefined);
};

const handleCallAuthedGrant = async () => {
Expand All @@ -129,15 +202,20 @@
};

const handleAccessRequest = async () => {
if (accessRequestUrl === undefined || !URL.canParse(accessRequestUrl)) {
console.error(

Check warning on line 206 in e2e/browser/test-app/components/accessGrants/index.tsx

View workflow job for this annotation

GitHub Actions / lint / lint

Unexpected console statement
"Please issue an Access Request and provide its URL before being redirected.",
);
return;
}
await redirectToAccessManagementUi(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
accessRequest!,
accessRequestUrl,
`http://localhost:3000/`,
{
redirectCallback: (url: string) => {
window.location.replace(url);
},
fallbackAccessManagementUi: `https://amc.inrupt.com/accessRequest/`,
fallbackAccessManagementUi: "https://amc.inrupt.com/accessRequest/",
fetch: session.fetch,
},
);
Expand Down Expand Up @@ -181,15 +259,69 @@
Created resource:{" "}
<span data-testid="resource-iri">{sharedResourceIri}</span>
</p>
<p>
Custom fields:{" "}
<form>
<input
id="customIntUrl"
name="customIntUrl"
value={customIntUrl}
onChange={(e) => setCustomIntUrl(e.currentTarget.value)}
/>
{": "}
<input
type="number"
id="customInt"
name="customInt"
value={customInt}
onChange={(e) =>
setCustomInt(Number.parseInt(e.currentTarget.value, 10))
}
/>
<br />
<input
data-testid="input-custom-string-url"
id="customStrUrl"
name="customStrUrl"
value={customStrUrl}
onChange={(e) => setCustomStrUrl(e.currentTarget.value)}
/>
{": "}
<input
data-testid="input-custom-string"
id="customText"
name="customText"
value={customStr}
onChange={(e) => setCustomStr(e.currentTarget.value)}
/>
<br />
<input
id="customBooleanUrl"
name="customBooleanUrl"
value={customBooleanUrl}
onChange={(e) => setCustomBooleanUrl(e.currentTarget.value)}
/>
{": "}
<input
id="customBoolean"
name="customBoolean"
type="checkbox"
checked={customBoolean}
onClick={() => setCustomBoolean((prev) => !prev)}
/>
<br />
</form>
</p>
<p>
Access Request to Approve:{" "}
<input
id="request-id"
data-testid="access-request-id"
placeholder="Access Request URL"
onChange={(e) => {
setAccessRequest(e.currentTarget.value);
setAccessRequestUrl(e.currentTarget.value);
}}
value={accessRequestUrl}
/>
</p>
<div>
Expand Down Expand Up @@ -217,15 +349,11 @@
</div>
<p>
Issued access request:{" "}
<pre data-testid="access-request">
{accessRequest && JSON.stringify(accessRequest, null, 2)}
</pre>
<AccessCredential vc={accessRequest} testId="access-request" />
</p>
<p>
Granted access:{" "}
<pre data-testid="access-grant">
{accessGrant && JSON.stringify(accessGrant, null, 2)}
</pre>
<AccessCredential vc={accessGrant} testId="access-grant" />
</p>

<button
Expand Down
14 changes: 13 additions & 1 deletion e2e/browser/test/e2e.playwright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,25 @@ test("Issue an access request, then revoking the access request", async ({
{ timeout: 30_000 },
);

await page
.getByTestId("input-custom-string-url")
.fill("https://example.org/test-string");

await page.getByTestId("input-custom-string").fill("test value");

// Issue an access request to the resource.
await page.getByTestId("issue-access").click();
await expect(page.getByTestId("access-request")).not.toBeEmpty();
const customFields = await page
.getByTestId("credential-custom")
.textContent();
expect(customFields).not.toBeNull();
const record = JSON.parse(customFields!);
expect(record["https://example.org/test-string"]).toBe("test value");

// Revoke the access request.
await page.getByTestId("revoke-access").click();
await expect(page.getByTestId("access-request")).toBeEmpty();
await expect(page.getByTestId("access-request")).toBeHidden();

// Cleanup the resource
await page.getByTestId("delete-resource").click();
Expand Down
Loading