refactor(news): remove retired research workflow
This commit is contained in:
1 parent
f3894c3728
commit
d79a10c2e6
69 files changed
+460
-6713
No files matched your search
@@ -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 },
|
||||
|
||||
Reference in new issue
Block a user