From b4d6f296ba6ae9f89a0f83c6330b4ed809b63720 Mon Sep 17 00:00:00 2001
From: Mai Vang <100221733+vmaineng@users.noreply.github.com>
Date: Fri, 11 Oct 2024 15:12:59 -0700
Subject: [PATCH 1/3] updated unit tests from #477 PR (#538)
# What does this PR do?
- [X] Updated tests from PR #477
# Related Issues/PRs
This is the PR that was submitted where tests were omitted to meet Alpha
deadline.
[-
https://github.com/LetsGetTechnical/gridiron-survivor/issues/513](https://github.com/LetsGetTechnical/gridiron-survivor/pull/491)
---
app/(main)/league/all/page.test.tsx | 277 +++++++++++++++++++++-------
app/(main)/league/all/page.tsx | 13 +-
store/dataStore.test.ts | 37 ++--
3 files changed, 246 insertions(+), 81 deletions(-)
diff --git a/app/(main)/league/all/page.test.tsx b/app/(main)/league/all/page.test.tsx
index c38f4503..b1a783c8 100644
--- a/app/(main)/league/all/page.test.tsx
+++ b/app/(main)/league/all/page.test.tsx
@@ -1,107 +1,183 @@
-import { render, screen, waitFor, fireEvent } from '@testing-library/react';
+import {
+ render,
+ screen,
+ waitFor,
+ waitForElementToBeRemoved,
+ fireEvent,
+} from '@testing-library/react';
import Leagues from './page';
import { useDataStore } from '@/store/dataStore';
import { getUserLeagues } from '@/utils/utils';
-import {
- getGameWeek,
- getAllLeagues,
- getUserDocumentId,
-} from '@/api/apiFunctions';
-import { AuthContext } from '@/context/AuthContextProvider';
+import { getAllLeagues, addUserToLeague } from '@/api/apiFunctions';
+import { toast } from 'react-hot-toast';
+import Alert from '@/components/AlertNotification/AlertNotification';
+import { AlertVariants } from '@/components/AlertNotification/Alerts.enum';
-jest.mock('@/store/dataStore', () => ({
- useDataStore: jest.fn(() => ({ user: { id: '123', leagues: [] } })),
-}));
+const mockUseAuthContext = {
+ isSignedIn: false,
+};
-jest.mock('@/utils/utils', () => ({
- getUserLeagues: jest.fn(() => Promise.resolve([])),
+jest.mock('@/context/AuthContextProvider', () => ({
+ useAuthContext() {
+ return {
+ ...mockUseAuthContext,
+ };
+ },
}));
-jest.mock('@/api/apiFunctions', () => ({
- getGameWeek: jest.fn(() =>
- Promise.resolve({
- week: 1,
- }),
- ),
- getAllLeagues: jest.fn(() =>
- Promise.resolve([
+jest.mock('@/store/dataStore', () => ({
+ useDataStore: jest.fn(() => ({
+ user: {
+ documentId: '123',
+ id: '1234',
+ email: 'test@test.com',
+ leagues: ['league1'],
+ },
+ allLeagues: [
{
leagueId: '123',
leagueName: 'Test League',
- logo: 'https://example.com/logo.png',
- participants: ['123456', '78', '9'],
+ logo: 'logo.png',
+ participants: ['123456', '78'],
survivors: ['123456', '78'],
},
- ]),
- ),
+ ],
+ updateUser: jest.fn(),
+ })),
}));
-jest.mock('@/context/AuthContextProvider', () => ({
- useAuthContext: jest.fn(() => ({ user: { id: '123' } })),
+jest.mock('@/utils/utils', () => ({
+ getUserLeagues: jest.fn(() => Promise.resolve([])),
+ cn: jest.fn(),
+}));
+
+jest.mock('@/api/apiFunctions', () => ({
+ getAllLeagues: jest.fn(),
+ addUserToLeague: jest.fn(),
+}));
+
+jest.mock('react-hot-toast', () => ({
+ toast: {
+ custom: jest.fn(),
+ },
}));
describe('Leagues Component', () => {
const mockUseDataStore = useDataStore as unknown as jest.Mock;
const mockGetUserLeagues = getUserLeagues as jest.Mock;
- const mockGetGameWeek = getGameWeek as jest.Mock;
const mockGetAllLeagues = getAllLeagues as jest.Mock;
+ const mockAddUserToLeague = addUserToLeague as jest.Mock;
beforeEach(() => {
jest.clearAllMocks();
});
- xtest('should render "You are not enrolled in any leagues" message when no leagues are found', async () => {
- mockUseDataStore.mockReturnValueOnce({ user: { id: '123', leagues: [] } });
- mockGetUserLeagues.mockResolvedValueOnce([]);
- mockGetGameWeek.mockResolvedValueOnce({ week: 1 });
+ it('should render "You are not enrolled in any leagues" message when no leagues are found', async () => {
+ mockUseAuthContext.isSignedIn = true;
+ mockUseDataStore.mockReturnValue({
+ user: {
+ documentId: '123',
+ email: 'test@test.com',
+ id: '123',
+ leagues: [],
+ },
+ allLeagues: [],
+ });
+
render();
+ await waitForElementToBeRemoved(() => screen.getByTestId('global-spinner'));
+
await waitFor(() => {
- expect(
- screen.getByText('You are not enrolled in any leagues'),
- ).toBeInTheDocument();
+ const messageElement = screen.getByTestId('no-leagues-message');
+ expect(messageElement).toBeInTheDocument();
});
});
- xtest('should display GlobalSpinner while loading data', async () => {
- mockUseDataStore.mockReturnValueOnce({ user: { id: '123', leagues: [] } });
- mockGetUserLeagues.mockResolvedValueOnce([]);
- mockGetGameWeek.mockResolvedValueOnce({ week: 1 });
- render();
+ it('should display GlobalSpinner while loading data', async () => {
+ mockUseAuthContext.isSignedIn = true;
- await waitFor(() => {
- expect(screen.getByTestId('global-spinner')).toBeInTheDocument();
+ mockUseDataStore.mockReturnValueOnce({
+ user: {
+ documentId: '123',
+ email: 'test@test.com',
+ id: '123',
+ leagues: [],
+ },
+ allLeagues: [],
});
- });
- xtest('should not display GlobalSpinner after loading data', async () => {
- mockUseDataStore.mockReturnValueOnce({ user: { id: '123', leagues: [] } });
- mockGetUserLeagues.mockResolvedValueOnce([]);
- mockGetGameWeek.mockResolvedValueOnce({ week: 1 });
render();
expect(screen.getByTestId('global-spinner')).toBeInTheDocument();
-
- await waitFor(() => {
- expect(screen.queryByTestId('global-spinner')).not.toBeInTheDocument();
- });
});
- xtest('should handle form submission to join a league', async () => {
- mockUseDataStore.mockReturnValueOnce({
- user: { id: '123', leagues: [] },
+ it('should not display GlobalSpinner after loading data', async () => {
+ mockUseAuthContext.isSignedIn = true;
+
+ mockUseDataStore.mockReturnValue({
+ user: {
+ documentId: '123',
+ email: 'test@test.com',
+ id: '123',
+ leagues: [],
+ },
allLeagues: [
{
leagueId: '123',
leagueName: 'Test League',
- logo: 'https://findmylogo.com/logo.png',
+ logo: 'logo.png',
participants: ['123456', '78'],
- survivors: ['123456', '78', '9'],
+ survivors: ['123456', '78'],
},
],
});
+
mockGetUserLeagues.mockResolvedValueOnce([]);
- mockGetGameWeek.mockResolvedValueOnce({ week: 1 });
+
+ render();
+
+ await waitForElementToBeRemoved(() => screen.getByTestId('global-spinner'));
+
+ expect(screen.queryByTestId('global-spinner')).not.toBeInTheDocument();
+ });
+
+ it('should handle form submission to join a league', async () => {
+ mockUseAuthContext.isSignedIn = true;
+
+ const user = {
+ documentId: '123',
+ email: 'test@test.com',
+ id: '123',
+ leagues: [],
+ };
+
+ const league = {
+ leagueId: '123',
+ leagueName: 'Test League',
+ logo: 'logo.png',
+ participants: [],
+ survivors: [],
+ };
+
+ const updateUser = jest.fn();
+
+ mockUseDataStore.mockReturnValue({
+ user,
+ allLeagues: [league],
+ updateUser,
+ });
+
+ mockGetAllLeagues.mockResolvedValueOnce([league]);
+ mockAddUserToLeague.mockResolvedValue(
+ Promise.resolve({
+ userDocumentId: user.documentId,
+ selectedLeague: league.leagueId,
+ selectedLeagues: [league.leagueId],
+ participants: [user.id],
+ survivors: [user.id],
+ }),
+ );
render();
@@ -109,16 +185,93 @@ describe('Leagues Component', () => {
expect(screen.queryByTestId('global-spinner')).not.toBeInTheDocument();
});
- const selectElement = screen.getByLabelText(/Select league to join/i);
- expect(selectElement).toBeInTheDocument();
+ const selectElement = screen.getByTestId('select-available-leagues');
+ fireEvent.change(selectElement, { target: { value: '123' } });
+ fireEvent.click(screen.getByTestId('join-league-button'));
+
+ await waitFor(() => {
+ expect(mockAddUserToLeague).toHaveBeenCalledWith({
+ userDocumentId: user.documentId,
+ selectedLeague: league.leagueId,
+ selectedLeagues: [league.leagueId],
+ participants: [user.id],
+ survivors: [user.id],
+ });
+ expect(updateUser).toHaveBeenCalledWith(
+ user.documentId,
+ user.id,
+ user.email,
+ [...user.leagues, league.leagueId],
+ );
+ expect(toast.custom).toHaveBeenCalledWith(
+ ,
+ );
+ });
+ });
+
+ it('should show error if adding to league fails', async () => {
+ mockUseAuthContext.isSignedIn = true;
+
+ const user = {
+ documentId: '123',
+ email: 'test@test.com',
+ id: '123',
+ leagues: [],
+ };
+ const league = {
+ leagueId: '123',
+ leagueName: 'Test League',
+ logo: 'logo.png',
+ participants: [],
+ survivors: [],
+ };
+
+ mockUseDataStore.mockReturnValue({
+ user,
+ allLeagues: [league],
+ });
+
+ mockGetUserLeagues.mockResolvedValueOnce([]);
+ mockGetAllLeagues.mockResolvedValueOnce([league]);
+ mockAddUserToLeague.mockResolvedValue(
+ Promise.resolve({
+ userDocumentId: user.documentId,
+ selectedLeague: league.leagueId,
+ selectedLeagues: [league.leagueId],
+ participants: [user.id],
+ survivors: [user.id],
+ }),
+ );
+
+ render();
+
+ await waitFor(() => {
+ expect(screen.queryByTestId('global-spinner')).not.toBeInTheDocument();
+ });
+
+ const selectElement = screen.getByTestId('select-available-leagues');
fireEvent.change(selectElement, { target: { value: '123' } });
- fireEvent.click(screen.getByText(/Join League/i));
+ fireEvent.click(screen.getByTestId('join-league-button'));
await waitFor(() => {
- expect(
- screen.getByText('Added Test League to your leagues!'),
- ).toBeInTheDocument();
+ expect(mockAddUserToLeague).toHaveBeenCalledWith({
+ userDocumentId: user.documentId,
+ selectedLeague: league.leagueId,
+ selectedLeagues: [league.leagueId],
+ participants: [user.id],
+ survivors: [user.id],
+ });
+
+ expect(toast.custom).toHaveBeenCalledWith(
+ ,
+ );
});
});
});
diff --git a/app/(main)/league/all/page.tsx b/app/(main)/league/all/page.tsx
index 3e9e78dd..56c04323 100644
--- a/app/(main)/league/all/page.tsx
+++ b/app/(main)/league/all/page.tsx
@@ -124,13 +124,12 @@ const Leagues = (): JSX.Element => {
return (
{loadingData ? (
-
+
) : (
<>
Your Leagues
-
{leagues.length > 0 ? (
leagues.map((league) => (
@@ -145,7 +144,10 @@ const Leagues = (): JSX.Element => {
))
) : (
-
+
You are not enrolled in any leagues
@@ -169,6 +171,7 @@ const Leagues = (): JSX.Element => {
render={({ field, fieldState }) => (
<>
-
+
>
)}
diff --git a/store/dataStore.test.ts b/store/dataStore.test.ts
index 515ffa4a..ab4f9acf 100644
--- a/store/dataStore.test.ts
+++ b/store/dataStore.test.ts
@@ -3,8 +3,9 @@ import { useDataStore } from './dataStore';
// test values
const userData = {
- userId: '123',
- userEmail: 'test@email.com',
+ documentId: '123',
+ id: '123',
+ email: 'test@email.com',
leagues: ['123456'],
};
@@ -44,7 +45,7 @@ const allLeagues = [
];
describe('Data Store', () => {
- xdescribe('User Test', () => {
+ describe('User Test', () => {
it('Check the default user state', () => {
const { result } = renderHook(() => useDataStore());
expect(result.current.user.id).toBe('');
@@ -56,6 +57,7 @@ describe('Data Store', () => {
act(() => {
result.current.updateUser(
+ userData.documentId,
userData.userId,
userData.userEmail,
userData.leagues,
@@ -70,6 +72,7 @@ describe('Data Store', () => {
act(() => {
result.current.updateUser(
+ userData.documentId,
userData.userId,
userData.userEmail,
userData.leagues,
@@ -112,18 +115,22 @@ describe('Data Store', () => {
leagueId: '123',
gameWeekId: '456',
userResults: {
- '66281d5ec5614f76bc91': {
- team: '66218f22b40deef340f8',
- correct: false,
- },
- '6628077faeeedd272637': {
- team: '6621b30ea57bd075e9d3',
- correct: false,
- },
- '66174f2362ec891167be': {
- team: '6621b30ea57bd075e9d3',
- correct: true,
- },
+ '123': {
+ '456': {
+ 'entry1': {
+ teamName: 'New England Patriots',
+ correct:true
+ },
+ 'entry2': {
+ teamName: 'Kansas City Chiefs',
+ correct:false
+ },
+ 'entry3': {
+ teamName: 'New England Patriots',
+ correct:false
+ }
+ }
+ }
},
};
act(() => {
From 062603a26d0430ffad01491dfa95c665172cfe32 Mon Sep 17 00:00:00 2001
From: Eduardo Vazquez <80133388+vazquezea96@users.noreply.github.com>
Date: Mon, 14 Oct 2024 09:37:39 -0700
Subject: [PATCH 2/3] Eddie/450-add-users-leagues-to-side-menu (#460)
Adding the user's leagues to the side menu.
Actions done:
- [x] Updated Api call so it only gets called once.
---------
Co-authored-by: Shashi Lo <362527+shashilo@users.noreply.github.com>
---
components/Nav/Nav.test.tsx | 39 +++++++++++++++++++++++++++++++++++++
components/Nav/Nav.tsx | 15 +++++++++++++-
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/components/Nav/Nav.test.tsx b/components/Nav/Nav.test.tsx
index 47abd352..b23ea7d9 100644
--- a/components/Nav/Nav.test.tsx
+++ b/components/Nav/Nav.test.tsx
@@ -1,6 +1,8 @@
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import Nav from './Nav';
import Login from '@/app/(main)/login/page';
+import { useDataStore } from '@/store/dataStore';
+import { getUserLeagues } from '@/utils/utils';
const mockPush = jest.fn();
const mockUsePathname = jest.fn();
@@ -32,6 +34,10 @@ jest.mock('../../context/AuthContextProvider', () => ({
},
}));
+jest.mock('@/store/dataStore', () => ({
+ useDataStore: jest.fn(() => ({ user: { id: '123', leagues: [] } })),
+}));
+
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation((query) => ({
@@ -47,10 +53,25 @@ Object.defineProperty(window, 'matchMedia', {
});
describe('Nav', () => {
+ const mockUseDataStore = useDataStore as unknown as jest.Mock;
+ const mockGetUserLeagues = getUserLeagues as jest.Mock;
+
beforeEach(() => {
jest.clearAllMocks();
});
+ it('renders link to /league/all', async () => {
+ render();
+
+ const drawTrigger = screen.getByTestId('drawer-trigger');
+ fireEvent.click(drawTrigger);
+
+ let linkNav: HTMLElement;
+ linkNav = await screen.getByTestId('league-link');
+ expect(linkNav).toBeInTheDocument();
+ expect(linkNav).toHaveAttribute('href', '/league/all');
+ });
+
it('it should render the default component state', () => {
mockUsePathname.mockImplementation(() => '/weeklyPicks');
@@ -163,4 +184,22 @@ describe('Nav', () => {
expect(drawerTrigger.getAttribute('data-state')).toBe('closed');
});
});
+
+ it('it should close the drawer when the leagues link is clicked', async () => {
+ mockUsePathname.mockImplementation(() => '/league/all');
+
+ render();
+
+ const drawerTrigger = screen.getByTestId('drawer-trigger');
+
+ fireEvent.click(drawerTrigger);
+
+ const linkNav = screen.getByTestId('league-link');
+
+ fireEvent.click(linkNav);
+
+ await waitFor(() => {
+ expect(drawerTrigger.getAttribute('data-state')).toBe('closed');
+ });
+ });
});
diff --git a/components/Nav/Nav.tsx b/components/Nav/Nav.tsx
index 47ed1bd0..9eba9c7e 100644
--- a/components/Nav/Nav.tsx
+++ b/components/Nav/Nav.tsx
@@ -6,6 +6,7 @@ import React, { JSX } from 'react';
import LogoNav from '../LogoNav/LogoNav';
import { Menu } from 'lucide-react';
import { Button } from '../Button/Button';
+import Link from 'next/link';
import {
Drawer,
DrawerContent,
@@ -68,9 +69,21 @@ export const Nav = (): JSX.Element => {
Gridiron Survivor
+ -
+ setOpen(false)}
+ >
+ Leagues
+
+
-