mirror of
https://github.com/openclaw/openclaw.git
synced 2026-02-19 18:39:20 -05:00
perf(test): reduce module reload churn in unit suites
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import * as authModule from "../agents/model-auth.js";
|
||||
import { createVoyageEmbeddingProvider, normalizeVoyageModel } from "./embeddings-voyage.js";
|
||||
|
||||
vi.mock("../agents/model-auth.js", () => ({
|
||||
resolveApiKeyForProvider: vi.fn(),
|
||||
@@ -20,7 +22,6 @@ const createFetchMock = () =>
|
||||
describe("voyage embedding provider", () => {
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
vi.resetModules();
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
@@ -28,9 +29,6 @@ describe("voyage embedding provider", () => {
|
||||
const fetchMock = createFetchMock();
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
|
||||
const { createVoyageEmbeddingProvider } = await import("./embeddings-voyage.js");
|
||||
const authModule = await import("../agents/model-auth.js");
|
||||
|
||||
vi.mocked(authModule.resolveApiKeyForProvider).mockResolvedValue({
|
||||
apiKey: "voyage-key-123",
|
||||
mode: "api-key",
|
||||
@@ -69,8 +67,6 @@ describe("voyage embedding provider", () => {
|
||||
const fetchMock = createFetchMock();
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
|
||||
const { createVoyageEmbeddingProvider } = await import("./embeddings-voyage.js");
|
||||
|
||||
const result = await createVoyageEmbeddingProvider({
|
||||
config: {} as never,
|
||||
provider: "voyage",
|
||||
@@ -103,9 +99,6 @@ describe("voyage embedding provider", () => {
|
||||
})) as unknown as typeof fetch;
|
||||
vi.stubGlobal("fetch", fetchMock);
|
||||
|
||||
const { createVoyageEmbeddingProvider } = await import("./embeddings-voyage.js");
|
||||
const authModule = await import("../agents/model-auth.js");
|
||||
|
||||
vi.mocked(authModule.resolveApiKeyForProvider).mockResolvedValue({
|
||||
apiKey: "voyage-key-123",
|
||||
mode: "api-key",
|
||||
@@ -131,7 +124,6 @@ describe("voyage embedding provider", () => {
|
||||
});
|
||||
|
||||
it("normalizes model names", async () => {
|
||||
const { normalizeVoyageModel } = await import("./embeddings-voyage.js");
|
||||
expect(normalizeVoyageModel("voyage/voyage-large-2")).toBe("voyage-large-2");
|
||||
expect(normalizeVoyageModel("voyage-4-large")).toBe("voyage-4-large");
|
||||
expect(normalizeVoyageModel(" voyage-lite ")).toBe("voyage-lite");
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { DEFAULT_GEMINI_EMBEDDING_MODEL } from "./embeddings-gemini.js";
|
||||
|
||||
vi.mock("../agents/model-auth.js", () => ({
|
||||
@@ -21,7 +21,6 @@ const createFetchMock = () =>
|
||||
describe("embedding provider remote overrides", () => {
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
vi.resetModules();
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
@@ -170,7 +169,6 @@ describe("embedding provider remote overrides", () => {
|
||||
describe("embedding provider auto selection", () => {
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
vi.resetModules();
|
||||
vi.unstubAllGlobals();
|
||||
});
|
||||
|
||||
@@ -266,6 +264,10 @@ describe("embedding provider auto selection", () => {
|
||||
});
|
||||
|
||||
describe("embedding provider local fallback", () => {
|
||||
beforeAll(() => {
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.resetAllMocks();
|
||||
vi.resetModules();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { removeReactionSignal, sendReactionSignal } from "./send-reactions.js";
|
||||
|
||||
const rpcMock = vi.fn();
|
||||
const loadSendReactions = async () => await import("./send-reactions.js");
|
||||
|
||||
vi.mock("../config/config.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("../config/config.js")>();
|
||||
@@ -28,11 +28,9 @@ vi.mock("./client.js", () => ({
|
||||
describe("sendReactionSignal", () => {
|
||||
beforeEach(() => {
|
||||
rpcMock.mockReset().mockResolvedValue({ timestamp: 123 });
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it("uses recipients array and targetAuthor for uuid dms", async () => {
|
||||
const { sendReactionSignal } = await loadSendReactions();
|
||||
await sendReactionSignal("uuid:123e4567-e89b-12d3-a456-426614174000", 123, "🔥");
|
||||
|
||||
const params = rpcMock.mock.calls[0]?.[1] as Record<string, unknown>;
|
||||
@@ -45,7 +43,6 @@ describe("sendReactionSignal", () => {
|
||||
});
|
||||
|
||||
it("uses groupIds array and maps targetAuthorUuid", async () => {
|
||||
const { sendReactionSignal } = await loadSendReactions();
|
||||
await sendReactionSignal("", 123, "✅", {
|
||||
groupId: "group-id",
|
||||
targetAuthorUuid: "uuid:123e4567-e89b-12d3-a456-426614174000",
|
||||
@@ -58,7 +55,6 @@ describe("sendReactionSignal", () => {
|
||||
});
|
||||
|
||||
it("defaults targetAuthor to recipient for removals", async () => {
|
||||
const { removeReactionSignal } = await loadSendReactions();
|
||||
await removeReactionSignal("+15551230000", 456, "❌");
|
||||
|
||||
const params = rpcMock.mock.calls[0]?.[1] as Record<string, unknown>;
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import * as ssrf from "../../infra/net/ssrf.js";
|
||||
import * as mediaStore from "../../media/store.js";
|
||||
import { fetchWithSlackAuth, resolveSlackMedia, resolveSlackThreadHistory } from "./media.js";
|
||||
|
||||
// Store original fetch
|
||||
const originalFetch = globalThis.fetch;
|
||||
@@ -15,13 +17,9 @@ describe("fetchWithSlackAuth", () => {
|
||||
afterEach(() => {
|
||||
// Restore original fetch
|
||||
globalThis.fetch = originalFetch;
|
||||
vi.resetModules();
|
||||
});
|
||||
|
||||
it("sends Authorization header on initial request with manual redirect", async () => {
|
||||
// Import after mocking fetch
|
||||
const { fetchWithSlackAuth } = await import("./media.js");
|
||||
|
||||
// Simulate direct 200 response (no redirect)
|
||||
const mockResponse = new Response(Buffer.from("image data"), {
|
||||
status: 200,
|
||||
@@ -42,8 +40,6 @@ describe("fetchWithSlackAuth", () => {
|
||||
});
|
||||
|
||||
it("rejects non-Slack hosts to avoid leaking tokens", async () => {
|
||||
const { fetchWithSlackAuth } = await import("./media.js");
|
||||
|
||||
await expect(
|
||||
fetchWithSlackAuth("https://example.com/test.jpg", "xoxb-test-token"),
|
||||
).rejects.toThrow(/non-Slack host|non-Slack/i);
|
||||
@@ -53,8 +49,6 @@ describe("fetchWithSlackAuth", () => {
|
||||
});
|
||||
|
||||
it("follows redirects without Authorization header", async () => {
|
||||
const { fetchWithSlackAuth } = await import("./media.js");
|
||||
|
||||
// First call: redirect response from Slack
|
||||
const redirectResponse = new Response(null, {
|
||||
status: 302,
|
||||
@@ -89,8 +83,6 @@ describe("fetchWithSlackAuth", () => {
|
||||
});
|
||||
|
||||
it("handles relative redirect URLs", async () => {
|
||||
const { fetchWithSlackAuth } = await import("./media.js");
|
||||
|
||||
// Redirect with relative URL
|
||||
const redirectResponse = new Response(null, {
|
||||
status: 302,
|
||||
@@ -113,8 +105,6 @@ describe("fetchWithSlackAuth", () => {
|
||||
});
|
||||
|
||||
it("returns redirect response when no location header is provided", async () => {
|
||||
const { fetchWithSlackAuth } = await import("./media.js");
|
||||
|
||||
// Redirect without location header
|
||||
const redirectResponse = new Response(null, {
|
||||
status: 302,
|
||||
@@ -131,8 +121,6 @@ describe("fetchWithSlackAuth", () => {
|
||||
});
|
||||
|
||||
it("returns 4xx/5xx responses directly without following", async () => {
|
||||
const { fetchWithSlackAuth } = await import("./media.js");
|
||||
|
||||
const errorResponse = new Response("Not Found", {
|
||||
status: 404,
|
||||
});
|
||||
@@ -146,8 +134,6 @@ describe("fetchWithSlackAuth", () => {
|
||||
});
|
||||
|
||||
it("handles 301 permanent redirects", async () => {
|
||||
const { fetchWithSlackAuth } = await import("./media.js");
|
||||
|
||||
const redirectResponse = new Response(null, {
|
||||
status: 301,
|
||||
headers: { location: "https://cdn.slack.com/new-url" },
|
||||
@@ -185,20 +171,14 @@ describe("resolveSlackMedia", () => {
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.fetch = originalFetch;
|
||||
vi.resetModules();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("prefers url_private_download over url_private", async () => {
|
||||
// Mock the store module
|
||||
vi.doMock("../../media/store.js", () => ({
|
||||
saveMediaBuffer: vi.fn().mockResolvedValue({
|
||||
path: "/tmp/test.jpg",
|
||||
contentType: "image/jpeg",
|
||||
}),
|
||||
}));
|
||||
|
||||
const { resolveSlackMedia } = await import("./media.js");
|
||||
vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValue({
|
||||
path: "/tmp/test.jpg",
|
||||
contentType: "image/jpeg",
|
||||
});
|
||||
|
||||
const mockResponse = new Response(Buffer.from("image data"), {
|
||||
status: 200,
|
||||
@@ -225,8 +205,6 @@ describe("resolveSlackMedia", () => {
|
||||
});
|
||||
|
||||
it("returns null when download fails", async () => {
|
||||
const { resolveSlackMedia } = await import("./media.js");
|
||||
|
||||
// Simulate a network error
|
||||
mockFetch.mockRejectedValueOnce(new Error("Network error"));
|
||||
|
||||
@@ -240,8 +218,6 @@ describe("resolveSlackMedia", () => {
|
||||
});
|
||||
|
||||
it("returns null when no files are provided", async () => {
|
||||
const { resolveSlackMedia } = await import("./media.js");
|
||||
|
||||
const result = await resolveSlackMedia({
|
||||
files: [],
|
||||
token: "xoxb-test-token",
|
||||
@@ -252,8 +228,6 @@ describe("resolveSlackMedia", () => {
|
||||
});
|
||||
|
||||
it("skips files without url_private", async () => {
|
||||
const { resolveSlackMedia } = await import("./media.js");
|
||||
|
||||
const result = await resolveSlackMedia({
|
||||
files: [{ name: "test.jpg" }], // No url_private
|
||||
token: "xoxb-test-token",
|
||||
@@ -265,15 +239,10 @@ describe("resolveSlackMedia", () => {
|
||||
});
|
||||
|
||||
it("falls through to next file when first file returns error", async () => {
|
||||
// Mock the store module
|
||||
vi.doMock("../../media/store.js", () => ({
|
||||
saveMediaBuffer: vi.fn().mockResolvedValue({
|
||||
path: "/tmp/test.jpg",
|
||||
contentType: "image/jpeg",
|
||||
}),
|
||||
}));
|
||||
|
||||
const { resolveSlackMedia } = await import("./media.js");
|
||||
vi.spyOn(mediaStore, "saveMediaBuffer").mockResolvedValue({
|
||||
path: "/tmp/test.jpg",
|
||||
contentType: "image/jpeg",
|
||||
});
|
||||
|
||||
// First file: 404
|
||||
const errorResponse = new Response("Not Found", { status: 404 });
|
||||
@@ -301,7 +270,6 @@ describe("resolveSlackMedia", () => {
|
||||
|
||||
describe("resolveSlackThreadHistory", () => {
|
||||
afterEach(() => {
|
||||
vi.resetModules();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
@@ -324,7 +292,6 @@ describe("resolveSlackThreadHistory", () => {
|
||||
})),
|
||||
response_metadata: { next_cursor: "" },
|
||||
});
|
||||
const { resolveSlackThreadHistory } = await import("./media.js");
|
||||
const client = {
|
||||
conversations: { replies },
|
||||
} as Parameters<typeof resolveSlackThreadHistory>[0]["client"];
|
||||
@@ -375,7 +342,6 @@ describe("resolveSlackThreadHistory", () => {
|
||||
],
|
||||
response_metadata: { next_cursor: "" },
|
||||
});
|
||||
const { resolveSlackThreadHistory } = await import("./media.js");
|
||||
const client = {
|
||||
conversations: { replies },
|
||||
} as Parameters<typeof resolveSlackThreadHistory>[0]["client"];
|
||||
@@ -394,7 +360,6 @@ describe("resolveSlackThreadHistory", () => {
|
||||
|
||||
it("returns empty when limit is zero without calling Slack API", async () => {
|
||||
const replies = vi.fn();
|
||||
const { resolveSlackThreadHistory } = await import("./media.js");
|
||||
const client = {
|
||||
conversations: { replies },
|
||||
} as Parameters<typeof resolveSlackThreadHistory>[0]["client"];
|
||||
@@ -412,7 +377,6 @@ describe("resolveSlackThreadHistory", () => {
|
||||
|
||||
it("returns empty when Slack API throws", async () => {
|
||||
const replies = vi.fn().mockRejectedValueOnce(new Error("slack down"));
|
||||
const { resolveSlackThreadHistory } = await import("./media.js");
|
||||
const client = {
|
||||
conversations: { replies },
|
||||
} as Parameters<typeof resolveSlackThreadHistory>[0]["client"];
|
||||
|
||||
Reference in New Issue
Block a user