diff --git a/src/cdk/accordion/accordion.spec.ts b/src/cdk/accordion/accordion.spec.ts index 209ed5114f00..acddb34109cc 100644 --- a/src/cdk/accordion/accordion.spec.ts +++ b/src/cdk/accordion/accordion.spec.ts @@ -1,8 +1,10 @@ import {waitForAsync, TestBed} from '@angular/core/testing'; -import {Component, ViewChild} from '@angular/core'; +import {Component, QueryList, ViewChild, ViewChildren} from '@angular/core'; import {By} from '@angular/platform-browser'; import {BrowserAnimationsModule} from '@angular/platform-browser/animations'; -import {CdkAccordionModule, CdkAccordionItem} from './public-api'; +import {CdkAccordion} from './accordion'; +import {CdkAccordionItem} from './accordion-item'; +import {CdkAccordionModule} from './accordion-module'; describe('CdkAccordion', () => { beforeEach(waitForAsync(() => { @@ -59,6 +61,61 @@ describe('CdkAccordion', () => { expect(innerItem.accordion).not.toBe(outerItem.accordion); }); + + it('should be able to expand and collapse all items in multiple mode', () => { + const fixture = TestBed.createComponent(SetOfItems); + fixture.componentInstance.multi = true; + fixture.detectChanges(); + fixture.componentInstance.accordion.openAll(); + fixture.detectChanges(); + + expect(fixture.componentInstance.items.toArray().every(item => item.expanded)).toBe(true); + + fixture.componentInstance.accordion.closeAll(); + fixture.detectChanges(); + + expect(fixture.componentInstance.items.toArray().some(item => item.expanded)).toBe(false); + }); + + it('should not be able to expand all items if multiple mode is off', () => { + const fixture = TestBed.createComponent(SetOfItems); + fixture.componentInstance.multi = false; + fixture.detectChanges(); + fixture.componentInstance.accordion.openAll(); + fixture.detectChanges(); + + expect(fixture.componentInstance.items.toArray().some(item => item.expanded)).toBe(false); + }); + + it('should be able to use closeAll even if multiple mode is disabled', () => { + const fixture = TestBed.createComponent(SetOfItems); + fixture.componentInstance.multi = false; + fixture.detectChanges(); + const item = fixture.componentInstance.items.first; + + item.expanded = true; + fixture.detectChanges(); + + fixture.componentInstance.accordion.closeAll(); + fixture.detectChanges(); + + expect(item.expanded).toBe(false); + }); + + it('should complete the accordion observables on destroy', () => { + const fixture = TestBed.createComponent(SetOfItems); + fixture.detectChanges(); + const stateSpy = jasmine.createSpy('stateChanges complete spy'); + const openCloseSpy = jasmine.createSpy('openCloseAllActions complete spy'); + + fixture.componentInstance.accordion._stateChanges.subscribe({complete: stateSpy}); + fixture.componentInstance.accordion._openCloseAllActions.subscribe({complete: openCloseSpy}); + fixture.destroy(); + + expect(stateSpy).toHaveBeenCalled(); + expect(openCloseSpy).toHaveBeenCalled(); + }); + }); @Component({template: ` @@ -67,6 +124,8 @@ describe('CdkAccordion', () => { `}) class SetOfItems { + @ViewChild(CdkAccordion) accordion: CdkAccordion; + @ViewChildren(CdkAccordionItem) items: QueryList; multi: boolean = false; } diff --git a/src/cdk/accordion/accordion.ts b/src/cdk/accordion/accordion.ts index f164eb2df95a..89cfeb555571 100644 --- a/src/cdk/accordion/accordion.ts +++ b/src/cdk/accordion/accordion.ts @@ -46,12 +46,14 @@ export class CdkAccordion implements OnDestroy, OnChanges { /** Opens all enabled accordion items in an accordion where multi is enabled. */ openAll(): void { - this._openCloseAll(true); + if (this._multi) { + this._openCloseAllActions.next(true); + } } /** Closes all enabled accordion items in an accordion where multi is enabled. */ closeAll(): void { - this._openCloseAll(false); + this._openCloseAllActions.next(false); } ngOnChanges(changes: SimpleChanges) { @@ -60,12 +62,7 @@ export class CdkAccordion implements OnDestroy, OnChanges { ngOnDestroy() { this._stateChanges.complete(); - } - - private _openCloseAll(expanded: boolean): void { - if (this.multi) { - this._openCloseAllActions.next(expanded); - } + this._openCloseAllActions.complete(); } static ngAcceptInputType_multi: BooleanInput;