Commit 4dae2267 by Afzal Wali

The remaining time is now independent of the browser's system clock.

Fixed the failing jasmine tests

JS test to verify that the client remaining time is updated after the server responds with an updated remaining time.
parent 617db2b2
......@@ -16,32 +16,24 @@
course_id: null,
lastFetched: new Date()
},
getRemainingSeconds: function () {
var currentTime = (new Date()).getTime();
var lastFetched = this.get('lastFetched').getTime();
var totalSeconds = this.get('time_remaining_seconds') - (currentTime - lastFetched) / 1000;
return totalSeconds;
},
getFormattedRemainingTime: function () {
var totalSeconds = this.getRemainingSeconds();
getFormattedRemainingTime: function (secondsLeft) {
/* since we can have a small grace period, we can end in the negative numbers */
if (totalSeconds < 0)
totalSeconds = 0;
if (secondsLeft < 0)
secondsLeft = 0;
var hours = parseInt(totalSeconds / 3600) % 24;
var minutes = parseInt(totalSeconds / 60) % 60;
var seconds = Math.floor(totalSeconds % 60);
var hours = parseInt(secondsLeft / 3600) % 24;
var minutes = parseInt(secondsLeft / 60) % 60;
var seconds = Math.floor(secondsLeft % 60);
return hours + ":" + (minutes < 10 ? "0" + minutes : minutes)
+ ":" + (seconds < 10 ? "0" + seconds : seconds);
},
getRemainingTimeState: function () {
var totalSeconds = this.getRemainingSeconds();
if (totalSeconds > this.get('low_threshold_sec')) {
getRemainingTimeState: function (secondsLeft) {
if (secondsLeft > this.get('low_threshold_sec')) {
return "";
}
else if (totalSeconds <= this.get('low_threshold_sec') && totalSeconds > this.get('critically_low_threshold_sec')) {
else if (secondsLeft <= this.get('low_threshold_sec') && secondsLeft > this.get('critically_low_threshold_sec')) {
// returns the class name that has some css properties
// and it displays the user with the waring message if
// total seconds is less than the low_threshold value.
......
......@@ -14,6 +14,7 @@ var edx = edx || {};
this.template = null;
this.timerId = null;
this.timerTick = 0;
this.secondsLeft = 0;
/* give an extra 5 seconds where the timer holds at 00:00 before page refreshes */
this.grace_period_secs = 5;
......@@ -48,6 +49,7 @@ var edx = edx || {};
// should not be navigating around the courseware
var taking_as_proctored = this.model.get('taking_as_proctored');
var time_left = this.model.get('time_remaining_seconds') > 0;
this.secondsLeft = this.model.get('time_remaining_seconds');
var status = this.model.get('attempt_status');
var in_courseware = document.location.href.indexOf('/courses/' + this.model.get('course_id') + '/courseware/') > -1;
......@@ -104,6 +106,7 @@ var edx = edx || {};
},
updateRemainingTime: function (self) {
self.timerTick ++;
self.secondsLeft --;
if (self.timerTick % 5 === 0){
var url = self.model.url + '/' + self.model.get('attempt_id');
$.ajax(url).success(function(data) {
......@@ -115,12 +118,15 @@ var edx = edx || {};
// refresh the page when the timer expired
location.reload();
}
else {
self.secondsLeft = data.time_remaining_seconds;
}
});
}
self.$el.find('div.exam-timer').removeClass("low-time warning critical");
self.$el.find('div.exam-timer').addClass(self.model.getRemainingTimeState());
self.$el.find('span#time_remaining_id b').html(self.model.getFormattedRemainingTime());
if (self.model.getRemainingSeconds() <= -self.grace_period_secs) {
self.$el.find('div.exam-timer').addClass(self.model.getRemainingTimeState(self.secondsLeft));
self.$el.find('span#time_remaining_id b').html(self.model.getFormattedRemainingTime(self.secondsLeft));
if (self.secondsLeft <= -self.grace_period_secs) {
clearInterval(self.timerId); // stop the timer once the time finishes.
$(window).unbind('beforeunload', this.unloadMessage);
// refresh the page when the timer expired
......
......@@ -46,31 +46,36 @@ describe('ProctoredExamView', function () {
expect(this.proctored_exam_view.$el.find('a')).toContainHtml(this.model.get('exam_display_name'));
});
it('changes behavior when clock time decreases low threshold', function () {
spyOn(this.model, 'getRemainingSeconds').and.callFake(function() {
return 25;
});
expect(this.model.getRemainingSeconds()).toEqual(25);
expect(this.proctored_exam_view.$el.find('div.exam-timer')).not.toHaveClass('low-time warning');
this.proctored_exam_view.secondsLeft = 25;
this.proctored_exam_view.render();
expect(this.proctored_exam_view.$el.find('div.exam-timer')).toHaveClass('low-time warning');
});
it('changes behavior when clock time decreases critically low threshold', function () {
spyOn(this.model, 'getRemainingSeconds').and.callFake(function () {
return 5;
});
expect(this.model.getRemainingSeconds()).toEqual(5);
expect(this.proctored_exam_view.$el.find('div.exam-timer')).not.toHaveClass('low-time critical');
this.proctored_exam_view.secondsLeft = 5;
this.proctored_exam_view.render();
expect(this.proctored_exam_view.$el.find('div.exam-timer')).toHaveClass('low-time critical');
});
it("reload the page when the exam time finishes", function(){
spyOn(this.model, 'getRemainingSeconds').and.callFake(function() {
return -10;
});
expect(this.model.getRemainingSeconds()).toEqual(-10);
this.proctored_exam_view.secondsLeft = -10;
var reloadPage = spyOn(this.proctored_exam_view, 'reloadPage');
this.proctored_exam_view.render();
this.proctored_exam_view.updateRemainingTime(this.proctored_exam_view);
expect(reloadPage).toHaveBeenCalled();
});
it("resets the remainig exam time after the ajax response", function(){
this.server.respondWith("GET", "/api/edx_proctoring/v1/proctored_exam/attempt/" + this.proctored_exam_view.model.get('attempt_id'),
[
200,
{"Content-Type": "application/json"},
JSON.stringify({
time_remaining_seconds: -10
})
]
);
this.proctored_exam_view.timerTick = 4; // to make the ajax call.
var reloadPage = spyOn(this.proctored_exam_view, 'reloadPage');
this.proctored_exam_view.updateRemainingTime(this.proctored_exam_view);
this.server.respond();
this.proctored_exam_view.updateRemainingTime(this.proctored_exam_view);
expect(reloadPage).toHaveBeenCalled();
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment