Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions scripts/api_smoke_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#!/usr/bin/env python3
import os
import sys
from http import cookiejar
from urllib import request, parse

BASE_URL = os.getenv("BASE_URL", "http://localhost:8585")
UID = os.getenv("UID", "toby")
PASSWORD = os.getenv("PASSWORD", "Admin14*&*41")

COOKIE_JAR = cookiejar.CookieJar()
OPENER = request.build_opener(request.HTTPCookieProcessor(COOKIE_JAR))


def http_request(method, url, data=None, headers=None):
if headers is None:
headers = {}
req_data = None
if data is not None:
req_data = data.encode("utf-8")
req = request.Request(url, data=req_data, headers=headers, method=method)
try:
with OPENER.open(req) as resp:
return resp.status, resp.read(), resp.headers
except Exception as exc:
if hasattr(exc, "code"):
return exc.code, b"", getattr(exc, "headers", {})
raise


def print_status(label, method, path, json_body=None):
url = f"{BASE_URL}{path}"
headers = {}
data = None
if json_body is not None:
headers["Content-Type"] = "application/json"
data = json_body
status, body, resp_headers = http_request(method, url, data=data, headers=headers)
location = resp_headers.get("Location") if hasattr(resp_headers, "get") else None
if location:
print(f"{label} -> {status} (Location: {location})")
else:
print(f"{label} -> {status}")
if status >= 400 and body:
try:
text = body.decode("utf-8", errors="replace")
except Exception:
text = "<non-text body>"
print(" Error body:", text[:500])
return status, body


def dump_cookies():
if not COOKIE_JAR:
print("Cookies: <none>")
return
print("Cookies:")
for cookie in COOKIE_JAR:
print(f" {cookie.name}={cookie.value}; path={cookie.path}; secure={cookie.secure}")


def main():
print("== Authenticate (JWT cookie) ==")
auth_body = '{"uid":"%s","password":"%s"}' % (UID, PASSWORD)
status, body = print_status("POST /authenticate", "POST", "/authenticate", json_body=auth_body)
if body:
try:
print("Auth response:", body.decode("utf-8"))
except Exception:
print("Auth response: <non-text body>")
dump_cookies()

print("\n== Person APIs (auth required) ==")
print_status("GET /api/person/get", "GET", "/api/person/get")
print_status("GET /api/people", "GET", "/api/people")

print("\n== Admin-only check ==")
print_status("DELETE /api/person/6", "DELETE", "/api/person/6")

print("\n== Analytics (auth required) ==")
print_status("GET /api/analytics/", "GET", "/api/analytics/")

print("\n== Code Runner (auth required) ==")
print_status("GET /api/challenge-submission/my-submissions", "GET", "/api/challenge-submission/my-submissions")

print("\n== Tinkle (auth required) ==")
print_status("GET /api/tinkle/all", "GET", "/api/tinkle/all")

print("\n== Export/Import (admin only) ==")
print_status("GET /api/exports/getAll", "GET", "/api/exports/getAll")
print_status("GET /api/imports/backups", "GET", "/api/imports/backups")

print("\nDone.")


if __name__ == "__main__":
try:
main()
except Exception as exc:
print(f"Error: {exc}", file=sys.stderr)
sys.exit(1)
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,75 @@ public class AnalyticsApiController {
// Get all analytics records
// Get all analytics records
@GetMapping("/")
public ResponseEntity<List<SynergyGrade>> getAllAnalytics() {
public ResponseEntity<List<AnalyticsGradeDto>> getAllAnalytics() {
List<SynergyGrade> gradeList = gradeJpaRepository.findAll(); // Fetch all grade records from database
if (gradeList.isEmpty()) {
return new ResponseEntity<>(HttpStatus.NO_CONTENT); // No records found
}
return new ResponseEntity<>(gradeList, HttpStatus.OK); // Return found records

List<AnalyticsGradeDto> dtoList = new ArrayList<>();
for (SynergyGrade grade : gradeList) {
dtoList.add(AnalyticsGradeDto.from(grade));
}

return new ResponseEntity<>(dtoList, HttpStatus.OK); // Return found records
}

public static class AnalyticsGradeDto {
private Long id;
private Double grade;
private Long assignmentId;
private String assignmentName;
private Long studentId;
private String studentUid;
private String studentName;

public static AnalyticsGradeDto from(SynergyGrade grade) {
AnalyticsGradeDto dto = new AnalyticsGradeDto();
if (grade == null) {
return dto;
}
dto.id = grade.getId();
dto.grade = grade.getGrade();
if (grade.getAssignment() != null) {
dto.assignmentId = grade.getAssignment().getId();
dto.assignmentName = grade.getAssignment().getName();
}
if (grade.getStudent() != null) {
dto.studentId = grade.getStudent().getId();
dto.studentUid = grade.getStudent().getUid();
dto.studentName = grade.getStudent().getName();
}
return dto;
}

public Long getId() {
return id;
}

public Double getGrade() {
return grade;
}

public Long getAssignmentId() {
return assignmentId;
}

public String getAssignmentName() {
return assignmentName;
}

public Long getStudentId() {
return studentId;
}

public String getStudentUid() {
return studentUid;
}

public String getStudentName() {
return studentName;
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ public class Assignment {


@OneToMany(mappedBy="assignment", cascade=CascadeType.ALL, orphanRemoval=true)
@JsonIgnore
private List<SynergyGrade> grades;

@NotNull
Expand Down
62 changes: 36 additions & 26 deletions src/main/java/com/open/spring/mvc/person/Person.java
Original file line number Diff line number Diff line change
Expand Up @@ -326,41 +326,43 @@ public int compareTo(Person other) {
public static Person[] init() {
ArrayList<Person> people = new ArrayList<>();
final Dotenv dotenv = Dotenv.load();

String defaultPassword = envOrDefault(dotenv, "DEFAULT_PASSWORD", "defaultPassword123");

// JSON-like list of person data using Map.ofEntries
List<Map<String, Object>> personData = Arrays.asList(
// Admin user from .env
Map.ofEntries(
Map.entry("name", dotenv.get("ADMIN_NAME")),
Map.entry("uid", dotenv.get("ADMIN_UID")),
Map.entry("email", dotenv.get("ADMIN_EMAIL")),
Map.entry("password", dotenv.get("ADMIN_PASSWORD")),
Map.entry("sid", dotenv.get("ADMIN_SID")),
Map.entry("pfp", dotenv.get("ADMIN_PFP")),
Map.entry("name", envOrDefault(dotenv, "ADMIN_NAME", "Admin User")),
Map.entry("uid", envOrDefault(dotenv, "ADMIN_UID", "admin")),
Map.entry("email", envOrDefault(dotenv, "ADMIN_EMAIL", "admin@example.com")),
Map.entry("password", envOrDefault(dotenv, "ADMIN_PASSWORD", defaultPassword)),
Map.entry("sid", envOrDefault(dotenv, "ADMIN_SID", "9999990")),
Map.entry("pfp", envOrDefault(dotenv, "ADMIN_PFP", "/images/default.png")),
Map.entry("kasmServerNeeded", false),
Map.entry("roles", Arrays.asList("ROLE_USER", "ROLE_STUDENT", "ROLE_TEACHER", "ROLE_ADMIN")),
Map.entry("stocks", "BTC,ETH")
),
// Teacher user from .env
Map.ofEntries(
Map.entry("name", dotenv.get("TEACHER_NAME")),
Map.entry("uid", dotenv.get("TEACHER_UID")),
Map.entry("email", dotenv.get("TEACHER_EMAIL")),
Map.entry("password", dotenv.get("TEACHER_PASSWORD")),
Map.entry("sid", dotenv.get("TEACHER_SID")),
Map.entry("pfp", dotenv.get("TEACHER_PFP")),
Map.entry("name", envOrDefault(dotenv, "TEACHER_NAME", "Teacher User")),
Map.entry("uid", envOrDefault(dotenv, "TEACHER_UID", "teacher")),
Map.entry("email", envOrDefault(dotenv, "TEACHER_EMAIL", "teacher@example.com")),
Map.entry("password", envOrDefault(dotenv, "TEACHER_PASSWORD", defaultPassword)),
Map.entry("sid", envOrDefault(dotenv, "TEACHER_SID", "9999998")),
Map.entry("pfp", envOrDefault(dotenv, "TEACHER_PFP", "/images/default.png")),
Map.entry("kasmServerNeeded", true),
Map.entry("roles", Arrays.asList("ROLE_USER", "ROLE_TEACHER")),
Map.entry("stocks", "BTC,ETH")
),
// Default user from .env
Map.ofEntries(
Map.entry("name", dotenv.get("USER_NAME")),
Map.entry("uid", dotenv.get("USER_UID")),
Map.entry("email", dotenv.get("USER_EMAIL")),
Map.entry("password", dotenv.get("USER_PASSWORD")),
Map.entry("sid", dotenv.get("USER_SID")),
Map.entry("pfp", dotenv.get("USER_PFP")),
Map.entry("name", envOrDefault(dotenv, "USER_NAME", "Default User")),
Map.entry("uid", envOrDefault(dotenv, "USER_UID", "user")),
Map.entry("email", envOrDefault(dotenv, "USER_EMAIL", "user@example.com")),
Map.entry("password", envOrDefault(dotenv, "USER_PASSWORD", defaultPassword)),
Map.entry("sid", envOrDefault(dotenv, "USER_SID", "9999999")),
Map.entry("pfp", envOrDefault(dotenv, "USER_PFP", "/images/default.png")),
Map.entry("kasmServerNeeded", true),
Map.entry("roles", Arrays.asList("ROLE_USER", "ROLE_STUDENT")),
Map.entry("stocks", "BTC,ETH")
Expand All @@ -370,7 +372,7 @@ public static Person[] init() {
Map.entry("name", "Alexander Graham Bell"),
Map.entry("uid", "lex"),
Map.entry("email", "lexb@gmail.com"),
Map.entry("password", dotenv.get("DEFAULT_PASSWORD")),
Map.entry("password", defaultPassword),
Map.entry("sid", "9999991"),
Map.entry("pfp", "/images/lex.png"),
Map.entry("kasmServerNeeded", false),
Expand All @@ -382,7 +384,7 @@ public static Person[] init() {
Map.entry("name", "Madam Curie"),
Map.entry("uid", "madam"),
Map.entry("email", "madam@gmail.com"),
Map.entry("password", dotenv.get("DEFAULT_PASSWORD")),
Map.entry("password", defaultPassword),
Map.entry("sid", "9999992"),
Map.entry("pfp", "/images/madam.png"),
Map.entry("kasmServerNeeded", false),
Expand All @@ -391,11 +393,11 @@ public static Person[] init() {
),
// My user - from .env
Map.ofEntries(
Map.entry("name", dotenv.get("MY_NAME")),
Map.entry("uid", dotenv.get("MY_UID")),
Map.entry("email", dotenv.get("MY_EMAIL")),
Map.entry("password", dotenv.get("DEFAULT_PASSWORD")),
Map.entry("sid", dotenv.get("MY_SID") != null ? dotenv.get("MY_SID") : "9999993"),
Map.entry("name", envOrDefault(dotenv, "MY_NAME", "My User")),
Map.entry("uid", envOrDefault(dotenv, "MY_UID", "myuser")),
Map.entry("email", envOrDefault(dotenv, "MY_EMAIL", "myuser@example.com")),
Map.entry("password", defaultPassword),
Map.entry("sid", envOrDefault(dotenv, "MY_SID", "9999993")),
Map.entry("pfp", "/images/default.png"),
Map.entry("kasmServerNeeded", true),
Map.entry("roles", Arrays.asList("ROLE_USER", "ROLE_STUDENT", "ROLE_TEACHER", "ROLE_ADMIN")),
Expand All @@ -406,7 +408,7 @@ public static Person[] init() {
Map.entry("name", "Alan Turing"),
Map.entry("uid", "alan"),
Map.entry("email", "turing@gmail.com"),
Map.entry("password", dotenv.get("DEFAULT_PASSWORD")),
Map.entry("password", defaultPassword),
Map.entry("sid", "9999994"),
Map.entry("pfp", "/images/alan.png"),
Map.entry("kasmServerNeeded", false),
Expand Down Expand Up @@ -450,6 +452,14 @@ public static Person[] init() {
return people.toArray(new Person[0]);
}

private static String envOrDefault(Dotenv dotenv, String key, String defaultValue) {
String value = dotenv.get(key);
if (value == null || value.isBlank()) {
return defaultValue;
}
return value;
}


//////////////////////////////////////////////////////////////////////////////////
/// override toString() method
Expand Down
Loading