@@ -4,7 +4,9 @@ import userEvent from '@testing-library/user-event';
44import { Provider } from 'react-redux' ;
55import configureStore from 'redux-mock-store' ;
66import { thunk } from 'redux-thunk' ;
7+ import cloneDeep from 'lodash/cloneDeep' ;
78
9+ import { CATEGORY } from '@app/pages/clinicworkspace/TideDashboardV2/tideDashboardSlice' ;
810import {
911 PatientCell ,
1012 NumericTemplateCell ,
@@ -18,6 +20,7 @@ import {
1820 ChangeTIRCell ,
1921 GMICell ,
2022 CGMUseCell ,
23+ FlagCell ,
2124 MoreMenuCell ,
2225} from '@app/pages/clinicworkspace/TideDashboardV2/Cells' ;
2326
@@ -174,4 +177,94 @@ describe('Cells', () => {
174177 expect ( screen . getByText ( '93 %' ) ) . toBeInTheDocument ( ) ; // timeCGMUsePercent 0.9312
175178 } ) ;
176179 } ) ;
180+
181+ describe ( 'FlagCell' , ( ) => {
182+ // Patient whose summary stats sit within every flag threshold, so no flag applies
183+ const meetingTargetsPatient = {
184+ summary : {
185+ cgmStats : {
186+ periods : {
187+ '14d' : {
188+ timeInVeryLowPercent : 0.004 ,
189+ timeInAnyLowPercent : 0.03 ,
190+ timeInTargetPercentDelta : - 0.05 ,
191+ timeInAnyHighPercent : 0.2 ,
192+ timeInVeryHighPercent : 0.04 ,
193+ timeCGMUsePercent : 0.85 ,
194+ } ,
195+ } ,
196+ } ,
197+ } ,
198+ } ;
199+
200+ const ui = ( props ) => < Provider store = { store } > < FlagCell { ...props } /> </ Provider > ;
201+
202+ it ( 'flags the highest-priority range whose threshold the summary meets' , ( ) => {
203+ let patient ;
204+
205+ // No flag when the summary is within every threshold
206+ patient = cloneDeep ( meetingTargetsPatient ) ;
207+ const { container, rerender } = render ( ui ( { patient } ) ) ;
208+ expect ( container ) . toBeEmptyDOMElement ( ) ;
209+
210+ // Time in very low at or above 1% flags Very Low
211+ patient = cloneDeep ( meetingTargetsPatient ) ;
212+ patient . summary . cgmStats . periods [ '14d' ] . timeInVeryLowPercent = 0.0134 ;
213+ rerender ( ui ( { patient } ) ) ;
214+ expect ( screen . getByText ( 'Very Low' ) ) . toBeInTheDocument ( ) ;
215+
216+ // Time in any low at or above 4% flags Low
217+ patient = cloneDeep ( meetingTargetsPatient ) ;
218+ patient . summary . cgmStats . periods [ '14d' ] . timeInAnyLowPercent = 0.0568 ;
219+ rerender ( ui ( { patient } ) ) ;
220+ expect ( screen . getByText ( 'Low' ) ) . toBeInTheDocument ( ) ;
221+ expect ( screen . queryByText ( 'Very Low' ) ) . not . toBeInTheDocument ( ) ;
222+
223+ // Drop in time in target at or below -15% flags Drop in TIR
224+ patient = cloneDeep ( meetingTargetsPatient ) ;
225+ patient . summary . cgmStats . periods [ '14d' ] . timeInTargetPercentDelta = - 0.1523 ;
226+ rerender ( ui ( { patient } ) ) ;
227+ expect ( screen . getByText ( 'Drop in TIR' ) ) . toBeInTheDocument ( ) ;
228+
229+ // Time in any high at or above 25% flags High
230+ patient = cloneDeep ( meetingTargetsPatient ) ;
231+ patient . summary . cgmStats . periods [ '14d' ] . timeInAnyHighPercent = 0.2733 ;
232+ rerender ( ui ( { patient } ) ) ;
233+ expect ( screen . getByText ( 'High' ) ) . toBeInTheDocument ( ) ;
234+
235+ // Time in very high at or above 5% flags Very High
236+ patient = cloneDeep ( meetingTargetsPatient ) ;
237+ patient . summary . cgmStats . periods [ '14d' ] . timeInVeryHighPercent = 0.0722 ;
238+ rerender ( ui ( { patient } ) ) ;
239+ expect ( screen . getByText ( 'Very High' ) ) . toBeInTheDocument ( ) ;
240+
241+ // CGM use below 70% flags Low CGM Wear
242+ patient = cloneDeep ( meetingTargetsPatient ) ;
243+ patient . summary . cgmStats . periods [ '14d' ] . timeCGMUsePercent = 0.65 ;
244+ rerender ( ui ( { patient } ) ) ;
245+ expect ( screen . getByText ( 'Low CGM Wear' ) ) . toBeInTheDocument ( ) ;
246+
247+ // When several thresholds are met, only the highest-priority flag shows
248+ patient = cloneDeep ( meetingTargetsPatient ) ;
249+ patient . summary . cgmStats . periods [ '14d' ] . timeInVeryLowPercent = 0.0134 ;
250+ patient . summary . cgmStats . periods [ '14d' ] . timeInAnyLowPercent = 0.0568 ;
251+ rerender ( ui ( { patient } ) ) ;
252+
253+ expect ( screen . getByText ( 'Very Low' ) ) . toBeInTheDocument ( ) ;
254+ expect ( screen . queryByText ( 'Low' ) ) . not . toBeInTheDocument ( ) ;
255+ } ) ;
256+
257+ it ( 'flags the current category ahead of a higher-priority flag' , ( ) => {
258+ // The summary meets both the Very Low and Low thresholds, which would normally flag Very Low
259+ let patient = cloneDeep ( meetingTargetsPatient ) ;
260+ patient . summary . cgmStats . periods [ '14d' ] . timeInVeryLowPercent = 0.0134 ;
261+ patient . summary . cgmStats . periods [ '14d' ] . timeInAnyLowPercent = 0.0568 ;
262+
263+ renderComponent ( < FlagCell patient = { patient } category = { CATEGORY . ANY_LOW } /> ) ;
264+
265+ // The current dashboard category wins
266+ expect ( screen . getByText ( 'Low' ) ) . toBeInTheDocument ( ) ;
267+ expect ( screen . queryByText ( 'Very Low' ) ) . not . toBeInTheDocument ( ) ;
268+ } ) ;
269+ } ) ;
177270} ) ;
0 commit comments