Skip to content

Commit

Permalink
Merge pull request #7 from lizzypy/participant-list-and-tests-for-hooks
Browse files Browse the repository at this point in the history
Add participants list view and tests for hooks
  • Loading branch information
lizzypy authored Sep 15, 2023
2 parents 8a4fdd8 + 6dbd13e commit d3105d5
Show file tree
Hide file tree
Showing 15 changed files with 20,977 additions and 9,889 deletions.
9 changes: 9 additions & 0 deletions frontend/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const nextJest = require("next/jest");
const createJestConfig = nextJest({
dir: "./",
});
const customJestConfig = {
moduleDirectories: ["node_modules", "<rootDir>/"],
testEnvironment: "jest-environment-jsdom",
};
module.exports = createJestConfig(customJestConfig);
28,768 changes: 19,052 additions & 9,716 deletions frontend/package-lock.json

Large diffs are not rendered by default.

15 changes: 5 additions & 10 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@
"@mui/material": "^5.9.2",
"@mui/styles": "^5.9.3",
"@mui/x-data-grid": "^6.0.0",
"@testing-library/jest-dom": "^5.16.4",
"@testing-library/react": "^13.3.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.0.1",
"@types/js-cookie": "^3.0.2",
Expand All @@ -22,6 +20,7 @@
"@typescript-eslint/parser": "^5.23.0",
"axios": "^0.27.2",
"check-prop-types": "^1.1.2",
"jest-environment-jsdom": "^29.7.0",
"next": "^13.4.19",
"react": "^18.2.0",
"react-data-table-component": "^7.5.2",
Expand All @@ -35,18 +34,11 @@
},
"scripts": {
"dev": "next dev",
"test": "jest --watch",
"proxy": "node proxy",
"build": "next build",
"start": "next start"
},
"jest": {
"collectCoverageFrom": [
"**/*.{js,jsx}",
"!**/node_modules/**",
"!**/coverage/**",
"!**/index.js"
]
},
"eslintConfig": {
"extends": [
"react-app",
Expand All @@ -66,6 +58,9 @@
]
},
"devDependencies": {
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^14.0.0",
"jest": "^29.7.0",
"jest-canvas-mock": "^2.4.0",
"jest-enzyme": "^7.1.2",
"jest-watch-typeahead": "^0.6.5",
Expand Down
1 change: 1 addition & 0 deletions frontend/pages/participants/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Participants as default } from "../../src/pages/Participants"
Binary file added frontend/pages/users/.index.tsx.swp
Binary file not shown.
1 change: 1 addition & 0 deletions frontend/pages/users/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Users as default } from "../../src/pages/Users"
57 changes: 57 additions & 0 deletions frontend/src/components/ParticipantsList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { DataGrid } from '@mui/x-data-grid';
import Box from '@mui/material/Box';
import {AppBar, Toolbar } from "@mui/material";
import useParticipants from "../hooks/useParticipants";
import type {NextPage} from 'next';
import SignUpForm from "../components/signUpForm";
import {Typography} from "@material-ui/core";

const ParticipantsList = () => {
const { participants, isLoading } = useParticipants();

const columns = [
{
field: 'id',
headerName: 'ID',
width: 90
},
{
field: 'first_name',
headerName: 'First Name',
width: 300,
editable: true,
},
{
field: 'last_name',
headerName: 'Last Name',
width: 300,
editable: true,
},
]

return (
<div>
<Box sx={{textAlign:'left', height: 400, width: '100%'}}>
<Typography variant={'h6'}> Participants </Typography>
<div style={{ height: 250, width: '100%' }}>
<DataGrid
rows={participants}
columns={columns}
initialState={{
pagination: {
paginationModel: {
pageSize: 5,
},
},
}}
pageSizeOptions={[5]}
checkboxSelection
disableRowSelectionOnClick
/>
</div>
</Box>
</div>
);
}

export default ParticipantsList;
69 changes: 69 additions & 0 deletions frontend/src/hooks/useParticipants.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import {waitFor, render, screen, act} from "@testing-library/react";
import {AxiosInstance} from "axios";
import useParticipants from "./useParticipants";
import React from "react";
import {useHttpClient} from "./useHttpClient";

jest.mock("./useHttpClient")

const mockedUseHttpClient = jest.mocked(useHttpClient, true)
const TestParticipantsComponent = () => {
const {participants, isLoading} = useParticipants()
return (
<>{
isLoading ?
<></> :
<div>
{
participants.map((p) => {
return (
<>
<li>First Name: {p.first_name}</li>
<li>Last Name: {p.last_name}</li>
<li>ID: {p.id}</li>
</>
)
})
}
</div>
}
</>
)
}

describe('useParticipants', () => {
const mockHttpClient = {
get: jest.fn(),
post: jest.fn()
}
beforeEach(async () => {
const expectedParticipantsResponse = {
data: [
{
"id":1,
"first_name":"clayton",
"last_name":"johnson",
"birthdate":"2016-04-16",
}
]
}
mockedUseHttpClient.mockReturnValue(((mockHttpClient as unknown) as AxiosInstance))
mockHttpClient.get.mockReturnValue(Promise.resolve(expectedParticipantsResponse))
mockHttpClient.post.mockReturnValue(expectedParticipantsResponse)
});

it('should return renderable participant data', async () => {
act(() => {
render (
<TestParticipantsComponent/>
)
})

expect(mockHttpClient.get.mock.calls[0][0]).toEqual(`/participants`)
await waitFor(() => {
expect(mockHttpClient.get).toHaveBeenCalledWith('/participants')
expect(screen.getByText(/clayton/)).not.toBeNull()
expect(screen.getByText(/1/)).not.toBeNull()
})
});
});
32 changes: 15 additions & 17 deletions frontend/src/hooks/useParticipants.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios from "axios";
import {useHttpClient} from "./useHttpClient";
import {useEffect, useState} from "react";

interface Participant {
Expand All @@ -8,26 +8,24 @@ interface Participant {
birthdate?: string;
}

function useParticipants(): Participant[] {
function useParticipants(): { participants: Participant[], isLoading: boolean } {
const [apiData, setApiData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const httpClient = useHttpClient();

useEffect(() => {
axios({
method: 'GET',
url: `/participants`,
headers: {
'Content-Type': 'application/json',
},
})
.then(response => {
console.log("This is the response: ", response)
setApiData(response.data)
})
.catch(error => {
console.log(error)
})
setIsLoading(true)
httpClient.get('/participants').then(response => {
setApiData(response.data)
setIsLoading(false)
return { participants: apiData, isLoading: isLoading }
})
.catch(error => {
console.log(error)
})
}, []);

return apiData ?? []
return { participants: apiData, isLoading: isLoading }
}

export default useParticipants;
9 changes: 6 additions & 3 deletions frontend/src/hooks/useUsers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@ interface User {
updated_at: string
}

function useUsers(): User[] {
function useUsers(): { users: User[], isLoading: boolean } {
const [apiData, setApiData] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const httpClient = useHttpClient();

useEffect(() => {
console.log(`httpClient BASE URL: ${httpClient.getUri()}`);
setIsLoading(true)
httpClient.get('/users').then(response => {
setApiData(response.data)
setIsLoading(false)
return { users: apiData, isLoading: isLoading }
})
.catch(error => {
console.log(error)
})
}, []);

return apiData ?? []
return { users: apiData, isLoading: isLoading }
}

export default useUsers;
28 changes: 28 additions & 0 deletions frontend/src/pages/Participants.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import ParticipantsList from "../components/ParticipantsList";
import {AppBar, Toolbar } from "@mui/material";
import SignUpForm from "../components/signUpForm";
import type {NextPage} from 'next';

export const Participants: NextPage = () => {
return (
<>
<AppBar position="static" sx={{ bgcolor: "pink" }}>
<section aria-label={"toolbar-section"}
style={{display: "flex", flexDirection: "row", justifyContent: "right"}}>
<Toolbar>
<SignUpForm/>
</Toolbar>
</section>
</AppBar>
<section aria-label={"participants-section"}
style={{
padding: "40px 30px",
display: "flex",
flexDirection: "column",
justifyContent: "space-around"
}}>
<ParticipantsList/>
</section>
</>
)
}
67 changes: 67 additions & 0 deletions frontend/src/pages/Users.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { DataGrid } from '@mui/x-data-grid';
import Box from '@mui/material/Box';
import {AppBar, Toolbar } from "@mui/material";
import useUsers from "../hooks/useUsers";
import type {NextPage} from 'next';
import SignUpForm from "../components/signUpForm";
import {Typography} from "@material-ui/core";

export const Users: NextPage = () => {
const { users, isLoading } = useUsers();

const columns = [
{ field: 'id', headerName: 'ID', width: 90 },
{
field: 'email',
headerName: 'Email',
width: 300,
editable: true,
},
{
field: 'updated_at',
headerName: 'Last Updated',
width: 300,
editable: true,
},
]

return (
<div>
<AppBar position="static" sx={{ bgcolor: "pink" }}>
<section aria-label={"toolbar-section"}
style={{display: "flex", flexDirection: "row", justifyContent: "right"}}>
<Toolbar>
<SignUpForm/>
</Toolbar>
</section>
</AppBar>
<section aria-label={"participants-section"}
style={{
padding: "40px 30px",
display: "flex",
flexDirection: "column",
justifyContent: "space-around"
}}>
<Box sx={{textAlign:'left', height: 400, width: '100%'}}>
<Typography variant={'h6'}> Users </Typography>
<div style={{ height: 250, width: '100%' }}>
<DataGrid
rows={users}
columns={columns}
initialState={{
pagination: {
paginationModel: {
pageSize: 5,
},
},
}}
pageSizeOptions={[5]}
checkboxSelection
disableRowSelectionOnClick
/>
</div>
</Box>
</section>
</div>
);
}
Loading

0 comments on commit d3105d5

Please sign in to comment.