fix: fallback to in-memory state when convex functions are unavailable
This commit is contained in:
@@ -2,7 +2,65 @@
|
||||
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { mapToAppRequest, normalizeHeaders, createMutationPersister } = require("../src/server");
|
||||
const {
|
||||
mapToAppRequest,
|
||||
normalizeHeaders,
|
||||
createMutationPersister,
|
||||
createRuntime,
|
||||
} = require("../src/server");
|
||||
|
||||
function createRuntimeConfig() {
|
||||
return {
|
||||
port: 3000,
|
||||
logLevel: "info",
|
||||
appBaseUrl: "http://localhost:3000",
|
||||
betterAuthSecret: "test-better-auth-secret",
|
||||
betterAuthBasePath: "/api/auth",
|
||||
betterAuthDevPassword: "xartaudio-dev-password",
|
||||
internalApiToken: "",
|
||||
convexDeploymentUrl: "",
|
||||
convexAuthToken: "",
|
||||
convexStateQuery: "state:getLatestSnapshot",
|
||||
convexStateMutation: "state:saveSnapshot",
|
||||
xWebhookSecret: "x-secret",
|
||||
xBearerToken: "",
|
||||
xBotUserId: "",
|
||||
polarWebhookSecret: "polar-secret",
|
||||
polarAccessToken: "",
|
||||
polarServer: "production",
|
||||
polarProductIds: [],
|
||||
qwenTtsApiKey: "",
|
||||
qwenTtsBaseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
qwenTtsModel: "qwen-tts-latest",
|
||||
qwenTtsVoice: "Cherry",
|
||||
qwenTtsFormat: "mp3",
|
||||
minioEndPoint: "",
|
||||
minioPort: 443,
|
||||
minioUseSSL: true,
|
||||
minioBucket: "",
|
||||
minioRegion: "us-east-1",
|
||||
minioAccessKey: "",
|
||||
minioSecretKey: "",
|
||||
minioSignedUrlTtlSec: 3600,
|
||||
rateLimits: {
|
||||
webhookPerMinute: 120,
|
||||
authPerMinute: 30,
|
||||
actionPerMinute: 60,
|
||||
},
|
||||
abuse: {
|
||||
maxJobsPerUserPerDay: 0,
|
||||
cooldownSec: 0,
|
||||
denyUserIds: [],
|
||||
},
|
||||
credit: {
|
||||
baseCredits: 1,
|
||||
includedChars: 25000,
|
||||
stepChars: 10000,
|
||||
stepCredits: 1,
|
||||
maxCharsPerArticle: 120000,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
test("normalizeHeaders lowercases and joins array values", () => {
|
||||
const headers = normalizeHeaders({
|
||||
@@ -49,3 +107,39 @@ test("createMutationPersister writes sequentially and flush waits", async () =>
|
||||
|
||||
assert.deepEqual(saved, ["s1", "s2"]);
|
||||
});
|
||||
|
||||
test("createRuntime falls back to in-memory state when initial load fails", async () => {
|
||||
const warnings = [];
|
||||
const runtime = await createRuntime({
|
||||
runtimeConfig: createRuntimeConfig(),
|
||||
logger: {
|
||||
warn(payload, message) {
|
||||
warnings.push({ payload, message });
|
||||
},
|
||||
info() {},
|
||||
error() {},
|
||||
},
|
||||
stateStore: {
|
||||
async load() {
|
||||
throw new Error("state_load_failed");
|
||||
},
|
||||
async save() {
|
||||
throw new Error("state_save_should_not_run");
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
assert.equal(warnings.length, 1);
|
||||
assert.match(String(warnings[0].message), /falling back to in-memory state/);
|
||||
|
||||
const response = await runtime.app.handleRequest({
|
||||
method: "POST",
|
||||
path: "/app/actions/topup",
|
||||
headers: { "x-user-id": "u1" },
|
||||
rawBody: "amount=3",
|
||||
query: {},
|
||||
});
|
||||
|
||||
assert.equal(response.status, 303);
|
||||
await runtime.persister.flush();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user