Skip to content

Commit b52957e

Browse files
committed
Merge branch 'development' into deployment
2 parents 506e36e + 0a77cbf commit b52957e

File tree

10 files changed

+131
-98
lines changed

10 files changed

+131
-98
lines changed

backend/code-execution-service/src/controllers/codeExecutionControllers.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import {
1010
ERROR_INVALID_TEST_CASES_MESSAGE,
1111
} from "../utils/constants";
1212
import { questionService } from "../utils/questionApi";
13-
import { testCasesApi } from "../utils/testCasesApi";
1413

1514
interface CompilerResult {
1615
status: string;

backend/code-execution-service/src/utils/testCasesApi.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

backend/code-execution-service/tests/codeExecutionRoutes.spec.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
ERROR_NOT_SAME_LENGTH_MESSAGE,
77
SUCCESS_MESSAGE,
88
} from "../src/utils/constants";
9-
import { testCasesApi } from "../src/utils/testCasesApi";
109
import { questionService } from "../src/utils/questionApi";
1110

1211
const request = supertest(app);

frontend/src/components/Chat/index.tsx

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { Box, styled, TextField, Typography } from "@mui/material";
22
import { useEffect, useRef, useState } from "react";
3-
import { communicationSocket } from "../../utils/communicationSocket";
3+
import {
4+
CommunicationEvents,
5+
communicationSocket,
6+
} from "../../utils/communicationSocket";
47
import { useMatch } from "../../contexts/MatchContext";
58
import {
69
USE_AUTH_ERROR_MESSAGE,
@@ -15,19 +18,6 @@ type Message = {
1518
createdTime: number;
1619
};
1720

18-
export enum CommunicationEvents {
19-
// receive
20-
JOIN = "join",
21-
SEND_TEXT_MESSAGE = "send_text_message",
22-
DISCONNECT = "disconnect",
23-
24-
// send
25-
USER_JOINED = "user_joined",
26-
ALREADY_JOINED = "already_joined",
27-
TEXT_MESSAGE_RECEIVED = "text_message_received",
28-
DISCONNECTED = "disconnected",
29-
}
30-
3121
type ChatProps = {
3222
isActive: boolean;
3323
};
@@ -66,13 +56,13 @@ const Chat: React.FC<ChatProps> = ({ isActive }) => {
6656
roomId: getMatchId(),
6757
username: user?.username,
6858
});
69-
// eslint-disable-next-line react-hooks/exhaustive-deps
7059

7160
return () => {
7261
console.log("closing socket...");
7362
communicationSocket.close();
7463
setMessages([]); // clear the earlier messages in dev mode
7564
};
65+
// eslint-disable-next-line react-hooks/exhaustive-deps
7666
}, []);
7767

7868
useEffect(() => {

frontend/src/components/CollabSessionControls/index.tsx

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,14 @@ import { Button, Stack } from "@mui/material";
22
import Stopwatch from "../Stopwatch";
33
import { useCollab } from "../../contexts/CollabContext";
44
import { USE_COLLAB_ERROR_MESSAGE } from "../../utils/constants";
5-
import { useEffect, useState } from "react";
65

76
const CollabSessionControls: React.FC = () => {
8-
const [time, setTime] = useState<number>(0);
9-
10-
useEffect(() => {
11-
const intervalId = setInterval(
12-
() => setTime((prevTime) => prevTime + 1),
13-
1000
14-
);
15-
16-
return () => clearInterval(intervalId);
17-
}, [time]);
18-
197
const collab = useCollab();
208
if (!collab) {
219
throw new Error(USE_COLLAB_ERROR_MESSAGE);
2210
}
2311

24-
const { handleSubmitSessionClick, handleEndSessionClick } = collab;
12+
const { handleSubmitSessionClick, handleEndSessionClick, time } = collab;
2513

2614
return (
2715
<Stack direction={"row"} alignItems={"center"} spacing={2}>
@@ -33,7 +21,7 @@ const CollabSessionControls: React.FC = () => {
3321
}}
3422
variant="outlined"
3523
color="success"
36-
onClick={() => handleSubmitSessionClick(time)}
24+
onClick={() => handleSubmitSessionClick()}
3725
>
3826
Submit
3927
</Button>

frontend/src/components/QuestionCodeTemplates/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ const QuestionCodeTemplates: React.FC<QuestionCodeTemplatesProps> = ({
6666
event.target.selectionEnd = cursorPosition + 1;
6767
}
6868
};
69-
/* eslint-enable @typescript-eslint/no-explicit-any */
7069

7170
return (
7271
<Box display="flex" flexDirection="column" marginTop={2}>

frontend/src/components/TestCase/index.tsx

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import { Box, styled, Typography } from "@mui/material";
2+
import { CompilerResult } from "../../contexts/CollabContext";
23

34
type TestCaseProps = {
45
input: string;
5-
output?: string;
6-
stdout: string;
7-
result?: string;
6+
expected: string;
7+
result: CompilerResult;
88
};
99

1010
const StyledBox = styled(Box)(({ theme }) => ({
@@ -18,34 +18,58 @@ const StyledTypography = styled(Typography)(({ theme }) => ({
1818
whiteSpace: "pre-line",
1919
}));
2020

21-
const TestCase: React.FC<TestCaseProps> = ({
22-
input,
23-
output,
24-
stdout,
25-
result,
26-
}) => {
21+
const TestCase: React.FC<TestCaseProps> = ({ input, expected, result }) => {
2722
return (
2823
<Box>
29-
<StyledBox sx={(theme) => ({ marginBottom: theme.spacing(2) })}>
24+
{"isMatch" in result && result.isMatch && (
25+
<StyledBox>
26+
<Typography variant="h4" color="success">
27+
Accepted
28+
</Typography>
29+
</StyledBox>
30+
)}
31+
{"isMatch" in result && !result.isMatch && (
32+
<StyledBox>
33+
<Typography variant="h4" color="error">
34+
Wrong Answer
35+
</Typography>
36+
</StyledBox>
37+
)}
38+
{result.stderr && (
39+
<StyledBox>
40+
<Typography variant="overline">Error</Typography>
41+
<StyledTypography
42+
fontFamily={"monospace"}
43+
sx={{ backgroundColor: "#EDAFAF" }}
44+
>
45+
{result.stderr}
46+
</StyledTypography>
47+
</StyledBox>
48+
)}
49+
<StyledBox>
3050
<Typography variant="overline">Input</Typography>
3151
<StyledTypography fontFamily={"monospace"}>{input}</StyledTypography>
3252
</StyledBox>
33-
{output && (
53+
<StyledBox>
54+
<Typography variant="overline">Expected</Typography>
55+
<StyledTypography fontFamily={"monospace"}>{expected}</StyledTypography>
56+
</StyledBox>
57+
{"actualResult" in result && (
3458
<StyledBox>
35-
<Typography variant="overline">Output</Typography>
36-
<StyledTypography fontFamily={"monospace"}>{output}</StyledTypography>
59+
<Typography variant="overline">Actual</Typography>
60+
<StyledTypography fontFamily={"monospace"}>
61+
{result.actualResult || "\u00A0"}
62+
</StyledTypography>
3763
</StyledBox>
3864
)}
39-
{stdout && (
65+
{"stdout" in result && (
4066
<StyledBox>
4167
<Typography variant="overline">Stdout</Typography>
42-
<StyledTypography fontFamily={"monospace"}>{stdout}</StyledTypography>
68+
<StyledTypography fontFamily={"monospace"}>
69+
{result.stdout || "\u00A0"}
70+
</StyledTypography>
4371
</StyledBox>
4472
)}
45-
<StyledBox>
46-
<Typography variant="overline">Expected</Typography>
47-
<StyledTypography fontFamily={"monospace"}>{result}</StyledTypography>
48-
</StyledBox>
4973
</Box>
5074
);
5175
};

frontend/src/contexts/CollabContext.tsx

Lines changed: 54 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable react-refresh/only-export-components */
22

3-
import React, { createContext, useContext, useState } from "react";
3+
import React, { createContext, useContext, useEffect, useState } from "react";
44
import {
55
USE_MATCH_ERROR_MESSAGE,
66
FAILED_TESTCASE_MESSAGE,
@@ -11,16 +11,15 @@ import {
1111
import { toast } from "react-toastify";
1212

1313
import { useMatch } from "./MatchContext";
14-
import { codeExecutionClient } from "../utils/api";
14+
import { qnHistoryClient, codeExecutionClient } from "../utils/api";
1515
import { useReducer } from "react";
1616
import { updateQnHistoryById } from "../reducers/qnHistoryReducer";
1717
import qnHistoryReducer, { initialQHState } from "../reducers/qnHistoryReducer";
1818
import { CollabEvents, collabSocket, leave } from "../utils/collabSocket";
19-
import { CommunicationEvents } from "../components/Chat";
2019
import { communicationSocket } from "../utils/communicationSocket";
2120
import useAppNavigate from "../components/UseAppNavigate";
2221

23-
type CompilerResult = {
22+
export type CompilerResult = {
2423
status: string;
2524
exception: string | null;
2625
stdout: string;
@@ -30,17 +29,21 @@ type CompilerResult = {
3029
stout: string;
3130
actualResult: string;
3231
expectedResult: string;
32+
isMatch: boolean;
3333
};
3434

3535
type CollabContextType = {
36-
handleSubmitSessionClick: (time: number) => void;
36+
handleSubmitSessionClick: () => void;
3737
handleEndSessionClick: () => void;
3838
handleRejectEndSession: () => void;
3939
handleConfirmEndSession: () => void;
4040
checkPartnerStatus: () => void;
4141
setCode: React.Dispatch<React.SetStateAction<string>>;
4242
compilerResult: CompilerResult[];
43+
setCompilerResult: React.Dispatch<React.SetStateAction<CompilerResult[]>>;
4344
isEndSessionModalOpen: boolean;
45+
time: number;
46+
resetCollab: () => void;
4447
};
4548

4649
const CollabContext = createContext<CollabContextType | null>(null);
@@ -65,6 +68,17 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
6568
qnHistoryId,
6669
} = match;
6770

71+
const [time, setTime] = useState<number>(0);
72+
73+
useEffect(() => {
74+
const intervalId = setInterval(
75+
() => setTime((prevTime) => prevTime + 1),
76+
1000
77+
);
78+
79+
return () => clearInterval(intervalId);
80+
}, [time]);
81+
6882
// eslint-disable-next-line
6983
const [_qnHistoryState, qnHistoryDispatch] = useReducer(
7084
qnHistoryReducer,
@@ -75,16 +89,16 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
7589
const [isEndSessionModalOpen, setIsEndSessionModalOpen] =
7690
useState<boolean>(false);
7791

78-
const handleSubmitSessionClick = async (time: number) => {
92+
const handleSubmitSessionClick = async () => {
7993
try {
8094
const res = await codeExecutionClient.post("/", {
8195
questionId,
82-
code,
96+
// Replace tabs with 4 spaces to prevent formatting issues
97+
code: code.replace(/\t/g, " ".repeat(4)),
8398
language: matchCriteria?.language.toLowerCase(),
8499
});
85-
86-
console.log(res.data.data);
87-
setCompilerResult(res.data.data);
100+
console.log([...res.data.data]);
101+
setCompilerResult([...res.data.data]);
88102

89103
let isMatch = true;
90104
for (let i = 0; i < res.data.data.length; i++) {
@@ -123,28 +137,39 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
123137
setIsEndSessionModalOpen(false);
124138
};
125139

126-
const handleConfirmEndSession = () => {
140+
const handleConfirmEndSession = async () => {
127141
setIsEndSessionModalOpen(false);
128142

143+
// Get queston history
144+
const data = await qnHistoryClient.get(qnHistoryId as string);
145+
146+
// Only update question history if it has not been submitted before
147+
if (!data.data.qnHistory.code) {
148+
updateQnHistoryById(
149+
qnHistoryId as string,
150+
{
151+
submissionStatus: "Attempted",
152+
dateAttempted: new Date().toISOString(),
153+
timeTaken: time,
154+
code: code.replace(/\t/g, " ".repeat(4)),
155+
},
156+
qnHistoryDispatch
157+
);
158+
}
159+
129160
// Leave collaboration room
130161
leave(matchUser?.id as string, getMatchId() as string, true);
131162
leave(partner?.id as string, getMatchId() as string, true);
132163

133164
// Leave chat room
134-
communicationSocket.emit(
135-
CommunicationEvents.LEAVE,
136-
getMatchId(),
137-
matchUser?.username
138-
);
139-
communicationSocket.emit(
140-
CommunicationEvents.LEAVE,
141-
getMatchId(),
142-
partner?.username
143-
);
165+
communicationSocket.disconnect();
144166

145167
// Delete match data
146168
stopMatch();
147169
appNavigate("/home");
170+
171+
// Reset collab state
172+
resetCollab();
148173
};
149174

150175
const checkPartnerStatus = () => {
@@ -156,6 +181,11 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
156181
});
157182
};
158183

184+
const resetCollab = () => {
185+
setCompilerResult([]);
186+
setTime(0);
187+
};
188+
159189
return (
160190
<CollabContext.Provider
161191
value={{
@@ -166,7 +196,10 @@ const CollabProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
166196
checkPartnerStatus,
167197
setCode,
168198
compilerResult,
199+
setCompilerResult,
169200
isEndSessionModalOpen,
201+
time,
202+
resetCollab,
170203
}}
171204
>
172205
{children}

0 commit comments

Comments
 (0)