Commit Graph
3 Commits
Author SHA1 Message Date
4grayandClaude Opus 5 4779642e6e test(settings): move the storage-failure coverage to its own spec
Rebase follow-up. #1274 split the settings page into facades and #1277 split
its spec along the same seams, so this PR's renderer changes moved:

- the failed-read warning is now raised by `SettingsFormFacade.loadSettings()`,
  which owns the store call
- the cover-size and EPG-view-mode writes moved into the facade, so their
  rejection handling went with them
- `showStorageFailure()` became `SettingsSnackbarService.storageFailure()`,
  because the component and the facade both need it and neither can reach the
  other's copy
- `onSubmit()` still owns the dialog, so the catch and the "close only after
  the write succeeded" ordering stay in the component

The four regression tests live in `settings.component.storage-failure.spec.ts`
rather than being appended to `settings.component.form.spec.ts`, which would
have pushed that file to 427 lines, past the 400-line lint maximum. They assert
against the MatDialog the component actually calls — spying on the instance
from `TestBed.inject(MatDialog)` does not observe it — and one of them stubs
the post-save EPG fetch, since a throw there would otherwise land in the same
catch and look like a failed write.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 20:32:56 +02:00
4grayandClaude Opus 5 917691b80c fix(settings): stop settings silently reverting on restart
Settings live in the renderer's IndexedDB. Two failure modes made them
look saved while nothing reached disk:

- A second app instance sharing the same userData directory cannot take
  the Chromium storage lock, so its renderer reads defaults and every
  write is dropped. The app now holds a single-instance lock and focuses
  the running window instead of starting a rival copy. The lock is
  requested after the userData override so E2E runs with their own data
  dir keep independent locks, and after Squirrel event handling.
  IPTVNATOR_ALLOW_MULTIPLE_INSTANCES=1 opts out for local CDP debugging.

- updateSettings() patches in-memory state before persisting and
  onSubmit() had no rejection handler, so a failed write produced an
  unhandled rejection and no user-visible feedback. SettingsStore now
  records which half of the round-trip failed and the settings page
  surfaces it via a dismissible error snackbar; the dialog stays open on
  failure so the save can be retried.

Closes #1156
Closes #102

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 20:08:12 +02:00
4gray e2300bea11 test(settings): split the settings spec along the facade seams (#1277)
settings.component.spec.ts was 1516 lines and the last settings file in the
max-lines baseline. The behaviour that moved into facades now has its own
specs, driven directly instead of through the rendered page.

- settings-app-update.facade.spec.ts: status polling/retry, bridge actions,
  release notes dialog, version messaging, dispose
- settings-epg.facade.spec.ts: refresh, clear flow, post-save re-fetch
- settings-playlist-reset.facade.spec.ts: summary, dialog, Electron progress,
  browser fallback, failure snackbar
- settings-backup.facade.spec.ts: desktop export, browser download fallback
- settings.component.spec.ts keeps the page shell, the facade lifecycle seam
  and runtime capabilities; settings.component.form.spec.ts takes hydration,
  section outputs, dashboard controls and submit
- settings-section-scroll.directive.spec.ts gives the directive its first spec
- shared TestBed fixtures live in settings/test-stubs/, kept out of both the
  app build (.stub.ts) and the coverage ratchet (test-stubs/)

105 settings tests, up from 94; every file is under the 400-line limit, so
settings.component.spec.ts leaves the baseline.
2026-07-27 08:31:14 +02:00