返回 DeepSeek-Reasonix
appIdentity.test.ts
根目录 / desktop / electron / src / main / appIdentity.test.ts
1 import assert from "node:assert/strict";
2 import { readFileSync } from "node:fs";
3 import { fileURLToPath } from "node:url";
4 import { test } from "node:test";
5 import { APP_USER_MODEL_ID, applyAppUserModelId, registerTaskbarRelaunch, windowsTaskbarDetails } from "./appIdentity.js";
6
7 function windowsApp() {
8 const applied: string[] = [];
9 return { applied, app: { setAppUserModelId: (id: string) => applied.push(id) } };
10 }
11
12 test("Desktop has its own identity across Studio generations", () => {
13 assert.equal(APP_USER_MODEL_ID, "io.reasonix.desktop");
14 for (const other of ["Reasonix", "io.reasonix.studio", "dev.reasonix.desktop"]) {
15 assert.notEqual(APP_USER_MODEL_ID, other);
16 }
17 });
18
19 test("Windows adopts the launcher's shared AppUserModelID before any window exists", () => {
20 const { applied, app } = windowsApp();
21 applyAppUserModelId(app, "win32");
22 assert.deepEqual(applied, [APP_USER_MODEL_ID]);
23 });
24
25 test("other platforms never touch the Windows identity", () => {
26 for (const platform of ["darwin", "linux"] as const) {
27 const { applied, app } = windowsApp();
28 applyAppUserModelId(app, platform);
29 assert.deepEqual(applied, [], `${platform} must not set an AppUserModelID`);
30 }
31 });
32
33 test("main applies the identity at load time rather than after readiness", () => {
34 const source = readFileSync(fileURLToPath(new URL("./index.ts", import.meta.url)), "utf8");
35 const applied = source.indexOf("applyAppUserModelId(app, process.platform)");
36 assert.notEqual(applied, -1, "index.ts must apply the AppUserModelID");
37 // app.whenReady() creates the window, so a later call would miss the taskbar.
38 const ready = source.indexOf("app.whenReady()");
39 assert.notEqual(ready, -1, "index.ts must still gate startup on app readiness");
40 assert.ok(applied < ready, "the AppUserModelID must be applied before app.whenReady()");
41 });
42
43 test("new taskbar pins relaunch the permanent launcher for versioned and flat installs", () => {
44 for (const executable of [String.raw`C:\Apps\Reasonix test\versions\v1.38.6\app\Reasonix.exe`, String.raw`C:\Apps\Reasonix test\app\Reasonix.exe`]) {
45 const launcher = String.raw`C:\Apps\Reasonix test\reasonix-launcher.exe`;
46 assert.deepEqual(windowsTaskbarDetails(executable, (path) => path === launcher), {
47 appId: APP_USER_MODEL_ID,
48 appIconPath: launcher,
49 appIconIndex: 0,
50 relaunchCommand: `"${launcher}"`,
51 relaunchDisplayName: "Reasonix",
52 });
53 }
54 assert.equal(windowsTaskbarDetails(String.raw`C:\Apps\Reasonix\app\Reasonix.exe`, () => false), undefined);
55 assert.equal(windowsTaskbarDetails(String.raw`C:\Other\electron.exe`, () => true), undefined);
56 });
57
58 test("every created Windows window gets relaunch metadata and other platforms do not", () => {
59 const source = readFileSync(fileURLToPath(new URL("./index.ts", import.meta.url)), "utf8");
60 const registered = source.indexOf("registerTaskbarRelaunch(app, process.platform, process.execPath, app.isPackaged)");
61 assert.ok(registered >= 0 && registered < source.indexOf("bootstrap(home)"));
62 type Listener = (event: unknown, window: { setAppDetails(details: object): void }) => void;
63 const listeners: Listener[] = [];
64 const target = { on: (event: string, callback: Listener) => { assert.equal(event, "browser-window-created"); listeners.push(callback); } };
65 registerTaskbarRelaunch(target, "darwin", "/Applications/Reasonix", true, () => true);
66 registerTaskbarRelaunch(target, "win32", String.raw`C:\Apps\Reasonix\app\Reasonix.exe`, false, () => true);
67 assert.equal(listeners.length, 0);
68 registerTaskbarRelaunch(target, "win32", String.raw`C:\Apps\Reasonix\app\Reasonix.exe`, true, () => true);
69 const listener = listeners[0];
70 assert.ok(listener);
71 const applied: object[] = [];
72 listener({}, { setAppDetails: (details) => applied.push(details) });
73 listener({}, { setAppDetails: (details) => applied.push(details) });
74 assert.equal(applied.length, 2);
75 assert.deepEqual(applied[0], applied[1]);
76 });
77
78 test("taskbar pins prefer the canonical entry even when the legacy launcher exists", () => {
79 const shell = String.raw`C:\Apps\Reasonix\versions\v1.38.9\app\Reasonix.exe`;
80 const canonical = String.raw`C:\Apps\Reasonix\Reasonix.exe`;
81 assert.equal(windowsTaskbarDetails(shell, () => true)?.relaunchCommand, `"${canonical}"`);
82 assert.equal(windowsTaskbarDetails(shell, path => path === canonical)?.appIconPath, canonical);
83 });
84
84 lines TYPESCRIPT