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
This commit is contained in:
parent
1531987da5
commit
a0b6decf34
2
.github/workflows/branchbuild.txt
vendored
2
.github/workflows/branchbuild.txt
vendored
@ -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 }}
|
||||
|
20
.github/workflows/build.yml
vendored
20
.github/workflows/build.yml
vendored
@ -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
|
||||
|
0
.github/workflows/semgrep.yml
vendored
0
.github/workflows/semgrep.yml
vendored
4
pom.xml
4
pom.xml
@ -669,10 +669,6 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>17</source>
|
||||
<target>17</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
@ -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<Object> {
|
||||
|
||||
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<Object> {
|
||||
}
|
||||
|
||||
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());
|
||||
|
@ -54,7 +54,7 @@ public class Assignment {
|
||||
|
||||
@Transient private List<String> hints;
|
||||
|
||||
private Assignment() {
|
||||
protected Assignment() {
|
||||
// Hibernate
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,3 @@
|
||||
package org.owasp.webgoat.container.report;
|
||||
|
||||
record LessonStatistics(String name, boolean solved, int numberOfAttempts) {}
|
@ -0,0 +1,93 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* <p>This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>Getting Source ==============
|
||||
*
|
||||
* <p>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> lessonStatistics) {}
|
||||
|
||||
private record LessonStatistics(String name, boolean solved, int numberOfAttempts) {}
|
||||
}
|
@ -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<String> excludeCategories;
|
||||
@ -77,7 +77,7 @@ public class LessonMenuService {
|
||||
public @ResponseBody List<LessonMenuItem> showLeftNav() {
|
||||
List<LessonMenuItem> menu = new ArrayList<>();
|
||||
List<Category> 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);
|
||||
|
@ -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();
|
||||
|
@ -1,105 +0,0 @@
|
||||
/**
|
||||
* *************************************************************************************************
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* <p>This file is part of WebGoat, an Open Web Application Security Project utility. For details,
|
||||
* please see http://www.owasp.org/
|
||||
*
|
||||
* <p>Copyright (c) 2002 - 2014 Bruce Mayhew
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>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.
|
||||
*
|
||||
* <p>Getting Source ==============
|
||||
*
|
||||
* <p>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> lessonStatistics = new ArrayList<>();
|
||||
}
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
private final class LessonStatistics {
|
||||
private String name;
|
||||
private boolean solved;
|
||||
private int numberOfAttempts;
|
||||
}
|
||||
}
|
@ -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<String, Flyway> flywayLessons;
|
||||
private final List<Initializeable> 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);
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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<String> challengesSolved(UserTracker userTracker) {
|
||||
private List<String> challengesSolved(UserProgress userTracker) {
|
||||
List<String> 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();
|
||||
}
|
||||
|
@ -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<LessonTracker> lessonTrackers = new HashSet<>();
|
||||
private Set<LessonProgress> 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> 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<LessonProgress> 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<LessonTracker> getLessonTracker(String id) {
|
||||
return lessonTrackers.stream().filter(l -> l.getLessonName().equals(id)).findFirst();
|
||||
public Optional<LessonProgress> 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<Assignment, Boolean> 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();
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
||||
* @author nbaars
|
||||
* @since 4/30/17.
|
||||
*/
|
||||
public interface UserTrackerRepository extends JpaRepository<UserTracker, String> {
|
||||
public interface UserProgressRepository extends JpaRepository<UserProgress, String> {
|
||||
|
||||
UserTracker findByUser(String user);
|
||||
UserProgress findByUser(String user);
|
||||
}
|
@ -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<String, Flyway> flywayLessons;
|
||||
private final List<Initializeable> 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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
22
src/main/resources/db/container/V4__rename_to_progress.sql
Normal file
22
src/main/resources/db/container/V4__rename_to_progress.sql
Normal file
@ -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;
|
@ -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'
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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")))
|
@ -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
|
||||
|
@ -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 =
|
||||
|
@ -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<Assignment> assignments = List.of(a1, a2);
|
||||
when(lesson.getAssignments()).thenReturn(assignments);
|
||||
LessonTracker lessonTracker = new LessonTracker(lesson);
|
||||
LessonProgress lessonTracker = new LessonProgress(lesson);
|
||||
lessonTracker.assignmentSolved("a1");
|
||||
|
||||
Map<Assignment, Boolean> lessonOverview = lessonTracker.getLessonOverview();
|
||||
@ -76,7 +76,7 @@ class LessonTrackerTest {
|
||||
Assignment a1 = new Assignment("a1");
|
||||
List<Assignment> 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");
|
||||
|
||||
|
@ -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<String, Flyway> flywayLessons;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user