TEST PLAN – AUTH MODULE
Module: Authentication
Endpoints: /auth/register, /auth/login, /auth/profile
Objective: Ensure users can register, login, and access their profile securely. Validate error
handling, authentication, and expected behavior.
1. Endpoint: POST /auth/register
Aspect Details
Description Registers a new user with username, password, and optional fields (email, DOB,
country, organization).
HTTP Method POST
URL /auth/register
Headers Content-Type: application/json
Body Parameters username (string, required)
password (string, required)
email (string, optional)
dateOfBirth (string, optional, YYYY-MM-DD)
country (string, optional)
organization (string, optional)
Preconditions Server running, no duplicate username exists
Expected - On valid input, create user, return 201 Created and user object (without
Behavior password)
- On missing username/password, return 400 Bad Request with error message
- On duplicate username, return 400 Bad Request with error message
Edge Cases / - Username with special characters
Notes - Password too short (no validation implemented, note in risk)
- Optional fields missing or null
Example Test Cases:
1. Happy Path
o Input: {"username":"alice","password":"Password123"}
o Expected Output: 201, JSON user object: {id, username, email:null, rating:1500}
2. Missing Username
o Input: {"password":"Password123"}
o Expected Output: 400, {message: 'Username and password are required'}
2. Endpoint: POST /auth/login
Aspect Details
Description Logs in a registered user and returns a JWT token.
HTTP Method POST
URL /auth/login
Headers Content-Type: application/json
Body Parameters username (string, required)
password (string, required)
Preconditions User already registered in the system
Expected - Valid credentials: 200 OK, {token, message: 'Login successful'}
Behavior - Invalid credentials: 401 Unauthorized, {message:'Invalid credentials'}
- Missing username/password: 400 Bad Request, {message:'Username and
password are required'}
Edge Cases / - Case sensitivity for username
Notes - Wrong password
- JWT contains sub (userId) and username
Example Test Cases:
1. Happy Path
o Input: {"username":"alice","password":"Password123"}
o Expected Output: 200 OK, JWT token returned
3. Endpoint: GET /auth/profile
Aspect Details
Description Returns the authenticated user's profile details.
HTTP Method GET
URL /auth/profile
Headers Authorization: Bearer <JWT>
Body None
Parameters
Preconditions User must be logged in and have a valid JWT
Expected - Valid token: 200 OK, JSON with user profile {id, username, email, dateOfBirth,
Behavior country, organization, rating}
- Missing token: 401 Unauthorized, {message:'No token provided'}
- Invalid token: 401 Unauthorized, {message:'Invalid token'}
- Expired token: 401 Unauthorized, {message:'Token expired'}
Edge Cases / - Token with quotes ("Bearer <token>") should still work
Notes - User deleted after token issued → 404 User Not Found
Example Test Cases:
1. Happy Path
o Header: Authorization: Bearer <valid JWT>
o Expected Output: 200 OK, user profile JSON
TEST CASES – AUTH MODULE
ID Title Pre- Steps Expected Actual Status Evidence
condit Result Result Link
ions
AU Regist Server 1. Send POST 201 { 201 evidence
/auth/regis /AUTH-
TH- er runnin Created, "message": Created, [Link],
01 New g, ter with body JSON user "User evidence
User userna { object registered /AUTH-
"username":
(Happ me returned successfully", [Link]
"alice",
y “alice "password": with "user": {
Path) ” does "Password12 fields: id, "id": 1,
not 3", username,
"email":
exist "alice@exam
email, "username":
[Link]" } dateOfBirt "alice",
h:null, "email":
country:n "alice@exam
ull, [Link]",
organizati
on:null,
rating:150 "dateOfBirth"
0 : null,
"country":
null,
"organization
": null,
"rating":
1500
}
}
AU Regist Server 1. Send POST 400 Bad { 400 Bad evidence
/AUTH-
TH- er runnin /auth/regis Request, { "message": Request [Link],
02 User g ter with body "message "Username evidence
Missin { ": and password /AUTH-
"password": "Usernam
g are required" [Link]
"Password12 e and
Usern 3" } password }
ame are
required
" }
AU Regist “alice 1. Send POST 400 Bad { 400 Bad evidence
/auth/regis /AUTH-
TH- er ” Request, { "message": Request [Link],
03 Duplic alread ter with body "message "Username evidence
ate y { ": already /AUTH-
"username": "Usernam
Usern exists exists" [Link]
"alice", e
ame "password": already }
"Password12 exists"
3" } }
AU Login User 1. Send POST 200 OK, { { 200 OK evidence
/auth/login "token": /AUTH-
TH- with “alice "token":
"<JWT>", "<JWT>", [Link],
04 Correc ” with body { "message": evidence
"username": "message
t exists ": "Login /AUTH-
"alice",
Crede "Login successful" [Link]
"password":
ntials successf }
"Password12
3" } ul" }
AU Login User 1. Send POST 401 { 401 evidence
/auth/login /AUTH-
TH- with “alice Unauthori "message": Unautho [Link],
05 Wrong ” with body { zed, { "Invalid rized evidence
Passw exists "username": "message credentials" /AUTH-
"alice", ":
ord } [Link]
"password": "Invalid
"WrongPassw credenti
ord" } als" }
AU Login User 1. Send POST 400 Bad { 400 Bad evidence
/auth/login /AUTH-
TH- Missin exists Request, { "message": Request [Link],
06 with body { "message "Username
g "username": ": and password evidence
"alice" } "Usernam /AUTH-
Fields are required"
e and [Link]
password }
are
required
" }
AU View User 1. Send GET 200 OK, { 200 OK evidence
/auth/profi /AUTH-
TH- Profile “alice JSON "id": 1, [Link],
07 with ” le with profile evidence
Valid logge header object "username": /AUTH-
Token d in, Authorizati {id, "alice", [Link]
on: Bearer username
has <JWT> "email":
, email,
JWT dateOfBi "alice@exam
rth, [Link]",
country,
organiza "dateOfBirth"
tion,
rating} : null,
"country":
null,
"organization
": null,
"rating":
1500
}
AU View User 1. Send GET 401 { 401 evidence
/auth/profi /AUTH-
TH- Profile exists Unauthori "message": Unautho [Link],
08 withou le without zed, { "No token rized evidence
t Authorization "message provided" /AUTH-
Token header ": "No } [Link]
token
provided
" }
AU View User 1. Send GET 401 { 401 evidence
/auth/profi /AUTH-
TH- Profile exists Unauthori "message": Unautho [Link],
09 with le with zed, { "Invalid rized, evidence
Invali header "message token" /AUTH-
d Authorizati ": } [Link]
on: Bearer "Invalid
Token invalidtoke token" }
n
AU View User 1. Issue a 401 { 401 evidence
"message": /AUTH-
TH- Profile exists JWT with Unauthori Unautho
"Token [Link],
10 with short expiry zed, { expired" } rized evidence
Expire (1s) 2. Wait "message /AUTH-
d 2s 3. Send ": [Link]
"Token
Token GET expired"
}
/auth/profi
le with token
TEST PLAN – USERS MODULE
Module: Users
Endpoints: /users, /users/:id, /users/:id/contests, /users/:id/submissions, /users/:id/rating, /users/:id
(PUT)
Objective: Ensure user information retrieval and profile updates work as intended. Validate
correct handling of valid/invalid IDs, authorization for updates, and retrieval of related contests,
submissions, and rating.
1. Endpoint: GET /users
Aspect Details
Description Returns list of all registered users with basic information.
HTTP Method GET
URL /users
Headers None
Body Parameters None
Preconditions At least one user must exist in the system.
Expected - Returns 200 OK with JSON array of users. Each object contains {id, username,
Behavior email, rating}.
Edge Cases / - Sorting is supported via query parameters sortBy and order.
Notes - Invalid sortBy field might cause incorrect sorting or unexpected order.
Example Test Cases:
1. Happy Path
o Input: GET /users
o Expected: 200 OK, [ { id:1, username:"alice", email:"alice@[Link]", rating:1500
}, … ]
2. Sorted by username asc
o Input: GET /users?sortBy=username&order=asc
o Expected: 200 OK, list sorted alphabetically.
2. Endpoint: GET /users/:id
Aspect Details
Description Returns profile info of a specific user by ID.
HTTP Method GET
URL /users/:id
Headers None
Body Parameters None
Preconditions User with the given ID must exist.
Expected Behavior - Valid ID → 200 OK with {id, username, email, rating}.
- Invalid/non-existing ID → 404 {message:"User not found"}.
Example Test Cases:
1. Valid user
o Input: GET /users/1
o Expected: 200 OK, {id:1, username:"alice", …}
2. Invalid user
o Input: GET /users/999
o Expected: 404, {message:"User not found"}
3. Endpoint: PUT /users/:id
Aspect Details
Description Updates user profile. Only the owner can update their profile.
HTTP Method PUT
URL /users/:id
Headers Authorization: Bearer <JWT>
Body Parameters username?, email?, dateOfBirth?, country?, organization?
Preconditions - User must be logged in.
- Token must belong to the user with :id.
Expected - If authorized, 200 OK with updated user JSON.
Behavior - Updating another user’s profile → 403 {message:"You can only update your
own profile"}.
- Non-existing user ID → 404 {message:"User not found"}.
Edge Cases / - Partial update supported.
Notes - Password cannot be updated here.
Example Test Cases:
1. Happy Path (own profile)
o Input: PUT /users/1 with valid token for alice and body
{email:"newalice@[Link]"}
o Expected: 200 OK, {message:"User updated successfully", user:{…updated values…}}
2. Update other user
o Input: PUT /users/2 with alice’s token
o Expected: 403, {message:"You can only update your own profile"}
4. Endpoint: GET /users/:id/contests
Aspect Details
Description Retrieves contests a user has participated in.
HTTP Method GET
URL /users/:id/contests
Headers None
Body Parameters None
Preconditions User must exist.
Expected - Returns contests the user joined. Each contest: {id, name, date, duration,
Behavior problems}.
- Non-existing user → 404 {message:"User not found"}.
Edge Cases / - New contests use dateTime, but response uses date field (risk: mismatch).
Notes
Example Test Cases:
1. User with contests
o Input: GET /users/1/contests
o Expected: 200 OK, contests array.
2. User not found
o Input: GET /users/999/contests
o Expected: 404, {message:"User not found"}
5. Endpoint: GET /users/:id/submissions
Aspect Details
Description Retrieves all submissions made by a user.
HTTP Method GET
URL /users/:id/submissions
Headers None
Body None
Parameters
Preconditions User must exist.
Expected - Returns {submissions:[{id, problemId, contestId, verdict, timestamp}]}.
Behavior - Non-existing user → 404.
Edge Cases / Bug risk: userId stored as string in submissions but compared against numeric ID in
Notes filter. This may result in empty list even for valid users.
Example Test Cases:
1. Valid user with submissions
o Input: GET /users/1/submissions
o Expected: 200 OK, list of submissions.
2. User not found
o Input: GET /users/999/submissions
o Expected: 404, {message:"User not found"}
6. Endpoint: GET /users/:id/rating
Aspect Details
Description Retrieves rating of a specific user.
HTTP Method GET
URL /users/:id/rating
Headers None
Body Parameters None
Preconditions User must exist.
Expected Behavior - Valid ID → 200 OK {id, username, rating}.
- Invalid ID → 404 {message:"User not found"}.
Example Test Cases:
1. Valid user
o Input: GET /users/2/rating
o Expected: 200 OK, {id:2, username:"bob", rating:1500}
2. User not found
o Input: GET /users/999/rating
o Expected: 404, {message:"User not found"}
Test Cases – Users Module
ID Title Pre- Steps Expected Actual Stat Evidenc
Cond Output us e
itions
US Get At 1. Send GET 200 OK with [ 200 Evidenc
ER all least /users array of all { OK e/USER
S- users 2 users {id, "id": 1, S-
01 users username, "username": "alice", [Link],
regist email, rating} "email": Evidenc
ered "alice@[Link]", e/USER
"dateOfBirth": null, S-
"country": null, [Link]
"organization": null,
"rating": 1500
},
{
"id": 2,
"username":
"sadik",
"email":
"alice@[Link]",
"dateOfBirth": null,
"country": null,
"organization": null,
"rating": 1500
}
]
US Get Multi 1. Send GET 200 OK, list [ 200 Evidenc
ER users ple /users?sortBy=us sorted by { OK e/USER
S- sorte users ername&order=a username "id": 1, S-
02 d by exist sc ascending "username": "alice", [Link],
usern "email": Evidenc
ame "alice@[Link]", e/USER
(asc) "dateOfBirth": null, S-
"country": null, [Link]
"organization": null,
"rating": 1500
},
{
"id": 2,
"username":
"sadik",
"email":
"alice@[Link]",
"dateOfBirth": null,
"country": null,
"organization": null,
"rating": 1500
}
]
US Get Multi 1. Send GET API should [ 200 Evidenc
ER users ple /users?sortBy=fo handle { OK e/USER
S- with users o gracefully "id": 1, S-
03 invali exist (doc "username": "alice", [Link],
d sort expected: "email": Evidenc
field ignore or "alice@[Link]", e/USER
error). "dateOfBirth": null, S-
Actual: TBD "country": null, [Link]
"organization": null,
"rating": 1500
},
{
"id": 2,
"username":
"sadik",
"email":
"alice@[Link]",
"dateOfBirth": null,
"country": null,
"organization": null,
"rating": 1500
}
]
US Get User 1. Send GET 200 OK { 200 Evidenc
ER user alice /users/1 {id:1, "id": 1, OK e/USER
S- by exists username:"ali "username": "alice", S-
04 valid with ce", "country": null, [Link],
ID ID=1 email:"alice "organization": null, Evidenc
@[Link] "rating": 1500 e/USER
m", } S-
rating:<num> [Link]
}
US Get No 1. Send GET 404 { 404 Evidenc
ER user user /users/999 {message:"U "message": "User not Not e/USER
S- by with ser not found" Fou S-
05 invali ID=9 found"} } nd [Link],
d ID 99 Evidenc
e/USER
S-
[Link]
US Upda Logg 1. PUT /users/1 200 OK, { 200 Evidenc
ER te ed in with JSON with "message": "Profile up OK e/USER
S- own as Authorization: updated dated successfully", S-
06 profil alice Bearer values and "user": { [Link],
e (toke message "id": 1,
(happ n), <aliceToken> + "User "username": "alice2 Evidenc
y user body updated ", e/USER
path) ID=1 successfully" "password": "Passw S-
ord123", [Link]
"email": "alice@exa
[Link]",
"dateOfBirth": null,
"country": null,
"organization": null,
"rating": 1500
}
}
US Upda Logg 1. PUT /users/1 403 { 403 Evidenc
ER te ed in with {message:"Y "message": "You can o Forb e/USER
S- other as Authorization: ou can only nly update your own prof idde S-
07 user’ sadik Bearer update your ile" n [Link],
s (toke <bobToken> + own profile"} } Evidenc
profil n), body e/USER
e trying S-
(forbi to [Link]
dden) updat
e
alice
US Upda Valid 1. PUT 404 { 403 Evidenc
ER te token /users/999 {message:"U "message": "You can o Forb e/USER
S- profil (alice ser not nly update your own prof idde S-
08 e of Toke found"} ile" n [Link],
non- n) } Evidenc
existi e/USER
ng S-
user [Link]
US Get User 1. GET 200 OK with TBD TB Evidenc
ER conte alice /users/1/contests list of D e/USER
S- sts joine contests (but S-
09 for a d past note: field is [Link],
user conte date, may be Evidenc
st undefined for e/USER
newly S-
created) [Link]
US Get 1. GET 404 { 404 Evidenc
ER conte /users/999/conte {message:"U "message": "User not f Not e/USER
S- sts sts ser not ound" Fou S-
10 for found"} } nd [Link],
invali Evidenc
d e/USER
user S-
[Link]
US Get User 1. GET 200 OK with Bug: likely empty TB Evidenc
ER subm alice /users/1/submissi submissions because userId stored as D e/USER
issio has ons list string, not numeric
S- ns for subm S-
11 user itted [Link],
with a Evidenc
activi probl e/USER
ty em S-
[Link]
US Get 1. GET 404 { 404 Evidenc
ER subm /users/999/submi {message:"U "message": "User not f Not e/USER
S- issio ssions ser not ound" Fou S-
12 ns for found"} } nd [Link],
invali Evidenc
d e/USER
user S-
[Link]
US Get User 1. GET 200 OK { 200 Evidenc
ER ratin bob /users/2/rating {id:2, "id": 2, OK e/USER
S- g for exists username:"bo "username": "sadik", S-
13 valid with b", "rating": 1500 [Link],
user rating rating:<num> } Evidenc
field } e/USER
S-
[Link]
US Get 1. GET 404 { 404 Evidenc
ER ratin /users/999/rating {message:"U "message": "User not f Not e/USER
S- g for ser not ound" Fou S-
14 invali found"} } nd [Link],
d Evidenc
user e/USER
S-
[Link]
TEST PLAN – CONTESTS MODULE
Module: Contests
Endpoints: /contests, /contests/upcoming, /contests/:id, /contests (POST), /contests/problems
(POST), /contests/:id/problems, /contests/:id/participants, /contests/:id/join,
/contests/:id/leaderboard, /contests/:id/participation/:userId
Objective:
Ensure contests can be created, browsed, joined, and managed correctly. Validate access restrictions for
setters, time-based logic (upcoming vs. past contests), problem attachment, participant management, and
leaderboard consistency.
1. Endpoint: GET /contests
Aspect Details
Description Returns list of all contests with basic info.
HTTP Method GET
URL /contests
Headers None
Body Parameters None
Preconditions At least one contest must exist.
Expected Behavior - 200 OK, array of contests {id, name, date, duration, problems}.
- Supports sortBy and order query params.
Edge Cases / Notes - Sorting on invalid field may break ordering.
Example Test Cases:
1. GET /contests → 200, contests list
2. GET /contests?sortBy=name&order=asc → sorted list
2. Endpoint: GET /contests/upcoming
Aspect Details
Description Returns only contests with dateTime > now.
HTTP Method GET
URL /contests/upcoming
Headers None
Preconditions At least one upcoming contest scheduled.
Expected Behavior - 200 OK, array of upcoming contests.
- Past contests excluded.
Edge Cases / Notes - Empty list if no upcoming contests.
3. Endpoint: GET /contests/:id
Aspect Details
Description Retrieves contest details.
HTTP Method GET
URL /contests/:id
Headers Authorization: Bearer <JWT> required only if viewing upcoming contest by
setter.
Preconditions Contest exists.
Expected - Past/ongoing contest: 200 OK {id, name, date, duration, problems, participants}.
Behavior - Upcoming contest: only visible to setter (with JWT). Others → 400
{message:"Contest is upcoming..."}.
- Invalid ID → 404.
Edge Cases / - Mix of date vs dateTime fields in code (risk).
Notes
4. Endpoint: POST /contests
Aspect Details
Description Creates a new contest.
HTTP Method POST
URL /contests
Headers Authorization: Bearer <JWT>
Body Parameters name (required), dateTime (required), duration (required)
Preconditions User must be logged in.
Expected Behavior - 201 Created with contest JSON.
- Missing fields → 400.
Edge Cases / Notes - Duplicate name not restricted.
5. Endpoint: POST /contests/problems
Aspect Details
Description Adds a problem to a contest.
HTTP Method POST
URL /contests/problems
Headers Authorization: Bearer <JWT>
Body Parameters contestId, problemName, description, input, output, category, difficulty,
timelimit
Preconditions Contest exists & current user is setter.
Expected - 201 Created with problem JSON.
Behavior - Wrong setter → 403.
- Missing fields → 400.
- Contest not found → 404.
Edge Cases / Notes - Problem IDs assigned incrementally; no validation for duplicates.
6. Endpoint: GET /contests/:id/problems
Aspect Details
Description Returns problems of a contest.
HTTP Method GET
URL /contests/:id/problems
Headers None
Preconditions Contest exists.
Expected Behavior - Past/ongoing contest → 200 list of problems.
- Upcoming contest → 400 {message:"Contest is upcoming..."}.
- Invalid contest ID → 404.
7. Endpoint: GET /contests/:id/participants
Aspect Details
Description Retrieves participants of a contest.
HTTP Method GET
URL /contests/:id/participants
Headers None
Preconditions Contest exists.
Expected Behavior - Past/ongoing → 200 list {id, username}.
- Upcoming → 400.
- Invalid ID → 404.
8. Endpoint: POST /contests/:id/join
Aspect Details
Description Allows a user to join a contest.
HTTP Method POST
URL /contests/:id/join
Headers Authorization: Bearer <JWT>
Preconditions User exists & contest exists.
Expected Behavior - 200 OK {message:"User X joined contest Y"}.
- Setter cannot join own contest → 400.
- Already joined → 400.
- Contest ended → 400.
- Invalid user or contest → 404.
9. Endpoint: GET /contests/:id/leaderboard
Aspect Details
Description Returns leaderboard of a contest.
HTTP Method GET
URL /contests/:id/leaderboard
Headers None
Preconditions Contest exists.
Expected Behavior - 200 OK, leaderboard sorted by points {userId, username, points, rank}.
- Empty if no participants.
- Invalid ID → 404.
Edge Cases / Notes - Current code uses random points (mock).
10. Endpoint: GET /contests/:id/participation/:userId
Aspect Details
Description Checks a user’s participation & leaderboard entry in a contest.
HTTP Method GET
URL /contests/:id/participation/:userId
Headers None
Preconditions Contest & user exist.
Expected Behavior - 200 OK {hasParticipated, leaderboardEntry}.
- Contest not found → 404.
- User not found → 404.
- Leaderboard not yet generated → 400.
TEST CASES – CONTESTS MODULE
I Titl Pre Steps Expected Actual Stat Evide
D e - us nce
Co
ndi
tion
s
C Get At 1. Send GET 200 OK, JSON list of [ 200 evide
O All leas /contests contests { OK nce/C
N Con t1 "id": 1, ON-
- tests con "name": "Spring Co [Link]
0 test ding Challenge", n,
1 exis "duration": 120, evide
ts "problems": 0 nce/C
}, ON-
{ [Link]
"id": 2, g
"name": "Spring Co
ders Combat",
"duration": 140,
"problems": 0
}
]
C Get Mul 1. Send GET 200 OK, contests sorted [ 200 evide
O Con tipl /contests?sort alphabetically { OK nce/C
N tests e By=name&or "id": 2, ON-
- Sort con der=asc "name": "Spring Co [Link]
0 ed test ders Combat", n,
2 Asc s "duration": 140, evide
exis "problems": 0 nce/C
t }, ON-
{ [Link]
"id": 1, g
"name": "Spring Co
ding Challenge",
"duration": 120,
"problems": 0
}
]
C Get Mul 1. Send GET 200 OK, sorted by date [ 200 evide
O Con tipl /contests?sort descending { OK nce/C
N tests e By=dateTime "id": 1, ON-
- Sort con &order=desc "name": "Spring Co [Link]
0 ed test ding Challenge", n,
3 Des s "duration": 120, evide
c exis "problems": 0 nce/C
t }, ON-
{ [Link]
"id": 2, g
"name": "Spring Co
ders Combat",
"duration": 140,
"problems": 0
}
]
C Get At 1. Send GET 200 OK, only future [ 200 evide
O Upc leas /contests/upco contests returned { OK nce/C
N omi t1 ming "id": 2, ON-
- ng futu "name": "Future [Link]
0 Con re Contest C2", n,
4 tests con "duration": 120 evide
test } nce/C
sch ] ON-
edu [Link]
led g
C Get Con 1. Send GET 200 OK, contest object { TB evide
O Con test /contests/1 returned "id": 1, D nce/C
N test wit "name": "Past Contest ON-
- by h C1", [Link]
0 ID id= "duration": 120, n,
5 (Pas 1 "problems": 0, evide
t alre "participants": 0 nce/C
Con ady } ON-
test) end [Link]
ed g
C Get Con 1. Send GET 200 OK, contest details { 200 evide
O Con test /contests/2 returned "id": 2, OK nce/C
N test upc with setter’s "name": "Future ON-
- by omi token Contest C2", [Link]
0 ID ng, "date": "2025-09- n,
6 (Up vali 20T12:00:00Z", evide
com d "duration": 120, nce/C
ing sett "problems": 0, ON-
by er "participants": 0, [Link]
Sett JW "setter": "alice" g
er) T }
C Get Con 1. Send GET 400 {message:"Contest { 400 evide
O Con test /contests/2 is upcoming, details not "message": "Contest is BA nce/C
N test upc with other available yet"} upcoming or you are not D ON-
- by omi token authorized to see the RE [Link]
0 ID ng, details yet" QU n,
7 (Up log } EST evide
com ged nce/C
ing in ON-
by as [Link]
Non diff g
- ere
Sett nt
er) user
C Get Con 1. Send GET 404 {message:"Contest { 404 evide
O Con test /contests/999 not found"} "message": "Contest NO nce/C
N test wit not found" T ON-
- by h } FO [Link]
0 Inva ID UN n,
8 lid doe D evide
ID s nce/C
not ON-
exis [Link]
t g
C Cre Use 1. POST 201 Created with { 201 evide
O ate r /contests with contest object "message": "Contest c Crea nce/C
N Con log {name, reated successfully", ted ON-
- test ged dateTime, "contest": { [Link]
0 (Val in duration} "id": 1, n,
9 id) "name": "Spring Co evide
ding Challenge", nce/C
"date": "2025-12- ON-
31T18:00:00Z", [Link]
"duration": 120, g
"problems": 0,
"participants": 0,
"setter": "alice"
}
}
C Cre Use 1. POST 400 {message:"Missing { 400 evide
O ate r /contests with required fields"} "message": "Name, da BA nce/C
N Con log {name:"Test teTime, and duration are D ON-
- test ged Only"} required" RE [Link]
1 Mis in } QU n,
0 sing EST evide
Fiel nce/C
ds ON-
[Link]
g
C Cre No 1. POST 401 { { 401 evide
O ate ne /contests message": "No token pr "message": "No token Una nce/C
N Con without JWT ovided "} provided" utho ON-
- test } rize [Link]
1 Wit d n,
1 hout evide
Tok nce/C
en ON-
[Link]
g
C Add Con 1. POST 201 Created, problem { 201 evide
O Pro test /contests/prob object returned "message": "Problem nce/C
N ble exis lems with added to contest ON-
- m to ts, valid body successfully", [Link]
1 Con log "problem": { n,
2 test ged "id": 1, evide
(Val in "name": "Two nce/C
id as Sum", ON-
Sett sett "description": [Link]
er) er "Given an array of g
integers, return indices
of the two numbers such
that they add up to a
target.",
"input": "n (size of
array), array elements,
target",
"output": "indices i,
j",
"category":
"Algorithms",
"difficulty": "Easy",
"timelimit": "1s",
"contestId": 1
}
}
C Add Con 1. POST 403 { { 403 evide
O Pro test /contests/prob "message": "You are "message": "You are n Forb nce/C
N ble exis lems not allowed to add probl ot allowed to add proble idde ON-
- m ts, ems to this contest" ms to this contest" n [Link]
1 by log } } n,
3 Non ged evide
- in nce/C
Sett as ON-
er non [Link]
- g
sett
er
C Add Inv 1. POST 404 {message:"Contest { 404 evide
O Pro alid /contests/prob not found"} "message": "Contest n Not nce/C
N ble con lems with ot found" Fou ON-
- m test invalid } nd [Link]
1 Con Id contestId n,
4 test pro evide
Not vid nce/C
Fou ed ON-
nd [Link]
g
C Get Con 1. GET 200 OK, problems list { 200 evide
O Con test /contests/:id/p "contestId": 3, OK nce/C
N test fini roblems "problems": [ ON-
- Pro she { [Link]
1 ble d "id": 2, n,
5 ms "name": "Maxim evide
(Pas um Subarray", nce/C
t "category": "Dyn ON-
Con amic Programming", [Link]
test) "timelimit": "2s" g
}
]
}
C Get Con 1. GET 400 {message:"Contest { 400 evide
O Con test /contests/:id/p is upcoming"} "message": "Contest is BA nce/C
N test not roblems upcoming, problems are D ON-
- Pro yet not available yet" RE [Link]
1 ble star } QU n,
6 ms ted EST evide
(Up nce/C
com ON-
ing [Link]
Con g
test)
C Get Con 1. GET 200 OK, list of { 400 evide
O Con test /contests/:id/p participants "message": "Contest h BA nce/C
N test end articipants as already ended" D ON-
- Part ed } RE [Link]
1 icip wit QU n,
7 ants h EST evide
(Pas part nce/C
t icip ON-
Con ants [Link]
test) g
C Get Con 1. GET 400 {message:"Contest { 400 evide
O Con test /contests/:id/p is upcoming"} "message": "Contest is BA nce/C
N test not articipants upcoming, participants a D ON-
- Part star re not available yet" RE [Link]
1 icip ted } QU n,
8 ants EST evide
(Up nce/C
com ON-
ing [Link]
Con g
test)
C Join Con 1. POST 200 OK { 200 evide
O Con test /contests/:id/j {message:"User "message": "User sadi OK nce/C
N test upc oin with valid joined"} k joined contest 1", ON-
- (Val omi JWT "contestId": 1 [Link]
1 id ng, } n,
9 Use user evide
r) not nce/C
sett ON-
er [Link]
g
C Join Use 1. Repeat 400 {message:"You { 400 evide
O Con r POST have already joined this "message": "You have BA nce/C
N test alre /contests/:id/j contest"} already joined this conte D ON-
- (Alr ady oin st" RE [Link]
2 ead join } QU n,
0 y ed EST evide
Join con nce/C
ed) test ON-
[Link]
g
C Join Use 1. POST 400 {message:"You { 400 evide
O Con r is /contests/:id/j cannot join your own "message": "You cann BA nce/C
N test con oin with contest"} ot join your own contest" D ON-
- (As test setter’s token } RE [Link]
2 Sett sett QU n,
1 er) er EST evide
nce/C
ON-
[Link]
g
C Join Con 1. POST 400 {message:"Contest { 400 evide
O Con test /contests/:id/j has already ended"} "message": "Contest h BA nce/C
N test alre oin as already ended" D ON-
- (Aft ady } RE [Link]
2 er end QU n,
2 End ed EST evide
) nce/C
ON-
[Link]
g
C Join Con 1. POST 404 {message:"Contest { 400 evide
O Con test /contests/999/ not found"} "message": "Contest n BA nce/C
N test doe join ot found" D ON-
- Inva s } RE [Link]
not n,
2 lid exis QU evide
3 ID t EST nce/C
ON-
[Link]
g
C Con Con 1. GET 200 OK, sorted { 200 evide
O test test /contests/:id/l leaderboard with ranks "contestId": 1, OK nce/C
N Lea fini eaderboard "leaderboard": [ ON-
- derb she { [Link]
2 oard d "userId": 2, n,
4 (Val wit "username": "sad evide
id) h ik", nce/C
part "points": 70, ON-
icip "rank": 1 [Link]
ants } g
]
}
C Con Con 1. GET 200 OK, leaderboard: [] { 200 evide
O test test /contests/:id/l "contestId": 4, OK nce/C
N Lea exis eaderboard "leaderboard": [] ON-
- derb ts, } [Link]
2 oard no n,
5 (Em part evide
pty) icip nce/C
ants ON-
[Link]
g
C Con Con 1. GET 404 {message:"Contest { TB scree
O test test /contests/999/ not found"} "message": "Contest n D nshot/
N Lea doe leaderboard ot found" CON-
- derb s } [Link]
2 oard not g
6 Inva exis
lid t
ID
C Part Con 1. GET 200 OK, { TB evide
O icip test /contests/:id/p {hasParticipated:true, "contestId": 1, D nce/C
N atio exis articipation/:u leaderboard:{…}} "userId": 2, ON-
- n ts, serId "username": "sadik", [Link]
2 Che user "hasParticipated": true n,
7 ck part , evide
(Val icip "leaderboard": { nce/C
id) ated "userId": 2, ON-
"username": "sadik" [Link]
, g
"points": 70,
"rank": 1
}
}
C Part Con 1. GET 200 OK, { 200 evide
O icip test /contests/:id/p {hasParticipated:false} "contestId": 4, OK nce/C
N atio exis articipation/:u "userId": 2, ON-
- n ts, serId "username": "sadik", [Link]
2 Che user "hasParticipated": fals n,
8 ck did e evide
(Us not } nce/C
er join ON-
Not [Link]
Part g
icip
ated
)
C Part Con 1. GET 400 {message:"Contest { 400 evide
O icip test /contests/:id/p leaderboard is not "message": "Contest le BA nce/C
N atio exis articipation/:u available yet"} aderboard is not availabl D ON-
- n ts serId e yet" RE [Link]
2 Che but } QU n,
9 ck lead EST evide
Lea erb nce/C
derb oar ON-
oard d [Link]
Not not g
Rea gen
dy erat
ed
C Part Con 1. GET 404 {message:"Contest {message:"Contest not 400 evide
O icip test /contests/999/ not found"} found"} BA nce/C
N atio doe participation/ D ON-
- n s 1 RE [Link]
3 Che not QU n,
0 ck exis EST evide
Inva t nce/C
lid ON-
Con [Link]
test g
C Part Con 1. GET 404 {message:"User not { 400 evide
O icip test /contests/:id/p found"} "message": "User not f BA nce/C
N atio exis articipation/9 ound" D ON-
- n ts, 99 } RE [Link]
3 Che user QU n,
1 ck Id EST evide
Inva not nce/C
lid fou ON-
Use nd [Link]
r g
TEST PLAN – PROBLEMS MODULE
Module: Problems
Endpoints: /problems, /problems/:id, /problems/:id (PUT), /problems/:id/submissions
Objective: Validate access to problem details, update operations, and retrieval of problem
submissions. Ensure correct filtering, sorting, and error handling.
1. Endpoint: GET /problems
Aspect Details
Description Retrieves list of problems from past contests. Supports sorting.
HTTP Method GET
URL /problems
Headers None
Body Parameters None
Query Parameters sortBy (string, optional), order (asc/desc, optional)
Preconditions At least one past contest and associated problems exist.
Expected Behavior
• 200 OK with array of problems: {id, name, category, difficulty, timelimit}
• Empty list if no past contest problems exist.
• If sortBy specified, list should be sorted accordingly.
Edge Cases / Notes
• Sorting by field not present (e.g., typo in sortBy) → fallback to no sorting.
• Empty database → return [] without error.
Example Test Cases:
1. Happy Path → GET /problems returns problems list.
2. Sorted Asc by difficulty → problems sorted ascending.
2. Endpoint: GET /problems/:id
Aspect Details
Description Retrieves details of a single problem.
HTTP Method GET
URL /problems/:id
Headers None
Body Parameters None
Preconditions Problem with given ID must exist.
Expected Behavior
• Valid ID: 200 OK, {id, name, description, input, output, category, difficulty, timelimit}
• Invalid ID: 404 {message:"Problem not found"}
Edge Cases / Notes |
• Non-numeric ID should return 404 (since parseInt fails).
• Access allowed for both guests and logged-in users.
Example Test Cases:
1. Happy Path → fetch valid problem.
2. Invalid ID → GET /problems/999, 404.
3. Endpoint: PUT /problems/:id
Aspect Details
Description Updates details of a problem.
HTTP Method PUT
URL /problems/:id
Headers Content-Type: application/json
Body Parameters Any subset of: name, description, input, output, category, difficulty, timelimit
Preconditions Problem must exist.
Expected Behavior
• Valid update: 200 OK with updated problem object.
• Invalid ID: 404 {message:"Problem not found"}
• Missing body fields: unchanged values retained.
Edge Cases / Notes |
• No authentication required (security gap).
• Empty body should return unchanged problem but still 200.
• Invalid data types not validated (e.g., difficulty: "hard" vs number).
Example Test Cases:
1. Update name and description only → values updated.
2. Invalid problem ID → 404.
3. Empty body {} → no changes, still 200.
4. Endpoint: GET /problems/:id/submissions
Aspect Details
Description Fetch all submissions made for a specific problem.
HTTP Method GET
URL /problems/:id/submissions
Headers None
Body Parameters None
Preconditions Problem must exist. Submissions may or may not exist.
Expected Behavior
• Valid problem with submissions: 200 OK, array of submissions {id, userId, contestId, verdict,
timestamp}
• Valid problem, no submissions: 200 OK, submissions: []
• Invalid problem ID: 404 {message:"Problem not found"}
Edge Cases / Notes |
• Users can view submissions of others (no auth required).
• Empty submission list should still return a valid JSON response.
Example Test Cases:
1. Valid problem with submissions → list returned.
2. Valid problem, no submissions → empty array.
Invalid problem ID → 404.
Test Cases – Problems Module
ID Title Pre- Steps Expecte Actual Result Sta Eviden
cond d Result tus ce
ition
s
PR Get At 1. Send GET 200 OK, [ 200 eviden
O All least /problems list of { OK ce/PR
B- Probl one problem "id": 2, OB-
01 ems past s {id, "name": "Maximum Subarr [Link]
(Hap conte name, ay", ,
py st category "category": "Dynamic Prog eviden
Path) with , ramming", ce/PR
probl difficult "difficulty": "Medium", OB-
ems y, "timelimit": "2s" [Link]
exist timelimi }
s t} ]
PR Get No 1. Send GET 200 OK, [] 200 eviden
O All conte /problems [] OK ce/PR
B- Probl sts (empty OB-
02 ems have list) [Link]
(No ende ,
Past d eviden
Conte ce/PR
sts) OB-
[Link]
PR Get At 1. Send GET 200 OK, [ 200 eviden
O All least /problems?sortBy problem { OK ce/PR
B- Probl two =difficulty&order s sorted "id": 3, OB-
03 ems probl =asc by "name": "Two Sum", [Link]
Sorte ems difficult "category": "Algorithms", ,
d Asc exist y "difficulty": "Easy", eviden
ascendin "timelimit": "1s" ce/PR
g }, OB-
{ [Link]
"id": 2,
"name": "Maximum Subarr
ay",
"category": "Dynamic Prog
ramming",
"difficulty": "Medium",
"timelimit": "2s"
}
]
PR Get At 1. Send GET 200 OK, [ 200 eviden
O All least /problems?sortBy problem { OK ce/PR
Probl two s sorted "id": 3, OB-
B- ems probl =difficulty&order by "name": "Two Sum", [Link]
04 Sorte ems =desc difficult "category": "Algorithms", ,
d exist y "difficulty": "Easy", eviden
Desc descendi "timelimit": "1s" ce/PR
ng }, OB-
{ [Link]
"id": 2,
"name": "Maximum Subarr
ay",
"category": "Dynamic Prog
ramming",
"difficulty": "Medium",
"timelimit": "2s"
}
]
PR Get Probl 1. Send GET 200 OK, {id, name, description, input, 200 eviden
O Probl em /problems/1 {id, output, category, difficulty, OK ce/PR
B- em with name, timelimit} OB-
05 by ID=1 descripti [Link]
Valid exist on, ,
ID s input, eviden
output, ce/PR
category OB-
, [Link]
difficult
y,
timelimi
t}
PR Get Probl 1. Send GET 404 { 400 eviden
O Probl em /problems/999 {messag "message": "Problem not fou NO ce/PR
B- em with e:"Probl nd" T OB-
06 by ID=9 em not } FO [Link]
Invali 99 found"} UN ,
d ID does D eviden
not ce/PR
exist OB-
[Link]
PR Get - 1. Send GET 404 { 400 eviden
O Probl /problems/abc {messag "message": "Problem not fou NO ce/PR
B- em e:"Probl nd" T OB-
07 by em not } FO [Link]
Non- found"} UN ,
nume D eviden
ric ID ce/PR
OB-
[Link]
PR Upda Probl 1. Send PUT 200 OK, { 200 eviden
O te em /problems/1 with updated "message": "Problem updated OK ce/PR
B- Probl with body problem successfully", OB-
08 em ID=1 {name:" "problem": { [Link]
(Hap exist {"name":"Update Updated "id": 1, ,
py s d Name"} Name"} "name": "Updated Name", eviden
Path) "description": "Find the co ce/PR
ntiguous subarray with the large OB-
st sum.", [Link]
"input": "n, array of integer
s",
"output": "maximum subar
ray sum",
"category": "Dynamic Prog
ramming",
"difficulty": "Medium",
"timelimit": "2s"
}
}
PR Upda - 1. Send PUT 404 { 404 eviden
O te /problems/999 {messag "message": "Problem not fou NO ce/PR
B- Probl with body e:"Probl nd" T OB-
09 em {"name":"Test"} em not } FO [Link]
(Inval found"} UN ,
id ID) D eviden
ce/PR
OB-
[Link]
PR Upda Probl 1. Send PUT 200 OK, { 200 eviden
O te em /problems/1 with problem "message": "Problem updated OK ce/PR
B- Probl with body {} unchang successfully", OB-
10 em ID=1 ed but "problem": { [Link]
(Emp exist returned "id": 1, ,
ty s "name": "Updated Name", eviden
Body "description": "Find the co ce/PR
) ntiguous subarray with the large OB-
st sum.", [Link]
"input": "n, array of integer
s",
"output": "maximum subar
ray sum",
"category": "Dynamic Prog
ramming",
"difficulty": "Medium",
"timelimit": "2s"
}
}
PR Upda Probl 1. Send PUT 200 OK, { TB eviden
O te em /problems/1 with accepts "message": "Problem updated D ce/PR
B- Probl with body but data successfully", OB-
11 em ID=1 {"difficulty":true} may be "problem": { [Link]
(Inval exist corrupte "id": 1, ,
id s d (no "name": "Updated Name", eviden
Data validatio ce/PR
n
Type impleme "description": "Find the co OB-
s) nted) ntiguous subarray with the large [Link]
st sum.",
"input": "n, array of integer
s",
"output": "maximum subar
ray sum",
"category": "Dynamic Prog
ramming",
"difficulty": true,
"timelimit": "2s"
}
}
PR Get At 1. Send GET 200 OK, { 200 eviden
O Subm least /problems/1/subm list of "problemId": 1, OK ce/PR
B- ission one issions submissi "submissions": [ OB-
12 s for subm ons {id, { [Link]
Probl issio userId, "id": 1, ,
em n contestI "userId": "alice", eviden
(With exist d, "verdict": "Accepted", ce/PR
Subm s for verdict, "timestamp": "2025-09- OB-
ission probl timesta 02T05:40:58.074Z" [Link]
s) em mp} },
ID=1 {
"id": 3,
"userId": "alice",
"verdict": "Accepted",
"timestamp": "2025-09-
02T05:47:46.867Z"
},
{
"id": 8,
"userId": "sadik",
"verdict": "Accepted",
"timestamp": "2025-09-
02T05:54:19.165Z"
}
]
}
PR Get Probl 1. Send GET 200 OK, { 200 eviden
O Subm em /problems/3/subm "submis "problemId": 3, OK ce/PR
B- ission ID=2 issions sions":[] "submissions": [] OB-
13 s for exist } [Link]
Probl s but ,
em no eviden
(No subm ce/PR
Subm issio OB-
ission ns [Link]
s)
PR Get Probl 1. Send GET 404 { 404 eviden
O Subm em /problems/999/sub {messag "message": "Problem not fou Not ce/PR
B- ission with missions e:"Probl nd" Fo OB-
14 s for ID=9 em not } und [Link]
Invali 99 found"} ,
d does eviden
Probl not ce/PR
em exist OB-
[Link]
TEST PLAN – SUBMISSION MODULE
Module: Submissions
Endpoints: /problems/:id/submit, /submissions, /submissions/:id
Objective: Ensure users can submit code to problems, view submissions, and enforce
access/authentication rules. Validate correct error handling, authorization, and contest constraints.
1. Endpoint: POST /problems/:id/submit
Aspect Details
Description Submit a solution (code) for a specific problem. Creates a submission record with
verdict, runtime, memory, and timestamp.
HTTP Method POST
URL /problems/:id/submit
Headers Content-Type: application/json, Authorization: Bearer <JWT>
Body Parameters code (string, required)
Preconditions - User logged in with valid JWT
- Problem exists
- Contest is not upcoming
- User must be a participant of the contest
Expected - Valid request: 201 Created, submission object with verdict, runtime, memory,
Behavior timestamp
- Missing code: 400 Bad Request
- Unauthorized (no/invalid token): 401 Unauthorized
- Contest upcoming: 400 Bad Request
- User not participant: 403 Forbidden
- Problem not found: 404 Not Found
Edge Cases / - Random verdict assignment in current system
Notes - Contest finished but user already participant → should still allow submissions?
(unclear behavior)
- Data consistency: [Link] vs code uses contestID (potential defect)
Example Test
Cases:
1.
Happy Path
Input: { "code": "print('Hello World')" } with valid JWT
Expected: 201, submission object {id, problemId, userId, verdict, runtime, memory, timestamp}
2. Missing Code
Input: {}
Expected: 400, { message: "Code is required" }
3. Unauthorized
Input: { "code": "print(123)" } without Authorization header
Expected: 401, { message: "Unauthorized" }
4. Contest Upcoming
Problem belongs to contest in future
Expected: 400, { message: "Contest is upcoming, submissions are not allowed yet" }
5. Not Participant
User not in [Link]
Expected: 403, { message: "You are not a participant in this contest" }
2. Endpoint: GET /submissions
Aspect Details
Description Retrieve all submissions with basic information. Supports filtering and sorting.
HTTP Method GET
URL /submissions
Headers None (public)
Body Parameters None
Preconditions At least one submission exists
Expected Behavior - Returns list of submissions {id, problemId, userId, contestId, verdict,
timestamp}
- Supports ?sortBy=field&order=asc/desc
Edge Cases / Notes - Exposes all users’ submissions (privacy concern)
- Sorting not fully validated (lexical comparison)
Example Test
Cases:
1. Get All Submissions
Input: GET /submissions
Expected: 200, array of submissions
3. Endpoint: GET /submissions/:id
Aspect Details
Description Retrieve details of a single submission. Only the user who submitted it can view.
HTTP Method GET
URL /submissions/:id
Headers Authorization: Bearer <JWT>
Body Parameters None
Preconditions Submission with given ID exists
Expected Behavior - If user is the owner: 200 OK, {id, problemId, userId, contestId, verdict,
runtime, memory, timestamp}
- If submission not found: 404 Not Found
- If user not owner: 403 Forbidden
- If no token: 401 Unauthorized
Edge Cases / Notes - JWT must map correctly to [Link] (bug risk: code uses username vs
id inconsistently)
- Expired token not handled
Example Test
Cases:
1. Valid Owner Access
Input: GET /submissions/1 with JWT of correct user
Expected: 200, submission details
2. Not Owner
Input: GET /submissions/1 with JWT of another user
Expected: 403, { message: "You are not authorized to view this submission" }
3. No Token
Input: No Authorization header
Expected: 401, { message: "Unauthorized" }
4. Submission Not Found
Input: GET /submissions/999
Expected: 404, { message: "Submission not found" }
Test Cases – Submissions Module
I Title Preco Steps Expected Actual Statu Evide
D nditio s nce
ns
S Sub User 1. POST 201 Created { 2001 evide
U mit alice /problems/1/submit json<br>{ Creat nce/S
B Solut regist 2. Headers: "message": "message": "Submission ed UB-
- ion – ered, Content-Type: "Submission successful", [Link]
0 Hap logge application/json, successful", "submission": { n,
1 py d in Authorization: "submission" evide
Path with Bearer <JWT> : { "id": "id": 1, nce/S
valid 3. Body: <id>, UB-
JWT. json<br>{ "code": "problemId": "problemId": 1, [Link]
Probl "print('Hello 1, "userId": g
"userId": "alice",
em 1 World')" }<br> <userId>,
exists "contestId": "verdict": "Accepted"
in a <contestId>, ,
past/o "verdict":
ngoin "Accepted/R "runtime": "287ms",
g ejected",
"memory": "46KB",
conte "runtime":
st "<X>ms", "timestamp": "2025-
where "memory": 09-02T05:40:58.074Z"
alice "<Y>KB",
is a "timestamp": }
partic "<ISO>" } }
}
ipant.
S Sub User 1. POST 400 Bad { 404 evide
U mit alice /problems/1/submit Request BAD nce/S
B With logge 2. Headers: json<br>{ "message": "Your reque REQ UB-
- out d in, Content-Type: "message": st must contain a code." UES [Link]
0 Code valid application/json, "Code is } T n,
2 JWT, Authorization: required" } evide
probl Bearer <JWT> nce/S
em 1 3. Body: UB-
exists json<br>{ }<br> [Link]
. g
S Sub Probl 1. POST 401 { 401 evide
U mit em 1 /problems/1/submit Unauthorize Unau nce/S
B With exists 2. Headers: d "message": "Unauthoriz thori UB-
- out . Content-Type: json<br>{ ed" zed [Link]
0 JWT application/json "message": } n,
3 3. Body: "Unauthorize evide
json<br>{ "code": d" } nce/S
"print(123)" }<br> UB-
[Link]
g
S Sub Probl 1. POST 400 Bad { 201 evide
U mit em 2 /problems/2/submit Request Creat nce/S
B to belon 2. Headers: json<br>{ "message": "Submission ed UB-
- Upc gs to Authorization: "message": successful", [Link]
0 omin conte Bearer <JWT> "Contest is n,
"submission": {
4 g st 3. Body: upcoming, evide
Cont with json<br>{ "code": submissions "id": 4, nce/S
est dateT "print('Future')" are not UB-
ime > }<br> allowed yet" "problemId": 2, [Link]
now. } g
"userId": "alice",
"verdict": "Accepted"
,
"runtime": "567ms",
"memory": "10KB",
"timestamp": "2025-
09-02T05:48:38.358Z"
}
}
S Sub Probl 1. POST 403 { 201 evide
U mit em 3 /problems/3/submit Forbidden Creat nce/S
B to belon 2. Headers: json<br>{ "message": "Submission ed UB-
- Cont gs to Authorization: "message": successful", [Link]
0 est conte Bearer <JWT> "You are not "submission": { n,
5 as st 3. Body: a participant evide
Non- where json<br>{ "code": in this "id": 8, nce/S
Parti alice "print('I should not contest" } UB-
cipa is not be here')" }<br> "problemId": 1, [Link]
nt a g
"userId": "sadik",
partic
ipant. "verdict": "Accepted"
,
"runtime": "245ms",
"memory": "2KB",
"timestamp": "2025-
09-02T05:54:19.165Z"
S Get At 1. GET 200 OK [ 200 evide
U All least /submissions json<br>[ { OK nce/S
B Sub one "id": <id>, { UB-
- missi submi "problemId": "id": 1, [Link]
0 ons ssion <pid>, n
6 exists "userId": "problemId": 1,
. <uid>,
"contestId": "userId": "alice",
<cid>,
"verdict": "Accepted"
"verdict":
,
"Accepted/R
ejected", "timestamp": "2025-
"timestamp": 09-02T05:40:58.074Z"
"<ISO>" },
... ] },
"id": 2,
"problemId": 2,
"userId": "alice",
"verdict": "Rejected",
"timestamp": "2025-
09-02T05:47:34.976Z"
S Get Multi 1. GET 200 OK [ 200 evide
U Sub ple /submissions?sortB Submissions OK nce/S
B missi submi y=timestamp&orde sorted in { UB-
- ons ssions r=desc reverse "id": 8, [Link]
0 Sorte exist. chronologica n
7 d by l order "problemId": 1,
Time
stam "userId": "sadik",
p
"verdict": "Accepted"
Desc
,
"timestamp": "2025-
09-02T05:54:19.165Z"
},
"id": 7,
"problemId": 2,
"userId": "sadik",
"verdict": "Accepted"
,
"timestamp": "2025-
09-02T05:54:13.598Z"
]
S Get Alice 1. GET 200 OK { 200 evide
U Singl has /submissions/1 json<br>{ OK nce/S
B e submi 2. Headers: "id": 1, "id": 1, UB-
- Sub ssion Authorization: "problemId": "problemId": 1, [Link]
0 missi 1. Bearer <Alice’s <pid>, n,
8 on – JWT> "userId": "userId": "alice", evide
Own <aliceId>, nce/S
er "contestId": "verdict": "Accepted", UB-
Acce <cid>, [Link]
"runtime": "287ms",
ss "verdict": g
"Accepted/R "memory": "46KB",
ejected",
"runtime": "timestamp": "2025-09-
"<X>ms", 02T05:40:58.074Z"
"memory":
}
"<Y>KB",
"timestamp":
"<ISO>" }
S Get Alice 1. GET 403 { 403 evide
U Singl has /submissions/1 Forbidden "message": "You are no Forbi nce/S
B e submi 2. Headers: json<br>{ t authorized to view this su dden UB-
- Sub ssion Authorization: "message": bmission" [Link]
0 missi 1. Bearer <Bob’s "You are not n
9 on – Bob JWT> authorized to }
Non- is view this
Own logge submission"
er d in }
Acce with
ss valid
JWT.
S Get Subm 1. GET 401 { 401 evide
U Singl ission /submissions/1 Unauthorize Unau nce/S
B e 1 without d "message": "No token p thori UB-
- Sub exists Authorization json<br>{ rovided" zed [Link]
1 missi . header message": " } n
0 on – No token pro
No vided"
Toke
n }
S Get Subm 1. GET 404 Not { 404 evide
U Singl ission /submissions/999 Found Not nce/S
B e 999 2. Headers: json<br>{ UB-
- Sub does Authorization: "message": "message": "Submission Foun [Link]
1 missi not Bearer <valid "Submission not found" d n
1 on – exist. JWT> not found" }
Not }
Foun
d
Defect Report
Authentication Defects
DEF-A01 – Weak Password Allowed
• Severity: Minor
• Steps to Reproduce:
1. Register user with empty/short password.
• Expected: Should reject weak or empty passwords with 400 error.
• Actual: User is created successfully.
DEF-A02 – Case Sensitivity in Usernames
• Severity: Minor
• Steps to Reproduce:
1. Register Alice.
2. Register alice.
• Expected: Duplicate check should be case-insensitive.
• Actual: Both accounts are created separately.
User Defects
DEF-U01 – Invalid Sort Field Not Handled
• Severity: Major
• Steps to Reproduce:
1. Call GET /users?sortBy=foo.
• Expected: API should return error or ignore invalid sort.
• Actual: Returns full list unsorted with 200 OK.
DEF-U02 – Update Non-Existing User Returns Wrong Error
• Severity: Major
• Steps to Reproduce:
1. Send PUT /users/999 with valid token.
• Expected: 404 User not found.
• Actual: Returns 403 with message “You can only update your own profile”.
DEF-U03 – User Submissions Not Returned
• Severity: Blocker
• Steps to Reproduce:
1. Submit a problem as user alice.
2. Call GET /users/1/submissions.
• Expected: Submissions list returned.
• Actual: Empty list because userId stored as string, not numeric.
DEF-U04 – Missing Authorization on User APIs
• Severity: Major
• Steps to Reproduce:
1. Call GET /users/1/contests without JWT.
• Expected: 401 Unauthorized.
• Actual: API allows access.
DEF-U05 – Inconsistent ID vs Username in Responses
• Severity: Minor
• Steps to Reproduce:
1. Call different user-related endpoints.
• Expected: All should consistently return id + username.
• Actual: Some APIs return only one field.
Contest Defects
DEF-C01 – Get Participants Not Available for Past Contest
• Severity: Major
• Steps to Reproduce:
1. Create contest, join with participants.
2. After contest ends, call GET /contests/:id/participants.
• Expected: Should list participants of past contests.
• Actual: Returns 400 with message “Contest has already ended”.
DEF-C02 – Join Contest Allows Midway Joining
• Severity: Major
• Steps to Reproduce:
1. Create contest with fixed start time.
2. Attempt join after start.
• Expected: Should reject late joins.
• Actual: API allows joining.
Problem Defects
DEF-P01 – Duplicate Route for /problems/:id
• Severity: Blocker
• Steps to Reproduce:
1. Call GET /problems/:id.
• Expected: One consistent response.
• Actual: Two handlers exist, Express routing order determines output.
DEF-P02 – Update Allowed Without Proper Authorization
• Severity: Major
• Steps to Reproduce:
1. PUT /problems/:id as any user.
• Expected: Only contest setter should update.
• Actual: Any logged-in user can update problem.
DEF-P03 – Sorting by Difficulty Incorrect
• Severity: Minor
• Steps to Reproduce:
1. GET /problems?sortBy=difficulty&order=desc.
• Expected: Problems sorted descending.
• Actual: Sorting inconsistent, ties and order mishandled.
Submission Defects
DEF-S01 – Contest ID Not Stored in Submission
• Severity: Blocker
• Steps to Reproduce:
1. Submit problem linked to contest.
• Expected: Submission contains contestId.
• Actual: Contest ID missing or undefined.
DEF-S02 – User ID/Username Mismatch in Submissions
• Severity: Blocker
• Steps to Reproduce:
1. Submit with JWT.
2. Fetch submission.
• Expected: Submissions linked consistently to numeric userId.
• Actual: Submissions store username, breaking ownership checks.
DEF-S03 – Submissions Accepted for Upcoming Contest
• Severity: Major
• Steps to Reproduce:
1. Create future contest and add problem.
2. Submit solution.
• Expected: 400 error, not allowed before start.
• Actual: Submission accepted with verdict.
DEF-S04 – Submissions Accepted for Non-Participant
• Severity: Major
• Steps to Reproduce:
1. Contest exists, user not joined.
2. Submit problem.
• Expected: 403 Forbidden.
• Actual: Submission accepted.
DEF-S05 – Unauthorized Access to Other User’s Submission
• Severity: Major
• Steps to Reproduce:
1. Submit as user A.
2. Fetch /submissions/:id as user B.
• Expected: 403 Forbidden.
• Actual: Access inconsistently allowed/denied due to ID mismatch.
General Defects
DEF-G01 – Inconsistent Date Fields
• Severity: Major
• Steps to Reproduce:
1. Create contests with date vs dateTime.
• Expected: One standard field for scheduling.
• Actual: Both exist, causing filter and logic errors.
DEF-G02 – Sorting Logic Generic Issues
• Severity: Minor
• Steps to Reproduce:
1. Use sortBy with invalid or unsupported fields.
• Expected: Error or safe ignore.
• Actual: API executes with unpredictable sorting.
Risk & Recommendations
Top Risks
1. Data Integrity & Inconsistent IDs
oSubmissions store usernames instead of user IDs, contests mix date and dateTime, and
sorting accepts invalid fields. This leads to broken relationships, empty responses, and
inconsistent behavior.
o Impact: High – breaks core functionality like submissions, leaderboards, and user
activity tracking.
2. Authorization & Access Control Gaps
o Users can attempt actions without proper checks (e.g., update problems not owned, view
other users’ submissions, join contests midway).
o Impact: High – security risk, unfair contest scenarios.
3. Incorrect Contest Logic
o Participants cannot be retrieved after contests end, submissions accepted in
future/unauthorized contests, and leaderboards rely on random scoring.
o Impact: High – undermines contest fairness and system credibility.
4. Error Handling & Validation Weaknesses
o APIs do not gracefully handle invalid input (e.g., wrong sort fields, weak passwords).
o Impact: Medium – reduces reliability and user trust.
Recommendations
1. Standardize Data Structures
oUse numeric userId consistently across submissions and contests.
oReplace mixed date/dateTime with a single ISO datetime format.
2. Strengthen Authorization
o Enforce ownership checks (users can only update their own profiles/problems).
o Validate JWT tokens strictly for all protected endpoints.
3. Fix Contest & Submission Logic
o Prevent submissions for future contests and non-participants.
o Allow retrieval of past contest participants.
o Implement leaderboard ranking based on actual submissions/verdicts.
4. Improve Error Handling
o Validate query parameters (e.g., sortBy) and return consistent error codes.
o Enforce minimum password rules during registration.
5. Testing & Hardening
o Add automated regression tests for sorting, authorization, and date-based logic.
o Consider migrating from in-memory storage to persistent DB for consistency.