From 54e270aa04b86c9b126ea1b34a74b524513f7b56 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Tue, 26 Jun 2018 17:03:00 +0200
Subject: [PATCH] OO-3544: leading time (based on Set assessment period
 setting) was not calculated like the max time limit based on time limit
 configuration.

---
 .../ui/AssessmentTestDisplayController.java   | 36 ++++++++++++-------
 .../AssessmentTimerComponentRenderer.java     |  8 ++---
 .../static/js/jquery/qti/jquery.qtiTimer.js   | 15 ++++----
 3 files changed, 35 insertions(+), 24 deletions(-)

diff --git a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
index 862453cbdae..78558e87425 100644
--- a/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
+++ b/src/main/java/org/olat/ims/qti21/ui/AssessmentTestDisplayController.java
@@ -629,35 +629,38 @@ public class AssessmentTestDisplayController extends BasicController implements
 	 */
 	private Long getAssessmentTestMaxTimeLimit() {
 		int extra = extraTime == null ? 0 : extraTime.intValue();
-		long leadingTime = getLeadingTimeEndTestOption();
+		Long leadingTimeInMilliSeconds = getLeadingTimeEndTestOption();
+		long leadingDuration = Long.MAX_VALUE;
+		if(leadingTimeInMilliSeconds != null) {
+			double leadingDurationInSeconds = (leadingTimeInMilliSeconds + getAssessmentTestDuration()) / 1000.0d;
+			leadingDuration = Math.round(leadingDurationInSeconds);
+		}
 		if(overrideOptions != null && overrideOptions.getAssessmentTestMaxTimeLimit() != null) {
 			long timeLimits = overrideOptions.getAssessmentTestMaxTimeLimit().longValue();
-			return timeLimits > 0 ? Math.min(leadingTime, timeLimits) + extra : null;
+			return timeLimits > 0 ? Math.min(leadingDuration, timeLimits) + extra : null;
 		}
 		AssessmentTest assessmentTest = resolvedAssessmentTest.getRootNodeLookup().extractIfSuccessful();
 		if(assessmentTest.getTimeLimits() != null && assessmentTest.getTimeLimits().getMaximum() != null) {
 			long timeLimits = assessmentTest.getTimeLimits().getMaximum().longValue();
-			return Math.min(leadingTime, timeLimits) + extra;
+			return Math.min(leadingDuration, timeLimits) + extra;
 		}
 		return null;
 	}
+
 	
 	/**
-	 * @return The number of seconds up to the defined end of the test (or a very long time if nothing is configured)
+	 * @return The number of milliseconds up to the defined end of the test (or a very long time if nothing is configured)
 	 */
-	private long getLeadingTimeEndTestOption() {
+	private Long getLeadingTimeEndTestOption() {
 		if(overrideOptions != null && overrideOptions.getEndTestDate() != null) {
 			Date endTestDate = overrideOptions.getEndTestDate();
 			long diff = endTestDate.getTime() - currentRequestTimestamp.getTime();
 			if(diff < 0l) {
 				diff = 0l;
 			}
-			if(diff > 0l) {
-				diff = diff / 1000l;
-			}
 			return diff;
 		}
-		return 365 * 24 * 60 * 60;// default is a year
+		return null;// default is a year
 	}
 	
 	/**
@@ -674,6 +677,16 @@ public class AssessmentTestDisplayController extends BasicController implements
 		}
 		return diff;
 	}
+	
+	/**
+	 * @return The test duration in milliseconds
+	 */
+	private long getAssessmentTestDuration() {
+		TestSessionState testSessionState = testSessionController.getTestSessionState();
+		long duration = testSessionState.getDurationAccumulated();
+		duration += getRequestTimeStampDifferenceToNow();
+		return duration;
+	}
 
 	private void processQTIEvent(UserRequest ureq, QTIWorksAssessmentTestEvent qe) {
 		if(timeLimitBarrier(ureq)) {
@@ -2341,10 +2354,7 @@ public class AssessmentTestDisplayController extends BasicController implements
 		 * @return The test duration in milliseconds
 		 */
 		public long getAssessmentTestDuration() {
-			TestSessionState testSessionState = testSessionController.getTestSessionState();
-			long duration = testSessionState.getDurationAccumulated();
-			duration += getRequestTimeStampDifferenceToNow();
-			return duration;
+			return AssessmentTestDisplayController.this.getAssessmentTestDuration();
 		}
 		
 		/**
diff --git a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTimerComponentRenderer.java b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTimerComponentRenderer.java
index 6cdd2f8db28..8a8fd9bab17 100644
--- a/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTimerComponentRenderer.java
+++ b/src/main/java/org/olat/ims/qti21/ui/components/AssessmentTimerComponentRenderer.java
@@ -50,9 +50,9 @@ public class AssessmentTimerComponentRenderer extends DefaultComponentRenderer {
 
 			sb.append("<div id='o_c").append(cmp.getDispatchID()).append("'><div id='o_qti_assessment_test_timer' class='clearfix'><i class='o_icon o_icon_timelimit'> </i> ");
 			String[] attrs = new String[] {
-					"<span class='o_qti_timer'></span>",
-					"<span class='o_qti_timer_duration'></span>",
-					qtiWorksStatus.getAssessmentTestEndTime()
+					"<span class='o_qti_timer'></span>",			// 0 The count down place holder
+					"<span class='o_qti_timer_duration'></span>",	// 1 Test time limit
+					qtiWorksStatus.getAssessmentTestEndTime()		// 2 End time formatted hh:mm
 				};
 			sb.append(translator.translate("timelimit.running", attrs))
 			  .append("<span class='o_qti_times_up' style='display:none;'>").append(translator.translate("timelimit.finished")).append("</span>")
@@ -64,7 +64,7 @@ public class AssessmentTimerComponentRenderer extends DefaultComponentRenderer {
 			  .append("/*<![CDATA[ */\n")
 			  .append("jQuery(function() {\n")
 			  .append("  jQuery('#o_qti_assessment_test_timer').qtiTimer({\n")
-			  .append("    startTime:").append(qtiWorksStatus.getAssessmentTestDuration()).append(",\n")
+			  .append("    testDuration:").append(qtiWorksStatus.getAssessmentTestDuration()).append(",\n")
 			  .append("    availableTime:").append(qtiWorksStatus.getAssessmentTestMaximumTimeLimits()).append(",\n")
 			  .append("    formName: '").append(form.getFormName()).append("',\n")//forn name
 			  .append("    dispIdField: '").append(form.getDispatchFieldId()).append("',\n")//form dispatch id
diff --git a/src/main/webapp/static/js/jquery/qti/jquery.qtiTimer.js b/src/main/webapp/static/js/jquery/qti/jquery.qtiTimer.js
index b4f23831260..18bab8432a2 100644
--- a/src/main/webapp/static/js/jquery/qti/jquery.qtiTimer.js
+++ b/src/main/webapp/static/js/jquery/qti/jquery.qtiTimer.js
@@ -1,8 +1,8 @@
 (function ($) {
     $.fn.qtiTimer = function(options) {
-    	
+    	"use strict";
     	var settings = $.extend({
-    		startTime: null,
+    		testDuration: null,
     		availableTime: null,
     		formName: null,//forn name
     		dispIdField: null,//form dispatch id
@@ -15,15 +15,16 @@
     	}
     	
     	var wrapperId = this.attr('id');
-    	var startTime = Date.now() - settings.startTime;
+    	var now = Date.now();
+    	var startTime = now - settings.testDuration;
     	var availableTime = startTime + settings.availableTime;
-    	var remainingTime = availableTime - Date.now();
+    	var remainingTime = availableTime - now;
 		displayRemainingTime(wrapperId, settings.availableTime, remainingTime);
     	
     	var periodic = jQuery.periodic({period: 1000, decay:1.0, max_period: remainingTime + 1000 }, function() {
-			remainingTime = availableTime - Date.now();
-			if(remainingTime >= 0) {
-				displayRemainingTime(wrapperId, settings.availableTime, remainingTime);
+			var remaining = availableTime - Date.now();
+			if(remaining >= 0) {
+				displayRemainingTime(wrapperId, settings.availableTime, remaining);
 			} else {
 				periodic.cancel();
 				timesUp(settings);
-- 
GitLab