Skip to content

Dialog - useHiddenLocation, added reduce motion listener for testing on Android. #3739

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

Closed
wants to merge 9 commits into from
Closed
14 changes: 14 additions & 0 deletions jestSetup/jest-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Object.defineProperties = (obj, props) => {
global._UILIB_TESTING = true;

jest.spyOn(AccessibilityInfo, 'isScreenReaderEnabled').mockImplementation(() => Promise.resolve(false));
jest.spyOn(AccessibilityInfo, 'isReduceMotionEnabled').mockImplementation(() => Promise.resolve(false));

// mock native modules
jest.mock('@react-native-community/blur', () => {});
Expand Down Expand Up @@ -98,6 +99,15 @@ jest.mock('react-native', () => {
const reactNative = jest.requireActual('react-native');
reactNative.NativeModules.KeyboardTrackingViewTempManager = {};
reactNative.NativeModules.StatusBarManager = {getHeight: jest.fn()};

reactNative.AccessibilityInfo = {
...reactNative.AccessibilityInfo,
isScreenReaderEnabled: jest.fn(() => Promise.resolve(false)),
isReduceMotionEnabled: jest.fn(() => Promise.resolve(false)),
addEventListener: jest.fn(),
removeEventListener: jest.fn()
};

const OriginalModal = reactNative.Modal;
const React = jest.requireActual('react');
const useDidUpdate = require('./useDidUpdate').default;
Expand Down Expand Up @@ -152,3 +162,7 @@ jest.mock('../src/optionalDependencies', () => {
DateTimePickerPackage: view
};
});

// Ensure AccessibilityInfo mocks are available globally after react-native mock
const RN = require('react-native');
global.AccessibilityInfo = RN.AccessibilityInfo;
11 changes: 10 additions & 1 deletion src/commons/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,28 @@ export function updateConstants(dimensions: any) {
}

const accessibility = {
isScreenReaderEnabled: false
isScreenReaderEnabled: false,
isReduceMotionEnabled: false
};

function handleScreenReaderChanged(isScreenReaderEnabled: AccessibilityChangeEvent) {
accessibility.isScreenReaderEnabled = isScreenReaderEnabled as boolean;
}

function handleReduceMotionChanged(isReduceMotionEnabled: AccessibilityChangeEvent) {
accessibility.isReduceMotionEnabled = isReduceMotionEnabled as boolean;
}

AccessibilityInfo.addEventListener('screenReaderChanged', handleScreenReaderChanged);
AccessibilityInfo.addEventListener('reduceMotionChanged', handleReduceMotionChanged);

function setAccessibility() {
AccessibilityInfo.isScreenReaderEnabled().then(isScreenReaderEnabled => {
accessibility.isScreenReaderEnabled = isScreenReaderEnabled;
});
AccessibilityInfo.isReduceMotionEnabled().then(isReduceMotionEnabled => {
accessibility.isReduceMotionEnabled = isReduceMotionEnabled;
});
}

setAccessibility();
Expand Down
17 changes: 15 additions & 2 deletions src/hooks/useOrientation/__tests__/useOrientation.spec.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,33 @@
import {renderHook, act} from '@testing-library/react-hooks';

jest.mock('../../../commons/new', () => {
return {
Constants: {
orientation: 'portrait',
addDimensionsEventListener: jest.fn(),
removeDimensionsEventListener: jest.fn()
}
};
});

let Constants;
let useOrientation;
let orientationChangeListeners;

describe('useOrientation hook', () => {
beforeEach(() => {
jest.mock('../../../commons/Constants');
Constants = require('../../../commons/Constants').default;
const {Constants: MockedConstants} = require('../../../commons/new');
Constants = MockedConstants;
useOrientation = require('../index').default;

orientationChangeListeners = [];

Constants.addDimensionsEventListener = jest.fn(callback => {
orientationChangeListeners.push(callback);
return {remove: jest.fn()};
});

Constants.removeDimensionsEventListener = jest.fn();
});

it('should return current orientation', () => {
Expand Down
15 changes: 14 additions & 1 deletion src/incubator/dialog/__tests__/index.new.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {useRef, useState, useEffect, useCallback} from 'react';
import {render, act} from '@testing-library/react-native';
import {AccessibilityInfo} from 'react-native';
import Dialog, {DialogProps} from '../index';
import {DialogDriver} from '../Dialog.driver.new';
import View from '../../../components/view';
Expand All @@ -22,7 +23,7 @@ const defaultProps = {
centerH: true
};

const TestCase2 = props => {
const TestCase2 = (props: any) => {
const [visible, setVisible] = useState(props.visible);

useEffect(() => {
Expand Down Expand Up @@ -108,4 +109,16 @@ describe('Incubator.Dialog sanity checks', () => {
expect(dialogDriver.exists()).toBeFalsy();
expect(dialogDriver.isVisible()).toBeFalsy();
});

it('Should show and dismiss dialog immediately when reduce motion is enabled', async () => {
jest.spyOn(AccessibilityInfo, 'isReduceMotionEnabled').mockResolvedValue(true);
const dismissFn = jest.fn();
const {dialogDriver} = getDriver(<TestCase1 visible onDismiss={dismissFn}/>);
expect(dialogDriver.isVisible()).toBeTruthy();
expect(dismissFn).not.toHaveBeenCalled();
dialogDriver.pressOnBackground();
expect(dialogDriver.isVisible()).toBeFalsy();
expect(dismissFn).toHaveBeenCalledTimes(1);
jest.restoreAllMocks();
});
});
13 changes: 11 additions & 2 deletions src/incubator/dialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,22 @@ const Dialog = (props: DialogProps, ref: ForwardedRef<DialogImperativeMethods>)

const close = useCallback(() => {
'worklet';
visibility.value = withTiming(0, undefined, _onDismiss);
if (Constants.accessibility.isReduceMotionEnabled) {
visibility.value = 0;
_onDismiss();
} else {
visibility.value = withTiming(0, undefined, _onDismiss);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [_onDismiss]);

const open = useCallback(() => {
'worklet';
visibility.value = withSpring(1);
if (Constants.accessibility.isReduceMotionEnabled) {
visibility.value = 1;
} else {
visibility.value = withSpring(1);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Expand Down
6 changes: 6 additions & 0 deletions src/style/__tests__/scheme.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import {AccessibilityInfo} from 'react-native';

let Scheme;
describe('Scheme', () => {
beforeEach(() => {
jest.resetModules();
// Re-apply the AccessibilityInfo mocks after resetModules
jest.spyOn(AccessibilityInfo, 'isScreenReaderEnabled').mockImplementation(() => Promise.resolve(false));
jest.spyOn(AccessibilityInfo, 'isReduceMotionEnabled').mockImplementation(() => Promise.resolve(false));

Scheme = require('../scheme').default;
});

Expand Down