mirror of
https://github.com/inaturalist/iNaturalistReactNative.git
synced 2026-04-26 09:48:11 -04:00
DQA Tests, Id withdraw icon change
This commit is contained in:
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
"data": [
|
||||
{
|
||||
"path": "assets/fonts/INatIcon.ttf",
|
||||
"sha1": "941a07384e3f0c242dd6717e1b01a2afcd863ca9"
|
||||
"sha1": "5ee81524df59ba0d7ef0efafdf940f528a8ee5af"
|
||||
},
|
||||
{
|
||||
"path": "assets/fonts/Whitney-BookItalic-Pro.otf",
|
||||
|
||||
Binary file not shown.
@@ -24,6 +24,7 @@
|
||||
BA2479FA3D7B40A7BEF7B3CD /* Whitney-Medium-Pro.otf in Resources */ = {isa = PBXBuildFile; fileRef = D09FA3A0162844FF80A5EF96 /* Whitney-Medium-Pro.otf */; };
|
||||
D1A158A7F6C9E77B651BB4AA /* libPods-iNaturalistReactNative-ShareExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = ADBDD0D061046941F61CA31D /* libPods-iNaturalistReactNative-ShareExtension.a */; };
|
||||
F005F5581901496B8576FB4E /* BuildFile in Resources */ = {isa = PBXBuildFile; };
|
||||
41DE3088F97E402FBC6E6DD8 /* INatIcon.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 63D7A2871FF24F76861F64DD /* INatIcon.ttf */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -89,6 +90,7 @@
|
||||
DEB901D3F8FB2DAE1CCED0CC /* Pods-iNaturalistReactNative-ShareExtension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-iNaturalistReactNative-ShareExtension.release.xcconfig"; path = "Target Support Files/Pods-iNaturalistReactNative-ShareExtension/Pods-iNaturalistReactNative-ShareExtension.release.xcconfig"; sourceTree = "<group>"; };
|
||||
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
|
||||
EE004FD2EC174086A7AB2908 /* inaturalisticons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = inaturalisticons.ttf; path = ../assets/fonts/inaturalisticons.ttf; sourceTree = "<group>"; };
|
||||
63D7A2871FF24F76861F64DD /* INatIcon.ttf */ = {isa = PBXFileReference; name = "INatIcon.ttf"; path = "../assets/fonts/INatIcon.ttf"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = unknown; explicitFileType = undefined; includeInIndex = 0; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -226,6 +228,7 @@
|
||||
D09FA3A0162844FF80A5EF96 /* Whitney-Medium-Pro.otf */,
|
||||
374CB22E29943E63005885ED /* Whitney-BookItalic-Pro.otf */,
|
||||
EE004FD2EC174086A7AB2908 /* inaturalisticons.ttf */,
|
||||
63D7A2871FF24F76861F64DD /* INatIcon.ttf */,
|
||||
);
|
||||
name = Resources;
|
||||
sourceTree = "<group>";
|
||||
@@ -356,6 +359,7 @@
|
||||
BA2479FA3D7B40A7BEF7B3CD /* Whitney-Medium-Pro.otf in Resources */,
|
||||
4FB3B444D46A4115B867B9CC /* inaturalisticons.ttf in Resources */,
|
||||
F005F5581901496B8576FB4E /* BuildFile in Resources */,
|
||||
41DE3088F97E402FBC6E6DD8 /* INatIcon.ttf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"data": [
|
||||
{
|
||||
"path": "assets/fonts/INatIcon.ttf",
|
||||
"sha1": "941a07384e3f0c242dd6717e1b01a2afcd863ca9"
|
||||
"sha1": "5ee81524df59ba0d7ef0efafdf940f528a8ee5af"
|
||||
},
|
||||
{
|
||||
"path": "assets/fonts/Whitney-BookItalic-Pro.otf",
|
||||
|
||||
@@ -54,6 +54,7 @@ const DQAVoteButtons = ( {
|
||||
if ( userAgrees ) {
|
||||
return (
|
||||
<INatIconButton
|
||||
testID="DQAVoteButton.UserAgree"
|
||||
icon="arrow-up-bold-circle"
|
||||
size={33}
|
||||
color={theme.colors.secondary}
|
||||
@@ -63,6 +64,7 @@ const DQAVoteButtons = ( {
|
||||
}
|
||||
return (
|
||||
<INatIconButton
|
||||
testID="DQAVoteButton.EmptyAgree"
|
||||
icon="arrow-up-bold-circle-outline"
|
||||
size={33}
|
||||
onPress={() => setVote( metric, true )}
|
||||
@@ -78,6 +80,7 @@ const DQAVoteButtons = ( {
|
||||
if ( userAgrees === null ) {
|
||||
return (
|
||||
<INatIconButton
|
||||
testID="DQAVoteButton.EmptyDisagree"
|
||||
icon="arrow-down-bold-circle-outline"
|
||||
size={33}
|
||||
onPress={() => setVote( metric, false )}
|
||||
@@ -87,6 +90,7 @@ const DQAVoteButtons = ( {
|
||||
if ( !userAgrees ) {
|
||||
return (
|
||||
<INatIconButton
|
||||
testID="DQAVoteButton.UserDisagree"
|
||||
icon="arrow-down-bold-circle"
|
||||
size={33}
|
||||
color={theme.colors.error}
|
||||
@@ -96,6 +100,7 @@ const DQAVoteButtons = ( {
|
||||
}
|
||||
return (
|
||||
<INatIconButton
|
||||
testID="DQAVoteButton.EmptyDisagree"
|
||||
icon="arrow-down-bold-circle-outline"
|
||||
size={33}
|
||||
onPress={() => setVote( metric, false )}
|
||||
|
||||
@@ -176,10 +176,20 @@ const DataQualityAssessment = ( ): React.Node => {
|
||||
const ifAgree = ifMajorityAgree( metric );
|
||||
if ( ifAgree || ifAgree === null ) {
|
||||
return (
|
||||
<INatIcon name="checkmark-circle" size={19} color={theme.colors.secondary} /> );
|
||||
<INatIcon
|
||||
testID="DQA.pass"
|
||||
name="checkmark-circle"
|
||||
size={19}
|
||||
color={theme.colors.secondary}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<INatIcon name="triangle-exclamation" size={19} color={theme.colors.error} />
|
||||
<INatIcon
|
||||
name="triangle-exclamation"
|
||||
size={19}
|
||||
color={theme.colors.error}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -221,7 +231,11 @@ const DataQualityAssessment = ( ): React.Node => {
|
||||
<INatIcon name="checkmark-circle" size={19} color={theme.colors.secondary} /> );
|
||||
}
|
||||
return (
|
||||
<INatIcon name="triangle-exclamation" size={19} color={theme.colors.error} />
|
||||
<INatIcon
|
||||
name="triangle-exclamation"
|
||||
size={19}
|
||||
color={theme.colors.error}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<svg width="24" height="24" viewBox="0 0 22 24">
|
||||
<path d="M5.16637 5.16637C6.71354 3.61919 8.81196 2.75 11 2.75C12.7243 2.75 14.3929 3.2898 15.78 4.27581L4.27582 15.78C3.2898 14.3929 2.75 12.7243 2.75 11C2.75 8.81196 3.61919 6.71354 5.16637 5.16637ZM6.22008 17.7242C7.60712 18.7102 9.27573 19.25 11 19.25C13.188 19.25 15.2865 18.3808 16.8336 16.8336C18.3808 15.2865 19.25 13.188 19.25 11C19.25 9.27573 18.7102 7.60712 17.7242 6.22008L6.22008 17.7242ZM18.7946 3.23824C20.8472 5.29955 22 8.09035 22 11C22 13.9174 20.8411 16.7153 18.7782 18.7782C16.7153 20.8411 13.9174 22 11 22C8.08262 22 5.28473 20.8411 3.22183 18.7782C1.15893 16.7153 0 13.9174 0 11C0 8.08262 1.15893 5.28473 3.22183 3.22183C5.28473 1.15893 8.08262 0 11 0C13.9097 0 16.7005 1.15282 18.7618 3.20552C18.7674 3.21087 18.7729 3.21628 18.7783 3.22173C18.7838 3.2272 18.7892 3.2327 18.7946 3.23824Z"/>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 27.7.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" x="0px" y="0px" width="24" height="24" viewBox="0 0 24 24" space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#454545;}
|
||||
</style>
|
||||
<path class="st0" d="M20.5,3.5L20.5,3.5L20.5,3.5C18.2,1.3,15.2,0,12,0S5.8,1.3,3.5,3.5C1.3,5.8,0,8.8,0,12s1.3,6.2,3.5,8.5 C5.8,22.7,8.8,24,12,24s6.2-1.3,8.5-3.5c2.3-2.3,3.5-5.3,3.5-8.5S22.7,5.8,20.5,3.5z M4.4,16.7c-0.9-1.4-1.3-3.1-1.3-4.7 c0-2.4,1-4.7,2.6-6.3S9.6,3.1,12,3.1c1.6,0,3.3,0.4,4.7,1.3C17,4.6,17,4.9,16.8,5.1L5.1,16.8C4.9,17,4.5,17,4.4,16.7z M18.3,18.3 c-1.6,1.6-3.9,2.6-6.3,2.6c-1.6,0-3.3-0.4-4.7-1.3C7,19.4,7,19.1,7.2,18.9L18.9,7.2C19.1,7,19.5,7,19.6,7.3c0.9,1.4,1.3,3.1,1.3,4.7 C20.9,14.4,20.1,16.7,18.3,18.3z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 894 B After Width: | Height: | Size: 825 B |
252
tests/unit/components/ObsDetails/DataQualityAssessment.test.js
Normal file
252
tests/unit/components/ObsDetails/DataQualityAssessment.test.js
Normal file
@@ -0,0 +1,252 @@
|
||||
import { faker } from "@faker-js/faker";
|
||||
import { fireEvent, screen } from "@testing-library/react-native";
|
||||
import DataQualityAssessment from "components/ObsDetails/DataQualityAssessment";
|
||||
import DQAVoteButtons from "components/ObsDetails/DQAVoteButtons";
|
||||
import initI18next from "i18n/initI18next";
|
||||
import { t } from "i18next";
|
||||
import React from "react";
|
||||
import { View } from "react-native";
|
||||
|
||||
import factory from "../../../factory";
|
||||
import { renderComponent } from "../../../helpers/render";
|
||||
|
||||
jest.mock( "sharedHooks/useIsConnected", ( ) => ( {
|
||||
__esModule: true,
|
||||
default: ( ) => true
|
||||
} ) );
|
||||
|
||||
const mockObservation = factory( "LocalObservation", {
|
||||
created_at: "2022-11-27T19:07:41-08:00",
|
||||
time_observed_at: "2023-12-14T21:07:41-09:30",
|
||||
observed_on: "2023-12-14T21:07:41-09:30",
|
||||
taxon: factory( "LocalTaxon", {
|
||||
id: "1234",
|
||||
rank_level: 10
|
||||
} ),
|
||||
observationPhotos: [
|
||||
factory( "LocalObservationPhoto", {
|
||||
photo: {
|
||||
id: faker.datatype.number( ),
|
||||
attribution: faker.lorem.sentence( ),
|
||||
licenseCode: "cc-by-nc",
|
||||
url: faker.image.imageUrl( )
|
||||
}
|
||||
} )
|
||||
],
|
||||
identifications: [factory( "LocalIdentification", {
|
||||
taxon: factory( "LocalTaxon", {
|
||||
id: "1234",
|
||||
rank_level: 10
|
||||
} )
|
||||
} )],
|
||||
latitude: Number( faker.address.latitude( ) ),
|
||||
longitude: Number( faker.address.longitude( ) ),
|
||||
description: faker.lorem.paragraph( ),
|
||||
quality_grade: "casual"
|
||||
} );
|
||||
|
||||
const mockQualityMetrics = [
|
||||
{
|
||||
id: 0,
|
||||
agree: true,
|
||||
metric: "wild",
|
||||
user_id: "0"
|
||||
}
|
||||
];
|
||||
|
||||
const mockObservationObject = {
|
||||
date: mockObservation.observed_on,
|
||||
location: [mockObservation.latitude, mockObservation.longitude],
|
||||
evidence: mockObservation.observationPhotos,
|
||||
taxon: {
|
||||
id: mockObservation.taxon.id,
|
||||
rank_level: mockObservation.taxon.rank_level
|
||||
},
|
||||
identifications: mockObservation.identifications
|
||||
};
|
||||
|
||||
const mockMutate = jest.fn();
|
||||
jest.mock( "sharedHooks/useAuthenticatedMutation", () => ( {
|
||||
__esModule: true,
|
||||
default: () => ( {
|
||||
mutate: mockMutate
|
||||
|
||||
} )
|
||||
} ) );
|
||||
|
||||
const mockAttribution = <View testID="mock-attribution" />;
|
||||
jest.mock( "components/ObsDetails/Attribution", () => ( {
|
||||
__esModule: true,
|
||||
default: () => mockAttribution
|
||||
} ) );
|
||||
|
||||
jest.mock( "@react-navigation/native", () => {
|
||||
const actualNav = jest.requireActual( "@react-navigation/native" );
|
||||
return {
|
||||
...actualNav,
|
||||
useRoute: () => ( {
|
||||
params: {
|
||||
observationUUID: mockObservation.uuid,
|
||||
observation: mockObservationObject,
|
||||
qualityGrade: mockObservation.quality_grade
|
||||
}
|
||||
} )
|
||||
};
|
||||
} );
|
||||
|
||||
describe( "Data Quality Assessment", ( ) => {
|
||||
beforeAll( async ( ) => {
|
||||
await initI18next( );
|
||||
} );
|
||||
test( "renders correct quality grade status", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const qualityGrade = await screen.findByTestId(
|
||||
`QualityGrade.${mockObservation.quality_grade}`
|
||||
);
|
||||
expect( qualityGrade ).toBeTruthy( );
|
||||
} );
|
||||
test( "renders correct quality grade status title", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const qualityGrade = await screen.findByText(
|
||||
t( "Data-quality-assessment-title-casual" )
|
||||
);
|
||||
expect( qualityGrade ).toBeTruthy( );
|
||||
} );
|
||||
test( "renders correct quality grade status description", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const qualityGrade = await screen.findByText(
|
||||
t( "Data-quality-assessment-description-casual" )
|
||||
);
|
||||
expect( qualityGrade ).toBeTruthy( );
|
||||
} );
|
||||
test( "renders correct metric titles", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const dateSpecified = await screen.findByText(
|
||||
t( "Data-quality-assessment-date-specified" )
|
||||
);
|
||||
const locationSpecified = await screen.findByText(
|
||||
t( "Data-quality-assessment-location-specified" )
|
||||
);
|
||||
const photosAndSounds = await screen.findByText(
|
||||
t( "Data-quality-assessment-has-photos-or-sounds" )
|
||||
);
|
||||
const idSupportedTwoOrMore = await screen.findByText(
|
||||
t( "Data-quality-assessment-id-supported-by-two-or-more" )
|
||||
);
|
||||
const communityTaxonSpeciesLevel = await screen.findByText(
|
||||
t( "Data-quality-assessment-community-taxon-species-level-or-lower" )
|
||||
);
|
||||
expect( dateSpecified ).toBeTruthy( );
|
||||
expect( locationSpecified ).toBeTruthy( );
|
||||
expect( photosAndSounds ).toBeTruthy( );
|
||||
expect( idSupportedTwoOrMore ).toBeTruthy( );
|
||||
expect( communityTaxonSpeciesLevel ).toBeTruthy( );
|
||||
} );
|
||||
|
||||
test( "renders correct metric vote titles", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const dateAccurate = await screen.findByText(
|
||||
t( "Data-quality-assessment-date-is-accurate" )
|
||||
);
|
||||
const locationAccurate = await screen.findByText(
|
||||
t( "Data-quality-assessment-location-is-accurate" )
|
||||
);
|
||||
const organismWild = await screen.findByText(
|
||||
t( "Data-quality-assessment-organism-is-wild" )
|
||||
);
|
||||
const organismEvidence = await screen.findByText(
|
||||
t( "Data-quality-assessment-evidence-of-organism" )
|
||||
);
|
||||
const recentEvidence = await screen.findByText(
|
||||
t( "Data-quality-assessment-recent-evidence-of-organism" )
|
||||
);
|
||||
expect( dateAccurate ).toBeTruthy( );
|
||||
expect( locationAccurate ).toBeTruthy( );
|
||||
expect( organismWild ).toBeTruthy( );
|
||||
expect( organismEvidence ).toBeTruthy( );
|
||||
expect( recentEvidence ).toBeTruthy( );
|
||||
} );
|
||||
test( "renders about section", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const title = await screen.findByText(
|
||||
t( "ABOUT-THE-DQA" )
|
||||
);
|
||||
const description = await screen.findByText(
|
||||
t( "About-the-DQA-description" )
|
||||
);
|
||||
expect( title ).toBeTruthy( );
|
||||
expect( description ).toBeTruthy( );
|
||||
} );
|
||||
} );
|
||||
|
||||
describe( "DQA Vote Buttons", ( ) => {
|
||||
beforeAll( async ( ) => {
|
||||
await initI18next( );
|
||||
} );
|
||||
test( "renders DQA vote buttons", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const emptyDisagreeButtons = await screen.findAllByTestId( "DQAVoteButton.EmptyDisagree" );
|
||||
fireEvent.press( emptyDisagreeButtons[0] );
|
||||
|
||||
expect( await mockMutate ).toHaveBeenCalled();
|
||||
} );
|
||||
|
||||
test( "calls api when DQA disagree button is pressed", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const emptyDisagreeButtons = await screen.findAllByTestId( "DQAVoteButton.EmptyDisagree" );
|
||||
fireEvent.press( emptyDisagreeButtons[0] );
|
||||
|
||||
expect( await mockMutate ).toHaveBeenCalled();
|
||||
} );
|
||||
|
||||
test( "calls api when DQA agree button is pressed", async ( ) => {
|
||||
renderComponent( <DataQualityAssessment observation={mockObservation} /> );
|
||||
|
||||
const emptyDisagreeButtons = await screen.findAllByTestId( "DQAVoteButton.EmptyAgree" );
|
||||
fireEvent.press( emptyDisagreeButtons[0] );
|
||||
|
||||
expect( await mockMutate ).toHaveBeenCalled();
|
||||
} );
|
||||
|
||||
test( "renders correct DQA user vote", async ( ) => {
|
||||
renderComponent( <DQAVoteButtons
|
||||
metric="wild"
|
||||
qualityMetrics={mockQualityMetrics}
|
||||
setVote={jest.fn()}
|
||||
loadingAgree={jest.fn()}
|
||||
loadingDisagree={jest.fn()}
|
||||
loadingMetric={jest.fn()}
|
||||
removeVote={jest.fn()}
|
||||
/> );
|
||||
|
||||
const button = await screen.findByTestId(
|
||||
"DQAVoteButton.UserAgree"
|
||||
);
|
||||
expect( button ).toBeTruthy( );
|
||||
} );
|
||||
|
||||
test( "renders correct DQA user vote number", async ( ) => {
|
||||
renderComponent( <DQAVoteButtons
|
||||
metric="wild"
|
||||
qualityMetrics={mockQualityMetrics}
|
||||
setVote={jest.fn()}
|
||||
loadingAgree={jest.fn()}
|
||||
loadingDisagree={jest.fn()}
|
||||
loadingMetric={jest.fn()}
|
||||
removeVote={jest.fn()}
|
||||
/> );
|
||||
|
||||
const voteNumber = await screen.findByText(
|
||||
"1"
|
||||
);
|
||||
expect( voteNumber ).toBeTruthy( );
|
||||
} );
|
||||
} );
|
||||
Reference in New Issue
Block a user