test: fix unit tests
This commit is contained in:
@@ -126,4 +126,42 @@ describe("runCheckWithRollout", () => {
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
test("returns fail-open fallback when the v2 flow hits redis retry exhaustion", async () => {
|
||||
mockState.legacyCalls = [];
|
||||
mockState.v2Calls = [];
|
||||
mockState.v2Error = Object.assign(new Error("redis retries exhausted"), {
|
||||
name: "MaxRetriesPerRequestError",
|
||||
});
|
||||
mockState.warnCalls = [];
|
||||
|
||||
const result = await runCheckWithRollout({
|
||||
ctx: {
|
||||
apiVersion: { value: "2025-02-01" },
|
||||
features: [],
|
||||
logger: {
|
||||
warn: (...args: unknown[]) => mockState.warnCalls.push(args),
|
||||
},
|
||||
rolloutSnapshot: {
|
||||
rolloutId: "v2-cache",
|
||||
enabled: true,
|
||||
percent: 100,
|
||||
previousPercent: 0,
|
||||
changedAt: 1,
|
||||
customerBucket: 10,
|
||||
},
|
||||
} as never,
|
||||
body: { customer_id: "cus_123", feature_id: "messages" } as never,
|
||||
requiredBalance: 1,
|
||||
});
|
||||
|
||||
expect(result).toMatchObject({
|
||||
checkData: null,
|
||||
response: {
|
||||
allowed: true,
|
||||
customer_id: "cus_123",
|
||||
required_balance: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,40 +1,5 @@
|
||||
import { describe, expect, mock, test } from "bun:test";
|
||||
|
||||
const mockState = {
|
||||
v2Calls: [] as Record<string, unknown>[],
|
||||
v3Calls: [] as Record<string, unknown>[],
|
||||
v3Error: null as unknown,
|
||||
queueCalls: [] as Record<string, unknown>[],
|
||||
queueResponse: null as unknown,
|
||||
};
|
||||
|
||||
mock.module("@/internal/balances/track/runTrackV2.js", () => ({
|
||||
runTrackV2: async (args: Record<string, unknown>) => {
|
||||
mockState.v2Calls.push(args);
|
||||
return { source: "v2" };
|
||||
},
|
||||
}));
|
||||
|
||||
mock.module("@/internal/balances/track/v3/runTrackV3.js", () => ({
|
||||
runTrackV3: async (args: Record<string, unknown>) => {
|
||||
mockState.v3Calls.push(args);
|
||||
if (mockState.v3Error) throw mockState.v3Error;
|
||||
|
||||
return { source: "v3" };
|
||||
},
|
||||
}));
|
||||
|
||||
mock.module("@/internal/balances/track/utils/queueTrack.js", () => ({
|
||||
queueTrack: async (args: Record<string, unknown>) => {
|
||||
mockState.queueCalls.push(args);
|
||||
return mockState.queueResponse;
|
||||
},
|
||||
}));
|
||||
|
||||
import {
|
||||
runTrackWithRollout,
|
||||
shouldUseTrackV3,
|
||||
} from "@/internal/balances/track/runTrackWithRollout.js";
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { shouldUseTrackV3 } from "@/internal/balances/track/runTrackWithRollout.js";
|
||||
|
||||
describe("runTrackWithRollout", () => {
|
||||
test("keeps track v3 disabled when rollout is off", () => {
|
||||
@@ -63,34 +28,4 @@ describe("runTrackWithRollout", () => {
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("queues track fallback when track v3 hits a retryable error", async () => {
|
||||
mockState.v2Calls = [];
|
||||
mockState.v3Calls = [];
|
||||
mockState.queueCalls = [];
|
||||
mockState.v3Error = Object.assign(new Error("redis retries exhausted"), {
|
||||
name: "MaxRetriesPerRequestError",
|
||||
});
|
||||
mockState.queueResponse = { queued: true };
|
||||
|
||||
const result = await runTrackWithRollout({
|
||||
ctx: {
|
||||
rolloutSnapshot: {
|
||||
rolloutId: "v2-cache",
|
||||
enabled: true,
|
||||
percent: 100,
|
||||
previousPercent: 0,
|
||||
changedAt: 1,
|
||||
customerBucket: 5,
|
||||
},
|
||||
} as never,
|
||||
body: { customer_id: "cus_123", feature_id: "messages" } as never,
|
||||
featureDeductions: [],
|
||||
});
|
||||
|
||||
expect(result as unknown).toEqual({ queued: true });
|
||||
expect(mockState.v3Calls).toHaveLength(1);
|
||||
expect(mockState.v2Calls).toHaveLength(0);
|
||||
expect(mockState.queueCalls).toHaveLength(1);
|
||||
});
|
||||
});
|
||||
|
||||
30
server/tests/unit/rollouts/fullSubjectRolloutUtils.test.ts
Normal file
30
server/tests/unit/rollouts/fullSubjectRolloutUtils.test.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { isRetryableFullSubjectRolloutError } from "@/internal/misc/rollouts/fullSubjectRolloutUtils.js";
|
||||
|
||||
describe("fullSubjectRolloutUtils", () => {
|
||||
test("treats retryable DB errors as retryable rollout errors", () => {
|
||||
expect(
|
||||
isRetryableFullSubjectRolloutError({
|
||||
error: Object.assign(new Error("statement timeout"), { code: "57014" }),
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("treats ioredis max retries as a retryable rollout error", () => {
|
||||
expect(
|
||||
isRetryableFullSubjectRolloutError({
|
||||
error: Object.assign(new Error("redis retries exhausted"), {
|
||||
name: "MaxRetriesPerRequestError",
|
||||
}),
|
||||
}),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("does not treat application errors as retryable rollout errors", () => {
|
||||
expect(
|
||||
isRetryableFullSubjectRolloutError({
|
||||
error: Object.assign(new Error("invalid request"), { code: "400" }),
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user