桌面下载端改用共享核心包,并修两处已知缺陷
- store 改由 createGalleryStore 生成:totalGalleryTask 成为唯一任务源, 收藏/下载/分类/搜索结果全部由 getter 派生,不再维护三份互相引用的数组 - 排序不再原地修改分类数组;本地搜索记住关键词,任务刷新后结果仍在 - 本地搜索结果补齐翻页入口:此前匹配 25 项却只显示 10 项,其余无法看到 - 取消收藏不再因本地找不到 gid 抛 TypeError - 删除重复的 taskSocket/progressiveImages/validate/thumbnail,改从共享包导入 - 远端搜索改用共享 fetchGalleries,关键词交给 axios 序列化,翻页按游标转发 - main.js 按需注册 Element Plus,入口 JS 由约 1.14MB 降到约 494KB - 依赖新增 file:../lionwebsite-frontend-shared 测试:14 项通过;构建成功,入口仍为 /asserts/index/index.js|css。
This commit is contained in:
+108
-78
@@ -1,95 +1,125 @@
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import fs from 'node:fs'
|
||||
import vm from 'node:vm'
|
||||
import test from "node:test"
|
||||
import assert from "node:assert/strict"
|
||||
|
||||
function fixture() {
|
||||
let code = fs.readFileSync(new URL('../src/store/index.js', import.meta.url), 'utf8')
|
||||
.replace(/^import .*$/gm, '')
|
||||
.replace('export default new vuex.Store(', 'globalThis.store = new vuex.Store(')
|
||||
const messages = []
|
||||
const showMessage = message => messages.push(message)
|
||||
showMessage.error = message => messages.push(message)
|
||||
const axios = {interceptors: {response: {use() {}}}}
|
||||
const context = vm.createContext({axios, vuex: {Store: function (config) {Object.assign(this, config)}},
|
||||
ElMessage: showMessage, URLSearchParams, console,
|
||||
qs: {stringify: () => ''}})
|
||||
vm.runInContext(code, context)
|
||||
const store = context.store
|
||||
const api = {state: store.state,
|
||||
commit: (name, data) => store.mutations[name](store.state, data),
|
||||
dispatch: (name, data) => Promise.resolve(store.actions[name](api, data))}
|
||||
return {store, messages, axios, api}
|
||||
// 直接加载真实的 store 模块;在 Node 里 import 到的就是下发到浏览器的那份配置。
|
||||
const store = (await import("../src/store/index.js")).default
|
||||
|
||||
const tasks = () => [
|
||||
{gid: 1, name: "beta [tag]", status: "下载完成", pages: 10, proceeding: 10,
|
||||
thumb_link: "", createTime: 2, downloader: 7, isCollect: true},
|
||||
{gid: 2, name: "alpha", status: "下载中", pages: 10, proceeding: 5,
|
||||
thumb_link: "", createTime: 1, downloader: 7, isCollect: false},
|
||||
{gid: 3, name: "gamma", status: "已提交", pages: 10, proceeding: 0,
|
||||
thumb_link: "", createTime: 3, downloader: 8, isCollect: false},
|
||||
]
|
||||
|
||||
function reset() {
|
||||
store.state.AuthCode = "test-auth"
|
||||
store.state.userId = 7
|
||||
store.state.category = "total"
|
||||
store.state.sortType = "createTime"
|
||||
store.state.length = 2
|
||||
store.state.page = 1
|
||||
store.state.isAdmin = false
|
||||
store.state.downloaderFilter = null
|
||||
store.commit("_updateGalleryTasks", tasks())
|
||||
}
|
||||
|
||||
test('link search matches a numeric gid and jumps to the right page', () => {
|
||||
const {store, messages} = fixture()
|
||||
store.state.currentTasks = [{gid: 1}, {gid: 2}, {gid: 12345, name: 'sample', shortName: 'sample'}]
|
||||
test("module exposes one normalized task list plus derived getters", () => {
|
||||
reset()
|
||||
assert.equal(store.state.totalGalleryTask.length, 3)
|
||||
assert.equal("collectGallery" in store.state, false)
|
||||
assert.equal("downloadGallery" in store.state, false)
|
||||
assert.equal(store.getters.downloadGallery.length, 2)
|
||||
assert.equal(store.getters.collectGallery.length, 1)
|
||||
})
|
||||
|
||||
test("json-string and object payloads decode to the same store result", () => {
|
||||
reset()
|
||||
const fromObjects = store.state.totalGalleryTask.map(task => task.gid)
|
||||
store.state.totalGalleryTask = []
|
||||
store.commit("_updateGalleryTasks", JSON.parse(JSON.stringify(tasks())))
|
||||
assert.deepEqual(store.state.totalGalleryTask.map(task => task.gid), fromObjects)
|
||||
})
|
||||
|
||||
test("local search keeps every match reachable through the pager", () => {
|
||||
reset()
|
||||
store.state.length = 2
|
||||
store.mutations._searchLocalByLink(store.state, 'https://example.org/g/12345/key/')
|
||||
assert.equal(store.state.page, 2)
|
||||
assert.match(messages[0], /已跳转/)
|
||||
store.commit("_searchLocalByKeyword", "a")
|
||||
assert.equal(store.state.isSearch, true)
|
||||
assert.equal(store.getters.filteredTasks.length, 3)
|
||||
assert.equal(store.getters.max, 2)
|
||||
assert.equal(store.getters.currentTasks.length, 2)
|
||||
store.commit("_changePage", 2)
|
||||
assert.equal(store.getters.currentTasks.length, 1)
|
||||
})
|
||||
|
||||
test('missing gid still reports no match', () => {
|
||||
const {store, messages} = fixture()
|
||||
store.state.currentTasks = [{gid: 12345}]
|
||||
store.mutations._searchLocalByLink(store.state, 'https://example.org/g/999/key/')
|
||||
assert.equal(messages[0], '未找到此任务')
|
||||
test("a search matching more than one page exposes every page", () => {
|
||||
store.state.AuthCode = "auth"
|
||||
store.state.userId = 7
|
||||
store.state.category = "total"
|
||||
const many = Array.from({length: 25}, (_, index) => ({
|
||||
gid: index + 1, name: "match " + index, status: "已提交",
|
||||
pages: 1, proceeding: 0, thumb_link: "", createTime: index, downloader: 7,
|
||||
}))
|
||||
store.state.length = 10
|
||||
store.commit("_updateGalleryTasks", many)
|
||||
store.commit("_searchLocalByKeyword", "match")
|
||||
assert.equal(store.getters.filteredTasks.length, 25)
|
||||
assert.equal(store.getters.max, 3)
|
||||
assert.equal(store.getters.currentTasks.length, 10)
|
||||
store.commit("_changePage", 3)
|
||||
assert.equal(store.getters.currentTasks.length, 5)
|
||||
})
|
||||
|
||||
test('submission reloads persisted status without duplicating a completed task', async () => {
|
||||
const {store, axios, api} = fixture()
|
||||
const gallery = {gid: 123, name: 'sample', status: '下载完成', thumb_link: '', createTime: 1, downloader: 7}
|
||||
store.state.chosenGallery = {...gallery, status: '已提交'}
|
||||
store.state.totalGalleryTask.push(gallery)
|
||||
axios.post = async () => ({data: {result: 'success'}})
|
||||
axios.get = async url => ({data: {result: 'success', data: JSON.stringify(url.endsWith('weekUsedAmount') ? {} : [gallery])}})
|
||||
await store.actions.postGalleryTask(api, {targetResolution: 'original'})
|
||||
assert.equal(store.state.totalGalleryTask.length, 1)
|
||||
assert.equal(store.state.totalGalleryTask[0].status, '下载完成')
|
||||
assert.equal(store.state.chosenGallery, false)
|
||||
test("cancelling a collect for a task missing from the list never throws", () => {
|
||||
reset()
|
||||
// 旧实现会在 collectGallery 里找不到 gid 时抛 TypeError。
|
||||
assert.doesNotThrow(() => store.commit("_setCollect", {gid: 999, collect: false}))
|
||||
store.commit("_setCollect", {gid: 1, collect: false})
|
||||
assert.equal(store.getters.collectGallery.length, 0)
|
||||
store.commit("_setCollect", {gid: 1, collect: true})
|
||||
assert.equal(store.getters.collectGallery.length, 1)
|
||||
})
|
||||
|
||||
test('gallery management subrequests carry the active auth code', async () => {
|
||||
const {store, axios, api} = fixture()
|
||||
store.state.AuthCode = 'test-auth'
|
||||
let call
|
||||
axios.post = async (...args) => {
|
||||
call = args
|
||||
return {data: {result: args[0].endsWith('/cache') ? 'failure' : 'success', data: 'expected test response'}}
|
||||
}
|
||||
await store.actions.reconnect(api)
|
||||
assert.equal(call[0], 'https://downloader.lionwebsite.xyz/GalleryManage/reconnect')
|
||||
assert.equal(call[1], null)
|
||||
assert.equal(call[2].params.AuthCode, 'test-auth')
|
||||
|
||||
await store.actions.readOnlineGallery(api, {link: 'https://example.org/g/1/key/', images: []})
|
||||
assert.equal(call[0], 'https://downloader.lionwebsite.xyz/GalleryManage/cache')
|
||||
assert.equal(call[1], null)
|
||||
assert.deepEqual({...call[2].params}, {
|
||||
url: 'https://example.org/g/1/key/',
|
||||
AuthCode: 'test-auth'
|
||||
})
|
||||
test("sorting never reorders the single source array", () => {
|
||||
reset()
|
||||
const before = store.state.totalGalleryTask.map(task => task.gid)
|
||||
store.commit("_setSortType", "name")
|
||||
assert.deepEqual(store.state.totalGalleryTask.map(task => task.gid), before)
|
||||
assert.deepEqual(store.state.currentTasks.map(task => task.name), ["alpha", "beta [tag]", "gamma"])
|
||||
})
|
||||
|
||||
test('thumbnail and online image URLs carry the active auth code', () => {
|
||||
const {store} = fixture()
|
||||
store.state.AuthCode = 'code with spaces'
|
||||
store.mutations._updateGalleryTasks(store.state, [{
|
||||
gid: 123,
|
||||
name: 'sample',
|
||||
status: '已提交',
|
||||
thumb_link: 'https://example.org/thumb?a=1&b=2',
|
||||
createTime: 1,
|
||||
downloader: 7
|
||||
test("admin downloader filter narrows the visible list only for admins", () => {
|
||||
reset()
|
||||
store.commit("_setDownloaderFilter", 8)
|
||||
assert.equal(store.getters.filteredTasks.length, 3)
|
||||
store.state.isAdmin = true
|
||||
store.commit("_setDownloaderFilter", 8)
|
||||
assert.equal(store.getters.filteredTasks.length, 1)
|
||||
assert.equal(store.getters.filteredTasks[0].gid, 3)
|
||||
})
|
||||
|
||||
test("thumbnail and online image urls carry the active auth code", () => {
|
||||
store.state.AuthCode = "code with spaces"
|
||||
store.commit("_updateGalleryTasks", [{
|
||||
gid: 123, name: "sample", status: "已提交",
|
||||
thumb_link: "https://example.org/thumb?a=1&b=2", createTime: 1, downloader: 7,
|
||||
}])
|
||||
const thumbnail = new URL(store.state.totalGalleryTask[0].thumb_link)
|
||||
assert.equal(thumbnail.searchParams.get('AuthCode'), 'code with spaces')
|
||||
assert.equal(thumbnail.searchParams.get('path'), 'https://example.org/thumb?a=1&b=2')
|
||||
assert.equal(thumbnail.searchParams.get("AuthCode"), "code with spaces")
|
||||
assert.equal(thumbnail.searchParams.get("path"), "https://example.org/thumb?a=1&b=2")
|
||||
|
||||
store.mutations._setReadingGallery(store.state, {gid: 123, pages: 1})
|
||||
store.commit("_setReadingGallery", {gid: 123, pages: 1})
|
||||
const image = new URL(store.state.readingGallery.images[0])
|
||||
assert.equal(image.searchParams.get('gid'), '123')
|
||||
assert.equal(image.searchParams.get('AuthCode'), 'code with spaces')
|
||||
assert.equal(image.searchParams.get("gid"), "123")
|
||||
assert.equal(image.searchParams.get("AuthCode"), "code with spaces")
|
||||
})
|
||||
|
||||
test("proceeding websocket updates refresh the progress text", () => {
|
||||
reset()
|
||||
store.commit("_updateGalleryTaskProceeding", [{gid: 3, status: 1, proceeding: 5}])
|
||||
const task = store.state.totalGalleryTask.find(item => item.gid === 3)
|
||||
assert.equal(task.status, "下载中")
|
||||
assert.equal(task.progress, "50%")
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user