diff --git a/tests/unit/composables/usePlotTooltips.spec.ts b/tests/unit/composables/usePlotTooltips.spec.ts
index 64695953..c94f4f12 100644
--- a/tests/unit/composables/usePlotTooltips.spec.ts
+++ b/tests/unit/composables/usePlotTooltips.spec.ts
@@ -6,7 +6,8 @@ import { nextTick } from "vue";
import usePlotTooltips from '@/composables/usePlotTooltips';
import { useAppStore } from '@/stores/appStore';
import { useColorStore } from '@/stores/colorStore';
-import { Axis, Dimension, type PointWithMetadata } from '@/types';
+import { useDataStore } from '@/stores/dataStore';
+import { Axis, Dimension, SummaryTableColumn, type PointWithMetadata, type SummaryTableDataRow } from '@/types';
describe('usePlotTooltips', () => {
beforeEach(() => {
@@ -28,14 +29,13 @@ describe('usePlotTooltips', () => {
const appStore = useAppStore();
const colorStore = useColorStore();
- // Set up store state for location-based coloring
appStore.filters = {
[Dimension.LOCATION]: ['AFG', 'global'],
[Dimension.DISEASE]: ['Cholera'],
};
expect(colorStore.colorDimension).toBe(Dimension.LOCATION);
+ expect(appStore.dimensions.row).toBe(Dimension.DISEASE);
- // Set colors so colorStore has the mapping
colorStore.setColors([afgPointMetadata, globalPointMetadata]);
const { tooltipCallback } = usePlotTooltips();
@@ -44,12 +44,15 @@ describe('usePlotTooltips', () => {
expect(afgTooltip).toContain('Location: Afghanistan');
expect(afgTooltip).toContain('style="color: #009d9a'); // teal50
+ // Row dimension (disease) is shown because it's different from color dimension (location)
+ expect(afgTooltip).toContain('Disease: Cholera');
expect(afgTooltip).not.toContain('Activity type');
const globalTooltip = tooltipCallback({ x: 1, y: 2, metadata: globalPointMetadata.metadata! });
expect(globalTooltip).toContain('Location: All 117 VIMC countries');
expect(globalTooltip).toContain('style="color: #6929c4'); // purple70
+ expect(globalTooltip).toContain('Disease: Cholera');
expect(globalTooltip).not.toContain('Activity type');
});
@@ -60,12 +63,12 @@ describe('usePlotTooltips', () => {
const appStore = useAppStore();
const colorStore = useColorStore();
- // Set up store state for disease-based coloring
appStore.filters = {
[Dimension.LOCATION]: ['AFG'],
[Dimension.DISEASE]: ['Cholera', 'Measles'],
};
expect(colorStore.colorDimension).toBe(Dimension.DISEASE);
+ expect(appStore.dimensions.row).toBe(Dimension.DISEASE);
colorStore.setColors([choleraPointMetadata, measlesPointMetadata]);
@@ -75,12 +78,16 @@ describe('usePlotTooltips', () => {
expect(choleraTooltip).toContain('Disease: Cholera');
expect(choleraTooltip).toContain('style="color: #6929c4'); // purple70
+ // Row dimension (disease) is NOT shown separately because it's the same as color dimension
+ expect(choleraTooltip.match(/Disease:/g)?.length).toBe(1);
expect(choleraTooltip).not.toContain('Activity type');
const measlesTooltip = tooltipCallback({ x: 1, y: 2, metadata: measlesPointMetadata.metadata! });
expect(measlesTooltip).toContain('Disease: Measles');
expect(measlesTooltip).toContain('style="color: #009d9a'); // teal50
+ // Row dimension (disease) is NOT shown separately because it's the same as color dimension
+ expect(measlesTooltip.match(/Disease:/g)?.length).toBe(1);
expect(measlesTooltip).not.toContain('Activity type');
});
@@ -95,13 +102,13 @@ describe('usePlotTooltips', () => {
await nextTick();
expect(appStore.dimensions.column).toBe(Dimension.ACTIVITY_TYPE);
- // Set up store state for disease-based coloring (single location)
appStore.filters = {
[Dimension.LOCATION]: ['AFG'],
[Dimension.DISEASE]: ['Cholera'],
[Dimension.ACTIVITY_TYPE]: ['routine', 'campaign'],
};
expect(colorStore.colorDimension).toBe(Dimension.DISEASE);
+ expect(appStore.dimensions.row).toBe(Dimension.DISEASE);
colorStore.setColors([routinePointMetadata, campaignPointMetadata]);
@@ -110,13 +117,90 @@ describe('usePlotTooltips', () => {
const routineTooltip = tooltipCallback({ x: 1, y: 2, metadata: routinePointMetadata.metadata! });
expect(routineTooltip).toContain('Disease: Cholera');
expect(routineTooltip).toContain('Activity type: Routine');
+ // Row dimension (disease) is NOT shown separately because it's the same as color dimension
+ expect(routineTooltip.match(/Disease:/g)?.length).toBe(1);
expect(routineTooltip).toContain('style="color: #6929c4'); // purple70
const campaignTooltip = tooltipCallback({ x: 1, y: 2, metadata: campaignPointMetadata.metadata! });
expect(campaignTooltip).toContain('Disease: Cholera');
expect(campaignTooltip).toContain('Activity type: Campaign');
+ // Row dimension (disease) is NOT shown separately because it's the same as color dimension
+ expect(campaignTooltip.match(/Disease:/g)?.length).toBe(1);
expect(campaignTooltip).toContain('style="color: #6929c4'); // purple70
});
+
+ it('displays summary data (median, mean, and 95% confidence interval) in tooltip', () => {
+ const afgPointMetadata = { metadata: { [Axis.WITHIN_BAND]: 'AFG', [Axis.ROW]: 'Cholera', [Axis.COLUMN]: '' } };
+
+ const appStore = useAppStore();
+ const colorStore = useColorStore();
+ const dataStore = useDataStore();
+
+ appStore.filters = {
+ [Dimension.LOCATION]: ['AFG'],
+ [Dimension.DISEASE]: ['Cholera'],
+ };
+
+ colorStore.setColors([afgPointMetadata]);
+
+ dataStore.summaryTableData = [
+ {
+ [Dimension.LOCATION]: 'AFG',
+ [Dimension.DISEASE]: 'Cholera',
+ [SummaryTableColumn.MEDIAN]: 1234.56,
+ [SummaryTableColumn.MEAN]: 1456.78,
+ [SummaryTableColumn.CI_LOWER]: 789.12,
+ [SummaryTableColumn.CI_UPPER]: 2345.67,
+ } as SummaryTableDataRow,
+ ];
+
+ const { tooltipCallback } = usePlotTooltips();
+
+ const tooltip = tooltipCallback({ x: 1, y: 2, metadata: afgPointMetadata.metadata! });
+
+ expect(tooltip).toContain('Median: 1234.56');
+ expect(tooltip).toContain('Mean: 1456.78');
+ expect(tooltip).toContain('95% confidence interval:');
+ expect(tooltip).toContain('789.12');
+ expect(tooltip).toContain('2345.67');
+ });
+
+ it('handles negative confidence interval values with appropriate sign', () => {
+ const afgPointMetadata = { metadata: { [Axis.WITHIN_BAND]: 'AFG', [Axis.ROW]: 'Cholera', [Axis.COLUMN]: '' } };
+
+ const appStore = useAppStore();
+ const colorStore = useColorStore();
+ const dataStore = useDataStore();
+
+ appStore.filters = {
+ [Dimension.LOCATION]: ['AFG'],
+ [Dimension.DISEASE]: ['Cholera'],
+ };
+
+ colorStore.setColors([afgPointMetadata]);
+
+ // Set up summary table data with negative lower bound (crossing zero)
+ dataStore.summaryTableData = [
+ {
+ [Dimension.LOCATION]: 'AFG',
+ [Dimension.DISEASE]: 'Cholera',
+ [SummaryTableColumn.MEDIAN]: 50.00,
+ [SummaryTableColumn.MEAN]: 55.00,
+ [SummaryTableColumn.CI_LOWER]: -100.50,
+ [SummaryTableColumn.CI_UPPER]: 200.75,
+ } as SummaryTableDataRow,
+ ];
+
+ const { tooltipCallback } = usePlotTooltips();
+
+ const tooltip = tooltipCallback({ x: 1, y: 2, metadata: afgPointMetadata.metadata! });
+
+ expect(tooltip).toContain('Median: 50.00');
+ expect(tooltip).toContain('Mean: 55.00');
+ // Check negative lower bound and positive upper bound with + sign when interval crosses zero
+ expect(tooltip).toContain('-100.50');
+ expect(tooltip).toContain('+200.75');
+ });
});
});