import { defaultExploreV2Location, EXPLORE_V2_ACTION, EXPLORE_V2_PLACE_MODE, exploreV2Reducer, initialExploreV2State, } from "providers/ExploreV2Context"; import fetchCoarseUserLocation from "sharedHelpers/fetchCoarseUserLocation"; import { OBSERVATIONS_SORT } from "sharedHelpers/observationsSort"; jest.mock( "sharedHelpers/fetchCoarseUserLocation", ( ) => ( { __esModule: true, default: jest.fn( ), } ) ); describe( "initialExploreV2State", ( ) => { it( "starts with no subject, UNINITIALIZED placeMode, newest-upload sort, empty filters", ( ) => { expect( initialExploreV2State.subject ).toBeNull( ); expect( initialExploreV2State.location.placeMode ).toBe( EXPLORE_V2_PLACE_MODE.UNINITIALIZED ); expect( initialExploreV2State.sortBy ).toBe( OBSERVATIONS_SORT.DATE_UPLOADED_NEWEST ); expect( initialExploreV2State.filters ).toEqual( {} ); } ); } ); describe( "exploreV2Reducer", ( ) => { describe( EXPLORE_V2_ACTION.SET_SUBJECT, ( ) => { it( "sets a taxon subject, replacing any prior subject", ( ) => { const taxon = { id: 42, name: "Foo" }; const state = { ...initialExploreV2State, subject: { type: "user", user: { id: 1 } }, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_SUBJECT, subject: { type: "taxon", taxon }, } ); expect( next.subject ).toEqual( { type: "taxon", taxon } ); } ); it( "preserves location, sortBy, and filters when changing subject", ( ) => { const state = { subject: null, location: { placeMode: EXPLORE_V2_PLACE_MODE.NEARBY, lat: 1, lng: 2, radius: 3, }, sortBy: OBSERVATIONS_SORT.MOST_FAVED, filters: { quality_grade: "research" }, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_SUBJECT, subject: { type: "taxon", taxon: { id: 1 } }, } ); expect( next.location ).toEqual( state.location ); expect( next.sortBy ).toBe( state.sortBy ); expect( next.filters ).toEqual( state.filters ); } ); } ); describe( EXPLORE_V2_ACTION.CLEAR_SUBJECT, ( ) => { it( "clears the selected subject", ( ) => { const state = { ...initialExploreV2State, subject: { type: "taxon", taxon: { id: 99 } }, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.CLEAR_SUBJECT } ); expect( next.subject ).toBeNull( ); } ); } ); describe( "location actions", ( ) => { it( "SET_LOCATION_NEARBY transitions from PLACE and drops place", ( ) => { const state = { ...initialExploreV2State, location: { placeMode: EXPLORE_V2_PLACE_MODE.PLACE, place: { id: 1 }, }, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_LOCATION_NEARBY, lat: 37.5, lng: -122.1, radius: 1, } ); expect( next.location.placeMode ).toBe( EXPLORE_V2_PLACE_MODE.NEARBY ); expect( next.location.lat ).toBe( 37.5 ); expect( next.location.lng ).toBe( -122.1 ); expect( next.location.radius ).toBe( 1 ); expect( next.location.place ).toBeUndefined( ); } ); it( "SET_LOCATION_WORLDWIDE transitions from NEARBY and drops coords", ( ) => { const state = { ...initialExploreV2State, location: { placeMode: EXPLORE_V2_PLACE_MODE.NEARBY, lat: 1, lng: 1, radius: 1, }, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_LOCATION_WORLDWIDE, } ); expect( next.location.placeMode ).toBe( EXPLORE_V2_PLACE_MODE.WORLDWIDE ); expect( next.location.lat ).toBeUndefined( ); expect( next.location.lng ).toBeUndefined( ); expect( next.location.radius ).toBeUndefined( ); } ); it( "SET_LOCATION_PLACE transitions from NEARBY and drops coords", ( ) => { const state = { ...initialExploreV2State, location: { placeMode: EXPLORE_V2_PLACE_MODE.NEARBY, lat: 1, lng: 1, radius: 1, }, }; const place = { id: 5, display_name: "Oakland" }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_LOCATION_PLACE, place, } ); expect( next.location.placeMode ).toBe( EXPLORE_V2_PLACE_MODE.PLACE ); expect( next.location.place ).toEqual( place ); expect( next.location.lat ).toBeUndefined( ); } ); it( "SET_LOCATION_PLACE replaces an existing place", ( ) => { const state = { ...initialExploreV2State, location: { placeMode: EXPLORE_V2_PLACE_MODE.PLACE, place: { id: 1, display_name: "Oakland" }, }, }; const place = { id: 2, display_name: "Berkeley" }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_LOCATION_PLACE, place, } ); expect( next.location.placeMode ).toBe( EXPLORE_V2_PLACE_MODE.PLACE ); expect( next.location.place ).toEqual( place ); } ); it( "SET_LOCATION_NEEDS_PERMISSION transitions from UNINITIALIZED", ( ) => { const next = exploreV2Reducer( initialExploreV2State, { type: EXPLORE_V2_ACTION.SET_LOCATION_NEEDS_PERMISSION, } ); expect( next.location.placeMode ).toBe( EXPLORE_V2_PLACE_MODE.NEEDS_PERMISSION ); } ); it( "SET_LOCATION_NEEDS_PERMISSION preserves subject, sortBy, and filters", ( ) => { const state = { subject: { type: "taxon", taxon: { id: 42 } }, location: { placeMode: EXPLORE_V2_PLACE_MODE.UNINITIALIZED }, sortBy: OBSERVATIONS_SORT.MOST_FAVED, filters: { quality_grade: "research" }, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_LOCATION_NEEDS_PERMISSION, } ); expect( next.subject ).toEqual( state.subject ); expect( next.sortBy ).toBe( state.sortBy ); expect( next.filters ).toEqual( state.filters ); } ); it( "preserves subject, sortBy, and filters when changing location", ( ) => { const state = { subject: { type: "taxon", taxon: { id: 42 } }, location: { placeMode: EXPLORE_V2_PLACE_MODE.UNINITIALIZED }, sortBy: OBSERVATIONS_SORT.MOST_FAVED, filters: { quality_grade: "research" }, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_LOCATION_WORLDWIDE, } ); expect( next.subject ).toEqual( state.subject ); expect( next.sortBy ).toBe( state.sortBy ); expect( next.filters ).toEqual( state.filters ); } ); } ); describe( EXPLORE_V2_ACTION.SET_SORT, ( ) => { it( "updates sortBy", ( ) => { const next = exploreV2Reducer( initialExploreV2State, { type: EXPLORE_V2_ACTION.SET_SORT, sortBy: OBSERVATIONS_SORT.DATE_OBSERVED_NEWEST, } ); expect( next.sortBy ).toBe( OBSERVATIONS_SORT.DATE_OBSERVED_NEWEST ); } ); } ); describe( EXPLORE_V2_ACTION.SET_FILTERS, ( ) => { it( "replaces filters with the provided object", ( ) => { const state = { ...initialExploreV2State, filters: { quality_grade: "research" }, }; const filters = { quality_grade: "needs_id", iconic_taxa: ["Aves"] }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.SET_FILTERS, filters, } ); expect( next.filters ).toEqual( filters ); } ); } ); describe( EXPLORE_V2_ACTION.RESET, ( ) => { it( "returns initial state", ( ) => { const state = { ...initialExploreV2State, subject: { type: "taxon", taxon: { id: 1 } }, sortBy: OBSERVATIONS_SORT.MOST_FAVED, }; const next = exploreV2Reducer( state, { type: EXPLORE_V2_ACTION.RESET } ); expect( next ).toEqual( initialExploreV2State ); } ); } ); } ); describe( "defaultExploreV2Location", ( ) => { beforeEach( ( ) => { fetchCoarseUserLocation.mockReset( ); } ); it( "returns NEARBY with radius 1 when a location is available", async ( ) => { fetchCoarseUserLocation.mockResolvedValueOnce( { latitude: 37.5, longitude: -122.1 } ); const result = await defaultExploreV2Location( ); expect( result ).toEqual( { placeMode: EXPLORE_V2_PLACE_MODE.NEARBY, lat: 37.5, lng: -122.1, radius: 1, } ); } ); it( "returns WORLDWIDE when fetchCoarseUserLocation returns null", async ( ) => { fetchCoarseUserLocation.mockResolvedValueOnce( null ); const result = await defaultExploreV2Location( ); expect( result ).toEqual( { placeMode: EXPLORE_V2_PLACE_MODE.WORLDWIDE } ); } ); } );