Skip to content

Commit

Permalink
fix: show no results if none found (#1199)
Browse files Browse the repository at this point in the history
* show no results if none found

* add test for no results banner

* remove excess useEffects

* update the tests

* use lazy search query

* add additional mock
  • Loading branch information
gidjin authored Jan 31, 2024
1 parent 21de664 commit d3dff33
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 45 deletions.
55 changes: 25 additions & 30 deletions src/__tests__/pages/guardian-directory.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,34 @@
import { screen, act, waitFor } from '@testing-library/react'
import { axe } from 'jest-axe'
import { renderWithAuthAndApollo } from '../../testHelpers'
import * as useUserHooks from 'hooks/useUser'
import GuardianDirectory from 'pages/guardian-directory'
import { GetGuardianDirectoryDocument } from 'operations/portal/queries/getGuardianDirectory.g'
import { SessionUser } from 'types'
import { GetUserQuery } from 'operations/portal/queries/getUser.g'
import { guardianDirectoryMock } from '__fixtures__/data/guardianDirectory'

type MockedImplementation = {
user: SessionUser | null
portalUser: GetUserQuery | undefined
loading: boolean
}
import { SearchGuardianDirectoryDocument } from 'operations/portal/queries/searchGuardianDirectory.g'
import { GetLastModifiedAtDocument } from 'operations/portal/queries/getLastModifiedAt.g'
import { GetGuardianDirectoryDocument } from 'operations/portal/queries/getGuardianDirectory.g'

const mockDirectory = [
{
request: {
query: GetLastModifiedAtDocument,
},
result: jest.fn(() => ({
data: {
getLastModifiedAt: new Date(),
},
})),
},
{
request: {
query: SearchGuardianDirectoryDocument,
variables: { search: '' },
},
result: jest.fn(() => ({
data: {
searchGuardianDirectory: guardianDirectoryMock,
},
})),
},
{
request: {
query: GetGuardianDirectoryDocument,
Expand All @@ -31,29 +45,10 @@ const mockDirectory = [
},
]

beforeEach(() => {
jest
.spyOn(useUserHooks, 'useUser')
.mockImplementation((): MockedImplementation => {
return {
user: null,
portalUser: undefined,
loading: false,
}
})
})

describe('GuardianDirectory', () => {
describe('without a user', () => {
test('renders the loader while fetching the user', () => {
jest.spyOn(useUserHooks, 'useUser').mockImplementation(() => {
return {
user: null,
portalUser: undefined,
loading: true,
}
})
renderWithAuthAndApollo(<GuardianDirectory />, {})
renderWithAuthAndApollo(<GuardianDirectory />, {}, mockDirectory)
expect(screen.getByText('Content is loading...')).toBeInTheDocument()
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/

import { render, screen } from '@testing-library/react'
import { axe } from 'jest-axe'
import React from 'react'
import { GuardianDirectoryTable } from './GuardianDirectoryTable'

Expand All @@ -21,4 +22,28 @@ describe('GuardianDirectoryTable component', () => {
expect(screen.getByText('value1')).toBeInTheDocument()
expect(screen.getByText('value2')).toBeInTheDocument()
})

test('renders the no results banner with no rows', async () => {
const { container } = render(
<GuardianDirectoryTable
headers={['header1', 'header2']}
rows={[]}
keys={['header1', 'header2']}
/>
)

expect(screen.queryByText('header1')).not.toBeInTheDocument()
expect(screen.queryByText('header2')).not.toBeInTheDocument()
expect(screen.queryAllByRole('img')).toHaveLength(2)
expect(
screen.queryByText('There are no results that match that query.')
).toBeInTheDocument()
expect(
await axe(container, {
rules: {
'image-alt': { enabled: false },
},
})
).toHaveNoViolations()
})
})
16 changes: 16 additions & 0 deletions src/components/GuardianDirectoryTable/GuardianDirectoryTable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import { Table } from '@trussworks/react-uswds'
import styles from './GuardianDirectoryTable.module.scss'
import { SearchBanner } from 'components/SearchBanner/SearchBanner'

type GuardianDirectoryTableProps = {
headers: string[]
Expand All @@ -13,6 +14,21 @@ export const GuardianDirectoryTable = ({
rows,
keys,
}: GuardianDirectoryTableProps) => {
if (rows.length === 0) {
// no results
return (
<SearchBanner icon={<img src="/assets/images/moon-flag.svg" alt=" " />}>
<div>
<h3>There are no results that match that query.</h3>
<p>
It seems you didn’t find what you were looking for. Please search
again with different keywords.
</p>
</div>
</SearchBanner>
)
}

return (
<div
data-testid="guardian-directory-table"
Expand Down
36 changes: 21 additions & 15 deletions src/pages/guardian-directory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,48 @@ import { useFlags } from 'launchdarkly-react-client-sdk'
import { useRouter } from 'next/router'
import { Button, Search } from '@trussworks/react-uswds'
import LoadingWidget from 'components/LoadingWidget/LoadingWidget'
import { useUser } from 'hooks/useUser'
import { withDefaultLayout } from 'layout/DefaultLayout/DefaultLayout'
import styles from 'styles/pages/guardianDirectory.module.scss'
import { GuardianDirectoryTable } from 'components/GuardianDirectoryTable/GuardianDirectoryTable'
import { useGetGuardianDirectoryQuery } from 'operations/portal/queries/getGuardianDirectory.g'
import { useSearchGuardianDirectoryQuery } from 'operations/portal/queries/searchGuardianDirectory.g'
import { useSearchGuardianDirectoryLazyQuery } from 'operations/portal/queries/searchGuardianDirectory.g'
import { useGetLastModifiedAtQuery } from 'operations/portal/queries/getLastModifiedAt.g'
import { GuardianDirectory as GuardianDirectoryType } from 'types'
import { useGetGuardianDirectoryQuery } from 'operations/portal/queries/getGuardianDirectory.g'

const GuardianDirectory = () => {
const flags = useFlags()
const router = useRouter()
const { loading } = useUser()
const [directory, setDirectory] = useState(Array<GuardianDirectoryType>)
const { data } = useGetGuardianDirectoryQuery()
const { data: lastModifiedAt } = useGetLastModifiedAtQuery()

const { data: guardianDirectoryData, loading: loadingGuardianData } =
useGetGuardianDirectoryQuery()
const [searchQuery, setSearchQuery] = useState('')
const { data: searchData, loading: loadingSearch } =
useSearchGuardianDirectoryQuery({
const [loadSearch, { data: searchData, loading: loadingSearchData }] =
useSearchGuardianDirectoryLazyQuery({
variables: { search: searchQuery },
})

useEffect(() => {
if (searchQuery && !loadingSearch) {
if (guardianDirectoryData && !loadingGuardianData) {
setDirectory(
guardianDirectoryData.guardianDirectory as GuardianDirectoryType[]
)
}
}, [loadingGuardianData, guardianDirectoryData])

useEffect(() => {
if (searchQuery && searchData && !loadingSearchData) {
setDirectory(
searchData?.searchGuardianDirectory as GuardianDirectoryType[]
searchData.searchGuardianDirectory as GuardianDirectoryType[]
)
}
}, [searchQuery, loading, searchData])
}, [loadingSearchData, searchData, searchQuery])

useEffect(() => {
if (data) {
setDirectory(data.guardianDirectory as GuardianDirectoryType[])
if (searchQuery) {
loadSearch()
}
}, [data])
}, [searchQuery])

const searchDirectory = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
Expand Down Expand Up @@ -85,7 +91,7 @@ const GuardianDirectory = () => {
</Button>
</div>

{!directory.length ? (
{!directory || loadingSearchData || loadingGuardianData ? (
<LoadingWidget />
) : (
<GuardianDirectoryTable
Expand Down

0 comments on commit d3dff33

Please sign in to comment.