Show course progress as a percentage
Java · Spring Boot · beginner · modification
Adds `progressPercent` to every enrollment in `GET /api/me/enrollments`, so the course list can draw a progress bar instead of printing a lesson count. The calculation lives in a small `Progress.percent` helper: it rounds down, so 100% always means finished, and a course without lessons shows 0 instead of dividing by zero. Unit tests for the helper are included.
Online learning platform backend on Spring Boot 3.3 (Java 21), JSON through Jackson (each record component becomes a field). `EnrollmentController` (existing, unchanged) maps `GET /api/me/enrollments` to `EnrollmentService.forLearner` with the signed-in learner's id. `EnrollmentRepository.findProgressByLearner` (existing, unchanged, a JDBC query) returns one `EnrollmentProgress(courseId, courseTitle, completedLessons, totalLessons)` per enrollment, counting only published lessons. Nothing else constructs an `EnrollmentView`. Tests use JUnit 5 and AssertJ from `spring-boot-starter-test`.
Requirements
- `GET /api/me/enrollments` (existing) lists the signed-in learner's courses with `completedLessons` and `totalLessons`. Each entry gains `progressPercent`: the share of the course's lessons the learner has completed, as a whole number from 0 to 100, rounded down, so a course shows 100 only once every lesson is done (199 of 200 shows 99).
- A course with no lessons published yet has `totalLessons` 0 and shows `progressPercent` 0.
- Both counts come from `EnrollmentRepository` (existing, unchanged) and are whole numbers with 0 ≤ `completedLessons` ≤ `totalLessons` ≤ 500.
- The web app's course list starts reading `progressPercent` in a follow-up PR; this one adds the field and unit tests for the calculation.
Files touched
- src/main/java/com/acme/learn/enrollments/EnrollmentView.java
- src/main/java/com/acme/learn/enrollments/EnrollmentService.java
- src/main/java/com/acme/learn/enrollments/Progress.java
- src/test/java/com/acme/learn/enrollments/ProgressTest.java
--- src/main/java/com/acme/learn/enrollments/EnrollmentView.java
package com.acme.learn.enrollments;
-public record EnrollmentView(long courseId, String title, int completedLessons, int totalLessons) {
+public record EnrollmentView(long courseId, String title, int completedLessons, int totalLessons,
+ int progressPercent) {
}
--- src/main/java/com/acme/learn/enrollments/EnrollmentService.java
public List<EnrollmentView> forLearner(long learnerId) {
return enrollments.findProgressByLearner(learnerId).stream()
- .map(p -> new EnrollmentView(p.courseId(), p.courseTitle(), p.completedLessons(), p.totalLessons()))
+ .map(p -> new EnrollmentView(p.courseId(), p.courseTitle(), p.completedLessons(), p.totalLessons(),
+ Progress.percent(p.completedLessons(), p.totalLessons())))
.toList();
}
--- src/main/java/com/acme/learn/enrollments/Progress.java
+package com.acme.learn.enrollments;
+
+final class Progress {
+
+ private Progress() {
+ }
+
+ /** Share of the course's lessons the learner has completed, as a whole percent rounded down. */
+ static int percent(int completedLessons, int totalLessons) {
+ if (totalLessons == 0) {
+ return 0;
+ }
+ int percent = completedLessons / totalLessons * 100;