Files
SubMiner/src/main/runtime/setup-window-factory.test.ts
T
sudacode 7c9b65db8b feat: inject bundled mpv plugin for managed launches, remove legacy glob (#62)
* feat: inject bundled mpv plugin for managed launches, remove legacy glob

- SubMiner-managed launcher and Windows shortcut launches inject the bundled plugin when no global plugin is detected
- First-run setup detects and removes legacy global plugin files via OS trash before managed playback starts
- Makefile `install-plugin` target and Windows config-rewrite script removed; Linux/macOS install now copies plugin to app data dir
- AniList stats search and post-watch tracking now go through the shared rate limiter
- Stats cover-art lookup reuses cached AniList data before issuing a new request
- Closing mpv in a launcher-managed session now terminates the background Electron app

* harden bootstrap version load and clean plugin on uninstall

- Use pcall for version.lua in bootstrap.lua so missing version module does not crash plugin startup
- Remove plugin/subminer from app-data dirs in uninstall-linux and uninstall-macos targets
- Add Lua compat test asserting bootstrap uses defensive pcall for version load
- Add release-workflow test asserting uninstall targets clean bundled plugin dirs
- Delete completed planning document
2026-05-12 23:11:19 -07:00

80 lines
2.2 KiB
TypeScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
createCreateAnilistSetupWindowHandler,
createCreateFirstRunSetupWindowHandler,
createCreateJellyfinSetupWindowHandler,
} from './setup-window-factory';
test('createCreateFirstRunSetupWindowHandler builds first-run setup window', () => {
let options: Electron.BrowserWindowConstructorOptions | null = null;
const createSetupWindow = createCreateFirstRunSetupWindowHandler({
createBrowserWindow: (nextOptions) => {
options = nextOptions;
return { id: 'first-run' } as never;
},
});
assert.deepEqual(createSetupWindow(), { id: 'first-run' });
assert.deepEqual(options, {
width: 560,
height: 640,
title: 'SubMiner Setup',
show: true,
autoHideMenuBar: true,
resizable: false,
minimizable: false,
maximizable: false,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
},
});
});
test('createCreateJellyfinSetupWindowHandler builds jellyfin setup window', () => {
let options: Electron.BrowserWindowConstructorOptions | null = null;
const createSetupWindow = createCreateJellyfinSetupWindowHandler({
createBrowserWindow: (nextOptions) => {
options = nextOptions;
return { id: 'jellyfin' } as never;
},
});
assert.deepEqual(createSetupWindow(), { id: 'jellyfin' });
assert.deepEqual(options, {
width: 520,
height: 560,
title: 'Jellyfin Setup',
show: true,
autoHideMenuBar: true,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
},
});
});
test('createCreateAnilistSetupWindowHandler builds anilist setup window', () => {
let options: Electron.BrowserWindowConstructorOptions | null = null;
const createSetupWindow = createCreateAnilistSetupWindowHandler({
createBrowserWindow: (nextOptions) => {
options = nextOptions;
return { id: 'anilist' } as never;
},
});
assert.deepEqual(createSetupWindow(), { id: 'anilist' });
assert.deepEqual(options, {
width: 1000,
height: 760,
title: 'Anilist Setup',
show: true,
autoHideMenuBar: true,
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
},
});
});