diff --git a/api/serverConfig.ts b/api/serverConfig.ts index 4e90354e..8f5c173d 100644 --- a/api/serverConfig.ts +++ b/api/serverConfig.ts @@ -13,3 +13,4 @@ const client = new sdk.Client() .setKey(API_KEY); export const users = new sdk.Users(client); +export const messaging = new sdk.Messaging(client); diff --git a/app/(admin)/admin/notifications/page.test.tsx b/app/(admin)/admin/notifications/page.test.tsx index 0b8ba6fa..cb45e94e 100644 --- a/app/(admin)/admin/notifications/page.test.tsx +++ b/app/(admin)/admin/notifications/page.test.tsx @@ -1,15 +1,76 @@ -// /Users/ryanfurrer/Developer/GitHub/gridiron-survivor/app/(admin)/admin/notifications/page.test.tsx - -import { render, screen } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { getCurrentLeague } from '@/api/apiFunctions'; +import { getUserTargets, sendEmailNotifications } from './serverFunctions/serverFunctionHelper'; import AdminNotifications from './page'; import React from 'react'; +let contentInput: HTMLInputElement, + selectAllUsersRadioOption: HTMLElement, + selectRecipientsRadioGroup: HTMLElement, + sendEmailButton: HTMLElement, + subjectInput: HTMLInputElement; + +jest.mock('@/api/apiFunctions', () => ({ + getCurrentLeague: jest.fn(), +})); + +jest.mock('./serverFunctions/serverFunctionHelper', () => ({ + sendEmailNotifications: jest.fn(), + getUserTargets: jest.fn(), +})); + describe('Admin notifications page', () => { - it(`should render it's content`, () => { + beforeEach(async () => { + jest.clearAllMocks(); + + (getCurrentLeague as jest.Mock).mockResolvedValue({ + participants: ['12345', '1234', '123'], + leagueName: 'Test League', + }); + + (getUserTargets as jest.Mock).mockResolvedValue([ + 'target1', + 'target2', + 'target3', + ]); + render(); + + contentInput = screen.getByTestId('content-text'); + selectAllUsersRadioOption = screen.getByTestId('all-users-option'); + selectRecipientsRadioGroup = screen.getByTestId('radio-group-default'); + sendEmailButton = screen.getByTestId('send-email'); + subjectInput = screen.getByTestId('subject-text'); + }); + + it(`should render it's content`, () => { + (sendEmailNotifications as jest.Mock).mockResolvedValue({}); + const adminNotificationsContent = screen.getByTestId( 'admin-notifications-content', ); expect(adminNotificationsContent).toBeInTheDocument(); }); + + it('should call the sendEmailNotifications function with the provided inputs', async () => { + fireEvent.click(selectAllUsersRadioOption); + fireEvent.change(subjectInput, { target: { value: 'Test Title' } }); + fireEvent.change(contentInput, { + target: { value: 'Test message section.' }, + }); + + await waitFor(() => { + expect(sendEmailButton).toBeInTheDocument(); + }); + + fireEvent.submit(sendEmailButton); + + await waitFor(() => { + expect(sendEmailNotifications as jest.Mock).toHaveBeenCalledWith({ + content: 'Test message section.', + groupUsers: ['target1', 'target2', 'target3'], + subject: 'Test Title', + }); + }); + }); }); diff --git a/app/(admin)/admin/notifications/page.tsx b/app/(admin)/admin/notifications/page.tsx index 30d5760c..221fc1a5 100644 --- a/app/(admin)/admin/notifications/page.tsx +++ b/app/(admin)/admin/notifications/page.tsx @@ -1,16 +1,163 @@ // Copyright (c) Gridiron Survivor. // Licensed under the MIT License. -import { JSX } from 'react'; +'use client'; +import { Button } from '@/components/Button/Button'; +import { getCurrentLeague } from '@/api/apiFunctions'; +import { Input } from '@/components/Input/Input'; +import { JSX, useState } from 'react'; +import { LabelText } from '@/components/LabelText/LabelText'; +import { + RadioGroupDefault, + RadioGroupDefaultItem, +} from '@/components/RadioGroupDefault/RadioGroupDefault'; +import { sendEmailNotifications } from './serverFunctions/serverFunctionHelper'; +import { Textarea } from '@/components/Textarea/Textarea'; +import React, { useEffect } from 'react'; +import { getUserTargets } from './serverFunctions/serverFunctionHelper'; /** * The admin home page. * @returns The rendered AdminHome page. */ const AdminNotifications = (): JSX.Element => { + const [content, setContent] = useState(''); + const [emailSubjects, setEmailSubjects] = useState('all users'); + const [groupUsers, setGroupUsers] = useState([]); + const [leagueName, setLeagueName] = useState(''); + const [subject, setSubject] = useState(''); + + /** + * To grab all users from the league. + * @returns The league data. + */ + const getLeagueData = async (): Promise => { + try { + const leagueId = '66f1a8e300102bff03ff'; // EMAIL TEST LEAGUE (DO NOT CHANGE) + const leagueData = await getCurrentLeague(leagueId); + const userTargets = await getUserTargets({ + userIDs: leagueData.participants, + }); + setGroupUsers(userTargets); + setLeagueName(leagueData.leagueName); + } catch (error) { + throw error; + } + }; + + /** + * Handle form submission + * @param event - Prevents the default reloading. + */ + const handleSubmit = async (event: React.FormEvent): Promise => { + event.preventDefault(); + await sendEmailNotifications({ + content, + groupUsers, + subject, + }); + }; + + /** + * Function to handle radio selection logic. + * @param value - Value of the radio buttons. + */ + const handleRadioChange = (value: string): void => { + setGroupUsers([value]); + setEmailSubjects(value); + }; + + useEffect(() => { + /** + * Fetches the league data. + * @returns The league data. + */ + const fetchData = async (): Promise => { + await getLeagueData(); + }; + fetchData(); + }, []); + return ( -
-

{`This is where I'd put my notifation dashboard, IF I HAD ONE!`}

+
+

+ Choose the users you would like to email in{' '} + {leagueName}. +

+ +
+ + All users +
+
+ + Only the survivors +
+
+ + Only the losers +
+
+
+
+ + Subject: + + setSubject(e.target.value)} + type="text" + /> +
+
+ + Message: + +