diff --git a/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.spec.ts b/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.spec.ts index b7bc00147..d2f1a1d3e 100644 --- a/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.spec.ts +++ b/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.spec.ts @@ -12,7 +12,11 @@ import { BehaviorSubject, firstValueFrom, of, Subject } from 'rxjs'; import { EpgService } from '@iptvnator/epg/data-access'; import { PlaylistContextFacade } from '@iptvnator/playlist/shared/util'; import { ChannelActions, PlaylistActions } from '@iptvnator/m3u-state'; -import { PlaylistsService, SettingsStore } from '@iptvnator/services'; +import { + PlaylistsService, + RuntimeCapabilitiesService, + SettingsStore, +} from '@iptvnator/services'; import { Channel, PlaylistMeta } from '@iptvnator/shared/interfaces'; import { ChannelListContainerComponent } from './channel-list-container.component'; @@ -62,11 +66,15 @@ describe('ChannelListContainerComponent', () => { let dispatch: jest.Mock; let activePlaylistSignal: ReturnType>; let favoriteChannelIds$: BehaviorSubject; + let runtimeCapabilities: { supportsEpg: boolean }; + let storageGet: jest.Mock; beforeEach(async () => { const routerEvents$ = new Subject(); dispatch = jest.fn(); favoriteChannelIds$ = new BehaviorSubject([]); + runtimeCapabilities = { supportsEpg: true }; + storageGet = jest.fn().mockReturnValue(of({})); activePlaylistSignal = signal({ _id: 'playlist-1', title: 'Playlist One', @@ -124,9 +132,13 @@ describe('ChannelListContainerComponent', () => { { provide: StorageMap, useValue: { - get: jest.fn().mockReturnValue(of({})), + get: storageGet, }, }, + { + provide: RuntimeCapabilitiesService, + useValue: runtimeCapabilities, + }, { provide: Store, useValue: { @@ -181,6 +193,16 @@ describe('ChannelListContainerComponent', () => { ); }); + it('does not enable EPG rows when runtime EPG support is unavailable', () => { + runtimeCapabilities.supportsEpg = false; + storageGet.mockReturnValue(of({ epgUrl: ['https://example.com/epg.xml'] })); + + fixture.detectChanges(); + + expect(fixture.componentInstance.shouldShowEpg()).toBe(false); + expect(storageGet).not.toHaveBeenCalled(); + }); + it('dispatches playlist meta updates when hidden group titles change', () => { fixture.componentInstance.onHiddenGroupTitlesChanged([ 'Movies', diff --git a/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.ts b/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.ts index 0586b32f9..8eb489b43 100644 --- a/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.ts +++ b/libs/ui/components/src/lib/channel-list-container/channel-list-container.component.ts @@ -40,7 +40,11 @@ import { firstValueFrom, map, } from 'rxjs'; -import { PlaylistsService, SettingsStore } from '@iptvnator/services'; +import { + PlaylistsService, + RuntimeCapabilitiesService, + SettingsStore, +} from '@iptvnator/services'; import { Channel, EpgProgram, @@ -109,6 +113,7 @@ export class ChannelListContainerComponent implements OnInit, OnDestroy { private readonly router = inject(Router); private readonly route = inject(ActivatedRoute); private readonly playlistContext = inject(PlaylistContextFacade); + private readonly runtime = inject(RuntimeCapabilitiesService); private readonly settingsStore = inject(SettingsStore); /** Map of channel ID to current EPG program */ @@ -287,8 +292,7 @@ export class ChannelListContainerComponent implements OnInit, OnDestroy { ngOnInit(): void { // Check if EPG should be shown (only in Electron with configured EPG URL) - const isElectron = !!window['electron']; - if (isElectron) { + if (this.runtime.supportsEpg) { this.storage .get(STORE_KEY.Settings) .subscribe((settings: unknown) => {