streetmix/streetmix

View on GitHub
client/src/dialogs/__tests__/GeotagDialog.test.jsx

Summary

Maintainability
D
2 days
Test Coverage
import React from 'react'
import { vi } from 'vitest'
import clone from 'just-clone'
import { screen } from '@testing-library/react'

import { render } from '~/test/helpers/render'
import * as constants from '~/src/app/config'
import { isOwnedByCurrentUser } from '~/src/streets/owner'
import GeotagDialog from '../GeotagDialog'

// Mock dependencies that could break tests
vi.mock('../../streets/owner', () => ({
  isOwnedByCurrentUser: vi.fn()
}))

// as mocked, the intial state is a street with a previously saved location, and a new marker location
// in practice, these tests don't really handle this 'new' marker location yet

const initialState = {
  street: {
    creatorId: 'mayorofnullisland',
    location: {
      label: 'Null Island',
      wofId: '1234',
      latlng: {
        lat: 0,
        lng: 0
      }
    }
  },
  map: {
    markerLocation: { lat: -1, lng: -1 },
    addressInformation: {
      street: 'Null Island Port',
      label: 'Null Island Port, Null Island',
      id: 'polyline123'
    }
  },
  user: {
    geolocation: {
      data: {
        lat: 10,
        lng: 10
      }
    }
  },
  system: {
    devicePixelRatio: 1,
    offline: false
  }
}

describe('GeotagDialog', () => {
  it('renders', () => {
    const { asFragment } = render(<GeotagDialog renderPopup={true} />, {
      initialState
    })
    expect(asFragment()).toMatchSnapshot()
  })

  it('allows a location to be cleared when the street is owned by the current user', () => {
    isOwnedByCurrentUser.mockReturnValueOnce(true)
    render(<GeotagDialog />, {
      initialState
    })

    expect(
      screen.getByRole('button', { name: 'Clear location' })
    ).toBeInTheDocument()
  })

  it('allows a location to be added when the current user started this street', () => {
    isOwnedByCurrentUser.mockReturnValueOnce(true)
    render(<GeotagDialog />, {
      initialState: {
        ...initialState,
        street: {
          creatorId: 'mayorofnullisland',
          location: null
        }
      }
    })
    expect(
      screen.getByRole('button', { name: 'Confirm location' })
    ).toBeInTheDocument()
  })

  /* neither confirm or clear location buttons should show up in this case */
  it('does not allow a location to be edited when the current user is not the street owner', () => {
    isOwnedByCurrentUser.mockReturnValueOnce(false)
    render(<GeotagDialog />, {
      initialState
    })
    // in this case we want to make sure neither button shows up, so we use regex to check the button name
    expect(
      screen.queryByRole('button', { name: /Confirm location|Clear location/ })
    ).not.toBeInTheDocument()
  })

  it('allows a location to be confirmed when the current anonymous user is not the street owner but there is no existing location attached', () => {
    isOwnedByCurrentUser.mockReturnValueOnce(false)
    render(<GeotagDialog />, {
      initialState: {
        ...initialState,
        street: {
          creatorId: 'creatorMadeThisWithNoLocation',
          location: null
        }
      }
    })

    expect(
      screen.getByRole('button', { name: 'Confirm location' })
    ).toBeInTheDocument()
  })

  describe('geocoding availability', () => {
    const errorText = 'Geocoding services are currently unavailable'
    const placeholderText = 'Search for a location'

    it('does not show error banner if geocoding services are available', () => {
      render(<GeotagDialog />, { initialState })

      expect(
        screen.queryByText(errorText, { exact: false })
      ).not.toBeInTheDocument()
      expect(screen.getByPlaceholderText(placeholderText)).toBeInTheDocument()
    })

    it('shows geocoding is unavailable if geocoder key is unset', () => {
      // Set API key to undefined
      vi.spyOn(constants, 'PELIAS_API_KEY', 'get').mockReturnValue(undefined)

      render(<GeotagDialog />, { initialState })

      expect(screen.getByText(errorText, { exact: false })).toBeInTheDocument()
      expect(
        screen.queryByPlaceholderText(placeholderText)
      ).not.toBeInTheDocument()

      // Restore API key value
      vi.restoreAllMocks()
    })

    it('shows geocoding is unavailable if geocoder host name is not set', () => {
      // Set API key to undefined
      vi.spyOn(constants, 'PELIAS_API_KEY', 'get').mockReturnValue(undefined)

      render(<GeotagDialog />, { initialState })

      expect(screen.getByText(errorText, { exact: false })).toBeInTheDocument()
      expect(
        screen.queryByPlaceholderText(placeholderText)
      ).not.toBeInTheDocument()

      // Restore API key value
      vi.restoreAllMocks()
    })

    it('shows geocoding is unavailable if offline mode is on', () => {
      const newInitialState = clone(initialState)
      newInitialState.system.offline = true

      render(<GeotagDialog />, {
        initialState: newInitialState
      })

      expect(screen.getByText(errorText, { exact: false })).toBeInTheDocument()
      expect(
        screen.queryByPlaceholderText(placeholderText)
      ).not.toBeInTheDocument()
    })
  })
})