diff --git a/libs/epg/data-access/src/lib/epg.service.spec.ts b/libs/epg/data-access/src/lib/epg.service.spec.ts index c5cab5637..cbdfeb941 100644 --- a/libs/epg/data-access/src/lib/epg.service.spec.ts +++ b/libs/epg/data-access/src/lib/epg.service.spec.ts @@ -2,15 +2,24 @@ import { TestBed } from '@angular/core/testing'; import { MatSnackBar } from '@angular/material/snack-bar'; import { TranslateService } from '@ngx-translate/core'; import { firstValueFrom } from 'rxjs'; +import { RuntimeCapabilitiesService } from '@iptvnator/services'; import { EpgService } from './epg.service'; describe('EpgService', () => { let service: EpgService; + let runtimeCapabilities: { supportsEpg: boolean }; + const originalElectron = window.electron; beforeEach(() => { + runtimeCapabilities = { supportsEpg: false }; + TestBed.configureTestingModule({ providers: [ EpgService, + { + provide: RuntimeCapabilitiesService, + useValue: runtimeCapabilities, + }, { provide: MatSnackBar, useValue: { @@ -29,6 +38,22 @@ describe('EpgService', () => { service = TestBed.inject(EpgService); }); + afterEach(() => { + window.electron = originalElectron; + }); + + it('does not fetch EPG when runtime EPG support is disabled', () => { + const fetchEpg = jest.fn(); + window.electron = { + ...window.electron, + fetchEpg, + } as unknown as typeof window.electron; + + service.fetchEpg(['https://example.com/epg.xml']); + + expect(fetchEpg).not.toHaveBeenCalled(); + }); + it('returns an empty batch result when the desktop bridge is unavailable', async () => { const result = await firstValueFrom( service.getCurrentProgramsForChannels(['channel-1']) diff --git a/libs/epg/data-access/src/lib/epg.service.ts b/libs/epg/data-access/src/lib/epg.service.ts index c71c6739e..c3a857fde 100644 --- a/libs/epg/data-access/src/lib/epg.service.ts +++ b/libs/epg/data-access/src/lib/epg.service.ts @@ -8,6 +8,7 @@ import { EpgChannelMetadata, EpgProgram, } from '@iptvnator/shared/interfaces'; +import { RuntimeCapabilitiesService } from '@iptvnator/services'; import { normalizeEpgPrograms } from './epg-program-normalization.util'; interface CachedProgram { @@ -29,6 +30,7 @@ const debugEpgService = createDevLogger('EpgService'); export class EpgService { private snackBar = inject(MatSnackBar); private translate = inject(TranslateService); + private readonly runtime = inject(RuntimeCapabilitiesService); private epgAvailable = new BehaviorSubject(false); private currentEpgPrograms = new BehaviorSubject([]); @@ -37,8 +39,6 @@ export class EpgService { private programCache = new Map(); private readonly CACHE_TTL = 60000; // 60 seconds - private readonly isDesktop = !!window.electron; - readonly epgAvailable$ = this.epgAvailable.asObservable(); readonly currentEpgPrograms$ = this.currentEpgPrograms.asObservable(); @@ -46,7 +46,7 @@ export class EpgService { * Fetches EPG from the given URLs */ fetchEpg(urls: string[]): void { - if (!this.isDesktop) return; + if (!this.runtime.supportsEpg) return; // Filter out empty URLs and send all URLs at once const validUrls = urls.filter((url) => url?.trim()); @@ -76,7 +76,7 @@ export class EpgService { * Gets EPG programs for a specific channel */ getChannelPrograms(channelId: string): void { - if (!this.isDesktop) return; + if (!this.runtime.supportsEpg) return; debugEpgService('Fetching EPG for channel ID:', channelId); from(window.electron.getChannelPrograms(channelId)) @@ -116,7 +116,7 @@ export class EpgService { getCurrentProgramForChannel( channelId: string ): Observable { - if (!this.isDesktop || !channelId) { + if (!this.runtime.supportsEpg || !channelId) { return of(null); } @@ -184,7 +184,7 @@ export class EpgService { getCurrentProgramsForChannels( channelIds: string[] ): Observable> { - if (!this.isDesktop) { + if (!this.runtime.supportsEpg) { return of(new Map()); } @@ -263,7 +263,7 @@ export class EpgService { getChannelMetadataForChannels( channelIds: string[] ): Observable> { - if (!this.isDesktop) { + if (!this.runtime.supportsEpg) { return of(new Map()); }