Merge remote-tracking branch 'origin/master' into gitea/feature/end
Resolved conflicts taking origin/master (v0.5.55) as canonical, with local features re-applied: - runtime log level (LOG_LEVEL env + dashboard Settings → Logging, applied immediately and persisted across restarts) - free/noAuth provider enable/disable toggle via providerStrategies.enabled - parallel model testing (Test All Models / Test Selected Keys)
This commit is contained in:
86
tests/unit/github-monthly-usage-lock.test.js
Normal file
86
tests/unit/github-monthly-usage-lock.test.js
Normal file
@@ -0,0 +1,86 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const dbMocks = vi.hoisted(() => ({
|
||||
getProviderConnections: vi.fn(),
|
||||
updateProviderConnection: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@/lib/localDb", () => dbMocks);
|
||||
vi.mock("@/lib/network/connectionProxy", () => ({
|
||||
pickProxyPoolId: vi.fn(),
|
||||
resolveConnectionProxyConfig: vi.fn(),
|
||||
}));
|
||||
vi.mock("@/shared/constants/providers.js", () => ({
|
||||
FREE_PROVIDERS: {},
|
||||
resolveProviderId: (provider) => provider,
|
||||
}));
|
||||
vi.mock("@/sse/utils/logger.js", () => ({ debug: vi.fn(), info: vi.fn(), warn: vi.fn() }));
|
||||
|
||||
const { markAccountUnavailable } = await import("../../src/sse/services/auth.js");
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
dbMocks.getProviderConnections.mockResolvedValue([{
|
||||
id: "github-a",
|
||||
provider: "github",
|
||||
name: "github-a",
|
||||
backoffLevel: 4,
|
||||
}]);
|
||||
});
|
||||
|
||||
describe("GitHub monthly usage exhaustion", () => {
|
||||
it("locks the whole account until the next UTC month", async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-08-04T19:30:00.000Z"));
|
||||
|
||||
try {
|
||||
await markAccountUnavailable(
|
||||
"github-a",
|
||||
402,
|
||||
"You've reached your additional usage limit for your plan. Go to GitHub settings for details.",
|
||||
"github",
|
||||
"claude-fable-5",
|
||||
);
|
||||
|
||||
expect(dbMocks.updateProviderConnection).toHaveBeenCalledWith(
|
||||
"github-a",
|
||||
expect.objectContaining({
|
||||
modelLock___all: "2026-09-01T00:00:00.000Z",
|
||||
testStatus: "unavailable",
|
||||
errorCode: 402,
|
||||
backoffLevel: 0,
|
||||
}),
|
||||
);
|
||||
expect(dbMocks.updateProviderConnection.mock.calls[0][1])
|
||||
.not.toHaveProperty("modelLock_claude-fable-5");
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
|
||||
it("keeps unrelated GitHub 402 errors model-scoped", async () => {
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2026-08-04T19:30:00.000Z"));
|
||||
|
||||
try {
|
||||
await markAccountUnavailable(
|
||||
"github-a",
|
||||
402,
|
||||
"Payment required",
|
||||
"github",
|
||||
"claude-fable-5",
|
||||
);
|
||||
|
||||
expect(dbMocks.updateProviderConnection).toHaveBeenCalledWith(
|
||||
"github-a",
|
||||
expect.objectContaining({
|
||||
"modelLock_claude-fable-5": "2026-08-04T19:32:00.000Z",
|
||||
}),
|
||||
);
|
||||
expect(dbMocks.updateProviderConnection.mock.calls[0][1])
|
||||
.not.toHaveProperty("modelLock___all");
|
||||
} finally {
|
||||
vi.useRealTimers();
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user