refactor(epg): use runtime capability for desktop guards

This commit is contained in:
4gray committed 2026-05-22 13:33:31 +03:00
1 parent 78a5a7af74
commit 096a8bb803
2 files changed
+32 -7

No files matched your search

@@ -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'])
+7 -7
View File
@@ -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<boolean>(false);
private currentEpgPrograms = new BehaviorSubject<EpgProgram[]>([]);
@@ -37,8 +39,6 @@ export class EpgService {
private programCache = new Map<string, CachedProgram>();
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<EpgProgram | null> {
if (!this.isDesktop || !channelId) {
if (!this.runtime.supportsEpg || !channelId) {
return of(null);
}
@@ -184,7 +184,7 @@ export class EpgService {
getCurrentProgramsForChannels(
channelIds: string[]
): Observable<Map<string, EpgProgram | null>> {
if (!this.isDesktop) {
if (!this.runtime.supportsEpg) {
return of(new Map());
}
@@ -263,7 +263,7 @@ export class EpgService {
getChannelMetadataForChannels(
channelIds: string[]
): Observable<Map<string, EpgChannelMetadata | null>> {
if (!this.isDesktop) {
if (!this.runtime.supportsEpg) {
return of(new Map());
}