Merge pull request #5 from o-development/risky-solid-react-tests

Risky solid react tests
main
jaxoncreed 2 years ago committed by GitHub
commit d128d8416d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 1
      packages/solid-react/src/UnauthenticatedSolidLdoProvider.tsx
  2. 13
      packages/solid-react/src/useLdoMethods.ts
  3. 1
      packages/solid-react/src/useResource.ts
  4. 11
      packages/solid-react/src/useRootContainer.ts
  5. 32
      packages/solid-react/test/.ldo/post.context.ts
  6. 155
      packages/solid-react/test/.ldo/post.schema.ts
  7. 19
      packages/solid-react/test/.ldo/post.shapeTypes.ts
  8. 45
      packages/solid-react/test/.ldo/post.typings.ts
  9. 328
      packages/solid-react/test/Integration.test.tsx
  10. 25
      packages/solid-react/test/setUpServer.ts
  11. 11
      packages/solid/src/util/RequestBatcher.ts
  12. 2
      packages/solid/test/Integration.test.ts

@ -1,3 +1,4 @@
/* istanbul ignore file */
import React, { useCallback, useMemo } from "react"; import React, { useCallback, useMemo } from "react";
import type { FunctionComponent, PropsWithChildren } from "react"; import type { FunctionComponent, PropsWithChildren } from "react";
import type { LoginOptions, SessionInfo } from "./SolidAuthContext"; import type { LoginOptions, SessionInfo } from "./SolidAuthContext";

@ -9,13 +9,18 @@ export interface UseLdoMethods {
getSubject<Type extends LdoBase>( getSubject<Type extends LdoBase>(
shapeType: ShapeType<Type>, shapeType: ShapeType<Type>,
subject: string | SubjectNode, subject: string | SubjectNode,
): Type | Error; ): Type;
createData<Type extends LdoBase>( createData<Type extends LdoBase>(
shapeType: ShapeType<Type>, shapeType: ShapeType<Type>,
subject: string | SubjectNode, subject: string | SubjectNode,
...resources: Resource[] resource: Resource,
...additionalResources: Resource[]
): Type;
changeData<Type extends LdoBase>(
input: Type,
resource: Resource,
...additionalResources: Resource[]
): Type; ): Type;
changeData<Type extends LdoBase>(input: Type, ...resources: Resource[]): Type;
commitData(input: LdoBase): ReturnType<SolidLdoDataset["commitChangesToPod"]>; commitData(input: LdoBase): ReturnType<SolidLdoDataset["commitChangesToPod"]>;
} }
@ -35,7 +40,7 @@ export function createUseLdoMethods(dataset: SolidLdoDataset): UseLdoMethods {
getSubject<Type extends LdoBase>( getSubject<Type extends LdoBase>(
shapeType: ShapeType<Type>, shapeType: ShapeType<Type>,
subject: string | SubjectNode, subject: string | SubjectNode,
): Type | Error { ): Type {
return dataset.usingType(shapeType).fromSubject(subject); return dataset.usingType(shapeType).fromSubject(subject);
}, },
/** /**

@ -70,6 +70,7 @@ export function useResource(
}, },
[resource], [resource],
); );
useEffect(() => { useEffect(() => {
// Remove listeners for the previous resource // Remove listeners for the previous resource
if (pastResource.current?.resource) { if (pastResource.current?.resource) {

@ -1,8 +1,13 @@
import type { Container, ContainerUri } from "@ldo/solid"; import type { Container, ContainerUri } from "@ldo/solid";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import type { UseResourceOptions } from "./useResource";
import { useResource } from "./useResource"; import { useResource } from "./useResource";
import { useLdo } from "./SolidLdoProvider"; import { useLdo } from "./SolidLdoProvider";
export function useRootContainerFor(uri?: string): Container | undefined {
export function useRootContainerFor(
uri?: string,
options?: UseResourceOptions,
): Container | undefined {
const { getResource } = useLdo(); const { getResource } = useLdo();
const [rootContainerUri, setRootContainerUri] = useState< const [rootContainerUri, setRootContainerUri] = useState<
@ -17,8 +22,10 @@ export function useRootContainerFor(uri?: string): Container | undefined {
setRootContainerUri(result.uri); setRootContainerUri(result.uri);
} }
}); });
} else {
setRootContainerUri(undefined);
} }
}, [uri]); }, [uri]);
return useResource(rootContainerUri); return useResource(rootContainerUri, options);
} }

@ -0,0 +1,32 @@
import { ContextDefinition } from "jsonld";
/**
* =============================================================================
* postContext: JSONLD Context for post
* =============================================================================
*/
export const postContext: ContextDefinition = {
type: {
"@id": "@type",
},
SocialMediaPosting: "http://schema.org/SocialMediaPosting",
CreativeWork: "http://schema.org/CreativeWork",
Thing: "http://schema.org/Thing",
articleBody: {
"@id": "http://schema.org/articleBody",
"@type": "http://www.w3.org/2001/XMLSchema#string",
},
uploadDate: {
"@id": "http://schema.org/uploadDate",
"@type": "http://www.w3.org/2001/XMLSchema#date",
},
image: {
"@id": "http://schema.org/image",
"@type": "@id",
},
publisher: {
"@id": "http://schema.org/publisher",
"@type": "@id",
"@container": "@set",
},
};

@ -0,0 +1,155 @@
import { Schema } from "shexj";
/**
* =============================================================================
* postSchema: ShexJ Schema for post
* =============================================================================
*/
export const postSchema: Schema = {
type: "Schema",
shapes: [
{
id: "https://example.com/PostSh",
type: "ShapeDecl",
shapeExpr: {
type: "Shape",
expression: {
type: "EachOf",
expressions: [
{
type: "TripleConstraint",
predicate: "http://www.w3.org/1999/02/22-rdf-syntax-ns#type",
valueExpr: {
type: "NodeConstraint",
values: [
"http://schema.org/SocialMediaPosting",
"http://schema.org/CreativeWork",
"http://schema.org/Thing",
],
},
},
{
type: "TripleConstraint",
predicate: "http://schema.org/articleBody",
valueExpr: {
type: "NodeConstraint",
datatype: "http://www.w3.org/2001/XMLSchema#string",
},
min: 0,
max: 1,
annotations: [
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#label",
object: {
value: "articleBody",
},
},
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
object: {
value: "The actual body of the article. ",
},
},
],
},
{
type: "TripleConstraint",
predicate: "http://schema.org/uploadDate",
valueExpr: {
type: "NodeConstraint",
datatype: "http://www.w3.org/2001/XMLSchema#date",
},
annotations: [
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#label",
object: {
value: "uploadDate",
},
},
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
object: {
value:
"Date when this media object was uploaded to this site.",
},
},
],
},
{
type: "TripleConstraint",
predicate: "http://schema.org/image",
valueExpr: {
type: "NodeConstraint",
nodeKind: "iri",
},
min: 0,
max: 1,
annotations: [
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#label",
object: {
value: "image",
},
},
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
object: {
value:
"A media object that encodes this CreativeWork. This property is a synonym for encoding.",
},
},
],
},
{
type: "TripleConstraint",
predicate: "http://schema.org/publisher",
valueExpr: {
type: "NodeConstraint",
nodeKind: "iri",
},
annotations: [
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#label",
object: {
value: "publisher",
},
},
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
object: {
value: "The publisher of the creative work.",
},
},
],
},
],
},
annotations: [
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#label",
object: {
value: "SocialMediaPost",
},
},
{
type: "Annotation",
predicate: "http://www.w3.org/2000/01/rdf-schema#comment",
object: {
value:
"A post to a social media platform, including blog posts, tweets, Facebook posts, etc.",
},
},
],
},
},
],
};

@ -0,0 +1,19 @@
import { ShapeType } from "@ldo/ldo";
import { postSchema } from "./post.schema";
import { postContext } from "./post.context";
import { PostSh } from "./post.typings";
/**
* =============================================================================
* LDO ShapeTypes post
* =============================================================================
*/
/**
* PostSh ShapeType
*/
export const PostShShapeType: ShapeType<PostSh> = {
schema: postSchema,
shape: "https://example.com/PostSh",
context: postContext,
};

@ -0,0 +1,45 @@
import { ContextDefinition } from "jsonld";
/**
* =============================================================================
* Typescript Typings for post
* =============================================================================
*/
/**
* PostSh Type
*/
export interface PostSh {
"@id"?: string;
"@context"?: ContextDefinition;
type:
| {
"@id": "SocialMediaPosting";
}
| {
"@id": "CreativeWork";
}
| {
"@id": "Thing";
};
/**
* The actual body of the article.
*/
articleBody?: string;
/**
* Date when this media object was uploaded to this site.
*/
uploadDate: string;
/**
* A media object that encodes this CreativeWork. This property is a synonym for encoding.
*/
image?: {
"@id": string;
};
/**
* The publisher of the creative work.
*/
publisher: {
"@id": string;
}[];
}

@ -1,9 +1,19 @@
import React from "react"; import React, { useEffect, useState } from "react";
import type { FunctionComponent } from "react"; import type { FunctionComponent } from "react";
import { render, screen } from "@testing-library/react"; import { render, screen, fireEvent } from "@testing-library/react";
import { SAMPLE_DATA_URI, setUpServer } from "./setUpServer"; import {
SAMPLE_BINARY_URI,
SAMPLE_DATA_URI,
SERVER_DOMAIN,
setUpServer,
} from "./setUpServer";
import { UnauthenticatedSolidLdoProvider } from "../src/UnauthenticatedSolidLdoProvider"; import { UnauthenticatedSolidLdoProvider } from "../src/UnauthenticatedSolidLdoProvider";
import { useResource } from "../src/useResource"; import { useResource } from "../src/useResource";
import { useRootContainerFor } from "../src/useRootContainer";
import { useLdo } from "../src/SolidLdoProvider";
import { PostShShapeType } from "./.ldo/post.shapeTypes";
import type { PostSh } from "./.ldo/post.typings";
import { useSubject } from "../src/useSubject";
// Use an increased timeout, since the CSS server takes too much setup time. // Use an increased timeout, since the CSS server takes too much setup time.
jest.setTimeout(40_000); jest.setTimeout(40_000);
@ -32,5 +42,317 @@ describe("Integration Tests", () => {
const resourceStatus = await screen.findByRole("status"); const resourceStatus = await screen.findByRole("status");
expect(resourceStatus.innerHTML).toBe("dataReadSuccess"); expect(resourceStatus.innerHTML).toBe("dataReadSuccess");
}); });
it("returns undefined when no uri is provided, then rerenders when one is", async () => {
const UseResourceUndefinedTest: FunctionComponent = () => {
const [uri, setUri] = useState<string | undefined>(undefined);
const resource = useResource(uri, { suppressInitialRead: true });
if (!resource)
return (
<div>
<p>Undefined</p>
<button onClick={() => setUri(SAMPLE_DATA_URI)}>Next</button>
</div>
);
return <p role="status">{resource.status.type}</p>;
};
render(
<UnauthenticatedSolidLdoProvider>
<UseResourceUndefinedTest />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("Undefined");
fireEvent.click(screen.getByText("Next"));
const resourceStatus = await screen.findByRole("status");
expect(resourceStatus.innerHTML).toBe("unfetched");
});
it("Reloads the data on mount", async () => {
const ReloadTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI, { reloadOnMount: true });
if (resource?.isLoading()) return <p>Loading</p>;
return <p role="status">{resource.status.type}</p>;
};
const ReloadParent: FunctionComponent = () => {
const [showComponent, setShowComponent] = useState(true);
return (
<div>
<button onClick={() => setShowComponent(!showComponent)}>
Show Component
</button>
{showComponent ? <ReloadTest /> : <p>Hidden</p>}
</div>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<ReloadParent />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("Loading");
const resourceStatus1 = await screen.findByRole("status");
expect(resourceStatus1.innerHTML).toBe("dataReadSuccess");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Hidden");
fireEvent.click(screen.getByText("Show Component"));
await screen.findByText("Loading");
const resourceStatus2 = await screen.findByRole("status");
expect(resourceStatus2.innerHTML).toBe("dataReadSuccess");
});
it("handles swapping to a new resource", async () => {
const SwapResourceTest: FunctionComponent = () => {
const [uri, setUri] = useState(SAMPLE_DATA_URI);
const resource = useResource(uri);
if (resource?.isLoading()) return <p>Loading</p>;
return (
<div>
<p role="status">{resource.status.type}</p>
<button onClick={() => setUri(SAMPLE_BINARY_URI)}>
Update URI
</button>
</div>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<SwapResourceTest />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("Loading");
const resourceStatus1 = await screen.findByRole("status");
expect(resourceStatus1.innerHTML).toBe("dataReadSuccess");
fireEvent.click(screen.getByText("Update URI"));
await screen.findByText("Loading");
const resourceStatus2 = await screen.findByRole("status");
expect(resourceStatus2.innerHTML).toBe("binaryReadSuccess");
});
});
describe("useRootContainer", () => {
it("gets the root container for a sub-resource", async () => {
const RootContainerTest: FunctionComponent = () => {
const rootContainer = useRootContainerFor(SAMPLE_DATA_URI, {
suppressInitialRead: true,
});
return rootContainer ? (
<p role="root">{rootContainer?.uri}</p>
) : undefined;
};
render(
<UnauthenticatedSolidLdoProvider>
<RootContainerTest />
</UnauthenticatedSolidLdoProvider>,
);
const container = await screen.findByRole("root");
expect(container.innerHTML).toBe(SERVER_DOMAIN);
});
it("returns undefined when a URI is not provided", async () => {
const RootContainerTest: FunctionComponent = () => {
const rootContainer = useRootContainerFor(undefined, {
suppressInitialRead: true,
});
return rootContainer ? (
<p role="root">{rootContainer?.uri}</p>
) : (
<p role="undefined">Undefined</p>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<RootContainerTest />
</UnauthenticatedSolidLdoProvider>,
);
const container = await screen.findByRole("undefined");
expect(container.innerHTML).toBe("Undefined");
});
});
describe("useLdoMethod", () => {
it("uses get subject to get a linked data object", async () => {
const GetSubjectTest: FunctionComponent = () => {
const [subject, setSubject] = useState<PostSh | undefined>();
const { getSubject } = useLdo();
useEffect(() => {
const someSubject = getSubject(
PostShShapeType,
"https://example.com/subject",
);
setSubject(someSubject);
}, []);
return subject ? <p role="subject">{subject["@id"]}</p> : undefined;
};
render(
<UnauthenticatedSolidLdoProvider>
<GetSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
const container = await screen.findByRole("subject");
expect(container.innerHTML).toBe("https://example.com/subject");
});
it("uses createData to create a new data object", async () => {
const GetSubjectTest: FunctionComponent = () => {
const [subject, setSubject] = useState<PostSh | undefined>();
const { createData, getResource } = useLdo();
useEffect(() => {
const someSubject = createData(
PostShShapeType,
"https://example.com/subject",
getResource("https://example.com/"),
);
someSubject.articleBody = "Cool Article";
setSubject(someSubject);
}, []);
return subject ? (
<p role="subject">{subject.articleBody}</p>
) : undefined;
};
render(
<UnauthenticatedSolidLdoProvider>
<GetSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
const container = await screen.findByRole("subject");
expect(container.innerHTML).toBe("Cool Article");
});
});
describe("useSubject", () => {
it("renders the article body from the useSubject value", async () => {
const UseSubjectTest: FunctionComponent = () => {
useResource(SAMPLE_DATA_URI);
const post = useSubject(PostShShapeType, `${SAMPLE_DATA_URI}#Post1`);
return <p role="article">{post.articleBody}</p>;
};
render(
<UnauthenticatedSolidLdoProvider>
<UseSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
await screen.findByText("test");
});
it("renders the array value from the useSubject value", async () => {
const UseSubjectTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI);
const post = useSubject(PostShShapeType, `${SAMPLE_DATA_URI}#Post1`);
if (resource.isLoading() || !post) return <p>loading</p>;
return (
<div>
<p role="single">{post.publisher[0]["@id"]}</p>
<ul role="list">
{post.publisher.map((publisher) => {
return <li key={publisher["@id"]}>{publisher["@id"]}</li>;
})}
</ul>
</div>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<UseSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
const single = await screen.findByRole("single");
expect(single.innerHTML).toBe("https://example.com/Publisher1");
const list = await screen.findByRole("list");
expect(list.children[0].innerHTML).toBe("https://example.com/Publisher1");
expect(list.children[1].innerHTML).toBe("https://example.com/Publisher2");
});
it("returns undefined in the subject URI is undefined", async () => {
const UseSubjectTest: FunctionComponent = () => {
useResource(SAMPLE_DATA_URI, { suppressInitialRead: true });
const post = useSubject(PostShShapeType, undefined);
return (
<p role="article">
{post === undefined ? "Undefined" : "Not Undefined"}
</p>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<UseSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
const article = await screen.findByRole("article");
expect(article.innerHTML).toBe("Undefined");
});
it("returns nothing if a symbol key is provided", async () => {
const UseSubjectTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI);
const post = useSubject(PostShShapeType, `${SAMPLE_DATA_URI}#Post1`);
if (resource.isLoading() || !post) return <p>loading</p>;
return <p role="value">{typeof post[Symbol.hasInstance]}</p>;
};
render(
<UnauthenticatedSolidLdoProvider>
<UseSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
const article = await screen.findByRole("value");
expect(article.innerHTML).toBe("undefined");
});
it("returns an id if an id key is provided", async () => {
const UseSubjectTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI);
const post = useSubject(PostShShapeType, `${SAMPLE_DATA_URI}#Post1`);
if (resource.isLoading() || !post) return <p>loading</p>;
return <p role="value">{post["@id"]}</p>;
};
render(
<UnauthenticatedSolidLdoProvider>
<UseSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
const article = await screen.findByRole("value");
expect(article.innerHTML).toBe(`${SAMPLE_DATA_URI}#Post1`);
});
it("does not set a value if a value is attempted to be set", async () => {
const warn = jest.spyOn(console, "warn").mockImplementation(() => {});
const UseSubjectTest: FunctionComponent = () => {
const resource = useResource(SAMPLE_DATA_URI);
const post = useSubject(PostShShapeType, `${SAMPLE_DATA_URI}#Post1`);
if (resource.isLoading() || !post) return <p>loading</p>;
return (
<div>
<p role="value">{post.articleBody}</p>
<button onClick={() => (post.articleBody = "bad")}>
Attempt Change
</button>
</div>
);
};
render(
<UnauthenticatedSolidLdoProvider>
<UseSubjectTest />
</UnauthenticatedSolidLdoProvider>,
);
const article = await screen.findByRole("value");
expect(article.innerHTML).toBe(`test`);
fireEvent.click(screen.getByText("Attempt Change"));
expect(article.innerHTML).not.toBe("bad");
expect(warn).toHaveBeenCalledWith(
"You've attempted to set a value on a Linked Data Object from the useSubject, useMatchingSubject, or useMatchingObject hooks. These linked data objects should only be used to render data, not modify it. To modify data, use the `changeData` function.",
);
warn.mockReset();
});
}); });
}); });

@ -17,21 +17,13 @@ export const SAMPLE2_BINARY_URI =
`${TEST_CONTAINER_URI}${SAMPLE2_BINARY_SLUG}` as LeafUri; `${TEST_CONTAINER_URI}${SAMPLE2_BINARY_SLUG}` as LeafUri;
export const SAMPLE_CONTAINER_URI = export const SAMPLE_CONTAINER_URI =
`${TEST_CONTAINER_URI}sample_container/` as ContainerUri; `${TEST_CONTAINER_URI}sample_container/` as ContainerUri;
export const SPIDER_MAN_TTL = `@base <http://example.org/> . export const EXAMPLE_POST_TTL = `@prefix schema: <http://schema.org/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix rel: <http://www.perceive.net/schemas/relationship/> .
<#green-goblin> <#Post1>
rel:enemyOf <#spiderman> ; a schema:CreativeWork, schema:Thing, schema:SocialMediaPosting ;
a foaf:Person ; # in the context of the Marvel universe schema:image <https://example.com/postImage.jpg> ;
foaf:name "Green Goblin" . schema:articleBody "test" ;
schema:publisher <https://example.com/Publisher1>, <https://example.com/Publisher2> .`;
<#spiderman>
rel:enemyOf <#green-goblin> ;
a foaf:Person ;
foaf:name "Spiderman", "Человек-паук"@ru .`;
export const TEST_CONTAINER_TTL = `@prefix dc: <http://purl.org/dc/terms/>. export const TEST_CONTAINER_TTL = `@prefix dc: <http://purl.org/dc/terms/>.
@prefix ldp: <http://www.w3.org/ns/ldp#>. @prefix ldp: <http://www.w3.org/ns/ldp#>.
@prefix posix: <http://www.w3.org/ns/posix/stat#>. @prefix posix: <http://www.w3.org/ns/posix/stat#>.
@ -73,19 +65,18 @@ export function setUpServer(): SetUpServerReturn {
beforeEach(async () => { beforeEach(async () => {
s.fetchMock = jest.fn(s.authFetch); s.fetchMock = jest.fn(s.authFetch);
// Create a new document called sample.ttl // Create a new document called sample.ttl
const result = await s.authFetch(ROOT_CONTAINER, { await s.authFetch(ROOT_CONTAINER, {
method: "POST", method: "POST",
headers: { headers: {
link: '<http://www.w3.org/ns/ldp#Container>; rel="type"', link: '<http://www.w3.org/ns/ldp#Container>; rel="type"',
slug: TEST_CONTAINER_SLUG, slug: TEST_CONTAINER_SLUG,
}, },
}); });
console.log("Created container", result.status);
await Promise.all([ await Promise.all([
s.authFetch(TEST_CONTAINER_URI, { s.authFetch(TEST_CONTAINER_URI, {
method: "POST", method: "POST",
headers: { "content-type": "text/turtle", slug: "sample.ttl" }, headers: { "content-type": "text/turtle", slug: "sample.ttl" },
body: SPIDER_MAN_TTL, body: EXAMPLE_POST_TTL,
}), }),
s.authFetch(TEST_CONTAINER_URI, { s.authFetch(TEST_CONTAINER_URI, {
method: "POST", method: "POST",

@ -99,10 +99,11 @@ export class RequestBatcher {
* the last process was triggered. * the last process was triggered.
*/ */
private triggerOrWaitProcess() { private triggerOrWaitProcess() {
if (!this.processQueue[0]) { if (!this.processQueue[0] || this.currentlyProcessing) {
return; return;
} }
const processName = this.processQueue[0].name; this.currentlyProcessing = this.processQueue.shift();
const processName = this.currentlyProcessing!.name;
// Set last request timestamp if not available // Set last request timestamp if not available
if (!this.lastRequestTimestampMap[processName]) { if (!this.lastRequestTimestampMap[processName]) {
@ -113,12 +114,10 @@ export class RequestBatcher {
const timeSinceLastTrigger = Date.now() - lastRequestTimestamp; const timeSinceLastTrigger = Date.now() - lastRequestTimestamp;
const triggerProcess = async () => { const triggerProcess = async () => {
if (this.currentlyProcessing) {
return;
}
this.lastRequestTimestampMap[processName] = Date.now(); this.lastRequestTimestampMap[processName] = Date.now();
this.lastRequestTimestampMap[ANY_KEY] = Date.now(); this.lastRequestTimestampMap[ANY_KEY] = Date.now();
const processToTrigger = this.processQueue.shift(); // Remove the process from the queue
const processToTrigger = this.currentlyProcessing;
if (processToTrigger) { if (processToTrigger) {
this.currentlyProcessing = processToTrigger; this.currentlyProcessing = processToTrigger;
try { try {

@ -134,7 +134,7 @@ async function testRequestLoads<ReturnVal>(
return returnVal; return returnVal;
} }
describe("SolidLdoDataset", () => { describe("Integration", () => {
let app: App; let app: App;
let authFetch: typeof fetch; let authFetch: typeof fetch;
let fetchMock: jest.Mock< let fetchMock: jest.Mock<

Loading…
Cancel
Save