Skip to content

Commit

Permalink
Write AR nav test; filter vision result from all suggestions list
Browse files Browse the repository at this point in the history
  • Loading branch information
albullington committed Mar 20, 2024
1 parent 24d9d60 commit b2c437a
Show file tree
Hide file tree
Showing 5 changed files with 137 additions and 7 deletions.
5 changes: 3 additions & 2 deletions src/api/taxa.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ function mapToLocalSchema( taxon ) {
async function fetchTaxon( id: any, params: Object = {}, opts: Object = {} ): Promise<any> {
try {
const fetchParams = { ...PARAMS, ...params };
const { results } = await inatjs.taxa.fetch( id, fetchParams, opts );
if ( results.length === 0 ) return null;
const response = await inatjs.taxa.fetch( id, fetchParams, opts );
const results = response?.results;
if ( !results || results.length === 0 ) return null;

return mapToLocalSchema( results[0] );
} catch ( e ) {
Expand Down
2 changes: 1 addition & 1 deletion src/components/Camera/Buttons/Close.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const Close = ( ): Node => {
return (
<TransparentCircleButton
onPress={( ) => navigation.goBack( )}
accessibilityLabel={t( "Close-AR-camera" )}
accessibilityLabel={t( "Close" )}
accessibilityHint={t( "Navigate-to-previous-screen" )}
icon="close"
/>
Expand Down
11 changes: 9 additions & 2 deletions src/components/Suggestions/SuggestionsContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,16 @@ const SuggestionsContainer = ( ): Node => {
tryOfflineSuggestions
} );

const suggestions = onlineSuggestions?.results?.length > 0
const hideVisionResultFromAllSuggestions = list => {
if ( !hasVisionSuggestion ) { return list; }
return list.filter(
result => result.taxon.id !== currentObservation.taxon.id
).map( r => r );
};

const suggestions = hideVisionResultFromAllSuggestions( onlineSuggestions?.results?.length > 0
? onlineSuggestions.results
: offlineSuggestions;
: offlineSuggestions );

const topSuggestion = hasVisionSuggestion
? currentObservation
Expand Down
120 changes: 120 additions & 0 deletions tests/integration/navigation/ARCamera.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import Geolocation from "@react-native-community/geolocation";
import {
screen,
userEvent
} from "@testing-library/react-native";
import * as usePredictions from "components/Camera/ARCamera/hooks/usePredictions";
import initI18next from "i18n/initI18next";
import { renderApp } from "tests/helpers/render";
import setupUniqueRealm from "tests/helpers/uniqueRealm";

// We're explicitly testing navigation here so we want react-navigation
// working normally
jest.unmock( "@react-navigation/native" );

jest.mock( "react-native/Libraries/Utilities/Platform", ( ) => ( {
OS: "ios",
select: jest.fn( ),
Version: 11
} ) );

const mockLocalTaxon = {
id: 144351,
name: "Poecile",
rank_level: 20,
default_photo: {
url: "fake_image_url"
}
};

// UNIQUE REALM SETUP
const mockRealmIdentifier = __filename;
const { mockRealmModelsIndex, uniqueRealmBeforeAll, uniqueRealmAfterAll } = setupUniqueRealm(
mockRealmIdentifier
);
jest.mock( "realmModels/index", ( ) => mockRealmModelsIndex );
jest.mock( "providers/contexts", ( ) => {
const originalModule = jest.requireActual( "providers/contexts" );
return {
__esModule: true,
...originalModule,
RealmContext: {
...originalModule.RealmContext,
useRealm: ( ) => global.mockRealms[mockRealmIdentifier]
}
};
} );
beforeAll( uniqueRealmBeforeAll );
afterAll( uniqueRealmAfterAll );
// /UNIQUE REALM SETUP

beforeAll( async () => {
await initI18next();
jest.useFakeTimers( );
} );

describe( "ARCamera navigation", ( ) => {
const actor = userEvent.setup( );

describe( "from MyObs", ( ) => {
it( "should return to MyObs when close button tapped", async ( ) => {
renderApp( );
expect( await screen.findByText( /Log in to contribute/ ) ).toBeVisible( );
const addObsButton = await screen.findByLabelText( "Add observations" );
await actor.press( addObsButton );
const cameraButton = await screen.findByLabelText( /AR Camera/ );
await actor.press( cameraButton );
expect( await screen.findByText( /Loading iNaturalist's AR Camera/ ) ).toBeVisible( );
const closeButton = await screen.findByLabelText( /Close/ );
await actor.press( closeButton );
expect( await screen.findByText( /Log in to contribute/ ) ).toBeVisible( );
} );
} );

describe( "to Suggestions", ( ) => {
beforeEach( ( ) => {
const mockGetCurrentPosition = jest.fn( ( success, _error, _options ) => success( {
coords: {
latitude: 56,
longitude: 9
}
} ) );
Geolocation.getCurrentPosition.mockImplementation( mockGetCurrentPosition );
} );

it( "should advance to Suggestions when photo taken", async ( ) => {
renderApp( );
expect( await screen.findByText( /Log in to contribute/ ) ).toBeVisible( );
const addObsButton = await screen.findByLabelText( "Add observations" );
await actor.press( addObsButton );
const cameraButton = await screen.findByLabelText( /AR Camera/ );
await actor.press( cameraButton );
expect( await screen.findByText( /Loading iNaturalist's AR Camera/ ) ).toBeVisible( );
const takePhotoButton = await screen.findByLabelText( /Take photo/ );
await actor.press( takePhotoButton );
expect( await screen.findByText( /ADD AN ID/ ) ).toBeVisible( );
} );

it( "should display top suggestion from ARCamera", async ( ) => {
jest.spyOn( usePredictions, "default" ).mockImplementation( () => ( {
handleTaxaDetected: jest.fn( ),
modelLoaded: true,
result: {
taxon: mockLocalTaxon
}
} ) );

renderApp( );
expect( await screen.findByText( /Log in to contribute/ ) ).toBeVisible( );
const addObsButton = await screen.findByLabelText( "Add observations" );
await actor.press( addObsButton );
const cameraButton = await screen.findByLabelText( /AR Camera/ );
await actor.press( cameraButton );
expect( await screen.findByText( mockLocalTaxon.name ) ).toBeVisible( );
const takePhotoButton = await screen.findByLabelText( /Take photo/ );
await actor.press( takePhotoButton );
expect( await screen.findByText( /ADD AN ID/ ) ).toBeVisible( );
expect( await screen.findByText( mockLocalTaxon.name ) ).toBeVisible( );
} );
} );
} );
6 changes: 4 additions & 2 deletions tests/jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ jest.mock( "../react-native-logs.config", () => {
} );

jest.mock( "vision-camera-plugin-inatvision", () => ( {
getPredictionsForImage: jest.fn( () => Promise.resolve( { predictions: [] } ) )
getPredictionsForImage: jest.fn( () => Promise.resolve( { predictions: [] } ) ),
removeLogListener: jest.fn( )
} ) );

jest.mock( "react-native-worklets-core", () => ( {
Expand Down Expand Up @@ -67,7 +68,8 @@ jest.mock( "react-native-vision-camera", ( ) => ( {
useCameraDevice: mockUseCameraDevice,
VisionCameraProxy: {
getFrameProcessorPlugin: jest.fn( )
}
},
useFrameProcessor: jest.fn( )
} ) );

jest.mock( "react-native-localize", () => mockRNLocalize );
Expand Down

0 comments on commit b2c437a

Please sign in to comment.