From 284cbc26c7341bddbbf19a7cac00b0f751cefcd8 Mon Sep 17 00:00:00 2001 From: sepeterson <10458078+sepeterson@users.noreply.github.com> Date: Sun, 21 Jun 2026 22:05:57 -0500 Subject: [PATCH] MOB-1327: add some tests --- .../ExploreV2/components/ExploreV2Header.tsx | 6 +- .../components/ExploreV2Header.test.js | 153 ++++++++++++++++++ .../components/ExploreV2Tabs.test.js | 37 +++++ 3 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 tests/unit/components/Explore/ExploreV2/components/ExploreV2Header.test.js create mode 100644 tests/unit/components/Explore/ExploreV2/components/ExploreV2Tabs.test.js diff --git a/src/components/Explore/ExploreV2/components/ExploreV2Header.tsx b/src/components/Explore/ExploreV2/components/ExploreV2Header.tsx index b18dd2dbf..c67663fff 100644 --- a/src/components/Explore/ExploreV2/components/ExploreV2Header.tsx +++ b/src/components/Explore/ExploreV2/components/ExploreV2Header.tsx @@ -86,6 +86,7 @@ const SubjectThumbnail = ( { subject }: { subject: ExploreV2Subject } ) => { : ( @@ -110,7 +111,10 @@ const ExploreV2Header = ( ) => { {state.subject ? ( - + {state.subject.type === "taxon" diff --git a/tests/unit/components/Explore/ExploreV2/components/ExploreV2Header.test.js b/tests/unit/components/Explore/ExploreV2/components/ExploreV2Header.test.js new file mode 100644 index 000000000..f4c95da73 --- /dev/null +++ b/tests/unit/components/Explore/ExploreV2/components/ExploreV2Header.test.js @@ -0,0 +1,153 @@ +import { screen } from "@testing-library/react-native"; +import ExploreV2Header from "components/Explore/ExploreV2/components/ExploreV2Header"; +import { EXPLORE_V2_PLACE_MODE } from "providers/ExploreV2Context"; +import React from "react"; +import { renderComponent } from "tests/helpers/render"; + +const mockNavigate = jest.fn(); + +jest.mock( "@react-navigation/native", () => { + const actualNav = jest.requireActual( "@react-navigation/native" ); + return { + ...actualNav, + useNavigation: () => ( { + navigate: mockNavigate, + goBack: jest.fn(), + push: jest.fn(), + canGoBack: jest.fn( () => false ), + dispatch: jest.fn(), + } ), + }; +} ); + +jest.mock( "providers/ExploreV2Context", () => { + const actual = jest.requireActual( "providers/ExploreV2Context" ); + return { + ...actual, + useExploreV2: jest.fn(), + }; +} ); + +const { useExploreV2 } = require( "providers/ExploreV2Context" ); + +const PLACE_LOCATION = { + placeMode: EXPLORE_V2_PLACE_MODE.PLACE, + place: { id: 1, display_name: "California" }, +}; + +const setState = ( subject, location = PLACE_LOCATION ) => { + useExploreV2.mockReturnValue( { + state: { + subject, + location, + sortBy: "created_at", + filters: {}, + }, + } ); +}; + +describe( "ExploreV2Header", () => { + beforeEach( () => { + mockNavigate.mockClear(); + } ); + + it( "renders a user subject with login and location", () => { + setState( { type: "user", user: { id: 7, login: "seth_msp" } } ); + renderComponent( ); + + expect( screen.getByText( "seth_msp" ) ).toBeTruthy(); + expect( screen.getByText( "California" ) ).toBeTruthy(); + } ); + + it( "renders a user subject icon", () => { + setState( { + type: "user", + user: { id: 7, login: "seth_msp", icon_url: "https://example.com/u.jpg" }, + } ); + renderComponent( ); + + expect( screen.getByTestId( "UserIcon.photo" ) ).toBeTruthy(); + } ); + + it( "renders a project subject with its icon image and location", () => { + setState( { + type: "project", + project: { id: 9, title: "Backyard Birds", icon: "https://example.com/p.jpg" }, + } ); + renderComponent( ); + + expect( screen.getByText( "Backyard Birds" ) ).toBeTruthy(); + expect( screen.getByTestId( "ExploreV2Header.projectImage" ) ).toBeTruthy(); + expect( screen.getByText( "California" ) ).toBeTruthy(); + } ); + + it( "renders a fallback briefcase for a project without an icon", () => { + setState( { + type: "project", + project: { id: 9, title: "Backyard Birds" }, + } ); + renderComponent( ); + + expect( screen.getByText( "Backyard Birds" ) ).toBeTruthy(); + expect( screen.queryByTestId( "ExploreV2Header.projectImage" ) ).toBeNull(); + expect( screen.getByTestId( "ExploreV2Header.projectFallbackIcon" ) ).toBeTruthy(); + } ); + + it( "renders a taxon subject with its photo and location", () => { + setState( { + type: "taxon", + taxon: { + id: 12, + name: "Eumyias thalassinus", + default_photo: { url: "https://example.com/photo.jpg" }, + iconic_taxon_name: "Aves", + }, + } ); + renderComponent( ); + + expect( screen.getByTestId( "ExploreV2Header.taxonImage" ) ).toBeTruthy(); + expect( screen.getByText( "California" ) ).toBeTruthy(); + } ); + + it( "renders an iconic taxon icon when a taxon has no photo", () => { + setState( { + type: "taxon", + taxon: { + id: 12, + name: "Eumyias thalassinus", + iconic_taxon_name: "Aves", + }, + } ); + renderComponent( ); + + expect( screen.queryByTestId( "ExploreV2Header.taxonImage" ) ).toBeNull(); + expect( screen.getByTestId( "IconicTaxonName.iconicTaxonIcon" ) ).toBeTruthy(); + } ); + + it( "renders only the place name when there is no subject", () => { + setState( null ); + renderComponent( ); + + expect( screen.getByText( "California" ) ).toBeTruthy(); + expect( screen.queryByTestId( "ExploreV2Header.subject" ) ).toBeNull(); + } ); + + it( "renders the Worldwide label when location is worldwide", () => { + setState( null, { placeMode: EXPLORE_V2_PLACE_MODE.WORLDWIDE } ); + renderComponent( ); + + expect( screen.getByText( "Worldwide" ) ).toBeTruthy(); + } ); + + it( "renders the Nearby label when location is nearby", () => { + setState( null, { + placeMode: EXPLORE_V2_PLACE_MODE.NEARBY, + lat: 1, + lng: 2, + radius: 1, + } ); + renderComponent( ); + + expect( screen.getByText( "Nearby" ) ).toBeTruthy(); + } ); +} ); diff --git a/tests/unit/components/Explore/ExploreV2/components/ExploreV2Tabs.test.js b/tests/unit/components/Explore/ExploreV2/components/ExploreV2Tabs.test.js new file mode 100644 index 000000000..b0c651d2b --- /dev/null +++ b/tests/unit/components/Explore/ExploreV2/components/ExploreV2Tabs.test.js @@ -0,0 +1,37 @@ +import { screen } from "@testing-library/react-native"; +import ExploreV2Tabs from "components/Explore/ExploreV2/components/ExploreV2Tabs"; +import React from "react"; +import { renderComponent } from "tests/helpers/render"; + +describe( "ExploreV2Tabs", () => { + it( "renders both the observations and species tabs", () => { + renderComponent( ); + + expect( screen.getByTestId( "ExploreV2Tabs.observations" ) ).toBeTruthy(); + expect( screen.getByTestId( "ExploreV2Tabs.species" ) ).toBeTruthy(); + } ); + + it( "marks the observations tab as the active tab", () => { + renderComponent( ); + + expect( + screen.getByTestId( "ExploreV2Tabs.observations" ).props.accessibilityState.selected, + ).toBe( true ); + expect( + screen.getByTestId( "ExploreV2Tabs.species" ).props.accessibilityState.selected, + ).toBe( false ); + } ); + + it( "renders the provided observation and species counts", () => { + renderComponent( ); + + expect( screen.getByText( "42" ) ).toBeTruthy(); + expect( screen.getByText( "7" ) ).toBeTruthy(); + } ); + + it( "renders a placeholder when counts are not provided", () => { + renderComponent( ); + + expect( screen.getAllByText( "--" ) ).toHaveLength( 2 ); + } ); +} );