fix: clear external player paths on save

Entire-Checkpoint: f957cd9849e0
This commit is contained in:
4gray committed 2026-05-04 23:26:56 +02:00
1 parent 2efdfea0c1
commit 4a21579aff
4 files changed
+111 -22

No files matched your search

@@ -25,6 +25,12 @@ jest.mock('../services/stalker-playback-context.service', () => ({
getStalkerPlaybackContextHeaders: jest.fn(() => undefined),
}));
import { ipcMain } from 'electron';
import {
MPV_PLAYER_PATH,
store,
VLC_PLAYER_PATH,
} from '../services/store.service';
import {
buildExternalPlayerSpawnSpec,
isRunningInFlatpak,
@@ -39,6 +45,22 @@ function createPathExists(existingPaths: string[]) {
return (candidatePath: string) => existingPaths.includes(candidatePath);
}
function getIpcMainHandler(channel: string): (...args: unknown[]) => unknown {
const handleMock = ipcMain.handle as unknown as jest.Mock;
const calls = handleMock.mock.calls as Array<
[string, (...args: unknown[]) => unknown]
>;
const match = calls.find(
([registeredChannel]) => registeredChannel === channel
);
if (!match) {
throw new Error(`Missing ipcMain handler for ${channel}`);
}
return match[1];
}
describe('player.events Flatpak launch helpers', () => {
it('detects Flatpak only on Linux when /.flatpak-info exists', () => {
expect(isRunningInFlatpak(createPathExists(['/.flatpak-info']), 'linux')).toBe(
@@ -170,3 +192,27 @@ Command Line Interface initialized. Type \`help' for help.
).toBe('stopped');
});
});
describe('player.events external player path settings', () => {
beforeEach(() => {
(store.set as unknown as jest.Mock).mockClear();
});
it('stores cleared VLC player paths as an empty string', () => {
getIpcMainHandler('SET_VLC_PLAYER_PATH')({}, ' ');
expect(store.set).toHaveBeenCalledWith(VLC_PLAYER_PATH, '');
});
it('trims custom MPV player paths before storing them', () => {
getIpcMainHandler('SET_MPV_PLAYER_PATH')(
{},
' /Applications/mpv.app/Contents/MacOS/mpv '
);
expect(store.set).toHaveBeenCalledWith(
MPV_PLAYER_PATH,
'/Applications/mpv.app/Contents/MacOS/mpv'
);
});
});
@@ -77,11 +77,17 @@ export function isRunningInFlatpak(
return platform === 'linux' && pathExists('/.flatpak-info');
}
function normalizeCustomPlayerPath(value: string | undefined): string | null {
function normalizeCustomPlayerPath(
value: string | null | undefined
): string | null {
const trimmedValue = value?.trim();
return trimmedValue ? trimmedValue : null;
}
function normalizePlayerPathForStore(value: string | null | undefined): string {
return normalizeCustomPlayerPath(value) ?? '';
}
function getDefaultPlayerPath(
player: ExternalPlayerName,
options: PlayerPathOptions = {}
@@ -921,10 +927,14 @@ ipcMain.handle(
}
);
ipcMain.handle('SET_MPV_PLAYER_PATH', (_event, mpvPlayerPath) => {
console.log('... setting mpv player path', mpvPlayerPath);
store.set(MPV_PLAYER_PATH, mpvPlayerPath);
});
ipcMain.handle(
'SET_MPV_PLAYER_PATH',
(_event, mpvPlayerPath: string | null | undefined) => {
const normalizedPlayerPath = normalizePlayerPathForStore(mpvPlayerPath);
console.log('... setting mpv player path', normalizedPlayerPath);
store.set(MPV_PLAYER_PATH, normalizedPlayerPath);
}
);
ipcMain.handle('SET_MPV_REUSE_INSTANCE', (_event, reuseInstance: boolean) => {
console.log('... setting mpv reuse instance', reuseInstance);
@@ -1247,10 +1257,14 @@ ipcMain.handle(
}
);
ipcMain.handle('SET_VLC_PLAYER_PATH', (_event, vlcPlayerPath) => {
console.log('... setting vlc player path', vlcPlayerPath);
store.set(VLC_PLAYER_PATH, vlcPlayerPath);
});
ipcMain.handle(
'SET_VLC_PLAYER_PATH',
(_event, vlcPlayerPath: string | null | undefined) => {
const normalizedPlayerPath = normalizePlayerPathForStore(vlcPlayerPath);
console.log('... setting vlc player path', normalizedPlayerPath);
store.set(VLC_PLAYER_PATH, normalizedPlayerPath);
}
);
ipcMain.handle(
CLOSE_EXTERNAL_PLAYER_SESSION,
@@ -925,4 +925,28 @@ describe('SettingsComponent', () => {
component.settingsForm.value
);
});
it('clears external player paths in Electron when saved as empty', async () => {
const mockStore = settingsStore as unknown as MockSettingsStore;
mockStore.updateSettings.mockResolvedValue(undefined);
const setMpvPlayerPath = jest.spyOn(
window.electron,
'setMpvPlayerPath'
);
const setVlcPlayerPath = jest.spyOn(
window.electron,
'setVlcPlayerPath'
);
component.settingsForm.patchValue({
mpvPlayerPath: '',
vlcPlayerPath: '',
});
component.onSubmit();
await fixture.whenStable();
expect(setMpvPlayerPath).toHaveBeenCalledWith('');
expect(setVlcPlayerPath).toHaveBeenCalledWith('');
});
});
+18 -13
View File
@@ -443,23 +443,22 @@ export class SettingsComponent implements OnInit, OnDestroy {
* the indexed db store
*/
onSubmit(): void {
this.settingsStore.updateSettings(this.settingsForm.value).then(() => {
const settings = this.settingsForm.value;
const mpvPlayerPath = this.normalizeExternalPlayerPath(
settings.mpvPlayerPath
);
const vlcPlayerPath = this.normalizeExternalPlayerPath(
settings.vlcPlayerPath
);
this.settingsStore.updateSettings(settings).then(() => {
this.applyChangedSettings();
if (window.electron) {
window.electron.updateSettings(this.settingsForm.value);
window.electron.updateSettings(settings);
// Set player paths if using external players
if (this.settingsForm.value.mpvPlayerPath) {
window.electron.setMpvPlayerPath(
this.settingsForm.value.mpvPlayerPath
);
}
if (this.settingsForm.value.vlcPlayerPath) {
window.electron.setVlcPlayerPath(
this.settingsForm.value.vlcPlayerPath
);
}
window.electron.setMpvPlayerPath(mpvPlayerPath);
window.electron.setVlcPlayerPath(vlcPlayerPath);
}
});
if (this.isDialog) {
@@ -467,6 +466,12 @@ export class SettingsComponent implements OnInit, OnDestroy {
}
}
private normalizeExternalPlayerPath(
playerPath: string | null | undefined
): string {
return playerPath?.trim() ?? '';
}
/**
* Applies the changed settings to the app
*/