diff --git a/package.serve.json b/package.serve.json
index ff9bf5879..02b2db208 100644
--- a/package.serve.json
+++ b/package.serve.json
@@ -90,7 +90,8 @@
"react-native-web": "^0.19.7",
"react-native-web-webview": "^1.0.2",
"react-qr-code": "^2.0.11",
- "shelljs": "^0.8.5"
+ "shelljs": "^0.8.5",
+ "setimmediate": "^1.0.5"
},
"cordova": {
"platforms": [
diff --git a/www/__tests__/Carousel.test.tsx b/www/__tests__/Carousel.test.tsx
index 7b8601109..d523f3afc 100644
--- a/www/__tests__/Carousel.test.tsx
+++ b/www/__tests__/Carousel.test.tsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { render } from '@testing-library/react-native';
+import { render, fireEvent } from '@testing-library/react-native';
import { View } from 'react-native';
import Carousel from '../js/components/Carousel';
@@ -23,4 +23,32 @@ describe('Carousel component', () => {
expect(renderedChild1).toBeTruthy();
expect(renderedChild2).toBeTruthy();
});
+
+ it('scrolls correctly to the next card', () => {
+ const { getByTestId } = render(
+
+ {child1}
+ {child2}
+ ,
+ );
+
+ const scrollView = getByTestId('carousel');
+ fireEvent.scroll(scrollView, {
+ // Scroll to the second card
+ nativeEvent: {
+ contentOffset: {
+ x: cardWidth + cardMargin,
+ },
+ contentSize: {
+ width: (cardWidth + cardMargin) * 2,
+ },
+ layoutMeasurement: {
+ width: cardWidth + cardMargin,
+ },
+ },
+ });
+
+ expect(scrollView.props.horizontal).toBe(true);
+ expect(scrollView.props.snapToInterval).toBe(cardWidth + cardMargin);
+ });
});
diff --git a/www/__tests__/DateSelect.test.tsx b/www/__tests__/DateSelect.test.tsx
index 79fdc1997..e66424f17 100644
--- a/www/__tests__/DateSelect.test.tsx
+++ b/www/__tests__/DateSelect.test.tsx
@@ -1,19 +1,81 @@
import React from 'react';
-import { render, screen } from '@testing-library/react-native';
+import { render, screen, fireEvent, waitFor } from '@testing-library/react-native';
import DateSelect from '../js/diary/list/DateSelect';
+import { DateTime } from 'luxon';
+import TimelineContext from '../js/TimelineContext';
+import initializedI18next from '../js/i18nextInit';
+window['i18next'] = initializedI18next;
jest.mock('react-native-safe-area-context', () => ({
useSafeAreaInsets: () => ({ bottom: 30, left: 0, right: 0, top: 30 }),
}));
-jest.spyOn(React, 'useState').mockImplementation((initialValue) => [initialValue, jest.fn()]);
-jest.spyOn(React, 'useEffect').mockImplementation((effect: () => void) => effect());
+
+jest.mock('react', () => ({
+ ...jest.requireActual('react'),
+ useMemo: (fn) => fn(),
+ useCallback: (fn) => fn,
+}));
describe('DateSelect', () => {
- it('renders correctly', () => {
+ const pipelineRangeMock = {
+ start_ts: DateTime.local().set({ month: 5, day: 20 }).startOf('day').toSeconds(),
+ end_ts: DateTime.local()
+ .set({ month: 5, day: 30 })
+ .endOf('day')
+ .set({ millisecond: 0 })
+ .toSeconds(),
+ };
+
+ const queriedDateRangeMock = [
+ DateTime.local().set({ month: 5, day: 20 }).startOf('day').toISO(),
+ DateTime.local().set({ month: 5, day: 30 }).endOf('day').set({ millisecond: 0 }).toISO(),
+ ];
+
+ const contextValue = {
+ pipelineRange: pipelineRangeMock,
+ queriedDateRange: queriedDateRangeMock,
+ };
+
+ it('renders correctly DatePickerModal after clicking the button and save date correctly', async () => {
const onChooseMock = jest.fn();
- const { getByText } = render();
+ render(
+
+
+ ,
+ );
+ // check if DateSelect rendered correctly
expect(screen.getByTestId('button-container')).toBeTruthy();
expect(screen.getByTestId('button')).toBeTruthy();
+ expect(screen.getByText('5/20/2024')).toBeTruthy();
+
+ fireEvent.press(screen.getByTestId('button'));
+ await waitFor(() => {
+ // 'save' and 'close' buttons should pop up correctly after DateSelect Modal Opens
+ expect(screen.getByTestId('react-native-paper-dates-close')).toBeTruthy();
+ expect(screen.getByTestId('react-native-paper-dates-save-text')).toBeTruthy();
+ });
+
+ // check if date changes corretly
+ // Start Date : 05/20/24 -> 05/25/2024
+ fireEvent.changeText(screen.getAllByTestId('text-input-flat')[0], '05/25/2024');
+ expect(screen.queryByDisplayValue('May 20')).toBeNull();
+ expect(screen.getByText('May 25')).toBeTruthy();
+ // End Date : 05/30/24 -> 05/28/2024
+ fireEvent.changeText(screen.getAllByTestId('text-input-flat')[1], '05/28/2024');
+ expect(screen.queryByDisplayValue('May 30')).toBeNull();
+ expect(screen.getByText('May 28')).toBeTruthy();
+
+ // check if onChoose function gets called with changed dates after clicking 'save' button.
+ fireEvent.press(screen.getByTestId('react-native-paper-dates-save-text'));
+ const expectedParams = {
+ startDate: DateTime.local().set({ month: 5, day: 25 }).startOf('day').toJSDate(),
+ endDate: DateTime.local()
+ .set({ month: 5, day: 28 })
+ .endOf('day')
+ .set({ millisecond: 0 })
+ .toJSDate(),
+ };
+ expect(onChooseMock).toHaveBeenCalledWith(expectedParams);
});
});
diff --git a/www/__tests__/metricsHelper.test.ts b/www/__tests__/metricsHelper.test.ts
index c914c5782..dbbf32c35 100644
--- a/www/__tests__/metricsHelper.test.ts
+++ b/www/__tests__/metricsHelper.test.ts
@@ -23,14 +23,23 @@ window['i18next'] = initializedI18next;
describe('metricsHelper', () => {
describe('getUniqueLabelsForDays', () => {
- const days1 = [
- { mode_confirm_a: 1, mode_confirm_b: 2 },
- { mode_confirm_b: 1, mode_confirm_c: 3 },
- { mode_confirm_c: 1, mode_confirm_d: 3 },
- ] as any as DayOfMetricData[];
it("should return unique labels for days with 'mode_confirm_*'", () => {
+ const days1 = [
+ { mode_confirm_a: 1, mode_confirm_b: 2 },
+ { mode_confirm_b: 1, mode_confirm_c: 3 },
+ { mode_confirm_c: 1, mode_confirm_d: 3 },
+ ] as any as DayOfMetricData[];
expect(getUniqueLabelsForDays(days1)).toEqual(['a', 'b', 'c', 'd']);
});
+
+ it('should return unique labels for days with duplicated labels', () => {
+ const days2 = [
+ { mode_confirm_a: 1, mode_confirm_b: 2 },
+ { mode_confirm_a: 1, mode_confirm_b: 2 },
+ { mode_confirm_a: 1, mode_confirm_b: 2 },
+ ] as any as DayOfMetricData[];
+ expect(getUniqueLabelsForDays(days2)).toEqual(['a', 'b']);
+ });
});
describe('getLabelsForDay', () => {
@@ -229,17 +238,17 @@ describe('metricsHelper', () => {
expect(result).toBe(true);
});
- it('returns true for all sensed labels', () => {
+ it('returns false for all sensed labels', () => {
const modeMap = [
{
- key: 'label_mode1',
+ key: 'SENSED_MODE_1',
values: [
['value1', 10],
['value2', 20],
],
},
{
- key: 'label_mode2',
+ key: 'SENSED_MODE_2',
values: [
['value3', 30],
['value4', 40],
@@ -247,7 +256,7 @@ describe('metricsHelper', () => {
},
];
const result = isCustomLabels(modeMap);
- expect(result).toBe(true);
+ expect(result).toBe(false);
});
it('returns false for mixed custom and sensed labels', () => {
diff --git a/www/js/components/Carousel.tsx b/www/js/components/Carousel.tsx
index 8afe6624a..81740fc8b 100644
--- a/www/js/components/Carousel.tsx
+++ b/www/js/components/Carousel.tsx
@@ -10,6 +10,7 @@ const Carousel = ({ children, cardWidth, cardMargin }: Props) => {
const numCards = React.Children.count(children);
return (
& {
mode: 'single' | 'range';
@@ -72,6 +74,7 @@ const DateSelect = ({ mode, onChoose, ...rest }: Props) => {
return (
<>