diff --git a/src/framework/theme/components/tabset/tabset.component.spec.ts b/src/framework/theme/components/tabset/tabset.component.spec.ts new file mode 100644 index 0000000000..788c1e5dc5 --- /dev/null +++ b/src/framework/theme/components/tabset/tabset.component.spec.ts @@ -0,0 +1,108 @@ +import { CommonModule } from '@angular/common'; +import { Component, QueryList, ViewChild, ViewChildren } from '@angular/core'; +import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; +import { ActivatedRoute, Params } from '@angular/router'; +import { RouterTestingModule } from '@angular/router/testing'; +import { NbTabComponent, NbTabsetComponent, NbTabsetModule } from '@nebular/theme'; +import { BehaviorSubject } from 'rxjs'; +import createSpy = jasmine.createSpy; + +@Component({ + template: ` + + 1 + 2 + 3 + + `, +}) +export class TabsetTestComponent { + showTabs = true; + + @ViewChild(NbTabsetComponent) tabsetComponent: NbTabsetComponent; + @ViewChildren(NbTabComponent) tabComponents: QueryList; + + getDisabledTab(): NbTabComponent { + return this.tabComponents.toArray()[2]; + } +} + +export class ActivatedRouteStub { + private subject = new BehaviorSubject(null); + readonly params = this.subject.asObservable(); + + constructor(params: Params = {}) { + this.subject.next(params); + } + + setParams(params?: Params) { + this.subject.next(params); + }; +} + +describe('NbTabsetComponent', () => { + let fixture: ComponentFixture; + let testComponent: TabsetTestComponent; + let tabsetComponent: NbTabsetComponent; + let activatedRouteStub: ActivatedRouteStub; + + beforeEach(fakeAsync(() => { + activatedRouteStub = new ActivatedRouteStub(); + + TestBed.configureTestingModule({ + declarations: [ TabsetTestComponent ], + imports: [ + CommonModule, + RouterTestingModule.withRoutes([]), + NbTabsetModule, + ], + providers: [{ provide: ActivatedRoute, useValue: activatedRouteStub }], + }); + + fixture = TestBed.createComponent(TabsetTestComponent); + testComponent = fixture.componentInstance; + + fixture.detectChanges(); + tick(); + + tabsetComponent = testComponent.tabsetComponent; + })); + + it('should mark tab as active if selected in route param', fakeAsync(() => { + const selectTabSpy = spyOn(tabsetComponent, 'selectTab'); + const tabToSelect: NbTabComponent = testComponent.tabComponents.first; + + activatedRouteStub.setParams({ tab: tabToSelect.route }); + fixture.detectChanges(); + tick(); + + expect(selectTabSpy).toHaveBeenCalledTimes(1); + expect(selectTabSpy).toHaveBeenCalledWith(tabToSelect); + expect(tabToSelect.active).toEqual(true); + })); + + it('should not mark disabled tab as active if selected in route param', fakeAsync(() => { + const changeTabSpy = createSpy('changeTabSpy'); + const disabledTab: NbTabComponent = testComponent.getDisabledTab(); + + activatedRouteStub.setParams({ tab: disabledTab.route }); + fixture.detectChanges(); + tick(); + + expect(changeTabSpy).not.toHaveBeenCalled(); + expect(disabledTab.active).toEqual(false); + })); + + it(`should not call 'selectTab' if no tabs found`, fakeAsync(() => { + const selectTabSpy = spyOn(tabsetComponent, 'selectTab'); + + testComponent.showTabs = false; + fixture.detectChanges(); + + activatedRouteStub.setParams({ tab: 1 }); + fixture.detectChanges(); + tick(); + + expect(selectTabSpy).not.toHaveBeenCalled(); + })); +}); diff --git a/src/framework/theme/components/tabset/tabset.component.ts b/src/framework/theme/components/tabset/tabset.component.ts index b911928c79..e6fd5f29df 100644 --- a/src/framework/theme/components/tabset/tabset.component.ts +++ b/src/framework/theme/components/tabset/tabset.component.ts @@ -4,7 +4,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. */ -import { map, delay } from 'rxjs/operators'; +import { map, delay, filter } from 'rxjs/operators'; import { Component, Input, @@ -301,11 +301,13 @@ export class NbTabsetComponent implements AfterContentInit { this.tabs.find((tab) => this.routeParam ? tab.route === params[this.routeParam] : tab.active), ), delay(0), + map((tab: NbTabComponent) => tab || this.tabs.first), + filter((tab: NbTabComponent) => !!tab), ) - .subscribe((activeTab) => { - this.selectTab(activeTab || this.tabs.first); + .subscribe((tabToSelect: NbTabComponent) => { + this.selectTab(tabToSelect); this.changeDetectorRef.markForCheck(); - }); + }); } // TODO: navigate to routeParam