From e97fc36290920514e3a614a1fa239976867a707c Mon Sep 17 00:00:00 2001 From: 4gray Date: Wed, 29 Dec 2021 11:39:16 +0100 Subject: [PATCH] test: update jest config and fix test issues --- jest.config.js | 14 +++ src/app/app.component.spec.ts | 100 +++++++++--------- .../file-upload/file-upload.component.spec.ts | 5 +- .../playlist-info.component.spec.ts | 10 +- .../recent-playlists.component.spec.ts | 13 ++- .../url-upload/url-upload.component.spec.ts | 7 +- .../channel-list-container.component.spec.ts | 15 ++- .../epg-list-item.component.spec.ts | 5 +- .../epg-list/epg-list.component.spec.ts | 14 +-- .../html-video-player.component.spec.ts | 10 +- .../video-player.component.spec.ts | 15 +-- src/app/services/dialog.service.spec.ts | 4 +- src/app/services/settings.service.spec.ts | 10 +- src/app/services/whats-new.service.spec.ts | 2 +- src/app/settings/settings.component.spec.ts | 32 +++--- src/setup-jest.ts | 1 + src/setupJest.ts | 1 - 17 files changed, 138 insertions(+), 120 deletions(-) create mode 100644 jest.config.js create mode 100644 src/setup-jest.ts delete mode 100644 src/setupJest.ts diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000..79e901f14 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,14 @@ +module.exports = { + "preset": "jest-preset-angular", + "resetMocks": true, + "setupFilesAfterEnv": [ + "/src/setup-jest.ts" + ], + "testMatch": [ + "**/+(*.)+(spec|test).+(ts)?(x)" + ], + "coverageReporters": [ + "html", + "lcov" + ] +}; \ No newline at end of file diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 11819a7e8..45ffee79b 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -7,14 +7,10 @@ import { } from '@angular/core/testing'; import { RouterTestingModule } from '@angular/router/testing'; import { AppComponent } from './app.component'; -import { - TranslateModule, - TranslatePipe, - TranslateService, -} from '@ngx-translate/core'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ElectronServiceStub } from './services/electron.service.stub'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; -import { MockModule, MockPipe } from 'ng-mocks'; +import { MockModule, MockPipe, MockProviders } from 'ng-mocks'; import { of } from 'rxjs'; import { WhatsNewService } from './services/whats-new.service'; import { Theme } from './settings/theme.enum'; @@ -40,6 +36,8 @@ class MatSnackBarStub { open(): void {} } +jest.spyOn(global.console, 'error').mockImplementation(() => {}); + describe('AppComponent', () => { let component: AppComponent; let electronService: DataService; @@ -56,7 +54,7 @@ describe('AppComponent', () => { providers: [ { provide: MatSnackBar, useClass: MatSnackBarStub }, { provide: WhatsNewService, useClass: WhatsNewServiceStub }, - TranslateService, + MockProviders(TranslateService), SettingsService, // TODO: stub { provide: DataService, @@ -67,7 +65,6 @@ describe('AppComponent', () => { MockModule(MatSnackBarModule), MockModule(NgxWhatsNewModule), RouterTestingModule, - TranslateModule.forRoot(), ], }).compileComponents(); }) @@ -85,8 +82,8 @@ describe('AppComponent', () => { }); it('should create the component and set default language', () => { - spyOn(translateService, 'setDefaultLang'); - spyOn(component, 'setRendererListeners'); + jest.spyOn(translateService, 'setDefaultLang'); + jest.spyOn(component, 'setRendererListeners'); const fixture = TestBed.createComponent(AppComponent); const app = fixture.debugElement.componentInstance; expect(app).toBeTruthy(); @@ -94,10 +91,10 @@ describe('AppComponent', () => { }); it('should init component', () => { - spyOn(translateService, 'setDefaultLang'); - spyOn(component, 'setRendererListeners'); - spyOn(component, 'initSettings'); - spyOn(component, 'handleWhatsNewDialog'); + jest.spyOn(translateService, 'setDefaultLang'); + jest.spyOn(component, 'setRendererListeners'); + jest.spyOn(component, 'initSettings'); + jest.spyOn(component, 'handleWhatsNewDialog'); component.ngOnInit(); expect(translateService.setDefaultLang).toHaveBeenCalledWith( defaultLanguage @@ -109,13 +106,13 @@ describe('AppComponent', () => { describe('Test ipc listeners and commands', () => { it('should set IPC listeners', () => { - spyOn(electronService, 'listenOn'); + jest.spyOn(electronService, 'listenOn'); component.setRendererListeners(); expect(electronService.listenOn).toHaveBeenCalledTimes(5); }); it('should remove all ipc listeners on destroy', () => { - spyOn(electronService, 'removeAllListeners'); + jest.spyOn(electronService, 'removeAllListeners'); component.ngOnDestroy(); expect(electronService.removeAllListeners).toHaveBeenCalledTimes(4); }); @@ -124,7 +121,7 @@ describe('AppComponent', () => { [Router], (router: Router) => { const route = '/add-playlists'; - spyOn(router, 'navigateByUrl'); + jest.spyOn(router, 'navigateByUrl'); component.navigateToRoute(route); expect(router.navigateByUrl).toHaveBeenCalledTimes(1); expect(router.navigateByUrl).toHaveBeenCalledWith( @@ -137,7 +134,7 @@ describe('AppComponent', () => { it('should show a notification on epg error', inject( [MatSnackBar], (snackbar: MatSnackBar) => { - spyOn(snackbar, 'open'); + jest.spyOn(snackbar, 'open'); component.onEpgError(); expect(snackbar.open).toHaveBeenCalledTimes(1); } @@ -146,8 +143,8 @@ describe('AppComponent', () => { it('should handle epg download success', inject( [MatSnackBar, ChannelStore], (snackbar: MatSnackBar, channelStore: ChannelStore) => { - spyOn(snackbar, 'open'); - spyOn(channelStore, 'setEpgAvailableFlag'); + jest.spyOn(snackbar, 'open'); + jest.spyOn(channelStore, 'setEpgAvailableFlag'); component.onEpgFetchDone(); expect(snackbar.open).toHaveBeenCalledTimes(1); expect(channelStore.setEpgAvailableFlag).toHaveBeenCalledWith( @@ -157,8 +154,8 @@ describe('AppComponent', () => { )); it('show show whats new dialog', () => { - spyOn(whatsNewService, 'getModalsByVersion'); - spyOn(component, 'setDialogVisibility'); + jest.spyOn(whatsNewService, 'getModalsByVersion'); + jest.spyOn(component, 'setDialogVisibility'); component.showWhatsNewDialog(); expect(whatsNewService.getModalsByVersion).toHaveBeenCalledTimes(1); expect(component.setDialogVisibility).toHaveBeenCalledWith(true); @@ -168,12 +165,13 @@ describe('AppComponent', () => { describe('Test version handling', () => { it('should get actual app version which is outdated and show updates dialog', () => { const currentAppVersion = '0.0.1'; - const spyOnSettingsGet = spyOn( - settingsService, - 'getValueFromLocalStorage' - ).and.returnValue(of(currentAppVersion)); - spyOn(whatsNewService, 'getModalsByVersion').and.returnValue([{}]); - spyOn(whatsNewService, 'changeDialogVisibleState'); + const spyOnSettingsGet = jest + .spyOn(settingsService, 'getValueFromLocalStorage') + .mockReturnValue(of(currentAppVersion)); + jest.spyOn(whatsNewService, 'getModalsByVersion').mockReturnValue([ + {}, + ]); + jest.spyOn(whatsNewService, 'changeDialogVisibleState'); component.handleWhatsNewDialog(); expect(spyOnSettingsGet).toHaveBeenCalled(); @@ -185,12 +183,13 @@ describe('AppComponent', () => { it('should get actual app version which is not outdated and do not shop updates dialog', () => { const currentAppVersion = '1.0.0'; - const spyOnSettingsGet = spyOn( - settingsService, - 'getValueFromLocalStorage' - ).and.returnValue(of(currentAppVersion)); - spyOn(whatsNewService, 'getModalsByVersion').and.returnValue([{}]); - spyOn(whatsNewService, 'changeDialogVisibleState'); + const spyOnSettingsGet = jest + .spyOn(settingsService, 'getValueFromLocalStorage') + .mockReturnValue(of(currentAppVersion)); + jest.spyOn(whatsNewService, 'getModalsByVersion').mockReturnValue([ + {}, + ]); + jest.spyOn(whatsNewService, 'changeDialogVisibleState'); component.handleWhatsNewDialog(); expect(spyOnSettingsGet).toHaveBeenCalled(); @@ -201,7 +200,7 @@ describe('AppComponent', () => { }); it('should change the visibility of the whats new dialog', () => { - spyOn(whatsNewService, 'changeDialogVisibleState'); + jest.spyOn(whatsNewService, 'changeDialogVisibleState'); component.modals = [{}, {}]; const visibilityFlag = true; component.setDialogVisibility(true); @@ -215,7 +214,7 @@ describe('AppComponent', () => { }); it('should not change the visibility of the whats new dialog', () => { - spyOn(whatsNewService, 'changeDialogVisibleState'); + jest.spyOn(whatsNewService, 'changeDialogVisibleState'); component.modals = []; component.setDialogVisibility(true); expect( @@ -230,17 +229,16 @@ describe('AppComponent', () => { const epgUrl = 'http://localhost/epg.xml'; beforeEach(() => { - spyOn(electronService, 'sendIpcEvent'); - spyOn(settingsService, 'changeTheme'); - spyOn(component, 'handleWhatsNewDialog'); - spyOn(translateService, 'use'); + jest.spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(settingsService, 'changeTheme'); + jest.spyOn(component, 'handleWhatsNewDialog'); + jest.spyOn(translateService, 'use'); }); it('should get and init settings (all settings are defined)', () => { - const spyOnSettingsGet = spyOn( - settingsService, - 'getValueFromLocalStorage' - ).and.returnValue(of({ theme, epgUrl, language })); + const spyOnSettingsGet = jest + .spyOn(settingsService, 'getValueFromLocalStorage') + .mockReturnValue(of({ theme, epgUrl, language })); component.initSettings(); @@ -251,10 +249,9 @@ describe('AppComponent', () => { }); it('should get and init settings (nothing is defined)', () => { - const spyOnSettingsGet = spyOn( - settingsService, - 'getValueFromLocalStorage' - ).and.returnValue(of()); + const spyOnSettingsGet = jest + .spyOn(settingsService, 'getValueFromLocalStorage') + .mockReturnValue(of()); component.initSettings(); @@ -265,10 +262,9 @@ describe('AppComponent', () => { }); it('should get and init settings (only theme is defined)', () => { - const spyOnSettingsGet = spyOn( - settingsService, - 'getValueFromLocalStorage' - ).and.returnValue(of({ theme })); + const spyOnSettingsGet = jest + .spyOn(settingsService, 'getValueFromLocalStorage') + .mockReturnValue(of({ theme })); component.initSettings(); diff --git a/src/app/home/file-upload/file-upload.component.spec.ts b/src/app/home/file-upload/file-upload.component.spec.ts index f17ef1ca2..2839172aa 100644 --- a/src/app/home/file-upload/file-upload.component.spec.ts +++ b/src/app/home/file-upload/file-upload.component.spec.ts @@ -14,7 +14,10 @@ describe('FileUploadComponent', () => { waitForAsync(() => { TestBed.configureTestingModule({ declarations: [FileUploadComponent, MockPipe(TranslatePipe)], - imports: [MockModule(MatIconModule), NgxUploaderModule], + imports: [ + MockModule(MatIconModule), + MockModule(NgxUploaderModule), + ], providers: [ { provide: TranslateService, diff --git a/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts b/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts index 92f51582b..0ffbd72c0 100644 --- a/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts +++ b/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts @@ -2,7 +2,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; import { PLAYLIST_SAVE_DETAILS } from './../../../../../shared/ipc-commands'; /* eslint-disable @typescript-eslint/unbound-method */ import { ElectronServiceStub } from '../../../services/electron.service.stub'; -import { ElectronService } from './../../../services/electron.service'; +import { DataService } from '../../../services/data.service'; import { TranslatePipe } from '@ngx-translate/core'; import { MockModule, MockPipe } from 'ng-mocks'; import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; @@ -16,7 +16,7 @@ import { Playlist } from './../../../../../shared/playlist.interface'; describe('PlaylistInfoComponent', () => { let component: PlaylistInfoComponent; let fixture: ComponentFixture; - let electronService: ElectronService; + let electronService: DataService; beforeEach( waitForAsync(() => { @@ -35,7 +35,7 @@ describe('PlaylistInfoComponent', () => { ], providers: [ { provide: MAT_DIALOG_DATA, useValue: {} }, - { provide: ElectronService, useClass: ElectronServiceStub }, + { provide: DataService, useClass: ElectronServiceStub }, FormBuilder, ], }).compileComponents(); @@ -45,7 +45,7 @@ describe('PlaylistInfoComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(PlaylistInfoComponent); component = fixture.componentInstance; - electronService = TestBed.inject(ElectronService); + electronService = TestBed.inject(DataService); fixture.detectChanges(); }); @@ -55,7 +55,7 @@ describe('PlaylistInfoComponent', () => { it('should send an event to the main process after save', () => { const playlistToSave = { _id: 'a12345', title: 'Playlist' } as Playlist; - spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(electronService, 'sendIpcEvent'); component.saveChanges(playlistToSave); expect(electronService.sendIpcEvent).toHaveBeenCalledTimes(1); expect(electronService.sendIpcEvent).toHaveBeenCalledWith( diff --git a/src/app/home/recent-playlists/recent-playlists.component.spec.ts b/src/app/home/recent-playlists/recent-playlists.component.spec.ts index 93f11e354..0fc9ab2db 100644 --- a/src/app/home/recent-playlists/recent-playlists.component.spec.ts +++ b/src/app/home/recent-playlists/recent-playlists.component.spec.ts @@ -1,7 +1,7 @@ import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { MockModule, MockPipe, MockProvider } from 'ng-mocks'; -import { ElectronService } from '../../services/electron.service'; +import { DataService } from '../../services/data.service'; import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { RecentPlaylistsComponent } from './recent-playlists.component'; import { PlaylistMeta } from '../home.component'; @@ -13,7 +13,7 @@ import { ElectronServiceStub } from '../../services/electron.service.stub'; describe('RecentPlaylistsComponent', () => { let component: RecentPlaylistsComponent; let fixture: ComponentFixture; - let electronService: ElectronService; + let electronService: DataService; let dialog: MatDialog; beforeEach( @@ -30,7 +30,7 @@ describe('RecentPlaylistsComponent', () => { MockModule(MatTooltipModule), ], providers: [ - { provide: ElectronService, useClass: ElectronServiceStub }, + { provide: DataService, useClass: ElectronServiceStub }, MockProvider(TranslateService), ], }).compileComponents(); @@ -42,8 +42,7 @@ describe('RecentPlaylistsComponent', () => { component = fixture.componentInstance; component.playlists = []; dialog = TestBed.inject(MatDialog); - electronService = TestBed.inject(ElectronService); - TestBed.inject(ElectronService); + electronService = TestBed.inject(DataService); fixture.detectChanges(); }); @@ -52,7 +51,7 @@ describe('RecentPlaylistsComponent', () => { }); it('should open the info dialog', () => { - spyOn(dialog, 'open'); + jest.spyOn(dialog, 'open'); component.openInfoDialog({} as PlaylistMeta); expect(dialog.open).toHaveBeenCalledTimes(1); }); @@ -68,7 +67,7 @@ describe('RecentPlaylistsComponent', () => { distance: { x: 0, y: 0 }, dropPoint: { x: 0, y: 0 }, }; - spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(electronService, 'sendIpcEvent'); component.drop(event); expect(electronService.sendIpcEvent).toHaveBeenCalledTimes(1); }); diff --git a/src/app/home/url-upload/url-upload.component.spec.ts b/src/app/home/url-upload/url-upload.component.spec.ts index d22348ff5..bc41c779e 100644 --- a/src/app/home/url-upload/url-upload.component.spec.ts +++ b/src/app/home/url-upload/url-upload.component.spec.ts @@ -39,11 +39,10 @@ describe('UrlUploadComponent', () => { it( 'submit form with playlist url', waitForAsync(() => { - spyOn(component.urlAdded, 'emit'); + jest.spyOn(component.urlAdded, 'emit'); const TEST_URL = 'http://example.org/playlist.m3u'; - const submitButton = fixture.debugElement.nativeElement.querySelector( - 'button' - ); + const submitButton = + fixture.debugElement.nativeElement.querySelector('button'); // test input field validation expect(submitButton.disabled).toBeTruthy(); diff --git a/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts b/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts index 4b131ec0d..bddf41b42 100644 --- a/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts +++ b/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts @@ -11,16 +11,16 @@ import { MatIconModule } from '@angular/material/icon'; import { MatListModule } from '@angular/material/list'; import { MatTabsModule } from '@angular/material/tabs'; import { MatExpansionModule } from '@angular/material/expansion'; -import { MockModule, MockPipe } from 'ng-mocks'; +import { MockModule, MockPipe, MockPipes } from 'ng-mocks'; import { FormsModule } from '@angular/forms'; import { RouterTestingModule } from '@angular/router/testing'; -import { FilterPipeModule } from 'ngx-filter-pipe'; +import { FilterPipe, FilterPipeModule } from 'ngx-filter-pipe'; import { By } from '@angular/platform-browser'; import { createChannel } from '../../../state'; import * as MOCKED_PLAYLIST from '../../../../mocks/playlist.json'; -import { ElectronService } from '../../../services/electron.service'; import { ElectronServiceStub } from '../../../services/electron.service.stub'; import { ScrollingModule } from '@angular/cdk/scrolling'; +import { DataService } from '../../../services/data.service'; class MatSnackBarStub { open(): void {} @@ -35,12 +35,12 @@ describe('ChannelListContainerComponent', () => { TestBed.configureTestingModule({ declarations: [ ChannelListContainerComponent, - MockPipe(TranslatePipe), + MockPipes(TranslatePipe, FilterPipe), ], providers: [ ChannelQuery, { provide: MatSnackBar, useClass: MatSnackBarStub }, - { provide: ElectronService, useClass: ElectronServiceStub }, + { provide: DataService, useClass: ElectronServiceStub }, ], imports: [ MockModule(MatSnackBarModule), @@ -53,7 +53,6 @@ describe('ChannelListContainerComponent', () => { MockModule(MatExpansionModule), FormsModule, RouterTestingModule, - FilterPipeModule, ], }).compileComponents(); }); @@ -146,14 +145,14 @@ describe('ChannelListContainerComponent', () => { }); it('should update store after channel was selected', () => { - spyOn(store, 'update'); + jest.spyOn(store, 'update'); component.selectChannel(component._channelList[0]); fixture.detectChanges(); expect(store.update).toHaveBeenCalledTimes(1); }); it('should update store after channel was favorited', () => { - spyOn(store, 'updateFavorite'); + jest.spyOn(store, 'updateFavorite'); component.toggleFavoriteChannel( component._channelList[0], new MouseEvent('click') diff --git a/src/app/player/components/epg-list/epg-list-item/epg-list-item.component.spec.ts b/src/app/player/components/epg-list/epg-list-item/epg-list-item.component.spec.ts index 4060e501b..aeb047107 100644 --- a/src/app/player/components/epg-list/epg-list-item/epg-list-item.component.spec.ts +++ b/src/app/player/components/epg-list/epg-list-item/epg-list-item.component.spec.ts @@ -20,8 +20,7 @@ const EPG_PROGRAM_ITEM = { desc: [ { lang: 'en', - value: - "Jordan's Queen Rania has made job creation a priority to help curb the staggering unemployment rates among youths in the Middle East.", + value: "Jordan's Queen Rania has made job creation a priority to help curb the staggering unemployment rates among youths in the Middle East.", }, ], date: ['20080711'], @@ -93,7 +92,7 @@ describe('EpgListItemComponent', () => { }); it('should trigger the function to open the details dialog', () => { - spyOn(dialog, 'open'); + jest.spyOn(dialog, 'open'); component.showDescription({} as EpgProgram); expect(dialog.open).toHaveBeenCalledTimes(1); expect(dialog.open).toHaveBeenCalledWith(EpgItemDescriptionComponent, { diff --git a/src/app/player/components/epg-list/epg-list.component.spec.ts b/src/app/player/components/epg-list/epg-list.component.spec.ts index 861fab1d2..1455791c6 100644 --- a/src/app/player/components/epg-list/epg-list.component.spec.ts +++ b/src/app/player/components/epg-list/epg-list.component.spec.ts @@ -6,7 +6,7 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { EpgListComponent, EpgData } from './epg-list.component'; import { MatListModule } from '@angular/material/list'; -import { ElectronService } from '../../../services/electron.service'; +import { DataService } from '../../../services/data.service'; import { ElectronServiceStub } from '../../../services/electron.service.stub'; import * as moment from 'moment'; import { EPG_GET_PROGRAM_DONE } from '../../../../../shared/ipc-commands'; @@ -18,7 +18,7 @@ import { EpgListItemComponent } from './epg-list-item/epg-list-item.component'; describe('EpgListComponent', () => { let component: EpgListComponent; let fixture: ComponentFixture; - let electronService: ElectronService; + let electronService: DataService; let channelStore: ChannelStore; const MOCKED_PROGRAMS = { @@ -100,7 +100,7 @@ describe('EpgListComponent', () => { MockModule(MatDialogModule), ], providers: [ - { provide: ElectronService, useClass: ElectronServiceStub }, + { provide: DataService, useClass: ElectronServiceStub }, MockProvider(MatDialog), ], }).compileComponents(); @@ -110,7 +110,7 @@ describe('EpgListComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(EpgListComponent); component = fixture.componentInstance; - electronService = TestBed.inject(ElectronService); + electronService = TestBed.inject(DataService); channelStore = TestBed.inject(ChannelStore); channelStore.setActiveChannel({ id: '', @@ -148,7 +148,7 @@ describe('EpgListComponent', () => { }); it('should remove ipc listeners on destroy', () => { - spyOn(electronService, 'removeAllListeners'); + jest.spyOn(electronService, 'removeAllListeners'); component.ngOnDestroy(); expect(electronService.removeAllListeners).toHaveBeenCalledTimes(1); expect(electronService.removeAllListeners).toHaveBeenCalledWith( @@ -157,7 +157,7 @@ describe('EpgListComponent', () => { }); it('should set epg program as active', () => { - spyOn(channelStore, 'setActiveEpgProgram'); + jest.spyOn(channelStore, 'setActiveEpgProgram'); component.setEpgProgram(MOCKED_PROGRAMS.items[0], false, true); expect(channelStore.setActiveEpgProgram).toHaveBeenCalledTimes(1); expect(channelStore.setActiveEpgProgram).toHaveBeenCalledWith( @@ -166,7 +166,7 @@ describe('EpgListComponent', () => { }); it('should reset active epg program', () => { - spyOn(channelStore, 'resetActiveEpgProgram'); + jest.spyOn(channelStore, 'resetActiveEpgProgram'); component.setEpgProgram(MOCKED_PROGRAMS.items[0], true); expect(channelStore.resetActiveEpgProgram).toHaveBeenCalledTimes(1); component.setEpgProgram(MOCKED_PROGRAMS.items[0], true, true); diff --git a/src/app/player/components/html-video-player/html-video-player.component.spec.ts b/src/app/player/components/html-video-player/html-video-player.component.spec.ts index 8e5fd6570..09a5c1501 100644 --- a/src/app/player/components/html-video-player/html-video-player.component.spec.ts +++ b/src/app/player/components/html-video-player/html-video-player.component.spec.ts @@ -1,9 +1,7 @@ import { MockPipe } from 'ng-mocks'; import { TranslatePipe } from '@ngx-translate/core'; -/* eslint-disable @typescript-eslint/unbound-method */ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { SimpleChange } from '@angular/core'; - import { HtmlVideoPlayerComponent } from './html-video-player.component'; describe('HtmlVideoPlayerComponent', () => { @@ -40,13 +38,15 @@ describe('HtmlVideoPlayerComponent', () => { }); it('should call play channel function after input changes', () => { - spyOn(component, 'playChannel'); + jest.spyOn(component, 'playChannel'); + jest.spyOn(global.console, 'error').mockImplementation(() => {}); component.ngOnChanges({ channel: new SimpleChange(null, TEST_CHANNEL, true), }); fixture.detectChanges(); - expect(component.playChannel).toBeCalledTimes(1); - expect(component.playChannel).toBeCalledWith(TEST_CHANNEL); + expect(component.playChannel).toHaveBeenCalledTimes(1); + expect(component.playChannel).toHaveBeenCalledWith(TEST_CHANNEL); + expect(console.error).toHaveBeenCalledTimes(1); }); }); diff --git a/src/app/player/components/video-player/video-player.component.spec.ts b/src/app/player/components/video-player/video-player.component.spec.ts index 4d2d69153..0e88adb4d 100644 --- a/src/app/player/components/video-player/video-player.component.spec.ts +++ b/src/app/player/components/video-player/video-player.component.spec.ts @@ -17,6 +17,8 @@ import { createChannel } from '../../../state'; import { HtmlVideoPlayerComponent } from '../html-video-player/html-video-player.component'; import { EpgListComponent } from '../epg-list/epg-list.component'; import { VideoPlayer } from '../../../settings/settings.interface'; +import { DataService } from '../../../services/data.service'; +import { ElectronServiceStub } from '../../../services/electron.service.stub'; class MatSnackBarStub { open(): void {} @@ -43,6 +45,7 @@ describe('VideoPlayerComponent', () => { ], providers: [ { provide: MatSnackBar, useClass: MatSnackBarStub }, + { provide: DataService, useClass: ElectronServiceStub }, ], imports: [ MockModule(MatSidenavModule), @@ -67,9 +70,9 @@ describe('VideoPlayerComponent', () => { it('should create and init component', () => { expect(component).toBeTruthy(); - spyOn(component, 'applySettings'); + jest.spyOn(component, 'applySettings'); fixture.detectChanges(); - expect(component.applySettings).toBeCalledTimes(1); + expect(component.applySettings).toHaveBeenCalledTimes(1); }); it('should check default component settings', () => { @@ -81,11 +84,11 @@ describe('VideoPlayerComponent', () => { }); it('should update store after channel was faved', () => { - spyOn(store, 'updateFavorite'); + jest.spyOn(store, 'updateFavorite'); const [firstChannel] = channels; component.addToFavorites(firstChannel); - fixture.detectChanges(); - expect(store.updateFavorite).toBeCalledTimes(1); - expect(store.updateFavorite).toBeCalledWith(firstChannel); + //fixture.detectChanges(); + expect(store.updateFavorite).toHaveBeenCalledTimes(1); + expect(store.updateFavorite).toHaveBeenCalledWith(firstChannel); }); }); diff --git a/src/app/services/dialog.service.spec.ts b/src/app/services/dialog.service.spec.ts index 716a5fe78..0898a08df 100644 --- a/src/app/services/dialog.service.spec.ts +++ b/src/app/services/dialog.service.spec.ts @@ -25,7 +25,9 @@ describe('Service: Dialog', () => { it('should open a confirm dialog', inject( [MatDialog, DialogService], (dialog: MatDialog, service: DialogService) => { - spyOn(dialog, 'open').and.returnValue({ afterClosed: () => EMPTY }); + jest.spyOn(dialog, 'open').mockReturnValue({ + afterClosed: () => EMPTY, + } as any); service.openConfirmDialog({ title: 'Remove dialog', message: 'Message', diff --git a/src/app/services/settings.service.spec.ts b/src/app/services/settings.service.spec.ts index ec8f01f1f..3c448c60d 100644 --- a/src/app/services/settings.service.spec.ts +++ b/src/app/services/settings.service.spec.ts @@ -23,7 +23,7 @@ describe('Service: Settings', () => { [SettingsService, StorageMap], (service: SettingsService, storage: StorageMap) => { const version = '2.1.0'; - spyOn(storage, 'set').and.returnValue(of([])); + jest.spyOn(storage, 'set').mockReturnValue(of([] as any)); service.setValueToLocalStorage(STORE_KEY.Version, version); expect(storage.set).toHaveBeenCalledWith( STORE_KEY.Version, @@ -48,10 +48,14 @@ describe('Service: Settings', () => { describe('Test theme switch', () => { let spyOnAdd, spyOnRemove; beforeEach(() => { - spyOnAdd = spyOn(document.body.classList, 'add'); - spyOnRemove = spyOn(document.body.classList, 'remove'); + spyOnAdd = jest.spyOn(document.body.classList, 'add'); + spyOnRemove = jest.spyOn(document.body.classList, 'remove'); }); + /* afterEach(() => { + jest.clearAllMocks(); + }); */ + it('should switch to the dark theme', inject( [SettingsService], (service: SettingsService) => { diff --git a/src/app/services/whats-new.service.spec.ts b/src/app/services/whats-new.service.spec.ts index aafd2c3a3..bc36c6cfa 100644 --- a/src/app/services/whats-new.service.spec.ts +++ b/src/app/services/whats-new.service.spec.ts @@ -16,7 +16,7 @@ describe('Service: WhatsNew', () => { it('should change the state', inject( [WhatsNewService], (service: WhatsNewService) => { - spyOn(service.dialogState$, 'next'); + jest.spyOn(service.dialogState$, 'next'); service.changeDialogVisibleState(true); expect(service.dialogState$.next).toHaveBeenCalledTimes(1); expect(service.dialogState$.next).toHaveBeenCalledWith(true); diff --git a/src/app/settings/settings.component.spec.ts b/src/app/settings/settings.component.spec.ts index 4b41143bc..f23f30ba0 100644 --- a/src/app/settings/settings.component.spec.ts +++ b/src/app/settings/settings.component.spec.ts @@ -1,7 +1,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; import { StorageMap } from '@ngx-pwa/local-storage'; /* eslint-disable @typescript-eslint/unbound-method */ -import { ElectronService } from './../services/electron.service'; +import { DataService } from '../services/data.service'; import { ElectronServiceStub } from '../services/electron.service.stub'; import { MatSelectModule } from '@angular/material/select'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -47,7 +47,7 @@ const DEFAULT_SETTINGS = { describe('SettingsComponent', () => { let component: SettingsComponent; let fixture: ComponentFixture; - let electronService: ElectronService; + let electronService: DataService; let router: Router; let storage: StorageMap; let translate: TranslateService; @@ -67,7 +67,7 @@ describe('SettingsComponent', () => { provide: TranslateService, useClass: TranslateServiceStub, }, - { provide: ElectronService, useClass: ElectronServiceStub }, + { provide: DataService, useClass: ElectronServiceStub }, { provide: Router, useClass: MockRouter, @@ -93,7 +93,7 @@ describe('SettingsComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(SettingsComponent); - electronService = TestBed.inject(ElectronService); + electronService = TestBed.inject(DataService); storage = TestBed.inject(StorageMap); router = TestBed.inject(Router); translate = TestBed.inject(TranslateService); @@ -110,12 +110,12 @@ describe('SettingsComponent', () => { let spyOnStorageGet; beforeEach(() => { - spyOnStorageGet = spyOn(storage, 'get'); + spyOnStorageGet = jest.spyOn(storage, 'get'); }); it('should init default settings if previous config was not saved', () => { - spyOnStorageGet.and.returnValue(of(null)); - spyOn(component.settingsForm, 'setValue'); + spyOnStorageGet.mockReturnValue(of(null)); + jest.spyOn(component.settingsForm, 'setValue'); component.ngOnInit(); expect(storage.get).toHaveBeenCalled(); expect(component.settingsForm.setValue).toHaveBeenCalledTimes(0); @@ -123,14 +123,14 @@ describe('SettingsComponent', () => { }); it('should call set value function if custom config exists', () => { - spyOnStorageGet.and.returnValue(of(settings)); - spyOn(component.settingsForm, 'setValue'); + spyOnStorageGet.mockReturnValue(of(settings)); + jest.spyOn(component.settingsForm, 'setValue'); component.ngOnInit(); expect(component.settingsForm.setValue).toHaveBeenCalled(); }); it('should get and apply custom settings', () => { - spyOnStorageGet.and.returnValue(of(settings)); + spyOnStorageGet.mockReturnValue(of(settings)); component.ngOnInit(); expect(storage.get).toHaveBeenCalled(); expect(component.settingsForm.value).toEqual({ @@ -145,7 +145,7 @@ describe('SettingsComponent', () => { const currentVersion = '0.1.0'; it('should return true if version is outdated', () => { - spyOn(electronService, 'getAppVersion').and.returnValue( + jest.spyOn(electronService, 'getAppVersion').mockReturnValue( currentVersion ); const isOutdated = @@ -154,8 +154,8 @@ describe('SettingsComponent', () => { }); it('should update notification message if version is outdated', () => { - spyOn(translate, 'instant'); - spyOn(electronService, 'getAppVersion').and.returnValue( + jest.spyOn(translate, 'instant'); + jest.spyOn(electronService, 'getAppVersion').mockReturnValue( currentVersion ); component.showVersionInformation(currentVersion); @@ -165,7 +165,7 @@ describe('SettingsComponent', () => { }); it('should send epg fetch command', () => { - spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(electronService, 'sendIpcEvent'); component.fetchEpg(); expect(electronService.sendIpcEvent).toHaveBeenCalledWith(EPG_FETCH, { url: '', @@ -173,13 +173,13 @@ describe('SettingsComponent', () => { }); it('should navigate back to home page', () => { - spyOn(router, 'navigateByUrl'); + jest.spyOn(router, 'navigateByUrl'); component.backToHome(); expect(router.navigateByUrl).toHaveBeenCalledTimes(1); }); it('should save settings on submit', () => { - spyOn(storage, 'set').and.returnValue(of([])); + jest.spyOn(storage, 'set').mockReturnValue(of([] as any)); component.onSubmit(); expect(storage.set).toHaveBeenCalled(); }); diff --git a/src/setup-jest.ts b/src/setup-jest.ts new file mode 100644 index 000000000..1100b3e8a --- /dev/null +++ b/src/setup-jest.ts @@ -0,0 +1 @@ +import 'jest-preset-angular/setup-jest'; diff --git a/src/setupJest.ts b/src/setupJest.ts deleted file mode 100644 index 8d88704e8..000000000 --- a/src/setupJest.ts +++ /dev/null @@ -1 +0,0 @@ -import 'jest-preset-angular';