diff --git a/.eslintrc.js b/.eslintrc.js
index 6011f4cd4..4ebc237d7 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -10,5 +10,6 @@ module.exports = {
// need this so jest doesn't show as undefined in jest.setup.js
env: {
"jest": true
- }
+ },
+ ignorePatterns: ["/coverage/*"]
};
diff --git a/components/ObsDetails/DataTab.js b/components/ObsDetails/DataTab.js
index 55fcc48a5..459643e9c 100644
--- a/components/ObsDetails/DataTab.js
+++ b/components/ObsDetails/DataTab.js
@@ -3,7 +3,7 @@
import * as React from "react";
import { View, Text } from "react-native";
-import { textStyles, viewStyles } from "../../styles/obsDetails";
+// import { textStyles, viewStyles } from "../../styles/obsDetails";
import Map from "../SharedComponents/Map";
type Props = {
diff --git a/components/ObsDetails/ObsDetails.js b/components/ObsDetails/ObsDetails.js
index d87543d9d..cb7033b5d 100644
--- a/components/ObsDetails/ObsDetails.js
+++ b/components/ObsDetails/ObsDetails.js
@@ -9,7 +9,7 @@ import { useNavigation, useRoute } from "@react-navigation/core";
import { viewStyles, textStyles } from "../../styles/obsDetails";
// import useFetchObsDetails from "./hooks/fetchObsDetails";
-import useFetchObsFromRealm from "./hooks/fetchObsFromRealm";
+import useFetchObsDetailsFromRealm from "./hooks/fetchObsFromRealm";
import ActivityTab from "./ActivityTab";
import UserIcon from "../SharedComponents/UserIcon";
import PhotoScroll from "./PhotoScroll";
@@ -22,7 +22,7 @@ const ObsDetails = ( ): Node => {
const { params } = useRoute( );
const uuid = params.obsId;
- const observation = useFetchObsFromRealm( uuid );
+ const observation = useFetchObsDetailsFromRealm( uuid );
const navToUserProfile = ( ) => navigation.navigate( "UserProfile" );
diff --git a/components/ObsDetails/hooks/fetchObsDetails.js b/components/ObsDetails/hooks/fetchObsDetails.js
deleted file mode 100644
index 9f59bcaae..000000000
--- a/components/ObsDetails/hooks/fetchObsDetails.js
+++ /dev/null
@@ -1,192 +0,0 @@
-// // @flow
-
-// import { useEffect, useMemo, useCallback, useRef, useState } from "react";
-// import inatjs from "inaturalistjs";
-// import Realm from "realm";
-
-// import realmConfig from "../../../models/index";
-
-// const useFetchObsDetails = ( uuid: string ): Object => {
-// const [comments, setComments] = useState( [] );
-// const [fetched, setFetched] = useState( false );
-// const [ids, setIds] = useState( [] );
-// const [photos, setPhotos] = useState( [] );
-// const realmRef = useRef( null );
-
-// const openRealm = useCallback( async ( ) => {
-// try {
-// const realm = await Realm.open( realmConfig );
-// realmRef.current = realm;
-// }
-// catch ( err ) {
-// console.error( "Error opening realm: ", err.message );
-// }
-// }, [realmRef] );
-
-// const closeRealm = useCallback( ( ) => {
-// const realm = realmRef.current;
-// realm?.close( );
-// realmRef.current = null;
-// // setComments( [] );
-// }, [realmRef] );
-
-// useEffect( ( ) => {
-// openRealm( );
-
-// // Return a cleanup callback to close the realm to prevent memory leaks
-// return closeRealm;
-// }, [openRealm, closeRealm] );
-
-// const FIELDS = useMemo( ( ) => {
-// // similar fields as web:
-// // https://github.com/inaturalist/inaturalist/blob/df6572008f60845b8ef5972a92a9afbde6f67829/app/webpack/observations/show/ducks/observation.js
-// const TAXON_FIELDS = {
-// ancestry: true,
-// ancestor_ids: true,
-// ancestors: {
-// id: true,
-// uuid: true,
-// name: true,
-// iconic_taxon_name: true,
-// is_active: true,
-// preferred_common_name: true,
-// rank: true,
-// rank_level: true
-// },
-// default_photo: {
-// attribution: true,
-// license_code: true,
-// url: true,
-// square_url: true
-// },
-// iconic_taxon_name: true,
-// id: true,
-// is_active: true,
-// name: true,
-// preferred_common_name: true,
-// rank: true,
-// rank_level: true
-// };
-
-// const PHOTO_FIELDS = {
-// id: true,
-// uuid: true,
-// url: true,
-// license_code: true
-// };
-
-// const USER_FIELDS = {
-// login: true,
-// icon_url: true
-// };
-
-// const MODERATOR_ACTION_FIELDS = {
-// action: true,
-// id: true,
-// created_at: true,
-// reason: true,
-// user: USER_FIELDS
-// };
-
-// const ID_FIELDS = {
-// body: true,
-// category: true,
-// created_at: true,
-// current: true,
-// disagreement: true,
-// flags: { id: true },
-// hidden: true,
-// moderator_actions: MODERATOR_ACTION_FIELDS,
-// previous_observation_taxon: TAXON_FIELDS,
-// spam: true,
-// taxon: TAXON_FIELDS,
-// taxon_change: { id: true, type: true },
-// updated_at: true,
-// user: Object.assign( { }, USER_FIELDS, { id: true } ),
-// uuid: true,
-// vision: true
-// };
-
-// const COMMENT_FIELDS = {
-// body: true,
-// created_at: true,
-// id: true,
-// user: USER_FIELDS
-// };
-
-// return {
-// comments: COMMENT_FIELDS,
-// identifications: ID_FIELDS,
-// photos: PHOTO_FIELDS
-// };
-// }, [] );
-
-// const createIdentificationForRealm = ( id ) => ( {
-// uuid: id.uuid,
-// body: id.body,
-// category: id.category,
-// commonName: id.taxon.preferred_common_name,
-// createdAt: id.created_at,
-// id: id.id,
-// name: id.taxon.name,
-// rank: id.taxon.rank,
-// taxonPhoto: id.taxon.default_photo.square_url,
-// userIcon: id.user.icon_url,
-// userLogin: id.user.login,
-// vision: id.vision
-// } );
-
-// const writeToDatabase = useCallback( ( results ) => {
-// if ( results.length === 0 ) {
-// return;
-// }
-// const realm = realmRef.current;
-// results.forEach( id => {
-// const newId = createIdentificationForRealm( id );
-// realm?.write( ( ) => {
-// const linkedObservation = realm.objects( "Observation" ).filtered( `uuid = '${uuid}'` );
-// console.log( linkedObservation, "linked obs" );
-// // linkedObservation.identifications.push( newId );
-// } );
-// } );
-// }, [uuid] );
-
-// useEffect( ( ) => {
-// let isCurrent = true;
-// const fetchIds = async ( ) => {
-// try {
-// const params = {
-// per_page: 50,
-// fields: FIELDS
-// };
-// const response = await inatjs.observations.fetch( [uuid], params );
-// const results = response.results;
-// const obsIds = results[0].identifications;
-// const obsPhotos = results[0].photos;
-// // const obsComments = results[0].comments;
-// if ( !isCurrent || obsIds.length === 0 || fetched ) { return; }
-// setIds( obsIds );
-// writeToDatabase( obsIds );
-// setPhotos( obsPhotos );
-// // setComments( obsComments );
-// setFetched( true );
-// // writeToDatabase( results );
-// } catch ( e ) {
-// if ( !isCurrent ) { return; }
-// console.log( e, "couldn't save ids to realm" );
-// }
-// };
-
-// fetchIds( );
-// return ( ) => {
-// isCurrent = false;
-// };
-// }, [FIELDS, comments, uuid, fetched, writeToDatabase] );
-
-// return {
-// ids,
-// photos
-// };
-// };
-
-// export default useFetchObsDetails;
diff --git a/components/ObsDetails/hooks/fetchObsFromRealm.js b/components/ObsDetails/hooks/fetchObsFromRealm.js
index 517d360f1..012170bd8 100644
--- a/components/ObsDetails/hooks/fetchObsFromRealm.js
+++ b/components/ObsDetails/hooks/fetchObsFromRealm.js
@@ -5,7 +5,7 @@ import Realm from "realm";
import realmConfig from "../../../models/index";
-const useFetchObsFromRealm = ( uuid: string ): Object => {
+const useFetchObsDetailsFromRealm = ( uuid: string ): Object => {
const [observation, setObservation] = useState( null );
const realmRef = useRef( null );
@@ -37,4 +37,4 @@ const useFetchObsFromRealm = ( uuid: string ): Object => {
return observation;
};
-export default useFetchObsFromRealm;
+export default useFetchObsDetailsFromRealm;
diff --git a/components/Observations/EmptyList.js b/components/Observations/EmptyList.js
index 14f013304..78cc0b18c 100644
--- a/components/Observations/EmptyList.js
+++ b/components/Observations/EmptyList.js
@@ -16,6 +16,7 @@ const EmptyList = ( ): Node => {
learn more
diff --git a/components/Observations/ObsCard.js b/components/Observations/ObsCard.js
index 863c4504c..ab9814f3a 100644
--- a/components/Observations/ObsCard.js
+++ b/components/Observations/ObsCard.js
@@ -16,6 +16,8 @@ const ObsCard = ( { item, handlePress }: Props ): Node => (
onPress={( ) => handlePress( item )}
style={viewStyles.row}
testID="ObsList.obsCard"
+ accessibilityRole="link"
+ accessibilityLabel="Navigate to observation details screen"
>
{
const navigation = useNavigation( );
const navToObsDetails = observation => navigation.navigate( "ObsDetails", { obsId: observation.uuid } );
- const localObservations = useFetchObsFromRealm( );
+ const localObservations = useFetchObsListFromRealm( );
// this custom hook fetches on first component render
// (and anytime you save while in debug - hot reloading mode )
useFetchObservations( );
diff --git a/components/Observations/__tests__/ObsCard.test.js b/components/Observations/__tests__/ObsCard.test.js
index 00cce14a0..2f075fab7 100644
--- a/components/Observations/__tests__/ObsCard.test.js
+++ b/components/Observations/__tests__/ObsCard.test.js
@@ -1,20 +1,23 @@
import React from "react";
import { fireEvent, render } from "@testing-library/react-native";
+import AccessibilityEngine from "react-native-accessibility-engine";
import ObsCard from "../ObsCard";
+const testObservation = {
+ userPhoto: "amazon_url",
+ commonName: "Insects",
+ placeGuess: "SF",
+ timeObservedAt: "May 1, 2021",
+ identificationCount: 3,
+ commentCount: 0,
+ qualityGrade: "research"
+};
+
test( "renders text passed into observation card", ( ) => {
const { getByTestId, getByText } = render(
);
@@ -45,3 +48,8 @@ test( "handles button press", ( ) => {
fireEvent.press( button );
expect( fakeNavigation.navigate ).toBeCalledWith( "ObsDetails" );
} );
+
+test( "should not have accessibility errors", ( ) => {
+ const obsCard = ;
+ expect( ( ) => AccessibilityEngine.check( obsCard ) ).not.toThrow();
+} );
diff --git a/components/Observations/__tests__/ObsList.test.js b/components/Observations/__tests__/ObsList.test.js
index 6944befcb..c76e16f2b 100644
--- a/components/Observations/__tests__/ObsList.test.js
+++ b/components/Observations/__tests__/ObsList.test.js
@@ -1,10 +1,10 @@
-// import React from "react";
-// import { FlatList } from "react-native";
-// import { render, waitForElement } from "@testing-library/react-native";
-// import { NavigationContainer } from "@react-navigation/native";
+import React from "react";
+import { render } from "@testing-library/react-native";
+import { NavigationContainer } from "@react-navigation/native";
import inatjs from "inaturalistjs";
+import AccessibilityEngine from "react-native-accessibility-engine";
-// import ObsList from "../ObsList";
+import ObsList from "../ObsList";
// import EmptyList from "../EmptyList";
// test( "it renders all inputs as expected", ( ) => {
@@ -48,4 +48,11 @@ test( "searches using the passed in parameters", async ( ) => {
expect( response ).toEqual( identifications );
} );
-
+test( "should not have accessibility errors", ( ) => {
+ const obsList = (
+
+
+
+ );
+ expect( ( ) => AccessibilityEngine.check( obsList ) ).not.toThrow();
+} );
diff --git a/components/Observations/hooks/fetchObsFromRealm.js b/components/Observations/hooks/fetchObsListFromRealm.js
similarity index 97%
rename from components/Observations/hooks/fetchObsFromRealm.js
rename to components/Observations/hooks/fetchObsListFromRealm.js
index d204adafc..4dcbce4ca 100644
--- a/components/Observations/hooks/fetchObsFromRealm.js
+++ b/components/Observations/hooks/fetchObsListFromRealm.js
@@ -5,7 +5,7 @@ import Realm from "realm";
import realmConfig from "../../../models/index";
-const useFetchObsFromRealm = ( ): Array