From 4043026d5613b05cacaaad51f7958b5e0b7320ee Mon Sep 17 00:00:00 2001 From: 4gray Date: Wed, 7 Dec 2022 20:07:26 +0100 Subject: [PATCH] test: replace akita store with ngrx --- src/app/app.component.spec.ts | 4 +- src/app/home/home.component.spec.ts | 14 +++++- .../channel-list-container.component.spec.ts | 47 ++++++++++--------- .../epg-list/epg-list.component.spec.ts | 47 ++++++++++++------- .../video-player.component.spec.ts | 26 ++++++---- src/app/services/epg.service.spec.ts | 11 +++-- src/app/settings/settings.component.spec.ts | 8 +++- 7 files changed, 97 insertions(+), 60 deletions(-) diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index cd3d1e932..8fba1cf11 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -3,11 +3,12 @@ import { ComponentFixture, inject, TestBed, - waitForAsync, + waitForAsync } from '@angular/core/testing'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; +import { provideMockStore } from '@ngrx/store/testing'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { MockModule, MockPipe, MockProviders } from 'ng-mocks'; import { NgxWhatsNewModule } from 'ngx-whats-new'; @@ -50,6 +51,7 @@ describe('AppComponent', () => { provide: DataService, useClass: ElectronServiceStub, }, + provideMockStore(), ], imports: [ MockModule(MatSnackBarModule), diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts index 152481069..0adcc4ae3 100644 --- a/src/app/home/home.component.spec.ts +++ b/src/app/home/home.component.spec.ts @@ -5,10 +5,13 @@ import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; import { MatTabsModule } from '@angular/material/tabs'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; +import { Actions } from '@ngrx/effects'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { MockComponent, MockModule, MockPipe, MockProvider } from 'ng-mocks'; import { NgxIndexedDBModule, NgxIndexedDBService } from 'ngx-indexed-db'; -import { of } from 'rxjs'; +import { Observable, of } from 'rxjs'; import { FileUploadComponent } from '../home/file-upload/file-upload.component'; import { RecentPlaylistsComponent } from '../home/recent-playlists/recent-playlists.component'; import { UrlUploadComponent } from '../home/url-upload/url-upload.component'; @@ -17,7 +20,7 @@ import { ElectronServiceStub } from '../services/electron.service.stub'; import { HeaderComponent } from '../shared/components/header/header.component'; import { PLAYLIST_PARSE, - PLAYLIST_PARSE_BY_URL, + PLAYLIST_PARSE_BY_URL } from './../../../shared/ipc-commands'; import { HomeComponent } from './home.component'; @@ -36,6 +39,8 @@ describe('HomeComponent', () => { let fixture: ComponentFixture; let electronService: DataService; let router: Router; + let mockStore: MockStore; + const actions$ = new Observable(); beforeEach(() => { TestBed.configureTestingModule({ @@ -63,6 +68,8 @@ describe('HomeComponent', () => { provide: NgxIndexedDBService, useClass: NgxIndexedDBServiceStub, }, + provideMockStore(), + provideMockActions(actions$), ], }).compileComponents(); }); @@ -72,6 +79,9 @@ describe('HomeComponent', () => { component = fixture.componentInstance; electronService = TestBed.inject(DataService); + mockStore = TestBed.inject(MockStore); + mockStore.setState({}); + router = TestBed.inject(Router); TestBed.inject(NgxIndexedDBService); fixture.detectChanges(); 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 b917dee23..6905daf4d 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 @@ -10,15 +10,17 @@ import { MatTabsModule } from '@angular/material/tabs'; import { MatTooltipModule } from '@angular/material/tooltip'; import { By } from '@angular/platform-browser'; import { RouterTestingModule } from '@angular/router/testing'; +import { Actions } from '@ngrx/effects'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslatePipe } from '@ngx-translate/core'; import { MockModule, MockPipes } from 'ng-mocks'; +import { Observable } from 'rxjs'; import * as MOCKED_PLAYLIST from '../../../../mocks/playlist.json'; import { DataService } from '../../../services/data.service'; import { ElectronServiceStub } from '../../../services/electron.service.stub'; +import { createChannel } from '../../../shared/channel.model'; import { FilterPipe } from '../../../shared/pipes/filter.pipe'; -import { createChannel } from '../../../state'; -import { ChannelQuery } from '../../../state/channel.query'; -import { ChannelStore } from '../../../state/channel.store'; import { ChannelListContainerComponent } from './channel-list-container.component'; class MatSnackBarStub { @@ -28,7 +30,8 @@ class MatSnackBarStub { describe('ChannelListContainerComponent', () => { let component: ChannelListContainerComponent; let fixture: ComponentFixture; - let store: ChannelStore; + let mockStore: MockStore; + const actions$ = new Observable(); beforeEach(() => { TestBed.configureTestingModule({ @@ -37,9 +40,10 @@ describe('ChannelListContainerComponent', () => { MockPipes(TranslatePipe, FilterPipe), ], providers: [ - ChannelQuery, { provide: MatSnackBar, useClass: MatSnackBarStub }, { provide: DataService, useClass: ElectronServiceStub }, + provideMockStore(), + provideMockActions(actions$), ], imports: [ MockModule(MatSnackBarModule), @@ -59,25 +63,22 @@ describe('ChannelListContainerComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(ChannelListContainerComponent); component = fixture.componentInstance; - TestBed.inject(ChannelQuery); - store = TestBed.inject(ChannelStore); - store.update({ - favorites: [], - playlistId: '', - active: undefined, - }); + mockStore = TestBed.inject(MockStore); // set channels const channels = MOCKED_PLAYLIST.playlist.items.map((element) => createChannel(element) ); - store.upsertMany(channels); - component.channelList = channels; - // set favorites - store.update({ - favorites: [MOCKED_PLAYLIST.playlist.items[0].url], + mockStore.setState({ + playlistState: { + channels, + favorites: [MOCKED_PLAYLIST.playlist.items[0].url], + playlistId: '', + active: undefined, + }, }); + component.channelList = channels; fixture.detectChanges(); }); @@ -144,22 +145,22 @@ describe('ChannelListContainerComponent', () => { }); it('should update store after channel was selected', () => { - jest.spyOn(store, 'update'); + jest.spyOn(mockStore, 'dispatch'); component.selectChannel(component._channelList[0]); fixture.detectChanges(); - expect(store.update).toHaveBeenCalledTimes(1); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); }); it('should update store after channel was favorited', () => { - jest.spyOn(store, 'updateFavorite'); + jest.spyOn(mockStore, 'dispatch'); component.toggleFavoriteChannel( component._channelList[0], new MouseEvent('click') ); fixture.detectChanges(); - expect(store.updateFavorite).toHaveBeenCalledWith( - component._channelList[0] + expect(mockStore.dispatch).toHaveBeenCalledWith( + {channel: component._channelList[0], type: expect.stringContaining('favorites')}, ); - expect(store.updateFavorite).toHaveBeenCalledTimes(1); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); }); }); 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 a9c4d6446..88cf50fca 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 @@ -4,15 +4,18 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { MatIconModule } from '@angular/material/icon'; import { MatListModule } from '@angular/material/list'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { Actions } from '@ngrx/effects'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslatePipe } from '@ngx-translate/core'; import * as moment from 'moment'; import { MockComponent, MockModule, MockPipe, MockProvider } from 'ng-mocks'; +import { Observable } from 'rxjs'; import { Channel } from '../../../../../shared/channel.interface'; import { EPG_GET_PROGRAM_DONE } from '../../../../../shared/ipc-commands'; import { DataService } from '../../../services/data.service'; import { ElectronServiceStub } from '../../../services/electron.service.stub'; import { MomentDatePipe } from '../../../shared/pipes/moment-date.pipe'; -import { ChannelStore } from '../../../state'; import { EpgListItemComponent } from './epg-list-item/epg-list-item.component'; import { EpgData, EpgListComponent } from './epg-list.component'; @@ -20,7 +23,8 @@ describe('EpgListComponent', () => { let component: EpgListComponent; let fixture: ComponentFixture; let electronService: DataService; - let channelStore: ChannelStore; + let mockStore: MockStore; + const actions$ = new Observable(); const MOCKED_PROGRAMS = { channel: { @@ -103,6 +107,8 @@ describe('EpgListComponent', () => { providers: [ { provide: DataService, useClass: ElectronServiceStub }, MockProvider(MatDialog), + provideMockStore(), + provideMockActions(actions$), ], }).compileComponents(); }) @@ -112,16 +118,21 @@ describe('EpgListComponent', () => { fixture = TestBed.createComponent(EpgListComponent); component = fixture.componentInstance; electronService = TestBed.inject(DataService); - channelStore = TestBed.inject(ChannelStore); - channelStore.setActiveChannel({ - id: '', - url: '', - name: '', - group: { title: '' }, - tvg: { - rec: '3', + + mockStore = TestBed.inject(MockStore); + mockStore.setState({ + playlistState: { + active: { + id: '', + url: '', + name: '', + group: { title: '' }, + tvg: { + rec: '3', + }, + } as unknown as Channel, }, - } as unknown as Channel); + }); fixture.detectChanges(); }); @@ -158,19 +169,19 @@ describe('EpgListComponent', () => { }); it('should set epg program as active', () => { - jest.spyOn(channelStore, 'setActiveEpgProgram'); + jest.spyOn(mockStore, 'dispatch'); component.setEpgProgram(MOCKED_PROGRAMS.items[0], false, true); - expect(channelStore.setActiveEpgProgram).toHaveBeenCalledTimes(1); - expect(channelStore.setActiveEpgProgram).toHaveBeenCalledWith( - MOCKED_PROGRAMS.items[0] + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); + expect(mockStore.dispatch).toHaveBeenCalledWith( + {program: MOCKED_PROGRAMS.items[0], type: expect.stringContaining('epg program')} ); }); it('should reset active epg program', () => { - jest.spyOn(channelStore, 'resetActiveEpgProgram'); + jest.spyOn(mockStore, 'dispatch'); component.setEpgProgram(MOCKED_PROGRAMS.items[0], true); - expect(channelStore.resetActiveEpgProgram).toHaveBeenCalledTimes(1); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); component.setEpgProgram(MOCKED_PROGRAMS.items[0], true, true); - expect(channelStore.resetActiveEpgProgram).toHaveBeenCalledTimes(2); + expect(mockStore.dispatch).toHaveBeenCalledTimes(2); }); }); 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 49c1115e8..c03594a08 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 @@ -7,14 +7,14 @@ import { MatToolbarModule } from '@angular/material/toolbar'; import { MatTooltipModule } from '@angular/material/tooltip'; import { ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslatePipe } from '@ngx-translate/core'; import { MockComponent, MockModule, MockPipe } from 'ng-mocks'; import * as MOCKED_PLAYLIST from '../../../../mocks/playlist.json'; import { DataService } from '../../../services/data.service'; import { ElectronServiceStub } from '../../../services/electron.service.stub'; import { VideoPlayer } from '../../../settings/settings.interface'; -import { createChannel } from '../../../state'; -import { ChannelStore } from '../../../state/channel.store'; +import { createChannel } from '../../../shared/channel.model'; import { ChannelListContainerComponent } from '../channel-list-container/channel-list-container.component'; import { EpgListComponent } from '../epg-list/epg-list.component'; import { HtmlVideoPlayerComponent } from '../html-video-player/html-video-player.component'; @@ -22,6 +22,10 @@ import { VjsPlayerComponent } from '../vjs-player/vjs-player.component'; import { InfoOverlayComponent } from './../info-overlay/info-overlay.component'; import { VideoPlayerComponent } from './video-player.component'; +import { Actions } from '@ngrx/effects'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { Observable } from 'rxjs'; + class MatSnackBarStub { open(): void {} } @@ -29,8 +33,9 @@ class MatSnackBarStub { describe('VideoPlayerComponent', () => { let component: VideoPlayerComponent; let fixture: ComponentFixture; - let store: ChannelStore; let channels; + let mockStore: MockStore; + const actions$ = new Observable(); beforeEach( waitForAsync(() => { @@ -58,6 +63,8 @@ describe('VideoPlayerComponent', () => { }, }, }, + provideMockStore(), + provideMockActions(actions$), ], imports: [ MockModule(MatSidenavModule), @@ -74,12 +81,14 @@ describe('VideoPlayerComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(VideoPlayerComponent); component = fixture.componentInstance; - store = TestBed.inject(ChannelStore); + mockStore = TestBed.inject(MockStore); + // set channels channels = MOCKED_PLAYLIST.playlist.items.map((element) => createChannel(element) ); - store.upsertMany(channels); + + mockStore.setState({ playlistState: {channels} }); }); it('should create and init component', () => { @@ -98,11 +107,10 @@ describe('VideoPlayerComponent', () => { }); it('should update store after channel was faved', () => { - jest.spyOn(store, 'updateFavorite'); + jest.spyOn(mockStore, 'dispatch'); const [firstChannel] = channels; component.addToFavorites(firstChannel); - //fixture.detectChanges(); - expect(store.updateFavorite).toHaveBeenCalledTimes(1); - expect(store.updateFavorite).toHaveBeenCalledWith(firstChannel); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); + expect(mockStore.dispatch).toHaveBeenCalledWith({channel: firstChannel, type: expect.stringContaining('favorite')}); }); }); diff --git a/src/app/services/epg.service.spec.ts b/src/app/services/epg.service.spec.ts index 00c18beb3..a62168c1c 100644 --- a/src/app/services/epg.service.spec.ts +++ b/src/app/services/epg.service.spec.ts @@ -1,8 +1,8 @@ import { inject, TestBed } from '@angular/core/testing'; import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslateService } from '@ngx-translate/core'; import { MockModule, MockProviders } from 'ng-mocks'; -import { ChannelStore } from '../state'; import { DataService } from './data.service'; import { EpgService } from './epg.service'; @@ -12,6 +12,7 @@ describe('EpgService', () => { providers: [ EpgService, MockProviders(DataService, TranslateService, MatSnackBar), + provideMockStore() ], imports: [MockModule(MatSnackBarModule)], }); @@ -34,17 +35,17 @@ describe('EpgService', () => { )); it('should handle epg download success', inject( - [MatSnackBar, ChannelStore, EpgService], + [MatSnackBar, MockStore, EpgService], ( snackbar: MatSnackBar, - channelStore: ChannelStore, + channelStore: MockStore, service: EpgService ) => { jest.spyOn(snackbar, 'open'); - jest.spyOn(channelStore, 'setEpgAvailableFlag'); + jest.spyOn(channelStore, 'dispatch'); service.onEpgFetchDone(); expect(snackbar.open).toHaveBeenCalledTimes(1); - expect(channelStore.setEpgAvailableFlag).toHaveBeenCalledWith(true); + expect(channelStore.dispatch).toHaveBeenCalledWith({value: true, type: expect.stringContaining('active epg')}); } )); }); diff --git a/src/app/settings/settings.component.spec.ts b/src/app/settings/settings.component.spec.ts index 5201b6400..575324ae0 100644 --- a/src/app/settings/settings.component.spec.ts +++ b/src/app/settings/settings.component.spec.ts @@ -1,6 +1,6 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; -import { UntypedFormBuilder, FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule, UntypedFormBuilder } from '@angular/forms'; import { MatCardModule } from '@angular/material/card'; import { MatCheckboxModule } from '@angular/material/checkbox'; import { MatDividerModule } from '@angular/material/divider'; @@ -12,12 +12,12 @@ import { MatSnackBar } from '@angular/material/snack-bar'; import { MatTooltipModule } from '@angular/material/tooltip'; import { Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { StorageMap } from '@ngx-pwa/local-storage'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { MockComponent, MockModule, MockPipe } from 'ng-mocks'; import { of } from 'rxjs'; import { EPG_FETCH } from '../../../shared/ipc-commands'; -/* eslint-disable @typescript-eslint/unbound-method */ import { DataService } from '../services/data.service'; import { ElectronServiceStub } from '../services/electron.service.stub'; import { TranslateServiceStub } from './../../testing/translate.stub'; @@ -52,6 +52,7 @@ describe('SettingsComponent', () => { let router: Router; let storage: StorageMap; let translate: TranslateService; + let mockStore: MockStore; beforeEach( waitForAsync(() => { @@ -74,6 +75,7 @@ describe('SettingsComponent', () => { useClass: MockRouter, }, StorageMap, + provideMockStore(), ], imports: [ HttpClientTestingModule, @@ -99,6 +101,8 @@ describe('SettingsComponent', () => { storage = TestBed.inject(StorageMap); router = TestBed.inject(Router); translate = TestBed.inject(TranslateService); + mockStore = TestBed.inject(MockStore); + component = fixture.componentInstance; fixture.detectChanges(); });