Skip to content

Commit

Permalink
Add more RTL tests
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksTeresh committed May 27, 2024
1 parent 2498076 commit 147c7e7
Show file tree
Hide file tree
Showing 8 changed files with 273 additions and 27 deletions.
13 changes: 13 additions & 0 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"test": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testMatch '**/server/**/*.test.*' --setupFilesAfterEnv ./setupTests.ts",
"test:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testMatch '**/server/**/*.test.*' --setupFilesAfterEnv ./setupTests.ts --watchAll",
"test:front": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testMatch '**/client/**/*.test.*' --setupFilesAfterEnv ./setupTests.ts",
"test:front:watch": "node --experimental-vm-modules node_modules/jest/bin/jest.js --testMatch '**/client/**/*.test.*' --setupFilesAfterEnv ./setupTests.ts --watchAll",
"test:front:watch": "DEBUG_PRINT_LIMIT=100000 node --experimental-vm-modules node_modules/jest/bin/jest.js --testMatch '**/client/**/*.test.*' --setupFilesAfterEnv ./setupTests.ts --watchAll",
"test:integration": "concurrently \"docker run -e PGDATA=/test-data -e POSTGRES_PASSWORD=postgres -p 5433:5432 postgres:15.6\" \"sleep 3 && NODE_ENV=test REACT_APP_E2E=true PORT=8001 DATABASE_URL=postgres://postgres:postgres@localhost:5433/postgres node --experimental-vm-modules node_modules/jest/bin/jest.js --setupFilesAfterEnv ./setupIntegrationTests.ts --forceExit\" --kill-others --success command-1 --hide 0 --prefix none",
"test:integration:watch": "concurrently \"docker run -e PGDATA=/test-data -e POSTGRES_PASSWORD=postgres -p 5433:5432 postgres:15.6\" \"NODE_ENV=test PORT=8001 DATABASE_URL=postgres://postgres:postgres@localhost:5433/postgres node --experimental-vm-modules node_modules/jest/bin/jest.js --watchAll --setupFilesAfterEnv ./setupIntegrationTests.ts\" --hide 0 --prefix none",
"lint": "eslint 'src/**/*.{ts,tsx}'",
Expand Down Expand Up @@ -44,6 +44,7 @@
"@tanstack/react-query": "^5.32.0",
"@tanstack/react-query-devtools": "^5.32.0",
"@testing-library/react": "^15.0.7",
"@testing-library/user-event": "^14.5.2",
"axios": "^1.6.8",
"connect-redis": "^7.1.1",
"cors": "^2.8.5",
Expand Down
16 changes: 11 additions & 5 deletions src/client/components/ThesisPage/SupervisorSelect.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from 'react'
import { render, screen } from '@testing-library/react'

import SupervisorSelect from './SupervisorSelect'
import initializeI18n from '../../util/il18n'

describe('SupervisorSelect', () => {
const supervisors = [
Expand All @@ -16,6 +17,8 @@ describe('SupervisorSelect', () => {

beforeEach(() => {
setSupervisorSelections = jest.fn()

initializeI18n()
})

it('renders the SupervisorSelect component', () => {
Expand All @@ -27,7 +30,7 @@ describe('SupervisorSelect', () => {
/>
)

expect(screen.getByText('Add Supervisor')).toBeInTheDocument()
expect(screen.getByText('Lisää ohjaaja')).toBeInTheDocument()
})

it('renders the SupervisorSelect component with a supervisor', () => {
Expand All @@ -40,8 +43,11 @@ describe('SupervisorSelect', () => {
setSupervisorSelections={setSupervisorSelections}
/>
)

expect(screen.getByText('Valitse ohjaaja')).toBeInTheDocument()
expect(screen.getByText('Osuus')).toBeInTheDocument()
expect(screen.getByText('John Doe')).toBeInTheDocument()
expect(screen.getByText('Add Supervisor')).toBeInTheDocument()
expect(screen.getByText('Lisää ohjaaja')).toBeInTheDocument()
})

it('renders the SupervisorSelect component with multiple supervisors', () => {
Expand All @@ -57,7 +63,7 @@ describe('SupervisorSelect', () => {
)
expect(screen.getByText('John Doe')).toBeInTheDocument()
expect(screen.getByText('Jane Smith')).toBeInTheDocument()
expect(screen.getByText('Add Supervisor')).toBeInTheDocument()
expect(screen.getByText('Lisää ohjaaja')).toBeInTheDocument()
})

describe('interactions', () => {
Expand All @@ -70,7 +76,7 @@ describe('SupervisorSelect', () => {
/>
)

const select = screen.getByText('Add Supervisor')
const select = screen.getByText('Lisää ohjaaja')
select.click()

expect(setSupervisorSelections).toHaveBeenCalledTimes(1)
Expand All @@ -90,7 +96,7 @@ describe('SupervisorSelect', () => {
/>
)

const removeButton = screen.getByText('Remove')
const removeButton = screen.getByText('Poista')
removeButton.click()

expect(setSupervisorSelections).toHaveBeenCalledTimes(1)
Expand Down
15 changes: 9 additions & 6 deletions src/client/components/ThesisPage/SupervisorSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@ import {
} from '@mui/material'
import { SupervisionData, User } from '@backend/types'
import { SupervisorSelection } from '@frontend/types'
import { useTranslation } from 'react-i18next'

const SupervisorSelect: React.FC<{
supervisors: User[]
supervisorSelections: SupervisorSelection[]
setSupervisorSelections: (newSupervisions: SupervisionData[]) => void
}> = ({ supervisors, supervisorSelections, setSupervisorSelections }) => {
const { t } = useTranslation()

const handleSupervisorChange = (index: number, supervisorId: string) => {
const updatedSelections = [...supervisorSelections]
updatedSelections[index].userId = supervisorId
Expand Down Expand Up @@ -59,14 +62,14 @@ const SupervisorSelect: React.FC<{
// eslint-disable-next-line react/no-array-index-key
<Stack key={index} spacing={1} direction="row">
<FormControl fullWidth>
<InputLabel id={`supervisor-select-label-${index}`}>
Select supervisor
<InputLabel id={`supervisor-${index}-select-label`}>
{t('thesisForm:selectSupervisor')}
</InputLabel>
<Select
required
value={selection.userId}
label="Select supervisor"
name={`supervisorId-${index}`}
name={`supervisor-${index}`}
onChange={(event) =>
handleSupervisorChange(index, event.target.value as string)
}
Expand All @@ -83,14 +86,14 @@ const SupervisorSelect: React.FC<{
type="number"
sx={{ width: 125 }}
inputProps={{ min: 1, max: 100 }}
label="Percentage"
label={t('thesisForm:selectSupervisorPercentage')}
value={selection.percentage}
onChange={(event) =>
handlePercentageChange(index, parseInt(event.target.value, 10))
}
/>
<Button onClick={() => handleRemoveSupervisor(index)}>
Remove
{t('removeButton')}
</Button>
</Stack>
)
Expand All @@ -99,7 +102,7 @@ const SupervisorSelect: React.FC<{
disabled={supervisorSelections.length === supervisors.length}
onClick={handleAddSupervisor}
>
Add Supervisor
{t('thesisForm:addSupervisor')}
</Button>
</Stack>
)
Expand Down
207 changes: 207 additions & 0 deletions src/client/components/ThesisPage/ThesisEditForm.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/**
* @jest-environment jsdom
*/
import * as React from 'react'
import dayjs from 'dayjs'
import userEvent from '@testing-library/user-event'
import {
fireEvent,
render,
screen,
waitFor,
} from '@testing-library/react'

import initializeI18n from '../../util/il18n'

jest.unstable_mockModule('./src/client/hooks/useUsers', () => ({
default: jest.fn().mockReturnValue({
users: [
{ id: 1, firstName: 'John', lastName: 'Doe', username: 'johndoe' },
{ id: 2, firstName: 'Jane', lastName: 'Smith', username: 'janesmith' },
{
id: 3,
firstName: 'Bob',
lastName: 'Luukkainen',
username: 'bobluukkainen',
},
],
}),
}))
jest.unstable_mockModule('@mui/icons-material/CloudUpload', () => ({
default: jest.fn().mockReturnValue('CloudUploadIcon'),
}))
jest.unstable_mockModule('@mui/icons-material/UploadFile', () => ({
default: jest.fn().mockReturnValue('UploadFileIcon'),
}))
jest.unstable_mockModule('@mui/icons-material/Error', () => ({
default: jest.fn().mockReturnValue('ErrorIcon'),
}))

const ThesisEditForm = (await import('./ThesisEditForm')).default

describe('ThesisEditForm', () => {
let mockOnClose
let mockOnSubmit

const programs = [{ key: 'KH50_001', name: 'Test Program' }]

beforeEach(() => {
mockOnClose = jest.fn()
mockOnSubmit = jest.fn()
})

describe('when initialThesis is a new thesis', () => {
beforeEach(() => {
const initialThesis = {
programId: programs[0].key,
supervisions: [{ userId: 1, percentage: 100 }],
authors: [],
topic: '',
status: 'PLANNING',
startDate: dayjs().format('YYYY-MM-DD'),
targetDate: dayjs().add(1, 'year').format('YYYY-MM-DD'),
}

initializeI18n()

render(
<ThesisEditForm
initialThesis={initialThesis}
onClose={mockOnClose}
onSubmit={mockOnSubmit}
/>
)
})

it('renders ThesisEditForm correctly, renders all validation error, and submit button is disabled', () => {
expect(screen.getByText('Muokkaa gradu')).toBeInTheDocument()
expect(screen.getByText('Aihe')).toBeInTheDocument()
expect(screen.getByText('Ohjelma')).toBeInTheDocument()
expect(screen.getByText('Tekijä')).toBeInTheDocument()
expect(screen.getByText('Vaihe')).toBeInTheDocument()
expect(screen.getByText('Lataa tutkimussuunnitelma')).toBeInTheDocument()
expect(screen.getByText('Lataa työskentelysopimus')).toBeInTheDocument()
expect(screen.getByText('Lisää ohjaaja')).toBeInTheDocument()

expect(
screen.getByText('Tutkimussuunnitelma puuttuu')
).toBeInTheDocument()
expect(screen.getByText('Työskentelysopimus puuttuu')).toBeInTheDocument()

expect(screen.getByRole('button', { name: 'Tallenna' })).toBeDisabled()
})

describe('when all required fields are filled', () => {
beforeEach(async () => {
const user = userEvent.setup()

const topicInput = screen.getByRole('textbox', { name: 'Aihe' })
const programSelect = screen.getAllByRole('combobox')[0]
const authorSelect = screen.getAllByRole('combobox')[1]
const statusSelect = screen.getAllByRole('combobox')[2]

const researchPlanInput = screen
.getByRole('button', {
name: 'CloudUploadIcon Lataa tutkimussuunnitelma',
})
.querySelector('input')

const waysOfWorkingInput = screen
.getByRole('button', {
name: 'CloudUploadIcon Lataa työskentelysopimus',
})
.querySelector('input')

// Fill all required fields
await user.type(topicInput, 'Test')
await user.click(programSelect)
await user.click(
screen.getAllByText(
"Bachelor's Programme in Mathematical Sciences"
)[0]
)

await user.click(authorSelect)
await waitFor(() => {
expect(screen.getByText('janesmith')).toBeInTheDocument()
})
await user.click(screen.getByText('janesmith'))

await user.click(statusSelect)
await user.click(screen.getAllByText('Planning')[0])

const testFile = new File(['test'], 'researchPlan.pdf', {
type: 'application/pdf',
})
fireEvent.change(researchPlanInput, {
target: { files: { item: () => testFile, length: 1, 0: testFile } },
})
expect(researchPlanInput.files[0]).toBe(testFile)

fireEvent.change(waysOfWorkingInput, {
target: { files: { item: () => testFile, length: 1, 0: testFile } },
})
expect(researchPlanInput.files[0]).toBe(testFile)
})

it('renders Submit button enabled and when clicked, calls onSubmit', async () => {
expect(
screen.queryByText('Tutkimussuunnitelma puuttuu')
).not.toBeInTheDocument()
expect(
screen.queryByText('Työskentelysopimus puuttuu')
).not.toBeInTheDocument()
expect(
screen.queryByText('Varmista, että ohjaajien yhteisprosentti on 100')
).not.toBeInTheDocument()

const submitButton = screen.getByText('Tallenna').closest('button')

expect(submitButton).toBeEnabled()

await userEvent.click(submitButton)

expect(mockOnSubmit).toHaveBeenCalledTimes(1)
})
})
})

describe('when initialThesis is an existing thesis', () => {
beforeEach(() => {
const initialThesis = {
programId: programs[0].key,
supervisions: [{ userId: 1, percentage: 100 }],
authors: [{ userId: 2 }],
topic: 'Test',
status: 'PLANNING',
startDate: dayjs().format('YYYY-MM-DD'),
targetDate: dayjs().add(1, 'year').format('YYYY-MM-DD'),
researchPlan: {},
waysOfWorking: {},
}

initializeI18n()

render(
<ThesisEditForm
initialThesis={initialThesis}
onClose={mockOnClose}
onSubmit={mockOnSubmit}
/>
)
})

it('renders ThesisEditForm correctly, renders no validation error, and submit button is enabled', () => {
expect(screen.getByText('Muokkaa gradu')).toBeInTheDocument()
expect(screen.getByText('Aihe')).toBeInTheDocument()
expect(screen.getByText('Ohjelma')).toBeInTheDocument()
expect(screen.getByText('Tekijä')).toBeInTheDocument()
expect(screen.getByText('Vaihe')).toBeInTheDocument()
expect(screen.getByText('Lataa tutkimussuunnitelma')).toBeInTheDocument()
expect(screen.getByText('Lataa työskentelysopimus')).toBeInTheDocument()
expect(screen.getByText('Lisää ohjaaja')).toBeInTheDocument()

expect(screen.getByRole('button', { name: 'Tallenna' })).toBeEnabled()
})
})
})
Loading

0 comments on commit 147c7e7

Please sign in to comment.