refactor(news): remove retired research workflow
Development CI / check-and-build (push) Successful in 2m53s
GitHub Git mirror / mirror (push) Successful in 7s
Development CI / deploy-development (push) Successful in 2m31s

This commit is contained in:
eezd committed 2026-11-05 18:38:25 +08:00
1 parent f3894c3728
commit d79a10c2e6
69 files changed
+460 -6713

No files matched your search

-230
View File
@@ -483,236 +483,6 @@ test("新闻列表只更新可见条目的匹配版本评级,保留滚动与
assert.equal(queries.length, 5)
})
test("事件详情忽略旧请求与旧会话,失败可重试", async () => {
const user = vue.reactive({ sessionVersion: 1 })
const pending: ReturnType<typeof Promise.withResolvers>[] = []
const load = moduleLoader({
"@/pinia/stores/user": { useUserStore: () => user },
"@/common/apis/risk": { getNewsEventApi: () => {
const request = Promise.withResolvers()
pending.push(request)
return request.promise
} },
"@@/utils/text": { formatTime: (value: string) => value }
}, globals)
const page = load("@/pages/home/components/EventResearch.vue").default.setup({}, { expose() {}, emit() {} })
const first = page.open(1)
const second = page.open(2)
pending[1].resolve({ id: 2 })
await second
pending[0].reject(new Error("Old failure"))
await first
assert.equal(page.detail.value.id, 2)
assert.equal(page.detailError.value, false)
const failed = page.open(3)
pending[2].reject(new Error("Failed"))
await failed
assert.equal(page.detailError.value, true)
const retry = page.open(3)
user.sessionVersion++
await vue.nextTick()
pending[3].resolve({ id: 3 })
await retry
assert.equal(page.detail.value, null)
assert.equal(page.opened.value, false)
})
test("重整理预览的旧会话完成不能解除新操作的忙碌状态", async () => {
const user = vue.reactive({ sessionVersion: 1 })
const pending: ReturnType<typeof Promise.withResolvers>[] = []
const load = moduleLoader({
"@/pinia/stores/user": { useUserStore: () => user },
"@/common/apis/risk": { previewReprocessApi: () => {
const request = Promise.withResolvers()
pending.push(request)
return request.promise
} },
"@@/utils/text": { formatTime: (value: string) => value }
}, globals)
const page = load("@/pages/home/components/EventResearch.vue").default.setup({}, { expose() {}, emit() {} })
page.range.value = [new Date("2026-11-01"), new Date("2026-11-02")]
await vue.nextTick()
const old = page.inspect()
user.sessionVersion++
await vue.nextTick()
const current = page.inspect()
pending[0].resolve({ articles: 1 })
await old
assert.equal(page.busy.value, true)
assert.equal(page.preview.value, null)
pending[1].resolve({ articles: 2 })
await current
assert.equal(page.busy.value, false)
assert.equal(page.preview.value.articles, 2)
})
test("AI 队列隔离旧会话与旧筛选响应,轮询隐藏页面时暂停并在卸载后清理", async () => {
const user = vue.reactive({ sessionVersion: 1 })
const pending: ReturnType<typeof Promise.withResolvers>[] = []
const queries: any[] = []
let poll = () => {}
let unmount = () => {}
let cleared = false
const doc = { hidden: true, addEventListener() {}, removeEventListener() {} }
const load = moduleLoader({
"@/pinia/stores/user": { useUserStore: () => user },
"@/common/apis/risk": { listRiskQueueApi: (query: unknown) => {
queries.push(query)
const request = Promise.withResolvers()
pending.push(request)
return request.promise
} },
"@@/utils/text": { formatTime: (value: string) => value }
}, { ...globals, document: doc, setInterval: (callback: () => void) => {
poll = callback
return 1
}, clearInterval: () => {
cleared = true
}, onMounted: (callback: () => void) => callback(), onBeforeUnmount: (callback: () => void) => {
unmount = callback
} })
const page = load("@/pages/home/components/AiQueue.vue").default.setup({}, { expose() {}, emit() {} })
assert.equal(queries.length, 1)
poll()
assert.equal(queries.length, 1)
user.sessionVersion++
await vue.nextTick()
const current = page.load()
pending[1].resolve({ total: 7, items: [] })
await current
pending[0].resolve({ total: 99, items: [] })
await setImmediate()
assert.equal(page.result.value.total, 7)
page.state.value = "queued"
await vue.nextTick()
assert.equal(queries[2].state, "queued")
page.stage.value = "analysis"
await vue.nextTick()
pending[2].resolve({ total: 999, items: [] })
await setImmediate()
assert.equal(page.result.value.total, 7)
doc.hidden = false
poll()
pending[3].resolve({ total: 4, items: [] })
await setImmediate()
assert.equal(queries[3].stage, "analysis")
assert.equal(page.result.value.total, 4)
const late = page.load()
unmount()
pending[4].resolve({ total: 100, items: [] })
await late
assert.equal(page.result.value.total, 4)
assert.equal(cleared, true)
})
test("回补确认绑定原预览,确认期间替换预览不能启动另一批次", async () => {
const confirmation = Promise.withResolvers()
const started: unknown[] = []
const load = moduleLoader({
"@/pinia/stores/user": { useUserStore: () => ({ sessionVersion: 1 }) },
"@/common/apis/risk": { startReprocessApi: async (body: unknown) => {
started.push(body)
} },
"@@/utils/text": { formatTime: (value: string) => value }
}, { ...globals, ElMessageBox: { confirm: () => confirmation.promise } })
const page = load("@/pages/home/components/EventResearch.vue").default.setup({}, { expose() {}, emit() {} })
page.range.value = [new Date("2026-10-01"), new Date("2026-11-01")]
await vue.nextTick()
page.preview.value = { preview_id: "accepted-preview", articles: 2 }
const action = page.start()
page.preview.value = { preview_id: "replacement-preview", articles: 10 }
confirmation.resolve(true)
await action
assert.deepEqual(started, [])
})
test("回补新闻明细随轮询和手动刷新更新,保留批次分页并支持失败重试", async () => {
const user = vue.reactive({ sessionVersion: 1 })
let state = "pending"
let fail = false
const requests: [number, number][] = []
let poll = () => {}
const doc = { hidden: false }
const load = moduleLoader({
"@/pinia/stores/user": { useUserStore: () => user },
"@/common/apis/risk": {
listNewsEventsApi: async () => ({ items: [], total: 0 }),
listReprocessApi: async () => [{ id: 7, state }],
getReprocessDetailApi: async (id: number, page: number) => {
requests.push([id, page])
if (fail) throw new Error("Synthetic detail failure")
return { id, state, total: 40, items: [{ id: 21, state }] }
}
},
"@@/utils/text": { formatTime: (value: string) => value }
}, { ...globals, document: doc, onMounted: (callback: () => void) => callback(), setInterval: (callback: () => void) => {
poll = callback
return 1
} })
const page = load("@/pages/home/components/EventResearch.vue").default.setup({}, { expose() {}, emit() {} })
await setImmediate()
await page.openBatch(7, 2)
state = "done"
poll()
await setImmediate()
assert.equal(page.batch.value.items[0].state, "done")
assert.equal(page.batchPage.value, 2)
assert.deepEqual(requests, [[7, 2], [7, 2]])
doc.hidden = true
poll()
await setImmediate()
assert.equal(requests.length, 2)
fail = true
await page.load()
assert.equal(page.batchError.value, true)
assert.equal(page.batch.value.items[0].state, "done")
assert.equal(page.batchLoading.value, false)
fail = false
await page.openBatch(7, 2)
assert.equal(page.batchError.value, false)
})
test("回补明细刷新不抢占新选择,旧会话与旧请求不能覆盖当前批次", async () => {
const user = vue.reactive({ sessionVersion: 1 })
const requests: { id: number, page: number, promise: ReturnType<typeof Promise.withResolvers> }[] = []
const load = moduleLoader({
"@/pinia/stores/user": { useUserStore: () => user },
"@/common/apis/risk": {
listNewsEventsApi: async () => ({ items: [], total: 0 }),
listReprocessApi: async () => [],
getReprocessDetailApi: (id: number, page: number) => {
const promise = Promise.withResolvers()
requests.push({ id, page, promise })
return promise.promise
}
},
"@@/utils/text": { formatTime: (value: string) => value }
}, globals)
const page = load("@/pages/home/components/EventResearch.vue").default.setup({}, { expose() {}, emit() {} })
const old = page.openBatch(7, 2)
const selected = page.openBatch(8, 1)
await page.load()
assert.deepEqual(requests.map(r => [r.id, r.page]), [[7, 2], [8, 1]])
requests[0].promise.resolve({ id: 7, items: [] })
await old
assert.equal(page.batchLoading.value, true)
requests[1].promise.resolve({ id: 8, items: [] })
await selected
assert.equal(page.batch.value.id, 8)
const late = page.openBatch(8, 2)
user.sessionVersion++
await vue.nextTick()
const current = page.openBatch(9, 1)
requests[2].promise.reject(new Error("Old session failure"))
await late
assert.equal(page.batchLoading.value, true)
assert.equal(page.batchError.value, false)
requests[3].promise.resolve({ id: 9, items: [] })
await current
assert.equal(page.batch.value.id, 9)
assert.equal(page.batchId.value, 9)
assert.equal(page.batchPage.value, 1)
})
function researchPage(api: Record<string, unknown> = {}, user = vue.reactive({ sessionVersion: 1 }), extra: Record<string, unknown> = {}, dependencies: Record<string, unknown> = {}) {
const load = moduleLoader({
"@@/apis/news-research": { getSettingsApi: async () => ({ config: {}, enabled: false }), listEventsApi: async () => ({ items: [], total: 0 }), listPackagesApi: async () => ({ items: [], total: 0 }), ...api },