Skip to content

Commit

Permalink
1125-fesso-add-status-dropdown (#1207)
Browse files Browse the repository at this point in the history
* 1125-fesso-add-status-dropdown

* 1125-fesso-add-status-dropdown

* 1125-fesso-add-status-dropdown

* 1125-fesso-add-status-dropdown

* 1125-fesso-add-status-dropdown

* 1125-fesso-add-status-dropdown
  • Loading branch information
NataliaR-BCN authored May 8, 2024
1 parent 628b515 commit 027f60e
Show file tree
Hide file tree
Showing 19 changed files with 282 additions and 65 deletions.
6 changes: 6 additions & 0 deletions web/usuaris/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

All notable changes to this project will be documented in this file.

## [0.15.0] - 2024-05-08

### Added

- Added Status filter

## [0.14.0] - 2024-05-06

### Added
Expand Down
8 changes: 4 additions & 4 deletions web/usuaris/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions web/usuaris/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "web_usuaris",
"private": true,
"version": "0.14.0",
"version": "0.15.0",
"type": "module",
"scripts": {
"dev": "vite",
Expand All @@ -14,7 +14,7 @@
"dependencies": {
"@hookform/resolvers": "^3.0.0",
"@itacademy/schemas": "^0.3.0",
"@itacademy/ui": "^0.31.6",
"@itacademy/ui": "^0.31.7",
"@tanstack/react-query": "^4.29.5",
"@tanstack/react-query-devtools": "^4.29.6",
"@tanstack/react-table": "^8.13.2",
Expand Down
4 changes: 4 additions & 0 deletions web/usuaris/src/__mocks__/handlers.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import { HttpResponse, http } from 'msw'
import { urls } from '../constants'
import { UserStatus } from '../types'

export const handlers = [
http.get(urls.getUsers, ({ request }) => {
const url = new URL(request.url)
const itinerarySlug = url.searchParams.get('itinerarySlug')
const status = url.searchParams.get('status')
const startDate = url.searchParams.get('startDate')
const endDate = url.searchParams.get('endDate')
const name = url.searchParams.get('name')
const dni = url.searchParams.get('dni')

if (
itinerarySlug === 'frontend-react' &&
status === UserStatus.ACTIVE &&
((startDate &&
startDate <= '2023/11/06 00:00:00.000' &&
endDate &&
Expand All @@ -34,6 +37,7 @@ export const handlers = [
{ status: 200 }
)
}

return HttpResponse.json(
[
{
Expand Down
3 changes: 2 additions & 1 deletion web/usuaris/src/__tests__/hooks/useGetUsers.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useGetUsers } from '../../hooks/useGetUsers'
import { renderHook, waitFor } from '../test-utils'
import { queryClient } from '../setup'
import { type TFilters } from '../../types'
import { UserStatus } from '../../types'

describe('useGetUsers', () => {
it('fetches users successfully', async () => {
Expand Down Expand Up @@ -63,7 +64,7 @@ describe('useGetUsers', () => {
it('handles filters correctly', async () => {
const filters: TFilters = {
itinerarySlug: 'example-slug',
status: 'ACTIVE',
status: UserStatus.ACTIVE,
startDate: '2023-03-05T00:00:00.000Z',
endDate: '2026-03-05T00:00:00.000Z',
name: 'John Doe',
Expand Down
3 changes: 2 additions & 1 deletion web/usuaris/src/__tests__/hooks/useUpdateUser.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { setupServer } from 'msw/node'
import { useUpdateUser } from '../../hooks'
import { queryClient } from '../setup'
import { handlers } from '../../__mocks__/handlers'
import { UserStatus } from '../../types'

const server = setupServer(...handlers)
beforeEach(() => {
Expand Down Expand Up @@ -50,7 +51,7 @@ describe('useUpdateUser hook', () => {
act(() => {
result.current.changeUserStatus.mutate({
id: '1',
status: 'BLOCKED',
status: UserStatus.BLOCKED,
})
})
await waitFor(() => {
Expand Down
40 changes: 40 additions & 0 deletions web/usuaris/src/__tests__/molecules/StatusDropdown.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { vi } from 'vitest'
import { fireEvent, render, screen } from '../test-utils'
import { StatusDropdown } from '../../components/molecules'
import { UserStatus } from '../../types'

const mockHandleClick = vi.fn()

afterEach(() => {
vi.restoreAllMocks()
})

describe('StatusDropdown', () => {
it('renders correctly', () => {
render(<StatusDropdown handleStatus={mockHandleClick} />)

expect(screen.getByText(/estat/i)).toBeInTheDocument()

expect(screen.getByTitle(/obre/i)).toBeInTheDocument()
})

it('renders all status with icon and returns selected option to parent', async () => {
render(<StatusDropdown handleStatus={mockHandleClick} />)

const dropdownHeader = screen.getByTestId('dropdown-header')
expect(dropdownHeader).toHaveTextContent(/estat/i)

fireEvent.click(dropdownHeader)

const activeStatus = screen.getByTestId('ACTIVE')
expect(activeStatus).toBeInTheDocument()
expect(screen.getByText(/pendent/i)).toBeInTheDocument()
expect(screen.getByText(/bloquejat/i)).toBeInTheDocument()

fireEvent.click(activeStatus)

expect(dropdownHeader).toHaveTextContent(/actiu/i)

expect(mockHandleClick).toHaveBeenCalledWith(UserStatus.ACTIVE)
})
})
113 changes: 94 additions & 19 deletions web/usuaris/src/__tests__/organisms/FiltersWidget.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { fireEvent, render, screen, waitFor } from '../test-utils'
import { fireEvent, render, screen, waitFor, within } from '../test-utils'
import { FiltersWidget } from '../../components/organisms'
import { UserStatus } from '../../types'

const mockSetFilters = vi.fn()

Expand All @@ -20,18 +21,21 @@ describe('FiltersWidget', () => {
expect(screen.getByText(/especialitat/i)).toBeInTheDocument()
)

const dropdownHeader = screen.getByTestId('dropdown-header')
const itineraryDropdown = screen.getByTestId('itinerary-dropdown')

expect(dropdownHeader).toHaveTextContent(/especialitat/i)
const itineraryDropdownHeader =
within(itineraryDropdown).getByTestId('dropdown-header')

fireEvent.click(dropdownHeader)
expect(itineraryDropdownHeader).toHaveTextContent(/especialitat/i)

const reactOption = screen.getByText('Frontend React')
fireEvent.click(itineraryDropdownHeader)

const reactOption = screen.getByTestId('1')
expect(reactOption).toBeInTheDocument()

fireEvent.click(reactOption)

expect(dropdownHeader).toHaveTextContent('Frontend React')
expect(itineraryDropdown).toHaveTextContent('Frontend React')
expect(screen.queryByText(/especialitat/i)).not.toBeInTheDocument()

expect(mockSetFilters).toHaveBeenCalledWith({
Expand All @@ -42,7 +46,7 @@ describe('FiltersWidget', () => {
it('deletes itinerary deselected and sends other filters to parent', async () => {
render(
<FiltersWidget
filters={{ status: 'ACTIVE' }}
filters={{ status: UserStatus.ACTIVE }}
setFilters={mockSetFilters}
/>
)
Expand All @@ -51,30 +55,101 @@ describe('FiltersWidget', () => {
expect(screen.getByText(/especialitat/i)).toBeInTheDocument()
)

const dropdownHeader = screen.getByTestId('dropdown-header')
const itineraryDropdown = screen.getByTestId('itinerary-dropdown')

const itineraryDropdownHeader =
within(itineraryDropdown).getByTestId('dropdown-header')

expect(itineraryDropdownHeader).toHaveTextContent(/especialitat/i)

fireEvent.click(dropdownHeader)
fireEvent.click(itineraryDropdownHeader)

const reactOption = screen.getByText('Frontend React')
const reactOption = screen.getByTestId('1')
expect(reactOption).toBeInTheDocument()

fireEvent.click(reactOption)

expect(dropdownHeader).toHaveTextContent('Frontend React')
expect(itineraryDropdownHeader).toHaveTextContent('Frontend React')

expect(mockSetFilters).toHaveBeenCalledWith({
itinerarySlug: 'react',
status: 'ACTIVE',
status: UserStatus.ACTIVE,
})

const deselectReact = within(itineraryDropdownHeader).getByTestId(
'deselect-1'
)

fireEvent.click(deselectReact)

expect(mockSetFilters).toHaveBeenCalledWith({
status: UserStatus.ACTIVE,
})
})

it('shows status selected in dropdown and sends it to parent', async () => {
render(<FiltersWidget filters={{}} setFilters={mockSetFilters} />)

const statusDropdown = screen.getByTestId('status-dropdown')

const statusDropdownHeader =
within(statusDropdown).getByTestId('dropdown-header')

expect(statusDropdownHeader).toHaveTextContent(/estat/i)

fireEvent.click(statusDropdownHeader)

const activeOption = screen.getByTestId('ACTIVE')
expect(activeOption).toBeInTheDocument()

fireEvent.click(activeOption)

expect(statusDropdownHeader).toHaveTextContent('Actiu')
expect(screen.queryByText(/estat/i)).not.toBeInTheDocument()

expect(mockSetFilters).toHaveBeenCalledWith({
status: UserStatus.ACTIVE,
})
})

it('deletes status deselected and sends other filters to parent', () => {
render(
<FiltersWidget
filters={{ itinerarySlug: 'frontend-react' }}
setFilters={mockSetFilters}
/>
)

const statusDropdown = screen.getByTestId('status-dropdown')

const statusDropdownHeader =
within(statusDropdown).getByTestId('dropdown-header')

expect(statusDropdownHeader).toHaveTextContent(/estat/i)

fireEvent.click(statusDropdownHeader)

const activeOption = screen.getByTestId('ACTIVE')
expect(activeOption).toBeInTheDocument()

fireEvent.click(activeOption)

expect(statusDropdownHeader).toHaveTextContent('Actiu')

expect(mockSetFilters).toHaveBeenCalledWith({
itinerarySlug: 'frontend-react',
status: UserStatus.ACTIVE,
})

fireEvent.click(dropdownHeader)
fireEvent.click(statusDropdownHeader)

const deselectReact = screen.getAllByTestId('deselect-1')
const deselectActive =
within(statusDropdownHeader).getByTestId('deselect-ACTIVE')

fireEvent.click(deselectReact[0])
fireEvent.click(deselectActive)

expect(mockSetFilters).toHaveBeenCalledWith({
status: 'ACTIVE',
itinerarySlug: 'frontend-react',
})
})

Expand All @@ -97,7 +172,7 @@ describe('FiltersWidget', () => {
it('deletes search value when closing search and updates filters accordingly', () => {
render(
<FiltersWidget
filters={{ status: 'ACTIVE' }}
filters={{ status: UserStatus.ACTIVE }}
setFilters={mockSetFilters}
/>
)
Expand All @@ -107,7 +182,7 @@ describe('FiltersWidget', () => {

waitFor(() =>
expect(mockSetFilters).toHaveBeenCalledWith({
status: 'ACTIVE',
status: UserStatus.ACTIVE,
name: 'marc',
dni: 'marc',
})
Expand Down Expand Up @@ -146,7 +221,7 @@ describe('FiltersWidget', () => {
it('deletes dates when closing dates inputs and updates filters accordingly', () => {
render(
<FiltersWidget
filters={{ status: 'ACTIVE' }}
filters={{ status: UserStatus.ACTIVE }}
setFilters={mockSetFilters}
/>
)
Expand Down
2 changes: 2 additions & 0 deletions web/usuaris/src/__tests__/organisms/UsersTable.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { fireEvent, render, screen, waitFor } from '../test-utils'
import { UsersTable } from '../../components/organisms'
import { errorHandlers } from '../../__mocks__/handlers'
import { server } from '../../__mocks__/server'
import { UserStatus } from '../../types'

afterEach(() => {
server.resetHandlers()
Expand Down Expand Up @@ -59,6 +60,7 @@ describe('UsersTable', () => {
<UsersTable
filtersSelected={{
itinerarySlug: 'frontend-react',
status: UserStatus.ACTIVE,
startDate: '2023/11/06 00:00:00.000',
endDate: '2023/11/06 00:00:00.000',
name: 'marc',
Expand Down
1 change: 1 addition & 0 deletions web/usuaris/src/components/molecules/ItineraryDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export const ItineraryDropdown: FC<TItineraryDropdown> = ({
openText={t('Abrir')}
closeText={t('Cerrar')}
deselectText={t('Deseleccionar')}
data-testid="itinerary-dropdown"
/>
) : null
}
Loading

0 comments on commit 027f60e

Please sign in to comment.