Skip to content

Infra/picker testing coverage #3107

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jun 27, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/components/picker/Picker.driver.new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,18 @@ export const PickerDriver = (props: ComponentProps) => {
itemDriver.press();
};

const getInput = () => {
return textFieldDriver;
};

return {
getValue,
open,
cancel,
done,
isOpen,
dismissDialog,
selectItem
selectItem,
getInput
};
};
220 changes: 140 additions & 80 deletions src/components/picker/__tests__/index.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useState} from 'react';
import {act, render, waitFor} from '@testing-library/react-native';
import {act, render, waitFor, screen} from '@testing-library/react-native';
import {Typography} from '../../../style';
import Picker from '../index';
import {PickerDriver} from '../Picker.driver.new';
const countries = [
Expand Down Expand Up @@ -27,38 +28,26 @@ const getDriver = (props?: any) => {
return PickerDriver({renderTree: render(<TestCase {...props}/>), testID});
};

const onPress = jest.fn();
const onDismiss = jest.fn();
// const onShow = jest.fn();

describe('Picker', () => {
beforeEach(() => {
jest.clearAllMocks();
});

describe('Modal', () => {
describe('Test value', () => {
it('Get correct value of a single item', () => {
const driver = getDriver({value: countries[2].value});
expect(driver.getValue()).toEqual(countries[2].label);
});

it('Get correct value of multiple selected items', () => {
const driver = getDriver({value: [countries[2].value, countries[4].value]});
expect(driver.getValue()).toEqual(`${countries[2].label}, ${countries[4].label}`);
});
});

describe('Test open', () => {
it('Should open when enabled', () => {
const driver = getDriver();

expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
});

it('Should not open when disabled', () => {
const driver = getDriver({editable: false});

expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeFalsy();
Expand All @@ -67,19 +56,28 @@ describe('Picker', () => {

it('Test close', () => {
const driver = getDriver();

expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.cancel();
expect(driver.isOpen()).toBeFalsy();
});

describe('Test value', () => {
it('Get correct value of a single item', () => {
const driver = getDriver({value: countries[2].value});
expect(driver.getValue()).toEqual(countries[2].label);
});

it('Get correct value of multiple selected items', () => {
const driver = getDriver({value: [countries[2].value, countries[4].value]});
expect(driver.getValue()).toEqual(`${countries[2].label}, ${countries[4].label}`);
});
});

describe('Test selection', () => {
it('Should select a single item', () => {
const driver = getDriver();
expect(driver.getValue()).toEqual('');
expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.selectItem(countries[2].label);
Expand All @@ -90,7 +88,6 @@ describe('Picker', () => {
it('Should select multiple items', () => {
const driver = getDriver({mode: 'MULTI'});
expect(driver.getValue()).toEqual('');
expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.selectItem(countries[2].label);
Expand All @@ -100,122 +97,185 @@ describe('Picker', () => {
});
});

it('Test onDismiss', () => {
const driver = getDriver({
pickerModalProps: {
onDismiss
}
});

expect(driver.isOpen()).toBeFalsy();
it('Test onPress', () => {
const driver = getDriver({onPress});
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.cancel();
expect(driver.isOpen()).toBeFalsy();
expect(onDismiss).toHaveBeenCalledTimes(2); // TODO: this should be 1
expect(onPress).toHaveBeenCalled();
});

describe('Test pickerModalProps', () => {
it('Test onDismiss', () => {
const driver = getDriver({
pickerModalProps: {
onDismiss
}
});
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.cancel();
expect(driver.isOpen()).toBeFalsy();
expect(onDismiss).toHaveBeenCalledTimes(2); // TODO: this should be 1
});

// TODO: this test is not passing yet
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When should this start working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue here is that the onShow function is triggered only when the modal is fully open.
Iv'e tried to use act and waitFor didn't help.

I'll change the TODO comment to fix this test in the future, WDYT ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't matter IMO

// it('Test onShow passed via pickerModalProps', async () => {
// const driver = getDriver({
// pickerModalProps: {
// onShow
// }
// });
// expect(driver.isOpen()).toBeFalsy();
// jest.useFakeTimers();
// expect(driver.isOpen()).toBeTruthy();
// expect(onShow).toHaveBeenCalled();
// });

describe('Test Modal TopBar', () => {
it('should close and select items when pressing on cancel button', () => {
const driver = getDriver({mode: 'MULTI', topBarProps: {cancelLabel: 'Cancel'}});
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.selectItem(countries[2].label);
driver.selectItem(countries[4].label);
driver.done();
expect(driver.isOpen()).toBeFalsy();
expect(driver.getValue()).toEqual(`${countries[2].label}, ${countries[4].label}`);
});

it('should close without selecting items when pressing on cancel button', () => {
const driver = getDriver({mode: 'MULTI', topBarProps: {cancelLabel: 'Cancel'}});
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.selectItem(countries[2].label);
driver.selectItem(countries[4].label);
driver.cancel();
expect(driver.getValue()).toEqual(``);
expect(driver.isOpen()).toBeFalsy();
});
});
});
});

// TODO: this is a work in progress, the tests are not passing yet
describe.skip('Dialog', () => {
describe('Dialog', () => {
const dialogProps = {useDialog: true, customPickerProps: {migrateDialog: true}};
describe('Test value', () => {
it('Get correct value of a single item', () => {
const driver = getDriver({
useDialog: true,
customPickerProps: {migrateDialog: true},
...dialogProps,
value: countries[2].value
});
expect(driver.getValue()).toEqual(countries[2].label);
});

it('Get correct value of multiple selected items', () => {
const driver = getDriver({
useDialog: true,
customPickerProps: {migrateDialog: true},
...dialogProps,
value: [countries[2].value, countries[4].value]
});
expect(driver.getValue()).toEqual(`${countries[2].label}, ${countries[4].label}`);
});
});

describe('Test open', () => {
describe('Test open/close', () => {
it('Should open when enabled', async () => {
const driver = getDriver({useDialog: true, customPickerProps: {migrateDialog: true}});

const driver = getDriver(dialogProps);
expect(driver.isOpen()).toBeFalsy();
// driver.open();
// expect(driver.isOpen()).toBeTruthy();
jest.useFakeTimers();
act(() => driver.open());
jest.runAllTimers();
// advanceAnimationByTime(10000);
// await new Promise(r => setTimeout(r, 1000));
await waitFor(() => expect(driver.isOpen()).toBeTruthy());
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeTruthy());
});

it('Should not open when disabled', () => {
const driver = getDriver({useDialog: true, customPickerProps: {migrateDialog: true}, editable: false});

expect(driver.isOpen()).toBeFalsy();
driver.open();
it('Should not open when disabled', async () => {
const driver = getDriver({...dialogProps, editable: false});
expect(driver.isOpen()).toBeFalsy();
act(() => driver.open());
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeFalsy());
});
});

it('Test close', () => {
const driver = getDriver({useDialog: true, customPickerProps: {migrateDialog: true}});

expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.cancel();
expect(driver.isOpen()).toBeFalsy();
it('Test close', async () => {
const driver = getDriver(dialogProps);
expect(driver.isOpen()).toBeFalsy();
act(() => driver.open());
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeTruthy());
act(() => driver.dismissDialog());
await waitFor(() => expect(driver.dismissDialog(dialogProps.useDialog)).toBeFalsy());
});
});

describe('Test selection', () => {
it('Should select a single item', () => {
const driver = getDriver({useDialog: true, customPickerProps: {migrateDialog: true}});
expect(driver.getValue()).toEqual(undefined);
expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
it('Should select a single item', async () => {
const driver = getDriver(dialogProps);
expect(driver.getValue()).toEqual('');
act(() => driver.open());
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeTruthy());
driver.selectItem(countries[2].label);
expect(driver.isOpen()).toBeFalsy();
act(() => driver.dismissDialog());
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeFalsy());
expect(driver.getValue()).toEqual(countries[2].label);
});

it('Should select multiple items', () => {
const driver = getDriver({useDialog: true, customPickerProps: {migrateDialog: true}, mode: 'MULTI'});
expect(driver.getValue()).toEqual(undefined);
it('Should select multiple items', async () => {
const driver = getDriver({...dialogProps, mode: 'MULTI'});
expect(driver.getValue()).toEqual('');
expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
act(() => driver.open());
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeTruthy());
driver.selectItem(countries[2].label);
driver.selectItem(countries[4].label);
driver.done();
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeFalsy());
expect(driver.getValue()).toEqual(`${countries[2].label}, ${countries[4].label}`);
});
});

it('Test onDismiss', () => {
it('Test onDismiss', async () => {
const driver = getDriver({
useDialog: true,
customPickerProps: {migrateDialog: true},
pickerModalProps: {
onDismiss
...dialogProps,
customPickerProps: {
dialogProps: {
onDismiss
}
}
});

expect(driver.isOpen()).toBeFalsy();
driver.open();
expect(driver.isOpen()).toBeTruthy();
driver.cancel();
expect(driver.isOpen()).toBeFalsy();
expect(onDismiss).toHaveBeenCalledTimes(2); // TODO: this should be 1
act(() => driver.open());
await waitFor(() => expect(driver.isOpen(dialogProps.useDialog)).toBeTruthy());
act(() => driver.dismissDialog());
await waitFor(() => expect(driver.dismissDialog(dialogProps.useDialog)).toBeFalsy());
expect(onDismiss).toHaveBeenCalledTimes(1);
});
});

// TODO: add tests for WheelPicker as well
// TODO: add tests for WheelPicker
// Note: the picker dialog should be opened and then the wheel picker should be rendered, this is the main issue with testing it for now
// describe.skip('WheelPicker', () => {
// });

//TODO: add more tests for different props
describe('Picker field types', () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are failing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, bad merging from master after merging the new useFieldType hook.

it('should render a form picker', () => {
const driver = getDriver({fieldType: 'form'});
const textFieldDriver = driver.getInput();
act(() => expect(textFieldDriver.exists()).toBeTruthy());
expect(textFieldDriver.getStyle()).toEqual(expect.objectContaining({textAlign: 'left'}));
});
it('should render a filter picker', () => {
const driver = getDriver({fieldType: 'filter'});
screen.debug();
const textFieldDriver = driver.getInput();
act(() => expect(textFieldDriver.exists()).toBeTruthy());
expect(textFieldDriver.getStyle()).toEqual(expect.objectContaining(Typography.text70));
});
it('should render a settings picker', async () => {
const driver = getDriver({fieldType: 'settings'});
const textFieldDriver = driver.getInput();
act(() => expect(textFieldDriver.exists()).toBeTruthy());
console.log(`textFieldDriver.getStyle():`, textFieldDriver.getStyle());
expect(textFieldDriver.getStyle()).toEqual(expect.objectContaining(Typography.text70));
});
});
});
8 changes: 5 additions & 3 deletions src/components/picker/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
preset: preset || null,
containerStyle: {flexDirection: 'row'},
labelStyle: Typography.text70,
trailingAccessory: themeProps.trailingAccessory ?? <Icon marginL-s1 source={dropdown}/>
trailingAccessory: themeProps.trailingAccessory ?? (
<Icon marginL-s1 source={dropdown} testID={`${testID}.input.icon`}/>
)
};
} else if (fieldType === PickerFieldTypes.settings) {
return {
Expand Down Expand Up @@ -275,14 +277,14 @@ const Picker = React.forwardRef((props: PickerProps, ref) => {
const renderPickerInnerInput = () => {
if (fieldType === PickerFieldTypes.filter) {
return (
<Text text70 numberOfLines={1} style={others.style}>
<Text text70 numberOfLines={1} style={others.style} testID={`${testID}.input`}>
{_.isEmpty(label) ? others.placeholder : label}
</Text>
);
} else if (fieldType === PickerFieldTypes.settings) {
return (
<View flexG row spread>
<Text text70 style={labelStyle}>
<Text text70 style={labelStyle} testID={`${testID}.input`}>
{others.label}
</Text>
<Text text70 $textPrimary style={others.style}>
Expand Down
Loading