refactor(web): split settings component into sections

Entire-Checkpoint: c2cea9c530e6
This commit is contained in:
4gray committed 2026-05-01 20:16:32 +02:00
1 parent d24c67c6e8
commit c51d8161ea
22 files changed
+1759 -1581

No files matched your search

@@ -15,6 +15,7 @@ import { MatListModule } from '@angular/material/list';
import { MatSelectModule } from '@angular/material/select';
import { MatSnackBar } from '@angular/material/snack-bar';
import { MatTooltipModule } from '@angular/material/tooltip';
import { By } from '@angular/platform-browser';
import { Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { EpgService } from '@iptvnator/epg/data-access';
@@ -52,6 +53,7 @@ import { from, of } from 'rxjs';
import { ElectronServiceStub } from '../services/electron.service.stub';
import { SettingsStore } from '../services/settings-store.service';
import { SettingsService } from '../services/settings.service';
import { SettingsSectionScrollDirective } from './settings-section-scroll.directive';
class MatSnackBarStub {
open = jest.fn();
@@ -111,6 +113,10 @@ class MockSettingsService {
);
}
interface SettingsSectionScrollDirectiveTestApi {
getScrollRoot(): HTMLElement | null;
}
describe('SettingsComponent', () => {
let component: SettingsComponent;
let fixture: ComponentFixture<SettingsComponent>;
@@ -118,7 +124,6 @@ describe('SettingsComponent', () => {
let router: Router;
let settingsStore: unknown;
let translate: TranslateService;
let epgService: EpgService;
let dialogService: DialogService;
let playlistsService: PlaylistsService;
let playlistBackupService: PlaylistBackupService;
@@ -245,7 +250,6 @@ describe('SettingsComponent', () => {
settingsStore = TestBed.inject(SettingsStore);
router = TestBed.inject(Router);
translate = TestBed.inject(TranslateService);
epgService = TestBed.inject(EpgService);
dialogService = TestBed.inject(DialogService);
playlistsService = TestBed.inject(PlaylistsService);
playlistBackupService = TestBed.inject(PlaylistBackupService);
@@ -333,10 +337,14 @@ describe('SettingsComponent', () => {
scrollComponent.fetchLocalIpAddresses = jest
.fn()
.mockResolvedValue(undefined);
jest.spyOn(scrollComponent as any, 'getScrollRoot').mockReturnValue(
scrollRoot
);
scrollFixture.detectChanges();
const scrollDirective = scrollFixture.debugElement
.query(By.directive(SettingsSectionScrollDirective))
.injector.get(SettingsSectionScrollDirective);
jest.spyOn(
scrollDirective as unknown as SettingsSectionScrollDirectiveTestApi,
'getScrollRoot'
).mockReturnValue(scrollRoot);
const getElementByIdSpy = jest
.spyOn(document, 'getElementById')
@@ -846,13 +854,35 @@ describe('SettingsComponent', () => {
expect(router.navigateByUrl).toHaveBeenCalledWith('/');
});
it('should update the selected theme and mark the form dirty', () => {
component.selectTheme(Theme.DarkTheme);
it('updates the selected theme through the general section and marks the form dirty', () => {
const darkThemeButton = (
fixture.nativeElement as HTMLElement
).querySelector('[data-test-id="DARK_THEME"]') as HTMLButtonElement;
darkThemeButton.click();
fixture.detectChanges();
expect(component.settingsForm.value.theme).toBe(Theme.DarkTheme);
expect(component.settingsForm.dirty).toBeTruthy();
});
it('updates cover size through the general section output', () => {
const mockStore = settingsStore as unknown as MockSettingsStore;
const largeCoverButton = (
fixture.nativeElement as HTMLElement
).querySelector(
'[data-test-id="cover-size-large"]'
) as HTMLButtonElement;
largeCoverButton.click();
fixture.detectChanges();
expect(component.settingsForm.value.coverSize).toBe('large');
expect(mockStore.updateSettings).toHaveBeenCalledWith({
coverSize: 'large',
});
});
it('renders workspace startup controls with the expected defaults', () => {
const nativeElement = fixture.nativeElement as HTMLElement;