11import { Component , QueryList , ViewChildren } from '@angular/core' ;
2- import { ComponentFixture , fakeAsync , flush , TestBed , tick } from '@angular/core/testing' ;
2+ import { ComponentFixture , TestBed } from '@angular/core/testing' ;
3+ import { NoopAnimationsModule } from '@angular/platform-browser/animations' ;
34import { MdbAccordionItemComponent } from './accordion-item.component' ;
45import { MdbAccordionModule } from './accordion.module' ;
56
6- const ANIMATION_TIME = 350 ; // animation time from collapse directive
7-
87const template = `
98<mdb-accordion [multiple]="multiple" [flush]="flush" [borderless]="borderless">
109 <mdb-accordion-item [disabled]="disabled">
@@ -67,10 +66,15 @@ describe('MDB Accordion', () => {
6766 let element : any ;
6867 let component : any ;
6968
69+ // Helper to dispatch transitionend event (jsdom doesn't fire CSS transitions)
70+ const dispatchTransitionEnd = ( el : HTMLElement ) => {
71+ el . dispatchEvent ( new Event ( 'transitionend' ) ) ;
72+ } ;
73+
7074 beforeEach ( ( ) => {
7175 TestBed . configureTestingModule ( {
7276 declarations : [ TestAccordionComponent ] ,
73- imports : [ MdbAccordionModule ] ,
77+ imports : [ MdbAccordionModule , NoopAnimationsModule ] ,
7478 teardown : { destroyAfterEach : false } ,
7579 } ) ;
7680 fixture = TestBed . createComponent ( TestAccordionComponent ) ;
@@ -79,95 +83,112 @@ describe('MDB Accordion', () => {
7983 element = fixture . nativeElement ;
8084 } ) ;
8185
82- it ( 'should toggle item on click' , fakeAsync ( ( ) => {
86+ it ( 'should toggle item on click' , async ( ) => {
8387 const item = document . querySelector ( '.accordion-item' ) as HTMLElement ;
8488 const button = item . querySelector ( '.accordion-button' ) as HTMLElement ;
89+ const collapseEl = item . querySelector ( '.collapse' ) as HTMLElement ;
8590
8691 button . click ( ) ;
8792 fixture . detectChanges ( ) ;
88- flush ( ) ;
89-
90- const itemCollapse = item . querySelector ( '.collapse' ) ;
93+ dispatchTransitionEnd ( collapseEl ) ;
94+ await fixture . whenStable ( ) ;
95+ fixture . detectChanges ( ) ;
9196
9297 expect ( button . classList ) . not . toContain ( 'collapsed' ) ;
93- expect ( itemCollapse . classList ) . toContain ( 'show' ) ;
98+ expect ( collapseEl . classList ) . toContain ( 'show' ) ;
9499
95100 button . click ( ) ;
96101 fixture . detectChanges ( ) ;
97- flush ( ) ;
102+ dispatchTransitionEnd ( collapseEl ) ;
103+ await fixture . whenStable ( ) ;
104+ fixture . detectChanges ( ) ;
98105
99106 expect ( button . classList ) . toContain ( 'collapsed' ) ;
100- expect ( itemCollapse . classList ) . not . toContain ( 'show' ) ;
101- } ) ) ;
107+ expect ( collapseEl . classList ) . not . toContain ( 'show' ) ;
108+ } ) ;
102109
103- it ( 'should toggle item when toggle method is used' , fakeAsync ( ( ) => {
110+ it ( 'should toggle item when toggle method is used' , async ( ) => {
104111 const item = document . querySelector ( '.accordion-item' ) as HTMLElement ;
105112 const button = item . querySelector ( '.accordion-button' ) as HTMLElement ;
106- component . accordionItems [ 0 ] . toggle ( ) ;
113+ const collapseEl = item . querySelector ( '.collapse' ) as HTMLElement ;
107114
115+ component . accordionItems [ 0 ] . toggle ( ) ;
116+ fixture . detectChanges ( ) ;
117+ dispatchTransitionEnd ( collapseEl ) ;
118+ await fixture . whenStable ( ) ;
108119 fixture . detectChanges ( ) ;
109- flush ( ) ;
110-
111- const itemCollapse = item . querySelector ( '.collapse' ) ;
112120
113121 expect ( button . classList ) . not . toContain ( 'collapsed' ) ;
114- expect ( itemCollapse . classList ) . toContain ( 'show' ) ;
122+ expect ( collapseEl . classList ) . toContain ( 'show' ) ;
115123
116124 component . accordionItems [ 0 ] . toggle ( ) ;
117125 fixture . detectChanges ( ) ;
118- flush ( ) ;
126+ dispatchTransitionEnd ( collapseEl ) ;
127+ await fixture . whenStable ( ) ;
128+ fixture . detectChanges ( ) ;
119129
120130 expect ( button . classList ) . toContain ( 'collapsed' ) ;
121- expect ( itemCollapse . classList ) . not . toContain ( 'show' ) ;
122- } ) ) ;
131+ expect ( collapseEl . classList ) . not . toContain ( 'show' ) ;
132+ } ) ;
123133
124- it ( 'should allow only one item to be opened if multiple is set to false' , fakeAsync ( ( ) => {
134+ it ( 'should allow only one item to be opened if multiple is set to false' , async ( ) => {
125135 const buttons = document . querySelectorAll ( '.accordion-button' ) ;
126136 const contents = document . querySelectorAll ( '.collapse' ) ;
127137
128138 component . accordionItems [ 0 ] . toggle ( ) ;
129139 fixture . detectChanges ( ) ;
130- flush ( ) ;
140+ dispatchTransitionEnd ( contents [ 0 ] as HTMLElement ) ;
141+ await fixture . whenStable ( ) ;
142+ fixture . detectChanges ( ) ;
131143
132144 expect ( buttons [ 0 ] . classList ) . not . toContain ( 'collapsed' ) ;
133145 expect ( contents [ 0 ] . classList ) . toContain ( 'show' ) ;
134146
135147 component . accordionItems [ 1 ] . toggle ( ) ;
136148 fixture . detectChanges ( ) ;
137- flush ( ) ;
149+ dispatchTransitionEnd ( contents [ 0 ] as HTMLElement ) ; // first item closing
150+ dispatchTransitionEnd ( contents [ 1 ] as HTMLElement ) ; // second item opening
151+ await fixture . whenStable ( ) ;
152+ fixture . detectChanges ( ) ;
138153
139154 expect ( buttons [ 0 ] . classList ) . toContain ( 'collapsed' ) ;
140155 expect ( contents [ 0 ] . classList ) . not . toContain ( 'show' ) ;
141156 expect ( buttons [ 1 ] . classList ) . not . toContain ( 'collapsed' ) ;
142157 expect ( contents [ 1 ] . classList ) . toContain ( 'show' ) ;
143- } ) ) ;
158+ } ) ;
144159
145- it ( 'should allow multiple items to be opened if multiple is set to true' , fakeAsync ( ( ) => {
160+ it ( 'should allow multiple items to be opened if multiple is set to true' , async ( ) => {
146161 component . multiple = true ;
162+ fixture . changeDetectorRef . markForCheck ( ) ;
147163 fixture . detectChanges ( ) ;
148164
149165 const buttons = document . querySelectorAll ( '.accordion-button' ) ;
150166 const contents = document . querySelectorAll ( '.collapse' ) ;
151167
152168 component . accordionItems [ 0 ] . toggle ( ) ;
153169 fixture . detectChanges ( ) ;
154- flush ( ) ;
170+ dispatchTransitionEnd ( contents [ 0 ] as HTMLElement ) ;
171+ await fixture . whenStable ( ) ;
172+ fixture . detectChanges ( ) ;
155173
156174 expect ( buttons [ 0 ] . classList ) . not . toContain ( 'collapsed' ) ;
157175 expect ( contents [ 0 ] . classList ) . toContain ( 'show' ) ;
158176
159177 component . accordionItems [ 1 ] . toggle ( ) ;
160178 fixture . detectChanges ( ) ;
161- flush ( ) ;
179+ dispatchTransitionEnd ( contents [ 1 ] as HTMLElement ) ;
180+ await fixture . whenStable ( ) ;
181+ fixture . detectChanges ( ) ;
162182
163183 expect ( buttons [ 0 ] . classList ) . not . toContain ( 'collapsed' ) ;
164184 expect ( contents [ 0 ] . classList ) . toContain ( 'show' ) ;
165185 expect ( buttons [ 1 ] . classList ) . not . toContain ( 'collapsed' ) ;
166186 expect ( contents [ 1 ] . classList ) . toContain ( 'show' ) ;
167- } ) ) ;
187+ } ) ;
168188
169189 it ( 'should add accordion-flush class if flush is set to true' , ( ) => {
170190 component . flush = true ;
191+ fixture . changeDetectorRef . markForCheck ( ) ;
171192 fixture . detectChanges ( ) ;
172193
173194 const accordion = document . querySelector ( '.accordion' ) ;
@@ -181,13 +202,15 @@ describe('MDB Accordion', () => {
181202 expect ( accordion . classList ) . not . toContain ( 'accordion-borderless' ) ;
182203
183204 component . borderless = true ;
205+ fixture . changeDetectorRef . markForCheck ( ) ;
184206 fixture . detectChanges ( ) ;
185207
186208 expect ( accordion . classList ) . toContain ( 'accordion-borderless' ) ;
187209 } ) ;
188210
189- it ( 'should emit correct events on item collapse and expand' , fakeAsync ( ( ) => {
211+ it ( 'should emit correct events on item collapse and expand' , async ( ) => {
190212 const item = component . accordionItems [ 0 ] ;
213+ const content = document . querySelectorAll ( '.collapse' ) [ 0 ] as HTMLElement ;
191214
192215 const showSpy = jest . spyOn ( item . itemShow , 'emit' ) ;
193216 const shownSpy = jest . spyOn ( item . itemShown , 'emit' ) ;
@@ -196,31 +219,30 @@ describe('MDB Accordion', () => {
196219
197220 item . show ( ) ;
198221 fixture . detectChanges ( ) ;
199-
200- expect ( showSpy ) . toHaveBeenCalled ( ) ;
201- expect ( shownSpy ) . not . toHaveBeenCalled ( ) ;
202-
203- tick ( ANIMATION_TIME ) ;
204- flush ( ) ;
222+ // First transitionend completes the initial show, which triggers a recursive show() in the setter
223+ dispatchTransitionEnd ( content ) ;
224+ await fixture . whenStable ( ) ;
225+ // Second transitionend completes the recursive show()
226+ dispatchTransitionEnd ( content ) ;
227+ await fixture . whenStable ( ) ;
205228 fixture . detectChanges ( ) ;
206229
230+ expect ( showSpy ) . toHaveBeenCalled ( ) ;
207231 expect ( shownSpy ) . toHaveBeenCalled ( ) ;
208232
209233 item . hide ( ) ;
210234 fixture . detectChanges ( ) ;
211-
212- expect ( hideSpy ) . toHaveBeenCalled ( ) ;
213- expect ( hiddenSpy ) . not . toHaveBeenCalled ( ) ;
214-
215- tick ( ANIMATION_TIME ) ;
216- flush ( ) ;
235+ dispatchTransitionEnd ( content ) ;
236+ await fixture . whenStable ( ) ;
217237 fixture . detectChanges ( ) ;
218238
239+ expect ( hideSpy ) . toHaveBeenCalled ( ) ;
219240 expect ( hiddenSpy ) . toHaveBeenCalled ( ) ;
220- } ) ) ;
241+ } ) ;
221242
222- it ( 'should not toggle item on click when disabled input is set to true' , fakeAsync ( ( ) => {
243+ it ( 'should not toggle item on click when disabled input is set to true' , async ( ) => {
223244 component . disabled = true ;
245+ fixture . changeDetectorRef . markForCheck ( ) ;
224246 fixture . detectChanges ( ) ;
225247
226248 const item = document . querySelector ( '.accordion-item' ) as HTMLElement ;
@@ -233,9 +255,9 @@ describe('MDB Accordion', () => {
233255
234256 button . click ( ) ;
235257 fixture . detectChanges ( ) ;
236- flush ( ) ;
258+ await fixture . whenStable ( ) ;
237259
238260 expect ( button . classList ) . toContain ( 'collapsed' ) ;
239261 expect ( itemCollapse . classList ) . not . toContain ( 'show' ) ;
240- } ) ) ;
262+ } ) ;
241263} ) ;
0 commit comments