/* * This file is part of ARSnova Backend. * Copyright (C) 2012-2017 The ARSnova Team * * ARSnova Backend 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 3 of the License, or * (at your option) any later version. * * ARSnova Backend 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, see <http://www.gnu.org/licenses/>. */ package de.thm.arsnova.domain; import de.thm.arsnova.dao.IDatabaseDao; import de.thm.arsnova.entities.TestUser; import de.thm.arsnova.entities.User; import de.thm.arsnova.entities.transport.LearningProgressValues; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; public class PointBasedLearningProgressTest { private CourseScore courseScore; private VariantLearningProgress lp; private int id = 1; private String addQuestion(String questionVariant, int points) { final String questionId = "question" + (id++); final int piRound = 1; courseScore.addQuestion(questionId, questionVariant, piRound, points); return questionId; } private void addAnswer(String questionId, User user, int points) { final int piRound = 1; courseScore.addAnswer(questionId, piRound, user.getUsername(), points); } @Before public void setUp() { this.courseScore = new CourseScore(); IDatabaseDao db = mock(IDatabaseDao.class); when(db.getLearningProgress(null)).thenReturn(courseScore); this.lp = new PointBasedLearningProgress(db); } @Test public void shouldFilterBasedOnQuestionVariant() { String q1 = this.addQuestion("lecture", 100); String q2 = this.addQuestion("preparation", 100); User u1 = new TestUser("user1"); User u2 = new TestUser("user2"); // first question is answered correctly, second one is not this.addAnswer(q1, u1, 100); this.addAnswer(q1, u2, 100); this.addAnswer(q2, u1, 0); this.addAnswer(q2, u2, 0); lp.setQuestionVariant("lecture"); LearningProgressValues lectureProgress = lp.getCourseProgress(null); LearningProgressValues myLectureProgress = lp.getMyProgress(null, u1); lp.setQuestionVariant("preparation"); LearningProgressValues prepProgress = lp.getCourseProgress(null); LearningProgressValues myPrepProgress = lp.getMyProgress(null, u1); assertEquals(100, lectureProgress.getCourseProgress()); assertEquals(100, myLectureProgress.getMyProgress()); assertEquals(0, prepProgress.getCourseProgress()); assertEquals(0, myPrepProgress.getMyProgress()); } @Test public void shouldNotContainRoundingErrors() { // Total of 300 Points String q1 = this.addQuestion("lecture", 100); String q2 = this.addQuestion("lecture", 100); String q3 = this.addQuestion("lecture", 100); User u1 = new TestUser("user1"); User u2 = new TestUser("user2"); // Both users achieve 200 points this.addAnswer(q1, u1, 100); this.addAnswer(q1, u2, 100); this.addAnswer(q2, u1, 0); this.addAnswer(q2, u2, 0); this.addAnswer(q3, u1, 100); this.addAnswer(q3, u2, 100); lp.setQuestionVariant("lecture"); LearningProgressValues u1LectureProgress = lp.getMyProgress(null, u1); // 200 / 300 = 0,67 assertEquals(67, u1LectureProgress.getCourseProgress()); assertEquals(67, u1LectureProgress.getMyProgress()); } @Test public void shouldConsiderAnswersOfSamePiRound() { User u1 = new TestUser("user1"); User u2 = new TestUser("user2"); // question is in round 2 courseScore.addQuestion("q1", "lecture", 2, 100); // 25 points in round 1, 75 points in round two for the first user courseScore.addAnswer("q1", 1, u1.getUsername(), 25); courseScore.addAnswer("q1", 2, u1.getUsername(), 75); // 75 points in round 1, 25 points in round two for the second user courseScore.addAnswer("q1", 1, u2.getUsername(), 75); courseScore.addAnswer("q1", 2, u2.getUsername(), 25); LearningProgressValues u1Progress = lp.getMyProgress(null, u1); LearningProgressValues u2Progress = lp.getMyProgress(null, u2); // only the answer for round 2 should be considered assertEquals(50, u1Progress.getCourseProgress()); assertEquals(75, u1Progress.getMyProgress()); assertEquals(50, u2Progress.getCourseProgress()); assertEquals(25, u2Progress.getMyProgress()); } @Test public void shouldIncludeNominatorAndDenominatorOfResultExcludingStudentCount() { // two questions String q1 = this.addQuestion("lecture", 10); String q2 = this.addQuestion("lecture", 10); // three users User u1 = new TestUser("user1"); User u2 = new TestUser("user2"); User u3 = new TestUser("user3"); // six answers this.addAnswer(q1, u1, 10); this.addAnswer(q2, u1, 0); this.addAnswer(q1, u2, 10); this.addAnswer(q2, u2, 0); this.addAnswer(q1, u3, 10); this.addAnswer(q2, u3, 0); int numerator = lp.getCourseProgress(null).getNumerator(); int denominator = lp.getCourseProgress(null).getDenominator(); // If the percentage is wrong, then we need to adapt this test case! assertEquals("Precondition failed -- The underlying calculation has changed", 50, lp.getCourseProgress(null).getCourseProgress()); assertEquals(10, numerator); assertEquals(20, denominator); } }