完成50%
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
"use strict";
|
||||
|
||||
const assert = require("assert");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const toDataModuleUrl = (source) =>
|
||||
`data:text/javascript;base64,${Buffer.from(source).toString("base64")}`;
|
||||
|
||||
const loadPageState = async (submitFeedback) => {
|
||||
const source = fs.readFileSync(
|
||||
path.join(__dirname, "../pages/profile/m07-feedback.vue"),
|
||||
"utf8",
|
||||
);
|
||||
const scriptMatch = source.match(/<script setup>([\s\S]*?)<\/script>/);
|
||||
if (!scriptMatch) throw new Error("M07 script setup is missing");
|
||||
const script = scriptMatch[1].replace(/^import[\s\S]*?;\s*$/gm, "");
|
||||
globalThis.__m07SubmitFeedback = submitFeedback;
|
||||
const prelude = `
|
||||
const computed = (getter) => ({ get value() { return getter(); } });
|
||||
const reactive = (value) => value;
|
||||
const ref = (value) => ({ value });
|
||||
const nextTick = (callback) => Promise.resolve().then(callback);
|
||||
let __watchCallback = null;
|
||||
const watch = (_source, callback) => { __watchCallback = callback; };
|
||||
const onBackPress = () => {};
|
||||
const onUnload = () => {};
|
||||
const appApi = { submitFeedback: (...args) => globalThis.__m07SubmitFeedback(...args) };
|
||||
const createRequestController = () => ({ abort() {}, bind() {}, release() {} });
|
||||
const isRequestCancelled = (error) => error?.code === "REQUEST_CANCELLED";
|
||||
const createDiscardConfirmation = () => ({
|
||||
request: () => Promise.resolve(true),
|
||||
confirm() {},
|
||||
cancel() {},
|
||||
dispose() {},
|
||||
});
|
||||
const handleBackPress = () => true;
|
||||
const runBackGuard = () => true;
|
||||
`;
|
||||
const exports = `
|
||||
export const __state = {
|
||||
feedbackForm,
|
||||
feedbackState,
|
||||
feedbackResult,
|
||||
feedbackResultTone,
|
||||
formSnapshot,
|
||||
baseline,
|
||||
isDirty,
|
||||
submitDisabled,
|
||||
submitFeedback,
|
||||
triggerWatch: () => __watchCallback(formSnapshot.value),
|
||||
};
|
||||
`;
|
||||
const module = await import(
|
||||
toDataModuleUrl(`${prelude}\n${script}\n${exports}\n// ${Math.random()}`),
|
||||
);
|
||||
return module.__state;
|
||||
};
|
||||
|
||||
const deferred = () => {
|
||||
let resolve;
|
||||
let reject;
|
||||
const promise = new Promise((resolvePromise, rejectPromise) => {
|
||||
resolve = resolvePromise;
|
||||
reject = rejectPromise;
|
||||
});
|
||||
return { promise, resolve, reject };
|
||||
};
|
||||
|
||||
const run = async () => {
|
||||
let calls = 0;
|
||||
let pending = deferred();
|
||||
const successState = await loadPageState(() => {
|
||||
calls += 1;
|
||||
return pending.promise;
|
||||
});
|
||||
successState.feedbackForm.feedbackContent = "第一份反馈";
|
||||
let request = successState.submitFeedback();
|
||||
assert.strictEqual(successState.feedbackState.value, "submitting");
|
||||
pending.resolve({ accepted: true });
|
||||
await request;
|
||||
assert.strictEqual(successState.feedbackState.value, "success");
|
||||
assert.strictEqual(successState.submitDisabled.value, true);
|
||||
assert.strictEqual(successState.isDirty.value, false);
|
||||
await successState.submitFeedback();
|
||||
assert.strictEqual(calls, 1, "成功快照不得原样重复提交");
|
||||
|
||||
successState.feedbackForm.feedbackContent = "编辑后的新反馈";
|
||||
successState.triggerWatch();
|
||||
assert.strictEqual(successState.feedbackState.value, "ready");
|
||||
assert.strictEqual(successState.submitDisabled.value, false);
|
||||
assert.strictEqual(successState.isDirty.value, true);
|
||||
|
||||
pending = deferred();
|
||||
request = successState.submitFeedback();
|
||||
successState.feedbackForm.feedbackContent = "请求期间迟到输入";
|
||||
successState.triggerWatch();
|
||||
pending.resolve({ accepted: true });
|
||||
await request;
|
||||
assert.strictEqual(successState.feedbackState.value, "ready");
|
||||
assert.match(successState.feedbackResult.value, /上一份反馈已提交.*当前修改尚未提交/);
|
||||
assert.strictEqual(successState.isDirty.value, true);
|
||||
|
||||
let uncertainCalls = 0;
|
||||
const uncertainState = await loadPageState(async () => {
|
||||
uncertainCalls += 1;
|
||||
const error = new Error("timeout");
|
||||
error.code = "REQUEST_TIMEOUT";
|
||||
throw error;
|
||||
});
|
||||
uncertainState.feedbackForm.feedbackContent = "结果未知反馈";
|
||||
await uncertainState.submitFeedback();
|
||||
assert.strictEqual(uncertainState.feedbackState.value, "uncertain");
|
||||
assert.strictEqual(uncertainState.submitDisabled.value, true);
|
||||
await uncertainState.submitFeedback();
|
||||
assert.strictEqual(uncertainCalls, 1, "未知结果快照不得原样重复提交");
|
||||
uncertainState.feedbackForm.feedbackContent = "修改后的另一份反馈";
|
||||
uncertainState.triggerWatch();
|
||||
assert.strictEqual(uncertainState.feedbackState.value, "ready");
|
||||
assert.strictEqual(uncertainState.submitDisabled.value, false);
|
||||
|
||||
const unexpectedSuccessState = await loadPageState(async () => {
|
||||
const error = new Error("unexpected success status");
|
||||
error.code = "HTTP_ERROR";
|
||||
error.httpStatus = 202;
|
||||
throw error;
|
||||
});
|
||||
unexpectedSuccessState.feedbackForm.feedbackContent = "服务返回意外成功状态";
|
||||
await unexpectedSuccessState.submitFeedback();
|
||||
assert.strictEqual(
|
||||
unexpectedSuccessState.feedbackState.value,
|
||||
"uncertain",
|
||||
"非幂等 POST 收到意外 2xx 时不能开放原样重试",
|
||||
);
|
||||
assert.strictEqual(unexpectedSuccessState.submitDisabled.value, true);
|
||||
|
||||
const lateUncertainRequest = deferred();
|
||||
const lateUncertainState = await loadPageState(() => lateUncertainRequest.promise);
|
||||
lateUncertainState.feedbackForm.feedbackContent = "正在提交的反馈";
|
||||
request = lateUncertainState.submitFeedback();
|
||||
lateUncertainState.feedbackForm.feedbackContent = "请求期间修改的新反馈";
|
||||
lateUncertainState.triggerWatch();
|
||||
const timeoutError = new Error("timeout");
|
||||
timeoutError.code = "REQUEST_TIMEOUT";
|
||||
lateUncertainRequest.reject(timeoutError);
|
||||
await request;
|
||||
assert.strictEqual(
|
||||
lateUncertainState.feedbackState.value,
|
||||
"ready",
|
||||
"旧快照结果未知时,请求期间的新输入必须保持可提交状态",
|
||||
);
|
||||
assert.match(lateUncertainState.feedbackResult.value, /结果仍待确认.*当前修改尚未提交/);
|
||||
assert.strictEqual(lateUncertainState.submitDisabled.value, false);
|
||||
|
||||
delete globalThis.__m07SubmitFeedback;
|
||||
process.stdout.write("M07-FEEDBACK-STATE-RUNTIME-SMOKE PASS\n");
|
||||
};
|
||||
|
||||
run().catch((error) => {
|
||||
delete globalThis.__m07SubmitFeedback;
|
||||
process.stderr.write(`${error.stack || error.message}\n`);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user