From d3bcd1c81ff4b78cfa3df2548610fcbcf52bcd32 Mon Sep 17 00:00:00 2001 From: Douglas Naphas Date: Mon, 28 Mar 2022 21:56:23 -0400 Subject: [PATCH] Insert new participant in sorted order (front-end) gh-250 --- frontend/src/components/RosterPage.js | 57 +++++++++------ frontend/src/components/RosterPage.test.js | 82 +++++++++++++++++++++- 2 files changed, 115 insertions(+), 24 deletions(-) diff --git a/frontend/src/components/RosterPage.js b/frontend/src/components/RosterPage.js index 9f4d2a59..ff974ef6 100644 --- a/frontend/src/components/RosterPage.js +++ b/frontend/src/components/RosterPage.js @@ -80,6 +80,39 @@ class RosterPage extends Component { } }); }; + messageHandler = (event) => { + if (!event) { + return; + } + if (!event.data) { + return; + } + const eventData = JSON.parse(event.data); + if (!eventData) { + return; + } + if (!eventData.newParticipant) { + return; + } + this.setState((state, props) => { + if (state.participants.includes(eventData.newParticipant)) { + return; + } + return { + participants: state.participants + .concat([eventData.newParticipant]) + .sort((a, b) => { + if (new String(a).toLowerCase() < new String(b).toLowerCase()) + return -1; + if (new String(a).toLowerCase() > new String(b).toLowerCase()) + return 1; + if (a < b) return -1; + if (a > b) return 1; + return 0; + }), + }; + }); + }; componentDidMount() { this._isMounted = true; const { @@ -114,29 +147,7 @@ class RosterPage extends Component { `roomcode=${roomCode}&` + `gamename=${encodeURIComponent(gameName)}` ); - webSocket.addEventListener("message", (event) => { - if (!event) { - return; - } - if (!event.data) { - return; - } - const eventData = JSON.parse(event.data); - if (!eventData) { - return; - } - if (!eventData.newParticipant) { - return; - } - this.setState((state, props) => { - if (state.participants.includes(eventData.newParticipant)) { - return; - } - return { - participants: state.participants.concat([eventData.newParticipant]), - }; - }); - }); + webSocket.addEventListener("message", this.messageHandler); } componentWillUnmount() { if (webSocket && webSocket.close) { diff --git a/frontend/src/components/RosterPage.test.js b/frontend/src/components/RosterPage.test.js index 27a9fea3..fdb0a7b3 100644 --- a/frontend/src/components/RosterPage.test.js +++ b/frontend/src/components/RosterPage.test.js @@ -1,7 +1,13 @@ import RosterPage from "./RosterPage"; import React from "react"; import { MemoryRouter } from "react-router-dom"; -import { findByText, render, screen, waitFor } from "@testing-library/react"; +import { + findByText, + getAllByRole, + render, + screen, + waitFor, +} from "@testing-library/react"; import "@testing-library/jest-dom"; import userEvent from "@testing-library/user-event"; import { ThemeProvider, createTheme } from "@mui/material/styles"; @@ -292,4 +298,78 @@ describe("RosterPage", () => { expect(mockWebSocket.addEventListener).toHaveBeenCalled(); await findByText(table, "Je Teste"); }); + // new participant shows up in the right order + test("New participant shows up in the right order", async () => { + let mockWebSocketConstructorCalls = 0; + let messageEventHandler; + const mockWebSocket = { + addEventListener: jest.fn((eventType, cb) => { + messageEventHandler = cb; + }), + }; + + class MockWebSocket { + constructor(server, protocol) { + mockWebSocketConstructorCalls++; + // expect server to be correct + expect(server).toEqual( + `wss://${window.location.hostname}/ws/?` + + `roomcode=${confirmedRoomCode}&` + + `gamename=${encodeURIComponent(confirmedGameName)}` + ); + return mockWebSocket; + } + } + global.WebSocket = MockWebSocket; + + const confirmedRoomCode = "TESTIN"; + const confirmedGameName = "car"; + function* participantsGenerator() { + yield ["ABx", "car", "castle", "Kastle", "Lill", "munoria"]; + } + const pGen = participantsGenerator(); + const roster = jest.fn(async () => { + return { status: 200, data: { participants: pGen.next().value } }; + }); + const closeSeder = jest.fn(); + const setConfirmedRoomCode = jest.fn(); + const setConfirmedGameName = jest.fn(); + const setChosenPath = jest.fn(); + render( + + + + + + ); + expect(mockWebSocketConstructorCalls).toEqual(1); + const testMessage = new MessageEvent("message", { + data: `{"newParticipant":"Draw"}`, + }); + let table = await screen.findByRole("table"); + await findByText(table, "ABx"); + expect(roster).toHaveBeenCalledTimes(1); + messageEventHandler(testMessage); + expect(mockWebSocket.addEventListener).toHaveBeenCalled(); + await findByText(table, "car"); + const cells = screen.getAllByRole("cell"); + expect(cells.map((cell) => cell.innerHTML)).toEqual([ + "ABx", + "car", + "castle", + "Draw", + "Kastle", + "Lill", + "munoria", + ]); + }); + // removeEventListener is called });