Skip to content
Draft
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
111 changes: 94 additions & 17 deletions frontend/__tests__/components/AsyncContent.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,9 @@ import { createResource, Resource } from "solid-js";
import { describe, it, expect } from "vitest";

import AsyncContent from "../../src/ts/components/common/AsyncContent";
import { AsyncStore, createAsyncStore } from "../../src/ts/hooks/asyncStore";

describe("AsyncContent", () => {
function renderWithResource<T>(
resource: Resource<T>,
errorMessage?: string,
): {
container: HTMLElement;
} {
const { container } = render(() => (
<AsyncContent resource={resource} errorMessage={errorMessage}>
{(data) => <div data-testid="content">{String(data)}</div>}
</AsyncContent>
));

return {
container,
};
}

it("renders loading state while resource is pending", () => {
const [resource] = createResource(async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
Expand Down Expand Up @@ -76,4 +60,97 @@ describe("AsyncContent", () => {
expect(screen.getByText(/An error occurred/)).toBeInTheDocument();
});
});

it("renders loading state while asyncStore is pending", () => {
const asyncStore = createAsyncStore<{ data?: string }>({
name: "test",
fetcher: async () => {
await new Promise((resolve) => setTimeout(resolve, 100));
return { data: "data" };
},
});

const { container } = renderWithAsyncStore(asyncStore);

const preloader = container.querySelector(".preloader");
expect(preloader).toBeInTheDocument();
expect(preloader).toHaveClass("preloader");
expect(preloader?.querySelector("i")).toHaveClass(
"fas",
"fa-fw",
"fa-spin",
"fa-circle-notch",
);
});

it("renders data when asyncStore resolves", async () => {
const asyncStore = createAsyncStore<{ data?: string }>({
name: "test",
fetcher: async () => {
return { data: "Test Data" };
},
autoLoad: () => true,
});

renderWithAsyncStore(asyncStore);

await waitFor(() => {
expect(screen.getByTestId("content")).toHaveTextContent("Test Data");
});
});

it.skip("renders error message when asyncStore fails", async () => {
const asyncStore = createAsyncStore({
name: "test",
fetcher: async () => {
throw new Error("Test error");
},
});

try {
renderWithAsyncStore(asyncStore as any, "Custom error message");
} catch {}

await expect(() => asyncStore.ready()).rejects;
await waitFor(() => {
expect(
screen.getByText(/Custom error message: Test error/),
).toBeInTheDocument();
});
});

function renderWithResource<T>(
resource: Resource<T>,
errorMessage?: string,
): {
container: HTMLElement;
} {
const { container } = render(() => (
<AsyncContent resource={resource} errorMessage={errorMessage}>
{(data) => <div data-testid="content">{String(data)}</div>}
</AsyncContent>
));

return {
container,
};
}

function renderWithAsyncStore(
asyncStore: AsyncStore<{ data?: string }>,
errorMessage?: string,
): {
container: HTMLElement;
} {
asyncStore.load();
const { container } = render(() => (
<AsyncContent asyncStore={asyncStore} errorMessage={errorMessage}>
{(data) => <span data-testid="content">{data?.data}</span>}
</AsyncContent>
));

return {
container,
};
}
});
Loading