mirror of
https://gitee.com/spark-store-project/spark-store
synced 2026-05-30 01:31:06 +08:00
fix(update): 统一忽略更新配置到用户目录
This commit is contained in:
@@ -69,10 +69,14 @@ const createStore = (
|
||||
selectedTaskKeys,
|
||||
snapshot,
|
||||
filteredItems: computed(() => snapshot.value.items),
|
||||
allSelected: computed(() => false),
|
||||
someSelected: computed(() => selectedTaskKeys.value.size > 0),
|
||||
bind: vi.fn(),
|
||||
unbind: vi.fn(),
|
||||
open: vi.fn(),
|
||||
refresh: vi.fn(),
|
||||
ignoreItem: vi.fn(),
|
||||
unignoreItem: vi.fn(),
|
||||
toggleSelection: vi.fn(),
|
||||
getSelectedItems: vi.fn(() =>
|
||||
snapshot.value.items.filter(
|
||||
@@ -87,7 +91,7 @@ const createStore = (
|
||||
};
|
||||
|
||||
describe("UpdateCenterModal", () => {
|
||||
it("renders source tags, running state, warnings, migration marker, and close confirmation", () => {
|
||||
it("renders source tags, running state, warnings, and migration marker", () => {
|
||||
const store = createStore();
|
||||
|
||||
render(UpdateCenterModal, {
|
||||
@@ -104,24 +108,6 @@ describe("UpdateCenterModal", () => {
|
||||
expect(screen.getByText("更新过程中请勿关闭商店")).toBeTruthy();
|
||||
expect(screen.getByText("下载中")).toBeTruthy();
|
||||
expect(screen.getByText("42%")).toBeTruthy();
|
||||
expect(screen.getByText(/确定关闭/)).toBeTruthy();
|
||||
});
|
||||
|
||||
it("close confirmation exposes a confirm-close path", async () => {
|
||||
const onConfirmClose = vi.fn();
|
||||
const store = createStore();
|
||||
|
||||
render(UpdateCenterModal, {
|
||||
props: {
|
||||
show: true,
|
||||
store,
|
||||
onConfirmClose,
|
||||
},
|
||||
});
|
||||
|
||||
await fireEvent.click(screen.getByRole("button", { name: "确认关闭" }));
|
||||
|
||||
expect(onConfirmClose).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("renders ignored items as disabled instead of normal selectable actions", () => {
|
||||
@@ -148,7 +134,34 @@ describe("UpdateCenterModal", () => {
|
||||
});
|
||||
|
||||
expect(screen.getByText("已忽略")).toBeTruthy();
|
||||
expect(screen.getByRole("checkbox")).toBeDisabled();
|
||||
expect(screen.getAllByRole("checkbox").at(-1)).toBeDisabled();
|
||||
expect(screen.getByRole("button", { name: "取消忽略" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders ignore action for normal items", () => {
|
||||
const store = createStore({
|
||||
items: [
|
||||
createItem({
|
||||
taskKey: "aptss:spark-weather",
|
||||
packageName: "spark-weather",
|
||||
displayName: "Spark Weather",
|
||||
source: "aptss",
|
||||
ignored: false,
|
||||
}),
|
||||
],
|
||||
tasks: [],
|
||||
warnings: [],
|
||||
hasRunningTasks: false,
|
||||
});
|
||||
|
||||
render(UpdateCenterModal, {
|
||||
props: {
|
||||
show: true,
|
||||
store,
|
||||
},
|
||||
});
|
||||
|
||||
expect(screen.getByRole("button", { name: "忽略更新" })).toBeTruthy();
|
||||
});
|
||||
|
||||
it("renders migration confirmation when requested", () => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
|
||||
@@ -6,7 +7,7 @@ import { describe, expect, it } from "vitest";
|
||||
|
||||
import type { UpdateCenterItem } from "../../../../electron/main/backend/update-center/types";
|
||||
import {
|
||||
LEGACY_IGNORE_CONFIG_PATH,
|
||||
IGNORE_CONFIG_PATH,
|
||||
applyIgnoredEntries,
|
||||
createIgnoreKey,
|
||||
loadIgnoredEntries,
|
||||
@@ -15,9 +16,9 @@ import {
|
||||
} from "../../../../electron/main/backend/update-center/ignore-config";
|
||||
|
||||
describe("update-center ignore config", () => {
|
||||
it("round-trips the legacy package|version format", async () => {
|
||||
expect(LEGACY_IGNORE_CONFIG_PATH).toBe(
|
||||
"/etc/spark-store/ignored_apps.conf",
|
||||
it("round-trips the package|version format at the user config path", async () => {
|
||||
expect(IGNORE_CONFIG_PATH).toBe(
|
||||
join(homedir(), ".config", "spark-store", "ignored_apps.conf"),
|
||||
);
|
||||
|
||||
const entries = new Set([
|
||||
|
||||
@@ -24,6 +24,8 @@ const createSnapshot = (overrides = {}) => ({
|
||||
describe("updateCenter store", () => {
|
||||
const open = vi.fn();
|
||||
const refresh = vi.fn();
|
||||
const ignore = vi.fn();
|
||||
const unignore = vi.fn();
|
||||
const start = vi.fn();
|
||||
const onState = vi.fn();
|
||||
const offState = vi.fn();
|
||||
@@ -31,6 +33,8 @@ describe("updateCenter store", () => {
|
||||
beforeEach(() => {
|
||||
open.mockReset();
|
||||
refresh.mockReset();
|
||||
ignore.mockReset();
|
||||
unignore.mockReset();
|
||||
start.mockReset();
|
||||
onState.mockReset();
|
||||
offState.mockReset();
|
||||
@@ -41,8 +45,8 @@ describe("updateCenter store", () => {
|
||||
value: {
|
||||
open,
|
||||
refresh,
|
||||
ignore: vi.fn(),
|
||||
unignore: vi.fn(),
|
||||
ignore,
|
||||
unignore,
|
||||
start,
|
||||
cancel: vi.fn(),
|
||||
getState: vi.fn(),
|
||||
@@ -132,6 +136,25 @@ describe("updateCenter store", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("forwards ignore and unignore actions with the package and target version", async () => {
|
||||
const snapshot = createSnapshot();
|
||||
open.mockResolvedValue(snapshot);
|
||||
const store = createUpdateCenterStore();
|
||||
|
||||
await store.open();
|
||||
await store.ignoreItem("spark-weather", "2.0.0");
|
||||
await store.unignoreItem("spark-weather", "2.0.0");
|
||||
|
||||
expect(ignore).toHaveBeenCalledWith({
|
||||
packageName: "spark-weather",
|
||||
newVersion: "2.0.0",
|
||||
});
|
||||
expect(unignore).toHaveBeenCalledWith({
|
||||
packageName: "spark-weather",
|
||||
newVersion: "2.0.0",
|
||||
});
|
||||
});
|
||||
|
||||
it("assigns update-center download ids from a separate range", async () => {
|
||||
downloads.value = [
|
||||
{
|
||||
@@ -178,8 +201,8 @@ describe("updateCenter store", () => {
|
||||
|
||||
store.requestClose();
|
||||
|
||||
expect(store.isOpen.value).toBe(true);
|
||||
expect(store.showCloseConfirm.value).toBe(true);
|
||||
expect(store.isOpen.value).toBe(false);
|
||||
expect(store.showCloseConfirm.value).toBe(false);
|
||||
});
|
||||
|
||||
it("applies pushed snapshots from the main process", () => {
|
||||
|
||||
@@ -48,6 +48,8 @@
|
||||
:tasks="store.snapshot.value.tasks"
|
||||
:selected-task-keys="store.selectedTaskKeys.value"
|
||||
@toggle-selection="emit('toggle-selection', $event)"
|
||||
@ignore-item="store.ignoreItem"
|
||||
@unignore-item="store.unignoreItem"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -63,6 +63,29 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<button
|
||||
v-if="item.ignored === true"
|
||||
type="button"
|
||||
class="inline-flex items-center gap-2 rounded-2xl border border-slate-300/80 px-3 py-2 text-sm font-semibold text-slate-600 transition hover:bg-slate-50 dark:border-slate-700 dark:text-slate-200 dark:hover:bg-slate-800"
|
||||
aria-label="取消忽略"
|
||||
@click.stop="$emit('unignore-item')"
|
||||
>
|
||||
<i class="fas fa-rotate-left"></i>
|
||||
取消忽略
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
type="button"
|
||||
class="inline-flex items-center gap-2 rounded-2xl border border-amber-300/80 px-3 py-2 text-sm font-semibold text-amber-700 transition hover:bg-amber-50 dark:border-amber-500/40 dark:text-amber-300 dark:hover:bg-amber-500/10"
|
||||
aria-label="忽略更新"
|
||||
@click.stop="$emit('ignore-item')"
|
||||
>
|
||||
<i class="fas fa-eye-slash"></i>
|
||||
忽略更新
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div v-if="showProgress" class="space-y-2">
|
||||
<div
|
||||
class="h-2 overflow-hidden rounded-full bg-slate-200 dark:bg-slate-800"
|
||||
@@ -96,6 +119,8 @@ const iconIndex = ref(0);
|
||||
|
||||
defineEmits<{
|
||||
(e: "toggle-selection"): void;
|
||||
(e: "ignore-item"): void;
|
||||
(e: "unignore-item"): void;
|
||||
}>();
|
||||
|
||||
const normalizeIconSrc = (icon: string): string => {
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
:task="taskMap.get(item.taskKey)"
|
||||
:selected="selectedTaskKeys.has(item.taskKey)"
|
||||
@toggle-selection="$emit('toggle-selection', item.taskKey)"
|
||||
@ignore-item="$emit('ignore-item', item.packageName, item.newVersion)"
|
||||
@unignore-item="
|
||||
$emit('unignore-item', item.packageName, item.newVersion)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -39,6 +43,8 @@ const props = defineProps<{
|
||||
|
||||
defineEmits<{
|
||||
(e: "toggle-selection", taskKey: string): void;
|
||||
(e: "ignore-item", packageName: string, newVersion: string): void;
|
||||
(e: "unignore-item", packageName: string, newVersion: string): void;
|
||||
}>();
|
||||
|
||||
const taskMap = computed(() => {
|
||||
|
||||
@@ -30,6 +30,8 @@ export interface UpdateCenterStore {
|
||||
unbind: () => void;
|
||||
open: () => Promise<void>;
|
||||
refresh: () => Promise<void>;
|
||||
ignoreItem: (packageName: string, newVersion: string) => Promise<void>;
|
||||
unignoreItem: (packageName: string, newVersion: string) => Promise<void>;
|
||||
toggleSelection: (taskKey: string) => void;
|
||||
toggleSelectAll: () => void;
|
||||
getSelectedItems: () => UpdateCenterItem[];
|
||||
@@ -139,6 +141,20 @@ export const createUpdateCenterStore = (): UpdateCenterStore => {
|
||||
applySnapshot(nextSnapshot);
|
||||
};
|
||||
|
||||
const ignoreItem = async (
|
||||
packageName: string,
|
||||
newVersion: string,
|
||||
): Promise<void> => {
|
||||
await window.updateCenter.ignore({ packageName, newVersion });
|
||||
};
|
||||
|
||||
const unignoreItem = async (
|
||||
packageName: string,
|
||||
newVersion: string,
|
||||
): Promise<void> => {
|
||||
await window.updateCenter.unignore({ packageName, newVersion });
|
||||
};
|
||||
|
||||
const toggleSelection = (taskKey: string): void => {
|
||||
const item = snapshot.value.items.find(
|
||||
(entry) => entry.taskKey === taskKey,
|
||||
@@ -260,6 +276,8 @@ export const createUpdateCenterStore = (): UpdateCenterStore => {
|
||||
unbind,
|
||||
open,
|
||||
refresh,
|
||||
ignoreItem,
|
||||
unignoreItem,
|
||||
toggleSelection,
|
||||
toggleSelectAll,
|
||||
getSelectedItems,
|
||||
|
||||
Reference in New Issue
Block a user