0% found this document useful (0 votes)
3 views55 pages

Report

The document outlines a test plan for the Authentication and Users modules, detailing endpoints, objectives, expected behaviors, and example test cases. It covers user registration, login, profile access, and user information retrieval, ensuring secure handling of user data and error management. Each endpoint includes specific preconditions, expected outputs, and edge cases to validate functionality.

Uploaded by

fayjullah.h.emon
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views55 pages

Report

The document outlines a test plan for the Authentication and Users modules, detailing endpoints, objectives, expected behaviors, and example test cases. It covers user registration, login, profile access, and user information retrieval, ensuring secure handling of user data and error management. Each endpoint includes specific preconditions, expected outputs, and edge cases to validate functionality.

Uploaded by

fayjullah.h.emon
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

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.

You might also like