Skip to content

Commit

Permalink
chore: Documentation cleanup (#216)
Browse files Browse the repository at this point in the history
Co-authored-by: Om Mishra <[email protected]>
  • Loading branch information
ccallendar and mishraomp authored Aug 3, 2024
1 parent e08208e commit b95424b
Show file tree
Hide file tree
Showing 47 changed files with 238 additions and 102 deletions.
20 changes: 1 addition & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

Organics Info (ORI) shares information on authorized biosolids land application and compost facilities regulated under the Organic Matter Recycling Regulation (OMRR) in BC.

This project is part of a the OMRR Transparency Enhancement Initiative led by the Environmental Policy and Initiatives Branch (EPIB) in the Ministry of Environment and Climate Change Strategy.
This project is part of the OMRR Transparency Enhancement Initiative led by the Environmental Policy and Initiatives Branch (EPIB) in the Ministry of Environment and Climate Change Strategy.

# Technologies used

Expand Down Expand Up @@ -52,24 +52,6 @@ Steps:
4. Run the following command in terminal `cd frontend && npm install && npm run dev`, this will start the frontend
application on port 3001.

## Running Frontend Tests

**End to end** tests are run using [Playwright](https://playwright.dev/).
Here are the steps to follow to run the end to end tests:
1. First install Playwright: `npx playwright install`
2. Then run start the server and frontend as shown above in steps 1-4.
3. Run Playwright with this command: `npx playwright test` or `npm run test:e2e`

To configure playwright edit the `playwright.config.ts` file.
End to end tests are located in the `/e2e` folder.

**Unit tests** do not require the server or frontend to be running.
You can run the unit tests with this command: `npm run test:unit`
To generate a coverage report, use this command: `npm run test:cov`
The coverage report can be viewed in the `coverage` folder.
Unit tests use [MSW](https://mswjs.io/) to mock API responses, see the
`src/test-setup.ts` file where it is set up.

# Contribution Guidelines

Follow the steps outlined in this repository to contribute: [CONTRIBUTING.md](./CONTRIBUTING.md).
Expand Down
98 changes: 98 additions & 0 deletions frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Organics Info Frontend

Refer to the project README file in the parent directory for details
on the architecture, libraries, and how to run the whole application.

The information in this README file will be specific to the frontend only.

## Scripts

See the `scripts` section of the `frontend/package.json` file to see
what command line scripts can be run. The most used ones are:
- `npm start` - Starts the local application
- `npm run dev` - Starts the app with network support
- `npm run lint` - Runs the eslint to check for linting issues
- `npm run tsc` - Runs the typescript checker for typing issues
- `npm run test:unit` - Runs unit tests in watch mode
- `npm run test:cov` - Runs unit tests and generates coverage report
- `npm run test-e2e` - Runs Playwright end to end tests

There is also a `scripts` folder that contains other utility scripts
that can be run. See the README file in that directory for more details.

## Tests - Playwright and Testing Library

The [Playwright](https://playwright.dev/) library is used for End to End tests.
It requires the backend server and front end client to be running.

[Vitest](https://vitest.dev/) is used for the unit tests, along with
[React Testing Library](https://testing-library.com/).
[MSW](https://mswjs.io/) is also used for mocking the 3 API calls.
Unit tests run using jsdom, which is not the same as a full functioning browser,
and as such some features don't work and need to be mocked.
See the `src/test-setup.ts` file for more details.

### Running End To End Tests

**End to end** tests are run using [Playwright](https://playwright.dev/).
Here are the steps to follow to run the end to end tests:
1. First install Playwright: `npx playwright install`
2. Then run start the server and frontend as shown above in steps 1-4.
3. Run Playwright with this command: `npx playwright test` or `npm run test:e2e`

To configure playwright edit the `playwright.config.ts` file.
End to end tests are located in the `/e2e` folder.

It is also really useful to run the `npx playwright test --ui` command if you
want to debug why a test is failing, or to run certain tests on specific browsers.

### Running Unit Tests

**Unit tests** do not require the server or frontend to be running.
You can run the unit tests with this command: `npm run test:unit`
To generate a coverage report, use this command: `npm run test:cov`
The coverage report can be viewed in the `coverage` folder.
Unit tests use [MSW](https://mswjs.io/) to mock API responses, see the
`src/test-setup.ts` file where it is set up.

## Application Styles - Figma, MUI and CSS

The [Figma design](https://www.figma.com/design/74nNxjyv6JM6hiT1FluULV/OMRR-(ORI)?node-id=675-3797)
for this application is the source of truth for the text and styles used.

This application uses a combination of [Material UI](https://mui.com/) components,
custom React components, and CSS stylesheets.

Material UI is convenient and very helpful for making the application
responsive to different screen sizes. Therefore, MUI components are often
used whenever styles need to change based on the screen size using the
`sx` or `style` attributes. See the MUI
[Responsive UI](https://mui.com/material-ui/guides/responsive-ui/)
page for more details on how it works.

Basic styling that don't need to change with screen size (for example
colors) is handled with plain CSS files.

[CSS Variables](https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties)
(also called custom properties) are used quite frequently to define
color and layout constants. These come directly from the Figma file
and makes it easy to copy styles directly from Figma.
All the custom properties can be found in the `src/properties.css` file.

## Application State - Redux

The application state is stored in
[Redux](https://redux.js.org/tutorials/essentials/part-1-overview-concepts).

The state is divided into 4 slices:
- **omrr-slice** - Stores the array of authorizations and all search filters,
and has the API call for loading authorizations.
- **applications-slice** - Stores the array of applications
- **documents-slice** - Stores the array of documents
- **map-slice** - Stores all the map related state including selected item,
sidebar width, etc.

Each slice defines selectors and hooks to allow extracting each piece of state
in the most efficient way.

It also contains the action functions for changing the state.
4 changes: 2 additions & 2 deletions frontend/src/assets/svgs/fa-chevron-left.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/src/assets/svgs/fa-chevron-right.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion frontend/src/components/DropdownButton.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.dropdown-button-menu .MuiPaper-root {
padding: 1rem;
padding: var(--layout-padding-medium);
border-radius: var(--layout-border-radius-medium);
border: 1px solid var(--surface-color-border-light);
background: var(--surface-color-background-white);
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/HorizontalScroller.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ button.horizontal-scroller-button.MuiButton-root {
height: 45px;
padding: 0;
margin: 0;
background: var(--surface-color-primary-default);
color: white;
background-color: var(--surface-color-primary-default);
border-radius: 50%;
box-shadow: var(--box-shadow-small);
display: flex;
Expand All @@ -38,4 +39,4 @@ button.horizontal-scroller-button.horizontal-scroller-button--left {

button.horizontal-scroller-button.horizontal-scroller-button--right {
right: 16px;
}
}
8 changes: 5 additions & 3 deletions frontend/src/components/HorizontalScroller.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { ReactNode, useEffect, useRef, useState } from 'react'
import { Button } from '@mui/material'
import { ChevronLeft, ChevronRight } from '@mui/icons-material'
import clsx from 'clsx'

import { SwipeDirection, useSwipe } from '@/hooks/useSwipe'

import ChevronLeft from '@/assets/svgs/fa-chevron-left.svg?react'
import ChevronRight from '@/assets/svgs/fa-chevron-right.svg?react'

import './HorizontalScroller.css'

const DEFAULT_SCROLL_OFFSET = 100
Expand Down Expand Up @@ -107,7 +109,7 @@ function HorizontalScrollerComponent({
className="horizontal-scroller-button horizontal-scroller-button--left"
title="Scroll left"
>
<ChevronLeft color="secondary" />
<ChevronLeft />
</Button>
)}
{scrollRightVisible && (
Expand All @@ -118,7 +120,7 @@ function HorizontalScrollerComponent({
className="horizontal-scroller-button horizontal-scroller-button--right"
title="Scroll right"
>
<ChevronRight color="secondary" />
<ChevronRight />
</Button>
)}
</div>
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/LocationIconButton.test.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { screen } from '@testing-library/react'
import { Mock } from 'vitest'
import { LatLngTuple } from 'leaflet'

import { render } from '@/test-utils'
import { useUserLocation } from '@/features/omrr/omrr-slice'
import { LocationIconButton } from './LocationIconButton'
import { Mock } from 'vitest'

interface State {
userLocation?: LatLngTuple
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/components/NotFound.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { vi } from 'vitest'
import { render, screen } from '@testing-library/react'
import NotFound from '@/components/NotFound'

import NotFound from './NotFound'

vi.mock('react-router', () => ({
useNavigate: vi.fn(),
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useNavigate } from 'react-router'
import { Box, Button, Container, Typography } from '@mui/material'
import Grid from '@mui/material/Grid'
import { useNavigate } from 'react-router'

export default function NotFound() {
const navigate = useNavigate()
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/SearchByRadioGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ import { ChangeEvent } from 'react'
import { useDispatch } from 'react-redux'
import { FormControlLabel, Radio, RadioGroup } from '@mui/material'
import { RadioGroupProps } from '@mui/material/RadioGroup/RadioGroup'
import clsx from 'clsx'

import {
SEARCH_BY_ACTIVE,
SEARCH_BY_ALL,
SEARCH_BY_INACTIVE,
} from '@/interfaces/types'
import { setSearchBy, useSearchBy } from '@/features/omrr/omrr-slice'
import clsx from 'clsx'

interface Props extends Omit<RadioGroupProps, 'value'> {
defaultValue?: string
Expand Down
8 changes: 8 additions & 0 deletions frontend/src/constants/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const MIN_SEARCH_LENGTH = 3
* How long to wait before performing a search.
*/
export const SEARCH_DELAY = 300

/**
* The zoom level when zooming to a place.
*/
Expand All @@ -25,8 +26,12 @@ export const FOOTER_HEIGHT = 64
* in its initial state. It can be expanded to full height.
*/
export const MAP_BOTTOM_DRAWER_HEIGHT = 320
/**
* The search by, polygon and point search will have a smaller height.
*/
export const MAP_BOTTOM_DRAWER_HEIGHT_SMALL = 160

// The positions of the map controls (zoom in/out etc)
export const MAP_CONTROLS_RIGHT_XL = 64
export const MAP_CONTROLS_RIGHT_LG = 48
export const MAP_CONTROLS_RIGHT_SM = 24
Expand All @@ -41,4 +46,7 @@ export enum ActiveToolEnum {
filterBy = 'filterBy',
}

/**
* The smallest allowed radius in meters for the Point Search feature.
*/
export const MIN_CIRCLE_RADIUS = 500
5 changes: 4 additions & 1 deletion frontend/src/constants/data-layers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ import { DataLayerGroup } from '@/interfaces/data-layers'
const BASE_URL = 'https://openmaps.gov.bc.ca/geo/pub'

/**
* All layer urls and params extracted from the ticket.
* All layer urls and params are extracted from these tickets.
* Many of them have multiple available styles that can be displayed.
* The `url` field is the WMS url. The `webUrl` is the data catalogue url.
* These values are displayed on the Map page and the Guidance page.
* @see https://github.com/bcgov/nr-epd-organics-info/issues/109
* @see https://github.com/bcgov/nr-epd-organics-info/issues/204
*/
export const DATA_LAYER_GROUPS: DataLayerGroup[] = [
{
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/constants/marker-icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const blueIcon1x = new L.Icon({
shadowAnchor: [8, 4],
})

// Used by Polygon and Point search tools
export const crosshairsIcon = new L.Icon({
iconUrl: crosshairsSvg,
iconSize: [32, 32],
Expand All @@ -46,6 +47,7 @@ export const emptyIcon = new L.DivIcon({
iconSize: [0, 0],
})

// Icon used by Polygon search at the vertices
export const blackSquareIcon = new L.DivIcon({
html: '<div />',
className: 'black-square-icon',
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/hooks/useMyLocation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export function useMyLocation(): MyLocationData {
return data
}

/**
* Allows querying the browser permissions to see if the geolocation
* permission has been set (granted, prompt, denied).
*/
export function useGeolocationPermission(): PermissionState | undefined {
const [state, setState] = useState<PermissionState | undefined>(undefined)

Expand Down
11 changes: 10 additions & 1 deletion frontend/src/hooks/useSwipe.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,18 @@ import { RefObject, useEffect, useRef } from 'react'
export type SwipeDirection = 'left' | 'right' | 'up' | 'down'
export type SwipeCallback = (swipeDirection: SwipeDirection) => void

/**
* A simple hook that will call a callback function
* when a swipe gesture is detected on the reference element.
* @param ref a reference to the HTML element which will receive gestures
* @param callback the callback function for when gestures are detected
* @param {number} [minDistance=20] the minimum distance in pixels required
* for a swipe to be recognized.
*/
export function useSwipe(
ref: RefObject<HTMLElement | null | undefined>,
callback: SwipeCallback,
minDistance = 30,
minDistance = 20,
) {
const callbackRef = useRef<SwipeCallback>(callback)
callbackRef.current = callback
Expand Down Expand Up @@ -53,6 +61,7 @@ export function useSwipe(

useEffect(() => {
const el = ref.current
// Determine if touch screen enabled device
const isTouch = 'ontouchstart' in window
if (el) {
if (isTouch) {
Expand Down
5 changes: 0 additions & 5 deletions frontend/src/interfaces/UserDto.ts

This file was deleted.

4 changes: 4 additions & 0 deletions frontend/src/mocks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## Mock Data

The files in this folder contain mock data that is used by the
Unit Tests. They are copied from the real data when possible.
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import { getByText, screen, waitFor } from '@testing-library/react'
import { render } from '@/test-utils'
import OmrrData from '@/interfaces/omrr'
import { OmrrAuthzDocsResponse } from '@/interfaces/omrr-documents'
import { mockOmrrData } from '@/mocks/mock-omrr-data'
import { initialState } from '@/features/omrr/omrr-slice'
import { mockOmrrData } from '@/mocks/mock-omrr-data'
import { mockOmrrApplicationStatusResponse } from '@/mocks/mock-omrr-application-status'
import AuthorizationDetails from './AuthorizationDetails'
import { mockOmrrDocuments } from '@/mocks/mock-omrr-documents'
import AuthorizationDetails from './AuthorizationDetails'

describe('Test suite for AuthorizationDetails', () => {
function renderComponent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function DetailsBackButton() {
color="primary"
variant="contained"
size="medium"
startIcon={<ChevronLeft />}
startIcon={<ChevronLeft width={8} />}
onClick={onClick}
>
Back to {searchType}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { render, screen } from '@testing-library/react'

import OmrrData, { omrrDataBooleanFields } from '@/interfaces/omrr'
import { DetailsSection } from './DetailsSection'
import { createMockOmrrData } from '@/mocks/mock-omrr-data'
import { OPERATION_TYPE_COMPOST_FACILITY } from '@/interfaces/omrr-filter'
import { createMockOmrrData } from '@/mocks/mock-omrr-data'
import { DetailsSection } from './DetailsSection'

describe('Test suite for DetailsSection', () => {
it('should render DetailsSection for old Notification', () => {
Expand Down
Loading

0 comments on commit b95424b

Please sign in to comment.