Skip to content

Commit

Permalink
test(*): finish test setup
Browse files Browse the repository at this point in the history
  • Loading branch information
pawcoding committed Feb 2, 2025
1 parent d8b9be1 commit f47f172
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 3 deletions.
1 change: 1 addition & 0 deletions test/_mocks/create-loader-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function createLoaderContext(
logger: new LoggerMock(),
parseData: vi.fn().mockResolvedValue({}),
store: new StoreMock(),
meta: new Map<string, string>(),
...context
} satisfies Partial<LoaderContext> as unknown as LoaderContext;
}
1 change: 1 addition & 0 deletions test/_mocks/create-pocketbase-entry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export function createPocketbaseEntry(
collectionId: Math.random().toString(36).substring(2, 17),
collectionName: "test",
customId: randomUUID(),
updated: new Date().toISOString().replace("T", " "),
...entry
};
}
20 changes: 20 additions & 0 deletions test/_mocks/superuser_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@
"system": true,
"type": "password"
},
{
"hidden": true,
"id": "file376926767",
"maxSelect": 1,
"maxSize": 0,
"mimeTypes": [
"image/jpeg",
"image/png",
"image/svg+xml",
"image/gif",
"image/webp"
],
"name": "avatar",
"presentable": false,
"protected": false,
"required": false,
"system": false,
"thumbs": null,
"type": "file"
},
{
"autogeneratePattern": "[a-zA-Z0-9]{50}",
"hidden": true,
Expand Down
137 changes: 137 additions & 0 deletions test/loader/loader.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import type { LoaderContext } from "astro/loaders";
import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
import packageJson from "../../package.json";
import { cleanupEntries } from "../../src/loader/cleanup-entries";
import { handleRealtimeUpdates } from "../../src/loader/handle-realtime-updates";
import { loadEntries } from "../../src/loader/load-entries";
import { loader } from "../../src/loader/loader";
import { getSuperuserToken } from "../../src/utils/get-superuser-token";
import { createLoaderContext } from "../_mocks/create-loader-context";
import { createLoaderOptions } from "../_mocks/create-loader-options";
import { createPocketbaseEntry } from "../_mocks/create-pocketbase-entry";

vi.mock("../../src/utils/get-superuser-token");
vi.mock("../../src/utils/should-refresh");
vi.mock("../../src/loader/cleanup-entries");
vi.mock("../../src/loader/handle-realtime-updates");
vi.mock("../../src/loader/load-entries");

describe("loader", async () => {
let context: LoaderContext;
const options = createLoaderOptions({ updatedField: "updated" });
const srm = await import("../../src/utils/should-refresh");
const hrum = await import("../../src/loader/handle-realtime-updates");
const gstm = await import("../../src/utils/get-superuser-token");

beforeEach(() => {
context = createLoaderContext();
context.meta.set("version", packageJson.version);
context.meta.set(
"last-modified",
new Date().toISOString().replace("T", " ")
);
});

afterEach(() => {
vi.resetAllMocks();
});

test("should not refresh if shouldRefresh returns false", async () => {
srm.shouldRefresh = vi.fn().mockReturnValue(false);

await loader(context, options);

expect(srm.shouldRefresh).toHaveBeenCalledOnce();
expect(handleRealtimeUpdates).not.toHaveBeenCalled();
expect(loadEntries).not.toHaveBeenCalled();
});

test("should not refresh if handleRealtimeUpdates handled update", async () => {
srm.shouldRefresh = vi.fn().mockReturnValue(true);
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(true);

await loader(context, options);

expect(handleRealtimeUpdates).toHaveBeenCalledOnce();
expect(loadEntries).not.toHaveBeenCalled();
});

test("should clear store and disable incremental builds if version changes", async () => {
srm.shouldRefresh = vi.fn().mockReturnValue(true);
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
const storeClearSpy = vi.spyOn(context.store, "clear");
context.meta.set("version", "invalidVersion");

await loader(context, options);

expect(storeClearSpy).toHaveBeenCalledOnce();
expect(loadEntries).toHaveBeenCalledWith(
options,
context,
undefined,
undefined
);
});

test("should disable incremental builds if no updatedField is provided", async () => {
srm.shouldRefresh = vi.fn().mockReturnValue(true);
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
options.updatedField = undefined;

await loader(context, options);

expect(loadEntries).toHaveBeenCalledWith(
options,
context,
undefined,
undefined
);
});

test("should get superuser token if superuserCredentials are provided", async () => {
const token = "token";
srm.shouldRefresh = vi.fn().mockReturnValue(true);
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
gstm.getSuperuserToken = vi.fn().mockResolvedValue(token);
const entry = createPocketbaseEntry();
context.store.set({ id: entry.id, data: entry });

await loader(context, options);

expect(getSuperuserToken).toHaveBeenCalledOnce();
expect(cleanupEntries).toHaveBeenCalledWith(options, context, token);
expect(loadEntries).toHaveBeenCalledWith(
options,
context,
token,
undefined
);
});

test("should cleanup old entries if store has keys", async () => {
srm.shouldRefresh = vi.fn().mockReturnValue(true);
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
const entry = createPocketbaseEntry();
context.store.set({ id: entry.id, data: entry });

await loader(context, options);

expect(cleanupEntries).toHaveBeenCalledWith(options, context, undefined);
});

test("should set last-modified and version in meta after loading entries", async () => {
srm.shouldRefresh = vi.fn().mockReturnValue(true);
hrum.handleRealtimeUpdates = vi.fn().mockResolvedValue(false);
gstm.getSuperuserToken = vi.fn().mockResolvedValue(undefined);
context.meta.delete("last-modified");
context.meta.delete("version");

await loader(context, options);

expect(context.meta.get("last-modified")).toBeDefined();
expect(context.meta.get("version")).toBe(packageJson.version);
});
});
8 changes: 8 additions & 0 deletions test/loader/parse-entry.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ describe("parseEntry", () => {
expect(context.logger.warn).toHaveBeenCalledOnce();
});

test("should use updated field as digest if provided", async () => {
const options = createLoaderOptions({ updatedField: "updated" });

await parseEntry(entry, context, options);

expect(context.generateDigest).toHaveBeenCalledWith(entry.updated);
});

test("should concatenate multiple content fields", async () => {
const options = createLoaderOptions({
contentFields: ["collectionName", "customId"]
Expand Down
3 changes: 1 addition & 2 deletions test/schema/generate-schema.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,14 @@ describe("generateSchema", () => {
it("should return schema from local file if path is provided", async () => {
const result = (await generateSchema({
...options,
superuserCredentials: undefined,
localSchema: "test/_mocks/superuser_schema.json"
})) as ZodObject<Record<string, ZodSchema<unknown>>>;

expect(Object.keys(result.shape)).toEqual([
"id",
"collectionId",
"collectionName",
"password",
"tokenKey",
"email",
"emailVisibility",
"verified",
Expand Down
13 changes: 13 additions & 0 deletions test/utils/get-superuser-token.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { beforeAll, describe, expect, it } from "vitest";
import { getSuperuserToken } from "../../src/utils/get-superuser-token";
import { checkE2eConnection } from "../_mocks/check-e2e-connection";
import { createLoaderContext } from "../_mocks/create-loader-context";
import { createLoaderOptions } from "../_mocks/create-loader-options";

describe("getSuperuserToken", () => {
Expand All @@ -18,6 +19,18 @@ describe("getSuperuserToken", () => {
expect(result).toBeUndefined();
});

it("should use integration logger if provided", async () => {
const { logger } = createLoaderContext();

await getSuperuserToken(
options.url,
{ email: "invalid", password: "invalid" },
logger
);

expect(logger.error).toHaveBeenCalled();
});

it("should return token if fetch request is successful", async () => {
const result = await getSuperuserToken(
options.url,
Expand Down
3 changes: 2 additions & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ export default defineConfig({
include: ["test/**/*.spec.ts", "test/**/*.e2e-spec.ts"],
silent: true,
coverage: {
include: ["src/**/*.ts"]
include: ["src/**/*.ts"],
exclude: ["src/types/**/*.ts", "src/index.ts", "src/pocketbase-loader.ts"]
}
}
});

0 comments on commit f47f172

Please sign in to comment.