11import { HighlightColorEnum , HighlightUpdateColorEnum } from '@openstax/highlighter/dist/api' ;
22import React from 'react' ;
33import renderer from 'react-test-renderer' ;
4+ import { RawIntlProvider } from 'react-intl' ;
5+ import createIntl from '../../../messages/createIntl' ;
46import createTestServices from '../../../../test/createTestServices' ;
57import createTestStore from '../../../../test/createTestStore' ;
68import { book as archiveBook , page , pageInChapter } from '../../../../test/mocks/archiveLoader' ;
@@ -25,17 +27,22 @@ import { highlightLocationFilters } from '../selectors';
2527import { HighlightData , SummaryHighlights } from '../types' ;
2628import { getHighlightLocationFilterForPage } from '../utils' ;
2729import Highlights from './Highlights' ;
28- import { NoHighlightsTip } from './Highlights' ;
2930import ContextMenu from './SummaryPopup/ContextMenu' ;
3031import HighlightAnnotation from './SummaryPopup/HighlightAnnotation' ;
3132import HighlightDeleteWrapper from './SummaryPopup/HighlightDeleteWrapper' ;
3233import { HighlightContentWrapper } from './SummaryPopup/HighlightListElement' ;
34+ import { NoHighlightsTip , VisuallyHiddenLiveRegion } from './HighlightsCards' ;
35+
36+
37+ jest . useFakeTimers ( ) ;
3338
3439const hlBlue = { id : 'hl1' , color : HighlightColorEnum . Blue , annotation : 'hl1' , sourceId : 'testbook1-testpage1-uuid' } ;
3540const hlGreen = { id : 'hl2' , color : HighlightColorEnum . Green , annotation : 'hl' , sourceId : 'testbook1-testpage1-uuid' } ;
3641const hlPink = { id : 'hl3' , color : HighlightColorEnum . Pink , annotation : 'hl' , sourceId : 'testbook1-testpage1-uuid' } ;
37- const hlPurple = { annotation : 'hl' , color : HighlightColorEnum . Purple ,
38- id : 'hl4' , sourceId : 'testbook1-testpage1-uuid' } ;
42+ const hlPurple = {
43+ annotation : 'hl' , color : HighlightColorEnum . Purple ,
44+ id : 'hl4' , sourceId : 'testbook1-testpage1-uuid' ,
45+ } ;
3946const hlYellow = { id : 'hl5' , color : HighlightColorEnum . Yellow , sourceId : 'testbook1-testpage1-uuid' } ;
4047
4148describe ( 'Highlights' , ( ) => {
@@ -51,7 +58,7 @@ describe('Highlights', () => {
5158 dispatch = jest . spyOn ( store , 'dispatch' ) ;
5259
5360 store . dispatch ( receiveBook ( book ) ) ;
54- store . dispatch ( receivePage ( { ...page , references : [ ] } ) ) ;
61+ store . dispatch ( receivePage ( { ...page , references : [ ] } ) ) ;
5562
5663 services = {
5764 ...createTestServices ( ) ,
@@ -71,10 +78,10 @@ describe('Highlights', () => {
7178 const location = getHighlightLocationFilterForPage ( locationFilters , pageInChapter ) ;
7279 expect ( location ) . toBeDefined ( ) ;
7380
74- store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
81+ store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
7582 store . dispatch ( receiveHighlightsTotalCounts ( {
76- [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
77- [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
83+ [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
84+ [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
7885 } , new Map ( ) ) ) ;
7986
8087 const summaryHighlights = {
@@ -86,10 +93,10 @@ describe('Highlights', () => {
8693 } ,
8794 } as SummaryHighlights ;
8895
89- store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
96+ store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
9097
9198 const component = renderer . create ( < TestContainer services = { services } store = { store } >
92- < Highlights />
99+ < Highlights />
93100 </ TestContainer > ) ;
94101
95102 const sections = component . root . findAllByType ( SectionHighlights ) ;
@@ -122,8 +129,8 @@ describe('Highlights', () => {
122129 expect ( location ) . toBeDefined ( ) ;
123130
124131 store . dispatch ( receiveHighlightsTotalCounts ( {
125- [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
126- [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
132+ [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
133+ [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
127134 } , new Map ( ) ) ) ;
128135
129136 const summaryHighlights = {
@@ -136,12 +143,12 @@ describe('Highlights', () => {
136143 } as SummaryHighlights ;
137144
138145 renderer . act ( ( ) => {
139- store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
140- store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
146+ store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
147+ store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
141148 } ) ;
142149
143150 const component = renderer . create ( < TestContainer services = { services } store = { store } >
144- < Highlights />
151+ < Highlights />
145152 </ TestContainer > ) ;
146153
147154 const sections = component . root . findAllByType ( SectionHighlights ) ;
@@ -150,7 +157,7 @@ describe('Highlights', () => {
150157 expect ( component . root . findAllByType ( LoaderWrapper ) . length ) . toEqual ( 0 ) ;
151158
152159 renderer . act ( ( ) => {
153- store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
160+ store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
154161 } ) ;
155162
156163 const isLoading = component . root . findByType ( LoaderWrapper ) ;
@@ -159,14 +166,14 @@ describe('Highlights', () => {
159166
160167 it ( 'show no highlights tip when there are no highlights for selected filters' , ( ) => {
161168 store . dispatch ( receiveHighlightsTotalCounts ( {
162- pageId : { [ HighlightColorEnum . Green ] : 5 } ,
163- pageId2 : { [ HighlightColorEnum . Green ] : 2 } ,
169+ pageId : { [ HighlightColorEnum . Green ] : 5 } ,
170+ pageId2 : { [ HighlightColorEnum . Green ] : 2 } ,
164171 } , new Map ( ) ) ) ;
165- store . dispatch ( setSummaryFilters ( { locationIds : [ 'not-in-book' ] } ) ) ;
166- store . dispatch ( receiveSummaryHighlights ( { } , { pagination : null } ) ) ;
172+ store . dispatch ( setSummaryFilters ( { locationIds : [ 'not-in-book' ] } ) ) ;
173+ store . dispatch ( receiveSummaryHighlights ( { } , { pagination : null } ) ) ;
167174
168175 const component = renderer . create ( < TestContainer services = { services } store = { store } >
169- < Highlights />
176+ < Highlights />
170177 </ TestContainer > ) ;
171178
172179 // i'm not sure why this type is wrong
@@ -176,7 +183,7 @@ describe('Highlights', () => {
176183
177184 it ( 'show add highlight message when there are no highlights in specific book' , ( ) => {
178185 const component = renderer . create ( < TestContainer services = { services } store = { store } >
179- < Highlights />
186+ < Highlights />
180187 </ TestContainer > ) ;
181188
182189 expect ( component . root . findByProps ( { id : 'i18n:toolbar:highlights:popup:body:add-highlight' } ) )
@@ -190,10 +197,10 @@ describe('Highlights', () => {
190197 const location = getHighlightLocationFilterForPage ( locationFilters , pageInChapter ) ;
191198 expect ( location ) . toBeDefined ( ) ;
192199
193- store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
200+ store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
194201 store . dispatch ( receiveHighlightsTotalCounts ( {
195- [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
196- [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
202+ [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
203+ [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
197204 } , locationFilters ) ) ;
198205
199206 const summaryHighlights = {
@@ -205,10 +212,10 @@ describe('Highlights', () => {
205212 } ,
206213 } as SummaryHighlights ;
207214
208- store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
215+ store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
209216
210217 const component = renderer . create ( < TestContainer services = { services } store = { store } >
211- < Highlights />
218+ < Highlights />
212219 </ TestContainer > ) ;
213220
214221 const editingMenus = component . root . findAllByType ( ContextMenu ) ;
@@ -222,10 +229,10 @@ describe('Highlights', () => {
222229 const location = getHighlightLocationFilterForPage ( locationFilters , pageInChapter ) ;
223230 expect ( location ) . toBeDefined ( ) ;
224231
225- store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
232+ store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
226233 store . dispatch ( receiveHighlightsTotalCounts ( {
227- [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
228- [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
234+ [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
235+ [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
229236 } , locationFilters ) ) ;
230237
231238 const summaryHighlights = {
@@ -237,13 +244,13 @@ describe('Highlights', () => {
237244 } ,
238245 } as SummaryHighlights ;
239246
240- store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
247+ store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
241248 dispatch . mockClear ( ) ;
242249
243250 const createNodeMock = ( ) => assertDocument ( ) . createElement ( 'div' ) ;
244251 const component = renderer . create ( < TestContainer services = { services } store = { store } >
245- < Highlights />
246- </ TestContainer > , { createNodeMock} ) ;
252+ < Highlights />
253+ </ TestContainer > , { createNodeMock } ) ;
247254
248255 let [ firstAnnotation ] = component . root . findAllByType ( HighlightAnnotation ) ;
249256 expect ( firstAnnotation . props . isEditing ) . toEqual ( false ) ;
@@ -270,7 +277,7 @@ describe('Highlights', () => {
270277 locationFilterId : pageId ,
271278 pageId,
272279 preUpdateData : {
273- highlight : { annotation : hlBlue . annotation , color : hlBlue . color as string as HighlightUpdateColorEnum } ,
280+ highlight : { annotation : hlBlue . annotation , color : hlBlue . color as string as HighlightUpdateColorEnum } ,
274281 id : hlBlue . id ,
275282 } ,
276283 } ) ) ;
@@ -290,7 +297,7 @@ describe('Highlights', () => {
290297
291298 const confirmButton = component . root . findByProps ( { 'data-testid' : 'delete' } ) ;
292299
293- renderer . act ( ( ) => confirmButton . props . onClick ( { preventDefault : ( ) => null } ) ) ;
300+ renderer . act ( ( ) => confirmButton . props . onClick ( { preventDefault : ( ) => null } ) ) ;
294301 expect ( dispatch ) . toHaveBeenCalled ( ) ;
295302 expect ( firstAnnotation . props . isEditing ) . toEqual ( false ) ;
296303
@@ -348,10 +355,10 @@ describe('Highlights', () => {
348355 const location = getHighlightLocationFilterForPage ( locationFilters , pageInChapter ) ;
349356 expect ( location ) . toBeDefined ( ) ;
350357
351- store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
358+ store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
352359 store . dispatch ( receiveHighlightsTotalCounts ( {
353- [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
354- [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
360+ [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
361+ [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
355362 } , locationFilters ) ) ;
356363
357364 const summaryHighlights = {
@@ -363,11 +370,11 @@ describe('Highlights', () => {
363370 } ,
364371 } as SummaryHighlights ;
365372
366- store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
373+ store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
367374 dispatch . mockClear ( ) ;
368375
369376 const component = renderer . create ( < TestContainer services = { services } store = { store } >
370- < Highlights />
377+ < Highlights />
371378 </ TestContainer > ) ;
372379
373380 renderer . act ( ( ) => {
@@ -384,7 +391,7 @@ describe('Highlights', () => {
384391 locationFilterId : pageId ,
385392 pageId,
386393 preUpdateData : {
387- highlight : { annotation : hlBlue . annotation , color : hlBlue . color as string as HighlightUpdateColorEnum } ,
394+ highlight : { annotation : hlBlue . annotation , color : hlBlue . color as string as HighlightUpdateColorEnum } ,
388395 id : hlBlue . id ,
389396 } ,
390397 } ) ) ;
@@ -397,10 +404,10 @@ describe('Highlights', () => {
397404 const location = getHighlightLocationFilterForPage ( locationFilters , pageInChapter ) ;
398405 expect ( location ) . toBeDefined ( ) ;
399406
400- store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
407+ store . dispatch ( setSummaryFilters ( { locationIds : [ location ! . id , pageId ] } ) ) ;
401408 store . dispatch ( receiveHighlightsTotalCounts ( {
402- [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
403- [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
409+ [ pageId ] : { [ HighlightColorEnum . Green ] : 5 } ,
410+ [ location ! . id ] : { [ HighlightColorEnum . Green ] : 2 } ,
404411 } , locationFilters ) ) ;
405412
406413 const summaryHighlights = {
@@ -412,11 +419,11 @@ describe('Highlights', () => {
412419 } ,
413420 } as SummaryHighlights ;
414421
415- store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
422+ store . dispatch ( receiveSummaryHighlights ( summaryHighlights , { pagination : null } ) ) ;
416423 dispatch . mockClear ( ) ;
417424
418425 const component = renderer . create ( < TestContainer services = { services } store = { store } >
419- < Highlights />
426+ < Highlights />
420427 </ TestContainer > ) ;
421428
422429 renderer . act ( ( ) => {
@@ -435,12 +442,12 @@ describe('Highlights', () => {
435442 dw . props . onCancel ( ) ;
436443 }
437444
438- requestDeleteHighlightHook . hookBody ( { ...services , getState : store . getState , dispatch : store . dispatch } ) (
445+ requestDeleteHighlightHook . hookBody ( { ...services , getState : store . getState , dispatch : store . dispatch } ) (
439446 requestDeleteHighlight ( hlBlue as HighlightData , {
440447 locationFilterId : pageId ,
441448 pageId,
442449 }
443- ) ) ;
450+ ) ) ;
444451 } ) ;
445452
446453 expect ( dispatch ) . toHaveBeenCalledWith ( requestDeleteHighlight ( hlBlue as HighlightData , {
@@ -451,3 +458,45 @@ describe('Highlights', () => {
451458 expect ( component . root . findAllByType ( HighlightDeleteWrapper ) . length ) . toEqual ( 0 ) ;
452459 } ) ;
453460} ) ;
461+
462+ describe ( 'VisuallyHiddenLiveRegion' , ( ) => {
463+
464+ const getTextContent = ( node : any ) : string => {
465+ if ( typeof node === 'string' ) return node ;
466+ if ( Array . isArray ( node ) ) return node . map ( getTextContent ) . join ( '' ) ;
467+ if ( node && node . props && node . props . children ) return getTextContent ( node . props . children ) ;
468+ return '' ;
469+ } ;
470+
471+ it ( 'announces the message after a delay when id changes' , async ( ) => {
472+ const intl = await createIntl ( 'en' ) ;
473+ const component = renderer . create (
474+ < RawIntlProvider value = { intl } >
475+ < VisuallyHiddenLiveRegion id = 'test-id' />
476+ </ RawIntlProvider >
477+ ) ;
478+
479+ const liveRegion = component . root . find (
480+ el => el . props [ 'aria-live' ] === 'polite'
481+ ) ;
482+
483+ expect ( getTextContent ( liveRegion ) ) . toBe ( '' ) ;
484+
485+ renderer . act ( ( ) => {
486+ jest . advanceTimersByTime ( 100 ) ;
487+ } ) ;
488+
489+ expect ( getTextContent ( liveRegion ) ) . toBe ( 'test-id' ) ;
490+ } ) ;
491+
492+ it ( 'clears the timer on unmount' , async ( ) => {
493+ // @ts -ignore
494+ const intl = await createIntl ( 'en' ) ;
495+ const component = renderer . create (
496+ < RawIntlProvider value = { intl } >
497+ < VisuallyHiddenLiveRegion id = 'test-id' />
498+ </ RawIntlProvider >
499+ ) ;
500+ component . unmount ( ) ;
501+ } ) ;
502+ } ) ;
0 commit comments