-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Automated tests for Unread Indicators feature and final polish #10929
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
b199711
add new test files and mocks
marcaaron f1dc534
remove unused import
marcaaron 3e90f5e
Make requested changes
marcaaron 973de5c
Remove docs from react-navigation setup and link to react-navigation …
marcaaron 261c712
Clean up all testID and use accessibilityHint or accessibilityLabel i…
marcaaron ac9fe71
Use accessibilityElementsHidden
marcaaron 8fc5b95
fix conflicts
marcaaron 68fed0c
Undo unnecessary refactor of back button
marcaaron efb1d62
Remove jest.setTimeout() by breaking test up into smaller chunks
marcaaron 1836742
Extract the one part of tests that actually does need async/await to …
marcaaron c350685
Cleanup Expensicons mock
marcaaron f51ed16
Clean up function names
marcaaron ff196b1
Add test for deleting comment
marcaaron 7b76284
improve a couple of comments and fix some incorrect changes
marcaaron 7fedd6e
Merge remote-tracking branch 'origin' into marcaaron-automatedUnreadTest
marcaaron d4fbfd6
Must mock useDrawerStatus in LHNOrderTest
marcaaron b6d9615
Fix icons and withDrawerState for LHNOrderTest
marcaaron b3ab1ba
improve comment and add explanation for icon name setting
marcaaron 6b8536a
Make some requested changes and improve comments further
marcaaron File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
// <App> uses <ErrorBoundary> and we need to mock the imported crashlytics module | ||
// due to an error that happens otherwise https://github.com/invertase/react-native-firebase/issues/2475 | ||
export default { | ||
log: jest.fn(), | ||
recordError: jest.fn(), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,9 @@ | ||
import {PusherMock} from 'pusher-js-mock'; | ||
|
||
export default PusherMock; | ||
class PusherMockWithDisconnect extends PusherMock { | ||
disconnect() { | ||
return jest.fn(); | ||
} | ||
} | ||
|
||
export default PusherMockWithDisconnect; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import React, {forwardRef} from 'react'; | ||
import {View} from 'react-native'; | ||
|
||
const insets = { | ||
top: 0, right: 0, bottom: 0, left: 0, | ||
}; | ||
|
||
function withSafeAreaInsets(WrappedComponent) { | ||
const WithSafeAreaInsets = props => ( | ||
<WrappedComponent | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
{...props} | ||
// eslint-disable-next-line react/prop-types | ||
ref={props.forwardedRef} | ||
insets={insets} | ||
/> | ||
); | ||
return forwardRef((props, ref) => ( | ||
// eslint-disable-next-line react/jsx-props-no-spreading | ||
<WithSafeAreaInsets {...props} forwardedRef={ref} /> | ||
)); | ||
} | ||
|
||
const SafeAreaView = View; | ||
const SafeAreaProvider = props => props.children; | ||
const SafeAreaConsumer = props => props.children(insets); | ||
const SafeAreaInsetsContext = { | ||
Consumer: SafeAreaConsumer, | ||
}; | ||
|
||
const useSafeAreaFrame = jest.fn(() => ({ | ||
x: 0, y: 0, width: 390, height: 844, | ||
})); | ||
const useSafeAreaInsets = jest.fn(() => insets); | ||
|
||
export { | ||
SafeAreaProvider, | ||
SafeAreaConsumer, | ||
SafeAreaInsetsContext, | ||
withSafeAreaInsets, | ||
SafeAreaView, | ||
useSafeAreaFrame, | ||
useSafeAreaInsets, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
// eslint-disable-next-line no-restricted-imports | ||
import * as ReactNative from 'react-native'; | ||
import _ from 'underscore'; | ||
import CONST from '../src/CONST'; | ||
|
||
jest.doMock('react-native', () => { | ||
let url = 'https://new.expensify.com/'; | ||
const getInitialURL = () => Promise.resolve(url); | ||
|
||
let appState = 'active'; | ||
let count = 0; | ||
const changeListeners = {}; | ||
|
||
// Tests will run with the app in a typical small screen size by default. We do this since the react-native test renderer | ||
// runs against index.native.js source and so anything that is testing a component reliant on withWindowDimensions() | ||
// would be most commonly assumed to be on a mobile phone vs. a tablet or desktop style view. This behavior can be | ||
// overridden by explicitly setting the dimensions inside a test via Dimensions.set() | ||
let dimensions = CONST.TESTING.SCREEN_SIZE.SMALL; | ||
|
||
return Object.setPrototypeOf( | ||
{ | ||
NativeModules: { | ||
...ReactNative.NativeModules, | ||
BootSplash: { | ||
getVisibilityStatus: jest.fn(), | ||
hide: jest.fn(), | ||
}, | ||
StartupTimer: {stop: jest.fn()}, | ||
}, | ||
Linking: { | ||
...ReactNative.Linking, | ||
getInitialURL, | ||
setInitialURL(newUrl) { | ||
url = newUrl; | ||
}, | ||
}, | ||
AppState: { | ||
...ReactNative.AppState, | ||
get currentState() { | ||
return appState; | ||
}, | ||
emitCurrentTestState(state) { | ||
appState = state; | ||
_.each(changeListeners, listener => listener(appState)); | ||
}, | ||
addEventListener(type, listener) { | ||
if (type === 'change') { | ||
const originalCount = count; | ||
changeListeners[originalCount] = listener; | ||
++count; | ||
return { | ||
remove: () => { | ||
delete changeListeners[originalCount]; | ||
}, | ||
}; | ||
} | ||
|
||
return ReactNative.AppState.addEventListener(type, listener); | ||
}, | ||
}, | ||
Dimensions: { | ||
...ReactNative.Dimensions, | ||
addEventListener: jest.fn(), | ||
get: () => dimensions, | ||
set: (newDimensions) => { | ||
dimensions = newDimensions; | ||
}, | ||
}, | ||
}, | ||
ReactNative, | ||
); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,64 @@ | ||
import fs from 'fs'; | ||
import path from 'path'; | ||
import 'react-native-gesture-handler/jestSetup'; | ||
import _ from 'underscore'; | ||
|
||
require('react-native-reanimated/lib/reanimated2/jestUtils').setUpTests(); | ||
|
||
// Silence the warning: Animated: `useNativeDriver` is not supported because the native animated module is missing | ||
jest.mock('react-native-blob-util', () => ({})); | ||
|
||
// These two mocks are required as per setup instructions for react-navigation testing | ||
// https://reactnavigation.org/docs/testing/#mocking-native-modules | ||
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper'); | ||
jest.mock('react-native-reanimated', () => { | ||
const Reanimated = require('react-native-reanimated/mock'); | ||
Reanimated.default.call = () => {}; | ||
return Reanimated; | ||
}); | ||
|
||
// Set up manual mocks for methods used in the actions so our test does not fail. | ||
jest.mock('../src/libs/Notification/PushNotification', () => ({ | ||
// There is no need for a jest.fn() since we don't need to make assertions against it. | ||
register: () => {}, | ||
deregister: () => {}, | ||
// The main app uses a NativeModule called BootSplash to show/hide a splash screen. Since we can't use this in the node environment | ||
// where tests run we simulate a behavior where the splash screen is always hidden (similar to web which has no splash screen at all). | ||
jest.mock('../src/libs/BootSplash', () => ({ | ||
marcaaron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
hide: jest.fn(), | ||
getVisibilityStatus: jest.fn().mockResolvedValue('hidden'), | ||
})); | ||
|
||
jest.mock('react-native-blob-util', () => ({})); | ||
// Local notifications (a.k.a. browser notifications) do not run in native code. Our jest tests will also run against | ||
// any index.native.js files as they are using a react-native plugin. However, it is useful to mock this behavior so that we | ||
// can test the expected web behavior and see if a browser notification would be shown or not. | ||
jest.mock('../src/libs/Notification/LocalNotification', () => ({ | ||
marcaaron marked this conversation as resolved.
Show resolved
Hide resolved
|
||
showCommentNotification: jest.fn(), | ||
})); | ||
|
||
/** | ||
* @param {String} imagePath | ||
*/ | ||
function mockImages(imagePath) { | ||
const imageFilenames = fs.readdirSync(path.resolve(__dirname, `../assets/${imagePath}/`)); | ||
// eslint-disable-next-line rulesdir/prefer-early-return | ||
_.each(imageFilenames, (fileName) => { | ||
if (/\.svg/.test(fileName)) { | ||
jest.mock(`../assets/${imagePath}/${fileName}`, () => () => ''); | ||
} | ||
}); | ||
} | ||
|
||
// We are mocking all images so that Icons and other assets cannot break tests. In the testing environment, importing things like .svg | ||
// directly will lead to undefined variables instead of a component or string (which is what React expects). Loading these assets is | ||
// not required as the test environment does not actually render any UI anywhere and just needs them to noop so the test renderer | ||
// (which is a virtual implemented DOM) can do it's thing. | ||
mockImages('images'); | ||
mockImages('images/avatars'); | ||
mockImages('images/bankicons'); | ||
mockImages('images/product-illustrations'); | ||
jest.mock('../src/components/Icon/Expensicons', () => { | ||
const reduce = require('underscore').reduce; | ||
const Expensicons = jest.requireActual('../src/components/Icon/Expensicons'); | ||
return reduce(Expensicons, (prev, _curr, key) => { | ||
// We set the name of the anonymous mock function here so we can dynamically build the list of mocks and access the | ||
// "name" property to use in accessibility hints for element querying | ||
const fn = () => ''; | ||
Object.defineProperty(fn, 'name', {value: key}); | ||
return {...prev, [key]: fn}; | ||
}, {}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️ I love this comment. It makes it so clear why the mock is necessary!