mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2026-10-09 03:23:13 -04:00
* Move one broken test and switch back to toBeVisible
* Remove comments
* Move without changes
* Add helper function
* Call mock helper in beforeAll
* Add fileName to mock assets
* Refactor navigateToPhotoImporter into helper
* Use fake timers and time travel
* File move without changes
* Add import
* Update addObsBottomSheet.js
* Refactor navigation steps into new helpers
* Add layout setup
* Use skipFakeTimers here
* Remove setup
* Replace final expectation
* Add mock for Mortal in a new helper file
* Sort imports
* Remove superfluous act
* Move file without changes
* Add time travel to final expect
* Use Mortal mock
* Change one test expect
TODO: is this still the same behaviour tested, toBeNull can be of other reasons as well?
* Refactor nav to Standard camera into new helpers
* Replace fireEvent with userEvent
* Update imports
* Move file without changesUpdate firebase mock
* Move file without changes
* Add Mortal mock
* Use toBeVisible again
* Use toBeVisible
* Refactor nav to AI camera into helpers
* Refactor take photo and na into helpers
* Refactor an action of the two previous combined actions
* Somehow there were two identical describe
* Wrong order
* No longer needed
* Refactor last expect of this test into helper
* Use global time travel here
* Remove import
* Move file without changes
* Use toBeVisible again
* Use Mortal mock
* Re-use already made helper fct here
* Fix imports
* Move file without changes
* Enable animated time travel
* Use toBeVisible
* Add time travel to last expects
* Remove double checks for being on the correct screen
* Move file without changes
* Add fileName to mock assets
* Switch back to toBeVisible
* Enable animated time travel
* Add time travel to last expect
* Re-use new navigation helper
* Add mock for InteractionManager
* Move file without changes
* Use toBeVisible again
* Add InteractionManager mock
* Add animate time travel
* Missing import
* Remove from previous commit
* Add helper shell
* Move the Save button press
* Move missing evidence sheet dismissal
* Update MyObservations.test.js
* Set screen after photo import
* Remove import
* Sort imports
* Add a mock for ImagePicker
* Navigate to PhotoImported instead of No evidence option
Does not matter for this test where the new obs comes from
* Re-use helper fct
* Arg name
* Disable lint
* Move file without changes
* Replace with new helper fct
* Enable animated time travel
* Replace also below with new helper
* Move fct call
* Use toBeVisible again
* Use toBeVisible again
* Use toBeVisible again with different find strategy
* Remove trip through Suggestions for this test
* Add InteractionManager mock
* Move beforeEach
* Move function call
* Re-use new helper function
* Handle saveOptions
* Missing imports
* Add helper function
* Wait for toolbar helper
* Wait for the element like we did before this PR
* Wait for one more element
* Update PhotoImport.test.js
* Comment out optional wait
* Rename arg
* File move without changes
* Re-use new helper function
* Re-use new helper function
* Use toBeVisible again
* Enable animated time travel
* Add a new find
* New helper fct
* Remove local version of confirm
* New take photo helper does more, so restrict to not confirm the photo yet here
* Update PhotoDeletion.test.js
* Update PhotoDeletion.test.js
* Remove fake timers
* Missing imports
* Add Mortal mock
* Update PhotoDeletion.test.js
* Update PhotoDeletion.test.js
* Copy PhotoDeletion test into new file to split out tests about existing photos
* Remove other todo test
* Add InteractionManager mock
* Remove Mortal mock
* Remove new photo test
* Delete new photo test
* Remove existing photo test
* Remove existing photo test
* Remove helper fct
* Remove import
* This should not have been deleted
* Refactor to use new helpers to create an obs with photo and wait on ObsEdit
* Add the part until we wait on ObsEdit
* Remove double await
* Rename describe
* This was wrongly inserted here
* Wait with time travel to be on camera
* At this point we have two photos, so tap on first one
* Update PhotoDeletionExisting.test.js
* Move beforeEach
* That was wrong, we should not have taken a second photo
* Remove cv mock
* Add import
* Add import
* Add import
* Remove location mock
* Update PhotoDeletionExisting.test.js
* Move file without changes
* Switch back to toBeVisible again
* Re-use new helper fct
* Add Mortal mock
* Move broken tests without changes
* Mock Mortal
* Use toBeVisible again
* Re-use new helper fct
* Enable animated time trael
* Camera needs different layout state
* This was pressing twice
* Remove tiny local helper
* Re-use local helper
* Remove unused code
* Remove ignore Paths
Yay
* Remove unused helper
* Update react-native-fs.ts
* Move fct out of try/catch
* Revert "Move fct out of try/catch"
This reverts commit f9a138e0dd.
* Only have find text in try catch
* Add mock for useObject
* Remove broken test
---------
Co-authored-by: Johannes Klein <17345891+jtklein@users.noreply.github.com>
222 lines
7.5 KiB
JavaScript
222 lines
7.5 KiB
JavaScript
// Recommendation from the uuid library is to import get-random-values before
|
|
// uuid, so we're importing it first thing in the entry point.
|
|
// https://www.npmjs.com/package/uuid#react-native--expo
|
|
// eslint-disable-next-line simple-import-sort/imports
|
|
import "react-native-get-random-values";
|
|
|
|
import "@shopify/flash-list/jestSetup";
|
|
|
|
import mockBottomSheet from "@gorhom/bottom-sheet/mock";
|
|
import mockRNCNetInfo from "@react-native-community/netinfo/jest/netinfo-mock";
|
|
import inatjs from "inaturalistjs";
|
|
import fetchMock from "jest-fetch-mock";
|
|
import mockRNDeviceInfo from "react-native-device-info/jest/react-native-device-info-mock";
|
|
import mockSafeAreaContext from "react-native-safe-area-context/jest/mock";
|
|
|
|
import factory, { makeResponse } from "./factory";
|
|
|
|
// tests seem to be slower without this global reanimated mock
|
|
global.ReanimatedDataMock = {
|
|
now: () => 0,
|
|
};
|
|
|
|
global.requestIdleCallback = callback => setTimeout( callback, 0 );
|
|
global.cancelIdleCallback = id => clearTimeout( id );
|
|
|
|
jest.mock( "react-native-volume-manager", () => ( {
|
|
VolumeManager: {
|
|
getVolume: jest.fn( () => Promise.resolve( 0.5 ) ),
|
|
setVolume: jest.fn( ),
|
|
addVolumeListener: jest.fn( () => ( { remove: jest.fn() } ) ),
|
|
showNativeVolumeUI: jest.fn(),
|
|
},
|
|
} ) );
|
|
|
|
// Mock the react-native-logs config because it has a dependency on AuthenticationService
|
|
// instead use console.logs for tests
|
|
jest.mock( "../react-native-logs.config", () => {
|
|
const log = {
|
|
extend: jest.fn( () => ( {
|
|
debug: msg => console.debug( msg ),
|
|
info: msg => console.info( msg ),
|
|
warn: msg => console.warn( msg ),
|
|
error: msg => console.error( msg ),
|
|
debugWithExtra: ( ...args ) => console.debug( ...args ),
|
|
infoWithExtra: ( ...args ) => console.info( ...args ),
|
|
warnWithExtra: ( ...args ) => console.warn( ...args ),
|
|
errorWithExtra: ( ...args ) => console.error( ...args ),
|
|
} ) ),
|
|
};
|
|
return {
|
|
log,
|
|
legacyLogfilePath: "inaturalist-rn-log.txt",
|
|
logFileNamePrefix: "inaturalist-rn-log",
|
|
logFileDirectory: "logs",
|
|
logWithoutRemote: log,
|
|
};
|
|
} );
|
|
|
|
jest.mock( "@gorhom/bottom-sheet", () => ( {
|
|
...mockBottomSheet,
|
|
__esModule: true,
|
|
} ) );
|
|
jest.mock( "@react-native-community/netinfo", () => mockRNCNetInfo );
|
|
jest.mock( "react-native-device-info", () => mockRNDeviceInfo );
|
|
jest.mock( "react-native-safe-area-context", () => mockSafeAreaContext );
|
|
|
|
// Reanimated 4.2 + Worklets 0.7: Jest loads native worklets which fails in Node. See:
|
|
// https://github.com/software-mansion/react-native-reanimated/discussions/8806
|
|
// we can remove this once the fix is released
|
|
jest.mock( "react-native-worklets", () => require( "react-native-worklets/src/mock" ) );
|
|
|
|
require( "react-native-reanimated" ).setUpTests();
|
|
|
|
// Some test environments may need a little more time
|
|
jest.setTimeout( 50000 );
|
|
|
|
// Mock inaturalistjs so we can make some fake responses
|
|
jest.mock( "inaturalistjs" );
|
|
inatjs.observations.observers.mockResolvedValue( makeResponse( ) );
|
|
inatjs.observations.search.mockResolvedValue( makeResponse( ) );
|
|
inatjs.observations.speciesCounts.mockResolvedValue( makeResponse( ) );
|
|
inatjs.observations.updates.mockResolvedValue( makeResponse( ) );
|
|
inatjs.users.projects.mockResolvedValue( makeResponse( ) );
|
|
inatjs.computervision.score_image.mockResolvedValue( makeResponse( ) );
|
|
|
|
// Set up mocked fetch for testing (or disabling) fetch requests
|
|
fetchMock.enableMocks( );
|
|
fetchMock.dontMock( );
|
|
|
|
const mockIconicTaxon = factory( "RemoteTaxon", {
|
|
is_iconic: true,
|
|
name: "Mock iconic taxon",
|
|
} );
|
|
inatjs.taxa.search.mockResolvedValue( makeResponse( [mockIconicTaxon] ) );
|
|
|
|
inatjs.announcements.search.mockResolvedValue( makeResponse( ) );
|
|
inatjs.observations.updates.mockResolvedValue( makeResponse( ) );
|
|
|
|
// the following two mocks are both needed for react-native-keep-awake
|
|
jest.mock( "@sayem314/react-native-keep-awake" );
|
|
jest.mock( "react-native/Libraries/TurboModule/TurboModuleRegistry", () => {
|
|
const turboModuleRegistry = jest
|
|
.requireActual( "react-native/Libraries/TurboModule/TurboModuleRegistry" );
|
|
return {
|
|
...turboModuleRegistry,
|
|
getEnforcing: name => {
|
|
// List of TurboModules libraries to mock.
|
|
const modulesToMock = ["ReactNativeKCKeepAwake", "FileReaderModule"];
|
|
if ( modulesToMock.includes( name ) ) {
|
|
return null;
|
|
}
|
|
return turboModuleRegistry.getEnforcing( name );
|
|
},
|
|
};
|
|
} );
|
|
|
|
jest.mock( "react-native-restart", ( ) => ( {
|
|
restart: jest.fn( ),
|
|
} ) );
|
|
|
|
jest.mock( "@react-native-firebase/analytics", () => ( {
|
|
getAnalytics: jest.fn( ),
|
|
logEvent: jest.fn( ),
|
|
setAnalyticsCollectionEnabled: jest.fn( ),
|
|
} ) );
|
|
|
|
jest.mock( "@react-native-firebase/perf", () => ( {
|
|
getPerformance: jest.fn( ( ) => ( {
|
|
dataCollectionEnabled: true,
|
|
startTrace: jest.fn( async ( ) => ( {
|
|
stop: jest.fn( ),
|
|
putAttribute: jest.fn( ),
|
|
} ) ),
|
|
} ) ),
|
|
} ) );
|
|
|
|
jest.mock( "react-native-legal", () => ( {
|
|
launchLicenseListScreen: jest.fn(),
|
|
} ) );
|
|
|
|
// see https://stackoverflow.com/questions/42268673/jest-test-animated-view-for-react-native-app
|
|
// for more details about this withAnimatedTimeTravelEnabled approach. basically, this
|
|
// allows us to step through animation frames when a screen is first loading when we're using the
|
|
// FadeInView animation for navigation screen transitions
|
|
global.withAnimatedTimeTravelEnabled = ( options = {} ) => {
|
|
beforeEach( () => {
|
|
if ( !options.skipFakeTimers ) jest.useFakeTimers();
|
|
jest.setSystemTime( new Date( 0 ) );
|
|
} );
|
|
if ( !options.skipFakeTimers ) {
|
|
afterEach( () => {
|
|
jest.useRealTimers();
|
|
} );
|
|
}
|
|
};
|
|
|
|
const frameTime = 10;
|
|
global.timeTravel = ( time = frameTime ) => {
|
|
const tickTravel = () => {
|
|
const now = Date.now();
|
|
jest.setSystemTime( new Date( now + frameTime ) );
|
|
jest.advanceTimersByTime( frameTime );
|
|
};
|
|
// Step through each of the frames
|
|
const frames = time / frameTime;
|
|
for ( let i = 0; i < frames; i += 1 ) {
|
|
tickTravel();
|
|
}
|
|
};
|
|
|
|
jest.mock( "sharedHelpers/installData", ( ) => ( {
|
|
// For most tests it's just going to be burden to dismiss this thing that
|
|
// most users only ever see once. If we do want to test it, we can redefine
|
|
// this mock
|
|
useOnboardingShown: jest.fn( ( ) => [true, jest.fn()] ),
|
|
getInstallID: jest.fn( ( ) => "fake-installation-id" ),
|
|
} ) );
|
|
|
|
jest.mock( "components/SharedComponents/Buttons/Button", () => {
|
|
const actualButton = jest.requireActual(
|
|
"components/SharedComponents/Buttons/Button",
|
|
).default;
|
|
// Use a very short debounce time (10ms) in tests to simulate the 300ms
|
|
// debounce time in the actual Button component
|
|
return jest.fn( props => actualButton( { ...props, debounceTime: 10 } ) );
|
|
} );
|
|
|
|
jest.mock( "navigation/FadeInView", () => {
|
|
const React = require( "react" );
|
|
const { View } = require( "react-native" );
|
|
|
|
return jest.fn( ( { children } ) => React.createElement( View, null, children ) );
|
|
} );
|
|
|
|
jest.mock( "components/Camera/FadeInOutView", () => {
|
|
const React = require( "react" );
|
|
const { View } = require( "react-native" );
|
|
|
|
return jest.fn( ( ) => React.createElement( View, null ) );
|
|
} );
|
|
|
|
// Disable bottom tab fade animation in tests to prevent act() warnings
|
|
jest.mock( "navigation/BottomTabNavigator/tabScreenOptions", () => ( {
|
|
__esModule: true,
|
|
default: {
|
|
lazy: true,
|
|
freezeOnBlur: true,
|
|
headerShown: false,
|
|
animation: "none",
|
|
},
|
|
} ) );
|
|
|
|
// this silences console methods in jest tests, to make them less noisy
|
|
// and easier to debug. uncomment if you want to silence them
|
|
global.console = {
|
|
...console,
|
|
// info: jest.fn(),
|
|
// error: jest.fn(),
|
|
// warn: jest.fn()
|
|
// log: jest.fn()
|
|
};
|