From a0b6decf34a282dad1cbd0d4886764ce7bd4c6a0 Mon Sep 17 00:00:00 2001 From: Nanne Baars Date: Tue, 9 Jul 2024 20:07:09 +0200 Subject: [PATCH] Fix report card (#1845) * fix: report card Fix and simplify calculation of the number of assignments a user solved. Rename `UserTracker` to `UserProgress` Rename `LessonTracker` to `LessonProgress` Rename tables in database --- .github/workflows/branchbuild.txt | 2 +- .github/workflows/build.yml | 20 +--- .github/workflows/semgrep.yml | 0 pom.xml | 4 - .../assignments/LessonTrackerInterceptor.java | 12 +- .../webgoat/container/lessons/Assignment.java | 2 +- .../container/report/LessonStatistics.java | 3 + .../report/ReportCardController.java | 93 ++++++++++++++++ .../container/service/LessonMenuService.java | 12 +- .../service/LessonProgressService.java | 6 +- .../container/service/ReportCardService.java | 105 ------------------ .../service/RestartLessonService.java | 8 +- ...LessonTracker.java => LessonProgress.java} | 10 +- .../webgoat/container/users/Scoreboard.java | 10 +- .../{UserTracker.java => UserProgress.java} | 66 +++++------ ...itory.java => UserProgressRepository.java} | 4 +- .../webgoat/container/users/UserService.java | 4 +- .../owasp/webgoat/lessons/csrf/CSRFLogin.java | 10 +- .../db/container/V4__rename_to_progress.sql | 22 ++++ .../js/goatApp/controller/LessonController.js | 6 +- .../assignments/AssignmentEndpointTest.java | 8 +- .../ReportCardControllerTest.java} | 22 ++-- .../service/LessonMenuServiceTest.java | 16 +-- .../service/LessonProgressServiceTest.java | 14 +-- .../container/session/LessonTrackerTest.java | 8 +- .../container/users/UserServiceTest.java | 2 +- .../users/UserTrackerRepositoryTest.java | 16 +-- 27 files changed, 237 insertions(+), 248 deletions(-) delete mode 100644 .github/workflows/semgrep.yml create mode 100644 src/main/java/org/owasp/webgoat/container/report/LessonStatistics.java create mode 100644 src/main/java/org/owasp/webgoat/container/report/ReportCardController.java delete mode 100644 src/main/java/org/owasp/webgoat/container/service/ReportCardService.java rename src/main/java/org/owasp/webgoat/container/users/{LessonTracker.java => LessonProgress.java} (95%) rename src/main/java/org/owasp/webgoat/container/users/{UserTracker.java => UserProgress.java} (61%) rename src/main/java/org/owasp/webgoat/container/users/{UserTrackerRepository.java => UserProgressRepository.java} (55%) create mode 100644 src/main/resources/db/container/V4__rename_to_progress.sql rename src/test/java/org/owasp/webgoat/container/{service/ReportCardServiceTest.java => report/ReportCardControllerTest.java} (77%) diff --git a/.github/workflows/branchbuild.txt b/.github/workflows/branchbuild.txt index 2062b9471..95a45a1f0 100644 --- a/.github/workflows/branchbuild.txt +++ b/.github/workflows/branchbuild.txt @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ ubuntu-latest, windows-latest, macos-latest ] - java-version: [ 17, 21 ] + java-version: [ 21 ] steps: - uses: actions/checkout@v4 - name: Set up JDK ${{ matrix.java-version }} diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 14e286ef3..1bf2ff5f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,7 +5,7 @@ on: - '.txt' - 'LICENSE' - 'docs/**' - branches: [main] + branches: [ main ] push: branches: - main @@ -14,8 +14,10 @@ jobs: build: runs-on: ${{ matrix.os }} strategy: + fail-fast: true matrix: - os: [ ubuntu-latest, windows-latest, macos-latest ] + os: [ windows-latest, ubuntu-latest, macos-13 ] + max-parallel: 1 steps: - uses: actions/checkout@v4.1.6 - name: Set up JDK 21 @@ -31,16 +33,4 @@ jobs: key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} restore-keys: ${{ runner.os }}-m2- - name: Build with Maven - run: | - if [ "$RUNNER_OS" == "macOS" ]; then - # Make "localhost" DNS entry available; see https://github.com/actions/runner-images/issues/6383 - # sudo networksetup -setdnsservers Ethernet 9.9.9.9 - echo -e "$(ipconfig getifaddr en0) $(hostname -f) $(hostname -s)" | sudo tee -a /etc/hosts - echo `sudo lsof -PiTCP -sTCP:LISTEN` - cat /etc/hosts - mvn --no-transfer-progress verify -DskipTests -DwaittimeForServerStart=150 - # skip tests on macos, takes too long with the current runners - else - mvn --no-transfer-progress verify -DwaittimeForServerStart=30 - fi - shell: bash + run: mvn --no-transfer-progress verify diff --git a/.github/workflows/semgrep.yml b/.github/workflows/semgrep.yml deleted file mode 100644 index e69de29bb..000000000 diff --git a/pom.xml b/pom.xml index 6919246d0..4160698fe 100644 --- a/pom.xml +++ b/pom.xml @@ -669,10 +669,6 @@ org.apache.maven.plugins maven-compiler-plugin - - 17 - 17 - diff --git a/src/main/java/org/owasp/webgoat/container/assignments/LessonTrackerInterceptor.java b/src/main/java/org/owasp/webgoat/container/assignments/LessonTrackerInterceptor.java index aa3cd40ce..b6407ed1a 100644 --- a/src/main/java/org/owasp/webgoat/container/assignments/LessonTrackerInterceptor.java +++ b/src/main/java/org/owasp/webgoat/container/assignments/LessonTrackerInterceptor.java @@ -23,8 +23,8 @@ package org.owasp.webgoat.container.assignments; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; @@ -36,11 +36,11 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @RestControllerAdvice public class LessonTrackerInterceptor implements ResponseBodyAdvice { - private UserTrackerRepository userTrackerRepository; + private UserProgressRepository userTrackerRepository; private WebSession webSession; public LessonTrackerInterceptor( - UserTrackerRepository userTrackerRepository, WebSession webSession) { + UserProgressRepository userTrackerRepository, WebSession webSession) { this.userTrackerRepository = userTrackerRepository; this.webSession = webSession; } @@ -66,9 +66,9 @@ public class LessonTrackerInterceptor implements ResponseBodyAdvice { } protected AttackResult trackProgress(AttackResult attackResult) { - UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); + UserProgress userTracker = userTrackerRepository.findByUser(webSession.getUserName()); if (userTracker == null) { - userTracker = new UserTracker(webSession.getUserName()); + userTracker = new UserProgress(webSession.getUserName()); } if (attackResult.assignmentSolved()) { userTracker.assignmentSolved(webSession.getCurrentLesson(), attackResult.getAssignment()); diff --git a/src/main/java/org/owasp/webgoat/container/lessons/Assignment.java b/src/main/java/org/owasp/webgoat/container/lessons/Assignment.java index 3c3c89d6d..3563a537e 100644 --- a/src/main/java/org/owasp/webgoat/container/lessons/Assignment.java +++ b/src/main/java/org/owasp/webgoat/container/lessons/Assignment.java @@ -54,7 +54,7 @@ public class Assignment { @Transient private List hints; - private Assignment() { + protected Assignment() { // Hibernate } diff --git a/src/main/java/org/owasp/webgoat/container/report/LessonStatistics.java b/src/main/java/org/owasp/webgoat/container/report/LessonStatistics.java new file mode 100644 index 000000000..055aaaaae --- /dev/null +++ b/src/main/java/org/owasp/webgoat/container/report/LessonStatistics.java @@ -0,0 +1,3 @@ +package org.owasp.webgoat.container.report; + +record LessonStatistics(String name, boolean solved, int numberOfAttempts) {} diff --git a/src/main/java/org/owasp/webgoat/container/report/ReportCardController.java b/src/main/java/org/owasp/webgoat/container/report/ReportCardController.java new file mode 100644 index 000000000..dc9d271de --- /dev/null +++ b/src/main/java/org/owasp/webgoat/container/report/ReportCardController.java @@ -0,0 +1,93 @@ +/** + * ************************************************************************************************* + * + *

+ * + *

This file is part of WebGoat, an Open Web Application Security Project utility. For details, + * please see http://www.owasp.org/ + * + *

Copyright (c) 2002 - 2014 Bruce Mayhew + * + *

This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + *

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + *

You should have received a copy of the GNU General Public License along with this program; if + * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + * + *

Getting Source ============== + * + *

Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository + * for free software projects. + */ +package org.owasp.webgoat.container.report; + +import java.util.List; +import org.owasp.webgoat.container.i18n.PluginMessages; +import org.owasp.webgoat.container.session.Course; +import org.owasp.webgoat.container.session.WebSession; +import org.owasp.webgoat.container.users.UserProgressRepository; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class ReportCardController { + + private final WebSession webSession; + private final UserProgressRepository userProgressRepository; + private final Course course; + private final PluginMessages pluginMessages; + + public ReportCardController( + WebSession webSession, + UserProgressRepository userProgressRepository, + Course course, + PluginMessages pluginMessages) { + this.webSession = webSession; + this.userProgressRepository = userProgressRepository; + this.course = course; + this.pluginMessages = pluginMessages; + } + + /** + * Endpoint which generates the report card for the current use to show the stats on the solved + * lessons + */ + @GetMapping(path = "/service/reportcard.mvc", produces = "application/json") + @ResponseBody + public ReportCard reportCard() { + var userProgress = userProgressRepository.findByUser(webSession.getUserName()); + var lessonStatistics = + course.getLessons().stream() + .map( + lesson -> { + var lessonTracker = userProgress.getLessonProgress(lesson); + return new LessonStatistics( + pluginMessages.getMessage(lesson.getTitle()), + lessonTracker.isLessonSolved(), + lessonTracker.getNumberOfAttempts()); + }) + .toList(); + return new ReportCard( + course.getTotalOfLessons(), + course.getTotalOfAssignments(), + userProgress.numberOfAssignmentsSolved(), + userProgress.numberOfLessonsSolved(), + lessonStatistics); + } + + private record ReportCard( + int totalNumberOfLessons, + int totalNumberOfAssignments, + long numberOfAssignmentsSolved, + long numberOfLessonsSolved, + List lessonStatistics) {} + + private record LessonStatistics(String name, boolean solved, int numberOfAttempts) {} +} diff --git a/src/main/java/org/owasp/webgoat/container/service/LessonMenuService.java b/src/main/java/org/owasp/webgoat/container/service/LessonMenuService.java index 961e10d47..76e42abf8 100644 --- a/src/main/java/org/owasp/webgoat/container/service/LessonMenuService.java +++ b/src/main/java/org/owasp/webgoat/container/service/LessonMenuService.java @@ -39,9 +39,9 @@ import org.owasp.webgoat.container.lessons.LessonMenuItem; import org.owasp.webgoat.container.lessons.LessonMenuItemType; import org.owasp.webgoat.container.session.Course; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.LessonTracker; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.LessonProgress; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -60,7 +60,7 @@ public class LessonMenuService { public static final String URL_LESSONMENU_MVC = "/service/lessonmenu.mvc"; private final Course course; private final WebSession webSession; - private UserTrackerRepository userTrackerRepository; + private UserProgressRepository userTrackerRepository; @Value("#{'${exclude.categories}'.split(',')}") private List excludeCategories; @@ -77,7 +77,7 @@ public class LessonMenuService { public @ResponseBody List showLeftNav() { List menu = new ArrayList<>(); List categories = course.getCategories(); - UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); + UserProgress userTracker = userTrackerRepository.findByUser(webSession.getUserName()); for (Category category : categories) { if (excludeCategories.contains(category.name())) { @@ -97,7 +97,7 @@ public class LessonMenuService { lessonItem.setName(lesson.getTitle()); lessonItem.setLink(lesson.getLink()); lessonItem.setType(LessonMenuItemType.LESSON); - LessonTracker lessonTracker = userTracker.getLessonTracker(lesson); + LessonProgress lessonTracker = userTracker.getLessonProgress(lesson); boolean lessonSolved = lessonCompleted(lessonTracker.getLessonOverview(), lesson); lessonItem.setComplete(lessonSolved); categoryItem.addChild(lessonItem); diff --git a/src/main/java/org/owasp/webgoat/container/service/LessonProgressService.java b/src/main/java/org/owasp/webgoat/container/service/LessonProgressService.java index 23fc38da5..5629ab215 100644 --- a/src/main/java/org/owasp/webgoat/container/service/LessonProgressService.java +++ b/src/main/java/org/owasp/webgoat/container/service/LessonProgressService.java @@ -6,7 +6,7 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import org.owasp.webgoat.container.lessons.Assignment; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @@ -20,7 +20,7 @@ import org.springframework.web.bind.annotation.ResponseBody; @RequiredArgsConstructor public class LessonProgressService { - private final UserTrackerRepository userTrackerRepository; + private final UserProgressRepository userTrackerRepository; private final WebSession webSession; /** @@ -36,7 +36,7 @@ public class LessonProgressService { var currentLesson = webSession.getCurrentLesson(); if (currentLesson != null) { - var lessonTracker = userTracker.getLessonTracker(currentLesson); + var lessonTracker = userTracker.getLessonProgress(currentLesson); return lessonTracker.getLessonOverview().entrySet().stream() .map(entry -> new LessonOverview(entry.getKey(), entry.getValue())) .toList(); diff --git a/src/main/java/org/owasp/webgoat/container/service/ReportCardService.java b/src/main/java/org/owasp/webgoat/container/service/ReportCardService.java deleted file mode 100644 index a01bce5c1..000000000 --- a/src/main/java/org/owasp/webgoat/container/service/ReportCardService.java +++ /dev/null @@ -1,105 +0,0 @@ -/** - * ************************************************************************************************* - * - *

- * - *

This file is part of WebGoat, an Open Web Application Security Project utility. For details, - * please see http://www.owasp.org/ - * - *

Copyright (c) 2002 - 2014 Bruce Mayhew - * - *

This program is free software; you can redistribute it and/or modify it under the terms of the - * GNU General Public License as published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - *

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; - * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - *

You should have received a copy of the GNU General Public License along with this program; if - * not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. - * - *

Getting Source ============== - * - *

Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository - * for free software projects. - */ -package org.owasp.webgoat.container.service; - -import java.util.ArrayList; -import java.util.List; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.Setter; -import org.owasp.webgoat.container.i18n.PluginMessages; -import org.owasp.webgoat.container.lessons.Lesson; -import org.owasp.webgoat.container.session.Course; -import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.LessonTracker; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * ReportCardService - * - * @author nbaars - * @version $Id: $Id - */ -@Controller -@AllArgsConstructor -public class ReportCardService { - - private final WebSession webSession; - private final UserTrackerRepository userTrackerRepository; - private final Course course; - private final PluginMessages pluginMessages; - - /** - * Endpoint which generates the report card for the current use to show the stats on the solved - * lessons - */ - @GetMapping(path = "/service/reportcard.mvc", produces = "application/json") - @ResponseBody - public ReportCard reportCard() { - final ReportCard reportCard = new ReportCard(); - reportCard.setTotalNumberOfLessons(course.getTotalOfLessons()); - reportCard.setTotalNumberOfAssignments(course.getTotalOfAssignments()); - - UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); - reportCard.setNumberOfAssignmentsSolved(userTracker.numberOfAssignmentsSolved()); - reportCard.setNumberOfLessonsSolved(userTracker.numberOfLessonsSolved()); - for (Lesson lesson : course.getLessons()) { - LessonTracker lessonTracker = userTracker.getLessonTracker(lesson); - final LessonStatistics lessonStatistics = new LessonStatistics(); - lessonStatistics.setName(pluginMessages.getMessage(lesson.getTitle())); - lessonStatistics.setNumberOfAttempts(lessonTracker.getNumberOfAttempts()); - lessonStatistics.setSolved(lessonTracker.isLessonSolved()); - reportCard.lessonStatistics.add(lessonStatistics); - } - return reportCard; - } - - @Getter - @Setter - private final class ReportCard { - - private int totalNumberOfLessons; - private int totalNumberOfAssignments; - private int solvedLessons; - private int numberOfAssignmentsSolved; - private int numberOfLessonsSolved; - private List lessonStatistics = new ArrayList<>(); - } - - @Setter - @Getter - private final class LessonStatistics { - private String name; - private boolean solved; - private int numberOfAttempts; - } -} diff --git a/src/main/java/org/owasp/webgoat/container/service/RestartLessonService.java b/src/main/java/org/owasp/webgoat/container/service/RestartLessonService.java index 2f0450d9e..5cf604c50 100644 --- a/src/main/java/org/owasp/webgoat/container/service/RestartLessonService.java +++ b/src/main/java/org/owasp/webgoat/container/service/RestartLessonService.java @@ -32,8 +32,8 @@ import org.flywaydb.core.Flyway; import org.owasp.webgoat.container.lessons.Initializeable; import org.owasp.webgoat.container.lessons.Lesson; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -45,7 +45,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; public class RestartLessonService { private final WebSession webSession; - private final UserTrackerRepository userTrackerRepository; + private final UserProgressRepository userTrackerRepository; private final Function flywayLessons; private final List lessonsToInitialize; @@ -55,7 +55,7 @@ public class RestartLessonService { Lesson al = webSession.getCurrentLesson(); log.debug("Restarting lesson: " + al); - UserTracker userTracker = userTrackerRepository.findByUser(webSession.getUserName()); + UserProgress userTracker = userTrackerRepository.findByUser(webSession.getUserName()); userTracker.reset(al); userTrackerRepository.save(userTracker); diff --git a/src/main/java/org/owasp/webgoat/container/users/LessonTracker.java b/src/main/java/org/owasp/webgoat/container/users/LessonProgress.java similarity index 95% rename from src/main/java/org/owasp/webgoat/container/users/LessonTracker.java rename to src/main/java/org/owasp/webgoat/container/users/LessonProgress.java index fd9af4dcf..e5d177795 100644 --- a/src/main/java/org/owasp/webgoat/container/users/LessonTracker.java +++ b/src/main/java/org/owasp/webgoat/container/users/LessonProgress.java @@ -52,7 +52,7 @@ import org.owasp.webgoat.container.lessons.Lesson; */ @Entity @EqualsAndHashCode -public class LessonTracker { +public class LessonProgress { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -69,11 +69,11 @@ public class LessonTracker { @Getter private int numberOfAttempts = 0; @Version private Integer version; - private LessonTracker() { + protected LessonProgress() { // JPA } - public LessonTracker(Lesson lesson) { + public LessonProgress(Lesson lesson) { lessonName = lesson.getId(); allAssignments.addAll(lesson.getAssignments() == null ? List.of() : lesson.getAssignments()); } @@ -119,4 +119,8 @@ public class LessonTracker { overview.putAll(solvedAssignments.stream().collect(Collectors.toMap(a -> a, b -> true))); return overview; } + + long numberOfSolvedAssignments() { + return solvedAssignments.size(); + } } diff --git a/src/main/java/org/owasp/webgoat/container/users/Scoreboard.java b/src/main/java/org/owasp/webgoat/container/users/Scoreboard.java index 3d94b056b..9a2a0d077 100644 --- a/src/main/java/org/owasp/webgoat/container/users/Scoreboard.java +++ b/src/main/java/org/owasp/webgoat/container/users/Scoreboard.java @@ -21,7 +21,7 @@ import org.springframework.web.bind.annotation.RestController; @AllArgsConstructor public class Scoreboard { - private final UserTrackerRepository userTrackerRepository; + private final UserProgressRepository userTrackerRepository; private final UserRepository userRepository; private final Course course; private final PluginMessages pluginMessages; @@ -46,7 +46,7 @@ public class Scoreboard { .collect(Collectors.toList()); } - private List challengesSolved(UserTracker userTracker) { + private List challengesSolved(UserProgress userTracker) { List challenges = List.of( "Challenge1", @@ -59,10 +59,10 @@ public class Scoreboard { "Challenge8", "Challenge9"); return challenges.stream() - .map(userTracker::getLessonTracker) + .map(userTracker::getLessonProgress) .flatMap(Optional::stream) - .filter(LessonTracker::isLessonSolved) - .map(LessonTracker::getLessonName) + .filter(LessonProgress::isLessonSolved) + .map(LessonProgress::getLessonName) .map(this::toLessonTitle) .toList(); } diff --git a/src/main/java/org/owasp/webgoat/container/users/UserTracker.java b/src/main/java/org/owasp/webgoat/container/users/UserProgress.java similarity index 61% rename from src/main/java/org/owasp/webgoat/container/users/UserTracker.java rename to src/main/java/org/owasp/webgoat/container/users/UserProgress.java index 72450f69e..f81d6d042 100644 --- a/src/main/java/org/owasp/webgoat/container/users/UserTracker.java +++ b/src/main/java/org/owasp/webgoat/container/users/UserProgress.java @@ -9,13 +9,10 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; import java.util.HashSet; -import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.stream.Collectors; import lombok.EqualsAndHashCode; import lombok.extern.slf4j.Slf4j; -import org.owasp.webgoat.container.lessons.Assignment; import org.owasp.webgoat.container.lessons.Lesson; /** @@ -52,7 +49,7 @@ import org.owasp.webgoat.container.lessons.Lesson; @Slf4j @Entity @EqualsAndHashCode -public class UserTracker { +public class UserProgress { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -62,11 +59,11 @@ public class UserTracker { private String user; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) - private Set lessonTrackers = new HashSet<>(); + private Set lessonProgress = new HashSet<>(); - private UserTracker() {} + protected UserProgress() {} - public UserTracker(final String user) { + public UserProgress(final String user) { this.user = user; } @@ -76,15 +73,15 @@ public class UserTracker { * @param lesson the lesson * @return a lesson tracker created if not already present */ - public LessonTracker getLessonTracker(Lesson lesson) { - Optional lessonTracker = - lessonTrackers.stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst(); - if (!lessonTracker.isPresent()) { - LessonTracker newLessonTracker = new LessonTracker(lesson); - lessonTrackers.add(newLessonTracker); + public LessonProgress getLessonProgress(Lesson lesson) { + Optional progress = + lessonProgress.stream().filter(l -> l.getLessonName().equals(lesson.getId())).findFirst(); + if (!progress.isPresent()) { + LessonProgress newLessonTracker = new LessonProgress(lesson); + lessonProgress.add(newLessonTracker); return newLessonTracker; } else { - return lessonTracker.get(); + return progress.get(); } } @@ -94,43 +91,34 @@ public class UserTracker { * @param id the id of the lesson * @return optional due to the fact we can only create a lesson tracker based on a lesson */ - public Optional getLessonTracker(String id) { - return lessonTrackers.stream().filter(l -> l.getLessonName().equals(id)).findFirst(); + public Optional getLessonProgress(String id) { + return lessonProgress.stream().filter(l -> l.getLessonName().equals(id)).findFirst(); } public void assignmentSolved(Lesson lesson, String assignmentName) { - LessonTracker lessonTracker = getLessonTracker(lesson); - lessonTracker.incrementAttempts(); - lessonTracker.assignmentSolved(assignmentName); + LessonProgress progress = getLessonProgress(lesson); + progress.incrementAttempts(); + progress.assignmentSolved(assignmentName); } public void assignmentFailed(Lesson lesson) { - LessonTracker lessonTracker = getLessonTracker(lesson); - lessonTracker.incrementAttempts(); + LessonProgress progress = getLessonProgress(lesson); + progress.incrementAttempts(); } public void reset(Lesson al) { - LessonTracker lessonTracker = getLessonTracker(al); - lessonTracker.reset(); + LessonProgress progress = getLessonProgress(al); + progress.reset(); } - public int numberOfLessonsSolved() { - int numberOfLessonsSolved = 0; - for (LessonTracker lessonTracker : lessonTrackers) { - if (lessonTracker.isLessonSolved()) { - numberOfLessonsSolved = numberOfLessonsSolved + 1; - } - } - return numberOfLessonsSolved; + public long numberOfLessonsSolved() { + return lessonProgress.stream().filter(LessonProgress::isLessonSolved).count(); } - public int numberOfAssignmentsSolved() { - int numberOfAssignmentsSolved = 0; - for (LessonTracker lessonTracker : lessonTrackers) { - Map lessonOverview = lessonTracker.getLessonOverview(); - numberOfAssignmentsSolved = - lessonOverview.values().stream().filter(b -> b).collect(Collectors.counting()).intValue(); - } - return numberOfAssignmentsSolved; + public long numberOfAssignmentsSolved() { + return lessonProgress.stream() + .map(LessonProgress::numberOfSolvedAssignments) + .mapToLong(Long::valueOf) + .sum(); } } diff --git a/src/main/java/org/owasp/webgoat/container/users/UserTrackerRepository.java b/src/main/java/org/owasp/webgoat/container/users/UserProgressRepository.java similarity index 55% rename from src/main/java/org/owasp/webgoat/container/users/UserTrackerRepository.java rename to src/main/java/org/owasp/webgoat/container/users/UserProgressRepository.java index 154360c3e..61c1ead5f 100644 --- a/src/main/java/org/owasp/webgoat/container/users/UserTrackerRepository.java +++ b/src/main/java/org/owasp/webgoat/container/users/UserProgressRepository.java @@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository; * @author nbaars * @since 4/30/17. */ -public interface UserTrackerRepository extends JpaRepository { +public interface UserProgressRepository extends JpaRepository { - UserTracker findByUser(String user); + UserProgress findByUser(String user); } diff --git a/src/main/java/org/owasp/webgoat/container/users/UserService.java b/src/main/java/org/owasp/webgoat/container/users/UserService.java index e12668f00..9e1971206 100644 --- a/src/main/java/org/owasp/webgoat/container/users/UserService.java +++ b/src/main/java/org/owasp/webgoat/container/users/UserService.java @@ -19,7 +19,7 @@ import org.springframework.stereotype.Service; public class UserService implements UserDetailsService { private final UserRepository userRepository; - private final UserTrackerRepository userTrackerRepository; + private final UserProgressRepository userTrackerRepository; private final JdbcTemplate jdbcTemplate; private final Function flywayLessons; private final List lessonInitializables; @@ -43,7 +43,7 @@ public class UserService implements UserDetailsService { if (!userAlreadyExists) { userTrackerRepository.save( - new UserTracker(username)); // if user previously existed it will not get another tracker + new UserProgress(username)); // if user previously existed it will not get another tracker createLessonsForUser(webGoatUser); } } diff --git a/src/main/java/org/owasp/webgoat/lessons/csrf/CSRFLogin.java b/src/main/java/org/owasp/webgoat/lessons/csrf/CSRFLogin.java index e41409457..ebf49de63 100644 --- a/src/main/java/org/owasp/webgoat/lessons/csrf/CSRFLogin.java +++ b/src/main/java/org/owasp/webgoat/lessons/csrf/CSRFLogin.java @@ -26,8 +26,8 @@ import jakarta.servlet.http.HttpServletRequest; import org.owasp.webgoat.container.assignments.AssignmentEndpoint; import org.owasp.webgoat.container.assignments.AssignmentHints; import org.owasp.webgoat.container.assignments.AttackResult; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @@ -40,9 +40,9 @@ import org.springframework.web.bind.annotation.RestController; @AssignmentHints({"csrf-login-hint1", "csrf-login-hint2", "csrf-login-hint3"}) public class CSRFLogin extends AssignmentEndpoint { - private final UserTrackerRepository userTrackerRepository; + private final UserProgressRepository userTrackerRepository; - public CSRFLogin(UserTrackerRepository userTrackerRepository) { + public CSRFLogin(UserProgressRepository userTrackerRepository) { this.userTrackerRepository = userTrackerRepository; } @@ -60,7 +60,7 @@ public class CSRFLogin extends AssignmentEndpoint { } private void markAssignmentSolvedWithRealUser(String username) { - UserTracker userTracker = userTrackerRepository.findByUser(username); + UserProgress userTracker = userTrackerRepository.findByUser(username); userTracker.assignmentSolved( getWebSession().getCurrentLesson(), this.getClass().getSimpleName()); userTrackerRepository.save(userTracker); diff --git a/src/main/resources/db/container/V4__rename_to_progress.sql b/src/main/resources/db/container/V4__rename_to_progress.sql new file mode 100644 index 000000000..d5213c454 --- /dev/null +++ b/src/main/resources/db/container/V4__rename_to_progress.sql @@ -0,0 +1,22 @@ +ALTER TABLE container.lesson_tracker + RENAME TO container.lesson_progress; + +ALTER TABLE container.lesson_tracker_all_assignments + ALTER COLUMN lesson_tracker_id RENAME TO lesson_progress_id; +ALTER TABLE container.lesson_tracker_all_assignments + RENAME TO container.lesson_progress_all_assignments; + +ALTER TABLE container.lesson_tracker_solved_assignments + ALTER COLUMN lesson_tracker_id RENAME TO lesson_progress_id; +ALTER TABLE container.lesson_tracker_solved_assignments + RENAME TO container.lesson_progress_solved_assignments; + +ALTER TABLE container.user_tracker + RENAME TO container.user_progress; + +ALTER TABLE container.user_tracker_lesson_trackers + ALTER COLUMN user_tracker_id RENAME TO user_progress_id; +ALTER TABLE container.user_tracker_lesson_trackers + ALTER COLUMN lesson_trackers_id RENAME TO lesson_progress_id; +ALTER TABLE container.user_tracker_lesson_trackers + RENAME TO container.user_progress_lesson_progress; diff --git a/src/main/resources/webgoat/static/js/goatApp/controller/LessonController.js b/src/main/resources/webgoat/static/js/goatApp/controller/LessonController.js index 39976e061..d4c0301ac 100644 --- a/src/main/resources/webgoat/static/js/goatApp/controller/LessonController.js +++ b/src/main/resources/webgoat/static/js/goatApp/controller/LessonController.js @@ -8,8 +8,7 @@ define(['jquery', 'goatApp/support/GoatUtils', 'goatApp/view/UserAndInfoView', 'goatApp/view/MenuButtonView', - 'goatApp/model/LessonInfoModel', - 'goatApp/view/TitleView' + 'goatApp/model/LessonInfoModel' ], function($, _, @@ -21,8 +20,7 @@ define(['jquery', GoatUtils, UserAndInfoView, MenuButtonView, - LessonInfoModel, - TitleView + LessonInfoModel ) { 'use strict' diff --git a/src/test/java/org/owasp/webgoat/container/assignments/AssignmentEndpointTest.java b/src/test/java/org/owasp/webgoat/container/assignments/AssignmentEndpointTest.java index 258919d81..5fb7c6cec 100644 --- a/src/test/java/org/owasp/webgoat/container/assignments/AssignmentEndpointTest.java +++ b/src/test/java/org/owasp/webgoat/container/assignments/AssignmentEndpointTest.java @@ -32,8 +32,8 @@ import org.owasp.webgoat.container.i18n.Messages; import org.owasp.webgoat.container.i18n.PluginMessages; import org.owasp.webgoat.container.session.UserSessionData; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.servlet.i18n.FixedLocaleResolver; @@ -41,8 +41,8 @@ import org.springframework.web.servlet.i18n.FixedLocaleResolver; // Do not remove is the base class for all assignments tests public class AssignmentEndpointTest { - @Mock protected UserTracker userTracker; - @Mock protected UserTrackerRepository userTrackerRepository; + @Mock protected UserProgress userTracker; + @Mock protected UserProgressRepository userTrackerRepository; @Mock protected WebSession webSession; @Mock protected UserSessionData userSessionData; diff --git a/src/test/java/org/owasp/webgoat/container/service/ReportCardServiceTest.java b/src/test/java/org/owasp/webgoat/container/report/ReportCardControllerTest.java similarity index 77% rename from src/test/java/org/owasp/webgoat/container/service/ReportCardServiceTest.java rename to src/test/java/org/owasp/webgoat/container/report/ReportCardControllerTest.java index 3df0efb76..4807987a5 100644 --- a/src/test/java/org/owasp/webgoat/container/service/ReportCardServiceTest.java +++ b/src/test/java/org/owasp/webgoat/container/report/ReportCardControllerTest.java @@ -1,4 +1,4 @@ -package org.owasp.webgoat.container.service; +package org.owasp.webgoat.container.report; import static org.hamcrest.CoreMatchers.is; import static org.mockito.ArgumentMatchers.any; @@ -18,22 +18,23 @@ import org.owasp.webgoat.container.i18n.PluginMessages; import org.owasp.webgoat.container.lessons.Lesson; import org.owasp.webgoat.container.session.Course; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.LessonTracker; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.LessonProgress; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @ExtendWith(MockitoExtension.class) -public class ReportCardServiceTest { +// TODO: Rewrite this as end-to-end test this mocks too many classes +public class ReportCardControllerTest { private MockMvc mockMvc; @Mock private Course course; - @Mock private UserTracker userTracker; + @Mock private UserProgress userTracker; @Mock private Lesson lesson; - @Mock private LessonTracker lessonTracker; - @Mock private UserTrackerRepository userTrackerRepository; + @Mock private LessonProgress lessonTracker; + @Mock private UserProgressRepository userTrackerRepository; @Mock private WebSession websession; @Mock private PluginMessages pluginMessages; @@ -41,7 +42,7 @@ public class ReportCardServiceTest { void setup() { this.mockMvc = standaloneSetup( - new ReportCardService(websession, userTrackerRepository, course, pluginMessages)) + new ReportCardController(websession, userTrackerRepository, course, pluginMessages)) .build(); when(pluginMessages.getMessage(anyString())).thenReturn("Test"); } @@ -54,12 +55,11 @@ public class ReportCardServiceTest { when(course.getTotalOfAssignments()).thenReturn(10); when(course.getLessons()).thenAnswer(x -> List.of(lesson)); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker); - when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker); + when(userTracker.getLessonProgress(any(Lesson.class))).thenReturn(lessonTracker); mockMvc .perform(MockMvcRequestBuilders.get("/service/reportcard.mvc")) .andExpect(status().isOk()) .andExpect(jsonPath("$.totalNumberOfLessons", is(1))) - .andExpect(jsonPath("$.solvedLessons", is(0))) .andExpect(jsonPath("$.numberOfAssignmentsSolved", is(0))) .andExpect(jsonPath("$.totalNumberOfAssignments", is(10))) .andExpect(jsonPath("$.lessonStatistics[0].name", is("Test"))) diff --git a/src/test/java/org/owasp/webgoat/container/service/LessonMenuServiceTest.java b/src/test/java/org/owasp/webgoat/container/service/LessonMenuServiceTest.java index 388b3081e..6462df5e8 100644 --- a/src/test/java/org/owasp/webgoat/container/service/LessonMenuServiceTest.java +++ b/src/test/java/org/owasp/webgoat/container/service/LessonMenuServiceTest.java @@ -41,9 +41,9 @@ import org.owasp.webgoat.container.lessons.Category; import org.owasp.webgoat.container.lessons.Lesson; import org.owasp.webgoat.container.session.Course; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.LessonTracker; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.LessonProgress; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -51,11 +51,11 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; public class LessonMenuServiceTest { @Mock(lenient = true) - private LessonTracker lessonTracker; + private LessonProgress lessonTracker; @Mock private Course course; - @Mock private UserTracker userTracker; - @Mock private UserTrackerRepository userTrackerRepository; + @Mock private UserProgress userTracker; + @Mock private UserProgressRepository userTrackerRepository; @Mock private WebSession webSession; private MockMvc mockMvc; @@ -81,7 +81,7 @@ public class LessonMenuServiceTest { when(lessonTracker.isLessonSolved()).thenReturn(false); when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1, l2)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.A1)); - when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker); + when(userTracker.getLessonProgress(any(Lesson.class))).thenReturn(lessonTracker); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker); mockMvc @@ -98,7 +98,7 @@ public class LessonMenuServiceTest { when(lessonTracker.isLessonSolved()).thenReturn(true); when(course.getLessons(any())).thenReturn(Lists.newArrayList(l1)); when(course.getCategories()).thenReturn(Lists.newArrayList(Category.A1)); - when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker); + when(userTracker.getLessonProgress(any(Lesson.class))).thenReturn(lessonTracker); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker); mockMvc diff --git a/src/test/java/org/owasp/webgoat/container/service/LessonProgressServiceTest.java b/src/test/java/org/owasp/webgoat/container/service/LessonProgressServiceTest.java index 25043330a..0bfe6c89b 100644 --- a/src/test/java/org/owasp/webgoat/container/service/LessonProgressServiceTest.java +++ b/src/test/java/org/owasp/webgoat/container/service/LessonProgressServiceTest.java @@ -16,9 +16,9 @@ import org.mockito.junit.jupiter.MockitoExtension; import org.owasp.webgoat.container.lessons.Assignment; import org.owasp.webgoat.container.lessons.Lesson; import org.owasp.webgoat.container.session.WebSession; -import org.owasp.webgoat.container.users.LessonTracker; -import org.owasp.webgoat.container.users.UserTracker; -import org.owasp.webgoat.container.users.UserTrackerRepository; +import org.owasp.webgoat.container.users.LessonProgress; +import org.owasp.webgoat.container.users.UserProgress; +import org.owasp.webgoat.container.users.UserProgressRepository; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; @@ -60,16 +60,16 @@ class LessonProgressServiceTest { private MockMvc mockMvc; @Mock private Lesson lesson; - @Mock private UserTracker userTracker; - @Mock private LessonTracker lessonTracker; - @Mock private UserTrackerRepository userTrackerRepository; + @Mock private UserProgress userTracker; + @Mock private LessonProgress lessonTracker; + @Mock private UserProgressRepository userTrackerRepository; @Mock private WebSession websession; @BeforeEach void setup() { Assignment assignment = new Assignment("test", "test", List.of()); when(userTrackerRepository.findByUser(any())).thenReturn(userTracker); - when(userTracker.getLessonTracker(any(Lesson.class))).thenReturn(lessonTracker); + when(userTracker.getLessonProgress(any(Lesson.class))).thenReturn(lessonTracker); when(websession.getCurrentLesson()).thenReturn(lesson); when(lessonTracker.getLessonOverview()).thenReturn(Maps.newHashMap(assignment, true)); this.mockMvc = diff --git a/src/test/java/org/owasp/webgoat/container/session/LessonTrackerTest.java b/src/test/java/org/owasp/webgoat/container/session/LessonTrackerTest.java index 033b136e8..876244f4c 100644 --- a/src/test/java/org/owasp/webgoat/container/session/LessonTrackerTest.java +++ b/src/test/java/org/owasp/webgoat/container/session/LessonTrackerTest.java @@ -10,7 +10,7 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.owasp.webgoat.container.lessons.Assignment; import org.owasp.webgoat.container.lessons.Lesson; -import org.owasp.webgoat.container.users.LessonTracker; +import org.owasp.webgoat.container.users.LessonProgress; /** * ************************************************************************************************ @@ -49,7 +49,7 @@ class LessonTrackerTest { Lesson lesson = mock(Lesson.class); when(lesson.getAssignments()) .thenReturn(List.of(new Assignment("assignment", "assignment", List.of("")))); - LessonTracker lessonTracker = new LessonTracker(lesson); + LessonProgress lessonTracker = new LessonProgress(lesson); lessonTracker.assignmentSolved("assignment"); Assertions.assertThat(lessonTracker.isLessonSolved()).isTrue(); @@ -62,7 +62,7 @@ class LessonTrackerTest { Assignment a2 = new Assignment("a2"); List assignments = List.of(a1, a2); when(lesson.getAssignments()).thenReturn(assignments); - LessonTracker lessonTracker = new LessonTracker(lesson); + LessonProgress lessonTracker = new LessonProgress(lesson); lessonTracker.assignmentSolved("a1"); Map lessonOverview = lessonTracker.getLessonOverview(); @@ -76,7 +76,7 @@ class LessonTrackerTest { Assignment a1 = new Assignment("a1"); List assignments = List.of(a1); when(lesson.getAssignments()).thenReturn(assignments); - LessonTracker lessonTracker = new LessonTracker(lesson); + LessonProgress lessonTracker = new LessonProgress(lesson); lessonTracker.assignmentSolved("a1"); lessonTracker.assignmentSolved("a1"); diff --git a/src/test/java/org/owasp/webgoat/container/users/UserServiceTest.java b/src/test/java/org/owasp/webgoat/container/users/UserServiceTest.java index 1bcef2496..90ca2b64e 100644 --- a/src/test/java/org/owasp/webgoat/container/users/UserServiceTest.java +++ b/src/test/java/org/owasp/webgoat/container/users/UserServiceTest.java @@ -18,7 +18,7 @@ import org.springframework.security.core.userdetails.UsernameNotFoundException; class UserServiceTest { @Mock private UserRepository userRepository; - @Mock private UserTrackerRepository userTrackerRepository; + @Mock private UserProgressRepository userTrackerRepository; @Mock private JdbcTemplate jdbcTemplate; @Mock private Function flywayLessons; diff --git a/src/test/java/org/owasp/webgoat/container/users/UserTrackerRepositoryTest.java b/src/test/java/org/owasp/webgoat/container/users/UserTrackerRepositoryTest.java index fd341a865..53cd9dd2e 100644 --- a/src/test/java/org/owasp/webgoat/container/users/UserTrackerRepositoryTest.java +++ b/src/test/java/org/owasp/webgoat/container/users/UserTrackerRepositoryTest.java @@ -34,23 +34,23 @@ class UserTrackerRepositoryTest { } } - @Autowired private UserTrackerRepository userTrackerRepository; + @Autowired private UserProgressRepository userTrackerRepository; @Test void saveUserTracker() { - UserTracker userTracker = new UserTracker("test"); + UserProgress userTracker = new UserProgress("test"); userTrackerRepository.save(userTracker); userTracker = userTrackerRepository.findByUser("test"); - Assertions.assertThat(userTracker.getLessonTracker("test")).isNotNull(); + Assertions.assertThat(userTracker.getLessonProgress("test")).isNotNull(); } @Test void solvedAssignmentsShouldBeSaved() { - UserTracker userTracker = new UserTracker("test"); + UserProgress userTracker = new UserProgress("test"); TestLesson lesson = new TestLesson(); - userTracker.getLessonTracker(lesson); + userTracker.getLessonProgress(lesson); userTracker.assignmentFailed(lesson); userTracker.assignmentFailed(lesson); userTracker.assignmentSolved(lesson, "test"); @@ -63,9 +63,9 @@ class UserTrackerRepositoryTest { @Test void saveAndLoadShouldHaveCorrectNumberOfAttempts() { - UserTracker userTracker = new UserTracker("test"); + UserProgress userTracker = new UserProgress("test"); TestLesson lesson = new TestLesson(); - userTracker.getLessonTracker(lesson); + userTracker.getLessonProgress(lesson); userTracker.assignmentFailed(lesson); userTracker.assignmentFailed(lesson); userTrackerRepository.saveAndFlush(userTracker); @@ -75,6 +75,6 @@ class UserTrackerRepositoryTest { userTracker.assignmentFailed(lesson); userTrackerRepository.saveAndFlush(userTracker); - Assertions.assertThat(userTracker.getLessonTracker(lesson).getNumberOfAttempts()).isEqualTo(4); + Assertions.assertThat(userTracker.getLessonProgress(lesson).getNumberOfAttempts()).isEqualTo(4); } }