Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests for dashboard page #272

Merged
merged 7 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions webapp/src/pages/Dashboard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ export default function Dashboard() {

useEffect(() => {
async function checkActiveStatus() {
const active = await isActive();
setActive(active);
const i = await isActive();
setActive(i.data.is_active);
}
checkActiveStatus();
}, []);
Expand Down Expand Up @@ -114,7 +114,7 @@ export default function Dashboard() {
<LateralMenu isOpen={isMenuOpen} onClose={() => setIsMenuOpen(false)} changeLanguage={changeLanguage} isDashboard={true}/>
{user && (
<>
<Avatar style={{ width: '8rem', height: '8rem' }} {...config} />
<Avatar style={{ width: '8rem', height: '8rem' }} {...config} data-testid={"avatar"}/>
<Heading as="h2" data-testid={"Welcome"}>{t("common.welcome") + " " + user.username}</Heading>

<Box minW={{ md: "400px" }} shadow="2xl">
Expand All @@ -126,9 +126,9 @@ export default function Dashboard() {
</TabList>
<TabPanels>
<TabPanel>
{active && (
{!active && (
<Flex justify="center" flexWrap="wrap" flexDirection={{ base: "column", md: "row" }}>
{modes.map(mode => (
{modes.length > 0 && modes.map(mode => (
<Button
key={mode.internal_representation}
colorScheme={"green"}
Expand Down Expand Up @@ -157,17 +157,17 @@ export default function Dashboard() {
</TabPanel>
<TabPanel>
<Stack spacing={2}>
<Heading as="h3" color="green.400" fontSize="xl">Username</Heading>
<Heading as="h3" color="green.400" fontSize="xl">{t("session.username")}</Heading>
<Text fontWeight='extrabold' color={"forest_green.400"}>{user.username}</Text>
<Heading as="h3" color="green.400" fontSize="xl">Email</Heading>
<Heading as="h3" color="green.400" fontSize="xl">{t("session.email")}</Heading>
<Text fontWeight='extrabold' color={"forest_green.400"}>{user.email}</Text>
<UserStatistics />
</Stack>
</TabPanel>
</TabPanels>
</Tabs>
<Flex justify="center">
{active && (
{!active ? (
<Button
type="submit"
data-testid={"Play"}
Expand All @@ -179,11 +179,11 @@ export default function Dashboard() {
size={"lg"}
fontSize={"2xl"}
flex="1"
id={"play"}
>
{t("common.play")}
</Button>
)}
{!active && (
) : (
<Button
type="submit"
data-testid={"Resume"}
Expand All @@ -193,6 +193,7 @@ export default function Dashboard() {
className={"custom-button effect2"}
onClick={initializeGameMode}
size={"lg"}
id={"resumeBtn"}
fontSize={"2xl"}
flex="1"
>
Expand Down
2 changes: 1 addition & 1 deletion webapp/src/pages/Results.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default function Results() {
<Center display="flex" flexDirection="column" w="100wh" h="100vh" justifyContent="center" alignItems="center" bgImage={'/background.svg'}>
<Heading as="h2">{t("common.results")}</Heading>
<Box bg="white" p={4} borderRadius="md" boxShadow="md" mt={4} mb={4} w="fit-content" shadow="2xl" rounded="1rem">
<Heading as="h3" color="green.400" fontSize="xl">{`Correct answers: ${correctAnswers}`}</Heading>
<Heading textAlign={"center"} as="h3" color="green.400" fontSize="xl">{`Correct answers: ${correctAnswers}`}</Heading>
<Flex direction="row" justifyContent="center" alignItems="center">
<Button data-testid={"GoBack"} type="submit" variant="solid" colorScheme="pigment_green" margin={"10px"} className={"custom-button effect1"} onClick={() => navigate("/dashboard")} w="100%">
{t("common.finish")}
Expand Down
253 changes: 241 additions & 12 deletions webapp/src/tests/Dashboard.test.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,266 @@
import React from 'react';
import { render, fireEvent, screen, act, waitFor } from '@testing-library/react';
import { MemoryRouter } from 'react-router';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import Dashboard from '../pages/Dashboard';
import AuthManager from 'components/auth/AuthManager';
import MockAdapter from 'axios-mock-adapter';
import { HttpStatusCode } from 'axios';
import { MemoryRouter } from 'react-router-dom';
import { ChakraProvider } from '@chakra-ui/react';
import theme from '../styles/theme';
import MockAdapter from 'axios-mock-adapter';
import AuthManager from 'components/auth/AuthManager';
import { HttpStatusCode } from 'axios';
import { __esModule } from '@testing-library/jest-dom/dist/matchers';

const api = process.env.REACT_APP_API_ENDPOINT;

jest.mock('react-i18next', () => ({
useTranslation: () => {
return {
t: (str) => str,
i18n: {
changeLanguage: () => new Promise(() => {}),
changeLanguage: () => new Promise(() => { }),
language: "en"
},
}
},
}));

const authManager = new AuthManager();
let mockAxios;
describe('Dashboard', () => {

describe('Dashboard component', () => {
const authManager = new AuthManager();
let mockAxios;

beforeEach(() => {
authManager.reset();
mockAxios = new MockAdapter(authManager.getAxiosInstance());
})
});

afterEach(() => {
jest.clearAllMocks();
});

test('renders Dashboard component with user data and game modes', async () => {
mockAxios.onGet(`${api}/games/is-active`).reply(HttpStatusCode.Ok, {
"is_active": true
});

mockAxios.onGet(`${api}/games/gamemodes`).reply(HttpStatusCode.Ok, {
name: "KiWiQ",
description: "Test description of the game mode",
internal_representation: "KIWIQ_QUEST",
icon_name: "FaKiwiBird"
});

mockAxios.onGet(`${api}/users/details`).reply(HttpStatusCode.Ok, {
id: 1,
username: 'testUser',
email: '[email protected]'
});

mockAxios.onGet(`${api}/games/question-categories`).reply(HttpStatusCode.Ok, [
{
"name": "Sports",
"description": "Test description of the question category",
"internal_representation": "SPORTS"
}
])

render(
<ChakraProvider theme={theme}>
<MemoryRouter>
<Dashboard />
</MemoryRouter>
</ChakraProvider>
);

await waitFor(() => {
expect(screen.getByTestId('Welcome')).toHaveTextContent('common.welcome testUser');
expect(mockAxios.history.get.length).toBeGreaterThan(4);
});
});

test('renders Play button when game is active', async () => {

mockAxios.onGet(`${api}/games/is-active`).reply(HttpStatusCode.Ok, {
"is_active": false
});

mockAxios.onGet(`${api}/games/gamemodes`).reply(HttpStatusCode.Ok, {
name: "KiWiQ",
description: "Test description of the game mode",
internal_representation: "KIWIQ_QUEST",
icon_name: "FaKiwiBird"
});

mockAxios.onGet(`${api}/users/details`).reply(HttpStatusCode.Ok, {
id: 1,
username: 'testUser',
email: '[email protected]'
});

mockAxios.onGet(`${api}/games/question-categories`).reply(HttpStatusCode.Ok, [
{
"name": "Sports",
"description": "Test description of the question category",
"internal_representation": "SPORTS"
}
])

const {container} = render(
<ChakraProvider theme={theme}>
<MemoryRouter>
<Dashboard />
</MemoryRouter>
</ChakraProvider>
);

it('renders dashboard elements correctly', async () => {
await waitFor(() => {
expect(container.querySelector('#play')).toBeInTheDocument();
});
});

it('navigates to the game route on "Play" button click', async () => {
test('renders Resume button when game is not active', async () => {
mockAxios.onGet(`${api}/games/is-active`).reply(HttpStatusCode.Ok, {
"is_active": true
});

mockAxios.onGet(`${api}/games/gamemodes`).reply(HttpStatusCode.Ok, {
name: "KiWiQ",
description: "Test description of the game mode",
internal_representation: "KIWIQ_QUEST",
icon_name: "FaKiwiBird"
});

mockAxios.onGet(`${api}/users/details`).reply(HttpStatusCode.Ok, {
id: 1,
username: 'testUser',
email: '[email protected]'
});

mockAxios.onGet(`${api}/games/question-categories`).reply(HttpStatusCode.Ok, [
{
"name": "Sports",
"description": "Test description of the question category",
"internal_representation": "SPORTS"
}
])

const {container} = render(
<ChakraProvider theme={theme}>
<MemoryRouter>
<Dashboard />
</MemoryRouter>
</ChakraProvider>
);

await waitFor(() => {
expect(container.querySelector('#resumeBtn')).toBeInTheDocument();
});
});

test('clicking Play button initializes a new game', async () => {
mockAxios.onGet(`${api}/games/is-active`).reply(HttpStatusCode.Ok, {
"is_active": false
});

mockAxios.onGet(`${api}/games/gamemodes`).reply(HttpStatusCode.Ok, {
name: "KiWiQ",
description: "Test description of the game mode",
internal_representation: "KIWIQ_QUEST",
icon_name: "FaKiwiBird"
});

mockAxios.onGet(`${api}/users/details`).reply(HttpStatusCode.Ok, {
id: 1,
username: 'testUser',
email: '[email protected]'
});

mockAxios.onGet(`${api}/games/question-categories`).reply(HttpStatusCode.Ok, [
{
"name": "Sports",
"description": "Test description of the question category",
"internal_representation": "SPORTS"
}
])

const {container} = render(
<ChakraProvider theme={theme}>
<MemoryRouter>
<Dashboard />
</MemoryRouter>
</ChakraProvider>
);

await waitFor(() => {
fireEvent.click(container.querySelector("#play"));

expect(mockAxios.history.post.length).toBeGreaterThan(0);
});
});

test('fetches user data and game modes on component mount', async () => {
mockAxios.onGet(`${api}/games/is-active`).reply(HttpStatusCode.Ok, {
"is_active": true
});

mockAxios.onGet(`${api}/games/gamemodes`).reply(HttpStatusCode.Ok, [
{
name: "KiWiQ",
description: "Test description of the game mode",
internal_representation: "KIWIQ_QUEST",
icon_name: "FaKiwiBird"
}
]);

mockAxios.onGet(`${api}/users/details`).reply(HttpStatusCode.Ok, {
id: 1,
username: 'testUser',
email: '[email protected]'
});

const {container} = render(
<ChakraProvider theme={theme}>
<MemoryRouter>
<Dashboard />
</MemoryRouter>
</ChakraProvider>
);

await waitFor(() => {
expect(mockAxios.history.get.length).toBe(3);
});
});

test('initializes a new game when Play button is clicked', async () => {
mockAxios.onGet(`${api}/games/is-active`).reply(HttpStatusCode.Ok, {
"is_active": false
});

mockAxios.onGet(`${api}/games/gamemodes`).reply(HttpStatusCode.Ok, [
{
name: "KiWiQ",
description: "Test description of the game mode",
internal_representation: "KIWIQ_QUEST",
icon_name: "FaKiwiBird"
}
]);

mockAxios.onGet(`${api}/users/details`).reply(HttpStatusCode.Ok, {
id: 1,
username: 'testUser',
email: '[email protected]'
});

const {container} = render(
<ChakraProvider theme={theme}>
<MemoryRouter>
<Dashboard />
</MemoryRouter>
</ChakraProvider>
);

await waitFor(() => {
fireEvent.click(container.querySelector("#play"));
expect(mockAxios.history.post.length).toBeGreaterThan(0);
});
});
});