mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
refactor: share model catalog test helpers
This commit is contained in:
@@ -35,6 +35,39 @@ function model(id: string): GatewayModelChoice {
|
||||
|
||||
const getConfig = () => ({}) as OpenClawConfig;
|
||||
|
||||
function createRefreshingCatalogLoader(
|
||||
firstCatalog: GatewayModelChoice[],
|
||||
secondCatalog: GatewayModelChoice[],
|
||||
) {
|
||||
return vi
|
||||
.fn<LoadModelCatalogForTest>()
|
||||
.mockResolvedValueOnce(firstCatalog)
|
||||
.mockResolvedValueOnce(secondCatalog);
|
||||
}
|
||||
|
||||
async function expectCatalog(
|
||||
loadModelCatalog: LoadModelCatalogForTest,
|
||||
catalog: GatewayModelChoice[],
|
||||
readOnly = true,
|
||||
) {
|
||||
await expect(
|
||||
loadGatewayModelCatalog({
|
||||
getConfig,
|
||||
loadModelCatalog,
|
||||
...(readOnly ? {} : { readOnly: false }),
|
||||
}),
|
||||
).resolves.toBe(catalog);
|
||||
}
|
||||
|
||||
async function markStaleAndExpectPreviousCatalog(
|
||||
loadModelCatalog: LoadModelCatalogForTest,
|
||||
catalog: GatewayModelChoice[],
|
||||
) {
|
||||
markGatewayModelCatalogStaleForReload();
|
||||
await expectCatalog(loadModelCatalog, catalog);
|
||||
await vi.waitFor(() => expect(loadModelCatalog).toHaveBeenCalledTimes(2));
|
||||
}
|
||||
|
||||
describe("loadGatewayModelCatalog", () => {
|
||||
beforeEach(async () => {
|
||||
await resetModelCatalogCacheForTest();
|
||||
@@ -82,46 +115,26 @@ describe("loadGatewayModelCatalog", () => {
|
||||
it("caches an empty read-only catalog until reload marks it stale", async () => {
|
||||
const emptyCatalog: GatewayModelChoice[] = [];
|
||||
const freshCatalog = [model("gpt-5.5")];
|
||||
const loadModelCatalog = vi
|
||||
.fn<LoadModelCatalogForTest>()
|
||||
.mockResolvedValueOnce(emptyCatalog)
|
||||
.mockResolvedValueOnce(freshCatalog);
|
||||
const loadModelCatalog = createRefreshingCatalogLoader(emptyCatalog, freshCatalog);
|
||||
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
emptyCatalog,
|
||||
);
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
emptyCatalog,
|
||||
);
|
||||
await expectCatalog(loadModelCatalog, emptyCatalog);
|
||||
await expectCatalog(loadModelCatalog, emptyCatalog);
|
||||
|
||||
expect(loadModelCatalog).toHaveBeenCalledTimes(1);
|
||||
|
||||
markGatewayModelCatalogStaleForReload();
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
emptyCatalog,
|
||||
);
|
||||
await vi.waitFor(() => expect(loadModelCatalog).toHaveBeenCalledTimes(2));
|
||||
await markStaleAndExpectPreviousCatalog(loadModelCatalog, emptyCatalog);
|
||||
await vi.waitFor(async () => {
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
freshCatalog,
|
||||
);
|
||||
await expectCatalog(loadModelCatalog, freshCatalog);
|
||||
});
|
||||
});
|
||||
|
||||
it("does not cache an empty full catalog so the next all-model request retries", async () => {
|
||||
const emptyCatalog: GatewayModelChoice[] = [];
|
||||
const freshCatalog = [model("gpt-5.5")];
|
||||
const loadModelCatalog = vi
|
||||
.fn<LoadModelCatalogForTest>()
|
||||
.mockResolvedValueOnce(emptyCatalog)
|
||||
.mockResolvedValueOnce(freshCatalog);
|
||||
const loadModelCatalog = createRefreshingCatalogLoader(emptyCatalog, freshCatalog);
|
||||
|
||||
await expect(
|
||||
loadGatewayModelCatalog({ getConfig, loadModelCatalog, readOnly: false }),
|
||||
).resolves.toBe(emptyCatalog);
|
||||
await expect(
|
||||
loadGatewayModelCatalog({ getConfig, loadModelCatalog, readOnly: false }),
|
||||
).resolves.toBe(freshCatalog);
|
||||
await expectCatalog(loadModelCatalog, emptyCatalog, false);
|
||||
await expectCatalog(loadModelCatalog, freshCatalog, false);
|
||||
|
||||
expect(loadModelCatalog).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
@@ -135,21 +148,13 @@ describe("loadGatewayModelCatalog", () => {
|
||||
.mockResolvedValueOnce(staleCatalog)
|
||||
.mockReturnValueOnce(refresh.promise);
|
||||
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
staleCatalog,
|
||||
);
|
||||
await expectCatalog(loadModelCatalog, staleCatalog);
|
||||
|
||||
markGatewayModelCatalogStaleForReload();
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
staleCatalog,
|
||||
);
|
||||
await vi.waitFor(() => expect(loadModelCatalog).toHaveBeenCalledTimes(2));
|
||||
await markStaleAndExpectPreviousCatalog(loadModelCatalog, staleCatalog);
|
||||
|
||||
refresh.resolve(freshCatalog);
|
||||
await vi.waitFor(async () => {
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
freshCatalog,
|
||||
);
|
||||
await expectCatalog(loadModelCatalog, freshCatalog);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -162,25 +167,15 @@ describe("loadGatewayModelCatalog", () => {
|
||||
.mockRejectedValueOnce(new Error("provider offline"))
|
||||
.mockResolvedValueOnce(freshCatalog);
|
||||
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
staleCatalog,
|
||||
);
|
||||
await expectCatalog(loadModelCatalog, staleCatalog);
|
||||
|
||||
markGatewayModelCatalogStaleForReload();
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
staleCatalog,
|
||||
);
|
||||
await vi.waitFor(() => expect(loadModelCatalog).toHaveBeenCalledTimes(2));
|
||||
await markStaleAndExpectPreviousCatalog(loadModelCatalog, staleCatalog);
|
||||
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
staleCatalog,
|
||||
);
|
||||
await expectCatalog(loadModelCatalog, staleCatalog);
|
||||
await vi.waitFor(() => expect(loadModelCatalog).toHaveBeenCalledTimes(3));
|
||||
|
||||
await vi.waitFor(async () => {
|
||||
await expect(loadGatewayModelCatalog({ getConfig, loadModelCatalog })).resolves.toBe(
|
||||
freshCatalog,
|
||||
);
|
||||
await expectCatalog(loadModelCatalog, freshCatalog);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user