test: align standard commands with maintained test surface

This commit is contained in:
2026-03-06 00:58:32 -08:00
parent f160ca6af8
commit e2b51c6306
15 changed files with 364 additions and 103 deletions

View File

@@ -22,6 +22,8 @@ function createMockWindow(): MockWindow & {
isFocused: () => boolean;
getURL: () => string;
setIgnoreMouseEvents: (ignore: boolean, options?: { forward?: boolean }) => void;
setAlwaysOnTop: (flag: boolean, level?: string, relativeLevel?: number) => void;
moveTop: () => void;
getShowCount: () => number;
getHideCount: () => number;
show: () => void;
@@ -59,6 +61,8 @@ function createMockWindow(): MockWindow & {
setIgnoreMouseEvents: (ignore: boolean, _options?: { forward?: boolean }) => {
state.ignoreMouseEvents = ignore;
},
setAlwaysOnTop: (_flag: boolean, _level?: string, _relativeLevel?: number) => {},
moveTop: () => {},
getShowCount: () => state.showCount,
getHideCount: () => state.hideCount,
show: () => {
@@ -100,6 +104,27 @@ function createMockWindow(): MockWindow & {
},
});
Object.defineProperty(window, 'visible', {
get: () => state.visible,
set: (value: boolean) => {
state.visible = value;
},
});
Object.defineProperty(window, 'focused', {
get: () => state.focused,
set: (value: boolean) => {
state.focused = value;
},
});
Object.defineProperty(window, 'webContentsFocused', {
get: () => state.webContentsFocused,
set: (value: boolean) => {
state.webContentsFocused = value;
},
});
Object.defineProperty(window, 'url', {
get: () => state.url,
set: (value: string) => {
@@ -318,7 +343,7 @@ test('notifyOverlayModalOpened enables input on visible main overlay window when
runtime.notifyOverlayModalOpened('runtime-options');
assert.equal(sent, true);
assert.equal(state, [true]);
assert.deepEqual(state, [true]);
assert.equal(mainWindow.ignoreMouseEvents, false);
assert.equal(mainWindow.isFocused(), true);
assert.equal(mainWindow.webContentsFocused, true);
@@ -400,7 +425,7 @@ test('modal fallback reveal keeps mouse events ignored until modal confirms open
});
assert.equal(window.getShowCount(), 1);
assert.equal(window.ignoreMouseEvents, true);
assert.equal(window.ignoreMouseEvents, false);
runtime.notifyOverlayModalOpened('jimaku');
assert.equal(window.ignoreMouseEvents, false);

View File

@@ -59,7 +59,7 @@ export function createOverlayModalRuntimeService(
const getTargetOverlayWindow = (): BrowserWindow | null => {
const visibleMainWindow = deps.getMainWindow();
if (visibleMainWindow && !visibleMainWindow.isDestroyed()) {
if (visibleMainWindow && !visibleMainWindow.isDestroyed() && visibleMainWindow.isVisible()) {
return visibleMainWindow;
}
return null;
@@ -221,7 +221,13 @@ export function createOverlayModalRuntimeService(
showModalWindow(modalWindow);
}
sendOrQueueForWindow(modalWindow, sendNow);
sendOrQueueForWindow(modalWindow, (window) => {
if (payload === undefined) {
window.webContents.send(channel);
} else {
window.webContents.send(channel, payload);
}
});
return true;
}

View File

@@ -1,6 +1,6 @@
import fs from 'node:fs';
import path from 'node:path';
import { parseClipboardVideoPath } from '../../core/services';
import { parseClipboardVideoPath } from '../../core/services/overlay-drop';
type MpvClientLike = {
connected: boolean;

View File

@@ -1,13 +1,15 @@
import type { RuntimeOptionsManager } from '../../runtime-options';
import type { JimakuApiResponse, JimakuLanguagePreference, ResolvedConfig } from '../../types';
import {
isAutoUpdateEnabledRuntime as isAutoUpdateEnabledRuntimeCore,
shouldAutoInitializeOverlayRuntimeFromConfig as shouldAutoInitializeOverlayRuntimeFromConfigCore,
} from '../../core/services/startup';
import {
getJimakuLanguagePreference as getJimakuLanguagePreferenceCore,
getJimakuMaxEntryResults as getJimakuMaxEntryResultsCore,
isAutoUpdateEnabledRuntime as isAutoUpdateEnabledRuntimeCore,
jimakuFetchJson as jimakuFetchJsonCore,
resolveJimakuApiKey as resolveJimakuApiKeyCore,
shouldAutoInitializeOverlayRuntimeFromConfig as shouldAutoInitializeOverlayRuntimeFromConfigCore,
} from '../../core/services';
} from '../../core/services/jimaku';
export type ConfigDerivedRuntimeDeps = {
getResolvedConfig: () => ResolvedConfig;

View File

@@ -1,5 +1,5 @@
import type { ConfigHotReloadDiff } from '../../core/services/config-hot-reload';
import { resolveKeybindings } from '../../core/utils';
import { resolveKeybindings } from '../../core/utils/keybindings';
import { DEFAULT_KEYBINDINGS } from '../../config';
import type { ConfigHotReloadPayload, ResolvedConfig, SecondarySubMode } from '../../types';

View File

@@ -5,7 +5,8 @@ async function loadRegistryOrSkip(t: test.TestContext) {
try {
return await import('./registry');
} catch (error) {
if (error instanceof Error && error.message.includes('node:sqlite')) {
const message = error instanceof Error ? error.message : String(error);
if (message.includes('node:sqlite')) {
t.skip('registry import requires node:sqlite support in this runtime');
return null;
}

View File

@@ -42,13 +42,12 @@ test('createReloadConfigHandler runs success flow with warnings', async () => {
calls.some((entry) => entry.includes('notify:SubMiner:1 config validation issue(s) detected.')),
);
assert.ok(calls.some((entry) => entry.includes('1. ankiConnect.pollingRate: must be >= 50')));
assert.ok(
calls.some((entry) =>
entry.includes(
'dialog:SubMiner config validation warning:SubMiner detected config validation issues.',
),
const showedWarningDialog = calls.some((entry) =>
entry.includes(
'dialog:SubMiner config validation warning:SubMiner detected config validation issues.',
),
);
assert.equal(showedWarningDialog, process.platform === 'darwin');
assert.ok(calls.some((entry) => entry.includes('actual=10 fallback=250')));
assert.ok(calls.includes('hotReload:start'));
assert.deepEqual(refreshCalls, [{ force: true }]);

View File

@@ -1,8 +1,8 @@
import type { MpvIpcClient } from '../../core/services';
import type { MpvIpcClient } from '../../core/services/mpv';
import {
runSubsyncManualFromIpcRuntime,
triggerSubsyncFromConfigRuntime,
} from '../../core/services';
} from '../../core/services/subsync-runner';
import type {
SubsyncResult,
SubsyncManualPayload,