mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 22:54:31 +00:00
120 lines
3.2 KiB
TypeScript
120 lines
3.2 KiB
TypeScript
import { describe, expect, it, vi, afterEach } from "vitest";
|
|
import { refreshQwenPortalCredentials } from "./qwen-portal-oauth.js";
|
|
|
|
const originalFetch = globalThis.fetch;
|
|
|
|
afterEach(() => {
|
|
vi.unstubAllGlobals();
|
|
globalThis.fetch = originalFetch;
|
|
});
|
|
|
|
describe("refreshQwenPortalCredentials", () => {
|
|
it("refreshes tokens with a new access token", async () => {
|
|
const fetchSpy = vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({
|
|
access_token: "new-access",
|
|
refresh_token: "new-refresh",
|
|
expires_in: 3600,
|
|
}),
|
|
});
|
|
vi.stubGlobal("fetch", fetchSpy);
|
|
|
|
const result = await refreshQwenPortalCredentials({
|
|
access: "old-access",
|
|
refresh: "old-refresh",
|
|
expires: Date.now() - 1000,
|
|
});
|
|
|
|
expect(fetchSpy).toHaveBeenCalledWith(
|
|
"https://chat.qwen.ai/api/v1/oauth2/token",
|
|
expect.objectContaining({
|
|
method: "POST",
|
|
}),
|
|
);
|
|
expect(result.access).toBe("new-access");
|
|
expect(result.refresh).toBe("new-refresh");
|
|
expect(result.expires).toBeGreaterThan(Date.now());
|
|
});
|
|
|
|
it("keeps refresh token when refresh response omits it", async () => {
|
|
const fetchSpy = vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({
|
|
access_token: "new-access",
|
|
expires_in: 1800,
|
|
}),
|
|
});
|
|
vi.stubGlobal("fetch", fetchSpy);
|
|
|
|
const result = await refreshQwenPortalCredentials({
|
|
access: "old-access",
|
|
refresh: "old-refresh",
|
|
expires: Date.now() - 1000,
|
|
});
|
|
|
|
expect(result.refresh).toBe("old-refresh");
|
|
});
|
|
|
|
it("keeps refresh token when response sends an empty refresh token", async () => {
|
|
const fetchSpy = vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({
|
|
access_token: "new-access",
|
|
refresh_token: "",
|
|
expires_in: 1800,
|
|
}),
|
|
});
|
|
vi.stubGlobal("fetch", fetchSpy);
|
|
|
|
const result = await refreshQwenPortalCredentials({
|
|
access: "old-access",
|
|
refresh: "old-refresh",
|
|
expires: Date.now() - 1000,
|
|
});
|
|
|
|
expect(result.refresh).toBe("old-refresh");
|
|
});
|
|
|
|
it("errors when refresh response has invalid expires_in", async () => {
|
|
const fetchSpy = vi.fn().mockResolvedValue({
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({
|
|
access_token: "new-access",
|
|
refresh_token: "new-refresh",
|
|
expires_in: 0,
|
|
}),
|
|
});
|
|
vi.stubGlobal("fetch", fetchSpy);
|
|
|
|
await expect(
|
|
refreshQwenPortalCredentials({
|
|
access: "old-access",
|
|
refresh: "old-refresh",
|
|
expires: Date.now() - 1000,
|
|
}),
|
|
).rejects.toThrow("Qwen OAuth refresh response missing or invalid expires_in");
|
|
});
|
|
|
|
it("errors when refresh token is invalid", async () => {
|
|
const fetchSpy = vi.fn().mockResolvedValue({
|
|
ok: false,
|
|
status: 400,
|
|
text: async () => "invalid_grant",
|
|
});
|
|
vi.stubGlobal("fetch", fetchSpy);
|
|
|
|
await expect(
|
|
refreshQwenPortalCredentials({
|
|
access: "old-access",
|
|
refresh: "old-refresh",
|
|
expires: Date.now() - 1000,
|
|
}),
|
|
).rejects.toThrow("Qwen OAuth refresh token expired or invalid");
|
|
});
|
|
});
|