Expand publishing and virtual product workflows
This commit is contained in:
@@ -0,0 +1,125 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import vm from 'node:vm'
|
||||
import test from 'node:test'
|
||||
|
||||
const testDirectory = dirname(fileURLToPath(import.meta.url))
|
||||
const script = readFileSync(resolve(testDirectory, '../background/service-worker.js'), 'utf8')
|
||||
|
||||
function createRuntime(initialStorage = {}) {
|
||||
const storage = { ...initialStorage }
|
||||
const createdTabs = []
|
||||
let nextTabId = 900
|
||||
const event = () => ({ addListener() {} })
|
||||
const chrome = {
|
||||
runtime: {
|
||||
getManifest: () => ({ version: '1.1.17' }),
|
||||
onInstalled: event(),
|
||||
onStartup: event(),
|
||||
onMessage: event(),
|
||||
sendMessage: async () => undefined
|
||||
},
|
||||
alarms: {
|
||||
onAlarm: event(),
|
||||
create: async () => undefined,
|
||||
clear: async () => true
|
||||
},
|
||||
sidePanel: { setPanelBehavior: async () => undefined },
|
||||
storage: {
|
||||
local: {
|
||||
get: async key => {
|
||||
if (key == null) return { ...storage }
|
||||
if (Array.isArray(key)) return Object.fromEntries(key.filter(item => item in storage).map(item => [item, storage[item]]))
|
||||
return key in storage ? { [key]: storage[key] } : {}
|
||||
},
|
||||
set: async values => Object.assign(storage, values),
|
||||
remove: async keys => {
|
||||
for (const key of Array.isArray(keys) ? keys : [keys]) delete storage[key]
|
||||
}
|
||||
}
|
||||
},
|
||||
tabs: {
|
||||
onUpdated: event(),
|
||||
onRemoved: event(),
|
||||
create: async options => {
|
||||
const tab = { id: nextTabId++, windowId: 12, ...options }
|
||||
createdTabs.push(tab)
|
||||
return tab
|
||||
},
|
||||
get: async () => { throw new Error('tab not found') },
|
||||
update: async (id, options) => ({ id, windowId: 12, ...options }),
|
||||
query: async () => [],
|
||||
sendMessage: async () => undefined
|
||||
},
|
||||
windows: { update: async () => undefined },
|
||||
scripting: { executeScript: async () => [] }
|
||||
}
|
||||
const context = {
|
||||
chrome,
|
||||
console,
|
||||
URL,
|
||||
setTimeout,
|
||||
clearTimeout,
|
||||
fetch: async () => ({ ok: true, json: async () => ({ code: 200 }) })
|
||||
}
|
||||
vm.createContext(context)
|
||||
vm.runInContext(script, context)
|
||||
return { context, storage, createdTabs }
|
||||
}
|
||||
|
||||
function task(taskId, platform, createdAt, status = 'FAILED') {
|
||||
return {
|
||||
taskId,
|
||||
token: 'a'.repeat(32),
|
||||
apiBaseUrl: 'https://feast.yidaima.cn/prod-api',
|
||||
platform,
|
||||
task: { title: platform + ' title' },
|
||||
status,
|
||||
statusMessage: '测试状态',
|
||||
createdAt,
|
||||
platformTabId: null
|
||||
}
|
||||
}
|
||||
|
||||
test('side panel lists only the latest task for each platform', async () => {
|
||||
const now = Date.now()
|
||||
const firstId = 'publish_' + '1'.repeat(32)
|
||||
const latestId = 'publish_' + '2'.repeat(32)
|
||||
const douyinId = 'publish_' + '3'.repeat(32)
|
||||
const runtime = createRuntime({
|
||||
['publisher_task_' + firstId]: task(firstId, 'xiaohongshu', now - 2000),
|
||||
['publisher_task_' + latestId]: task(latestId, 'xiaohongshu', now - 1000),
|
||||
['publisher_task_' + douyinId]: task(douyinId, 'douyin', now)
|
||||
})
|
||||
|
||||
const tasks = await runtime.context.listSidePanelTasks()
|
||||
|
||||
assert.equal(tasks.length, 2)
|
||||
assert.equal(tasks.find(item => item.platform === 'xiaohongshu').taskId, latestId)
|
||||
assert.equal(tasks.find(item => item.platform === 'douyin').taskId, douyinId)
|
||||
})
|
||||
|
||||
test('retry reopens a closed platform tab and stores the new mapping', async () => {
|
||||
const taskId = 'publish_' + '4'.repeat(32)
|
||||
const runtime = createRuntime({
|
||||
['publisher_task_' + taskId]: task(taskId, 'xianyu', Date.now())
|
||||
})
|
||||
|
||||
const result = await runtime.context.retryTask(taskId)
|
||||
|
||||
assert.equal(result.tabId, 900)
|
||||
assert.equal(runtime.createdTabs[0].url, 'https://www.goofish.pro/sale/product/add?from=%2Fon-sale')
|
||||
assert.equal(runtime.storage['publisher_task_' + taskId].status, 'OPENING')
|
||||
assert.equal(runtime.storage.publisher_tab_900, taskId)
|
||||
})
|
||||
|
||||
test('retry rejects a successfully published task', async () => {
|
||||
const taskId = 'publish_' + '5'.repeat(32)
|
||||
const runtime = createRuntime({
|
||||
['publisher_task_' + taskId]: task(taskId, 'bilibili', Date.now(), 'SUCCEEDED')
|
||||
})
|
||||
|
||||
await assert.rejects(() => runtime.context.retryTask(taskId), /不能重试/)
|
||||
})
|
||||
Reference in New Issue
Block a user