From 57f2ee798be22a9ff2316e34d324b43ba63270cd Mon Sep 17 00:00:00 2001 From: Carlo Costino Date: Thu, 28 Sep 2023 15:31:08 -0400 Subject: [PATCH] Made several adjustments for session timer tests - Turned the timeoutPopup module into a proper module that is exported - Pulled out the setInterval inner function to be its own method - Adjusted the session timer tests to have additional setup and teardown pieces - Added a few tests There may be some additional adjustments needed, e.g., we may not have to expose all of the methods, but then we have to figure out how to make them accessible in the tests another way. h/t @A-Shumway42 for pairing with me to review all of these changes and approach! Signed-off-by: Carlo Costino --- app/assets/javascripts/timeoutPopup.js | 50 ++++++------ tests/javascripts/timeoutPopup.test.js | 103 ++++++++++++++++++++++--- 2 files changed, 119 insertions(+), 34 deletions(-) diff --git a/app/assets/javascripts/timeoutPopup.js b/app/assets/javascripts/timeoutPopup.js index be64d7d22..f8b5b4cee 100644 --- a/app/assets/javascripts/timeoutPopup.js +++ b/app/assets/javascripts/timeoutPopup.js @@ -1,25 +1,23 @@ (function(global) { "use strict"; + const sessionTimer = document.getElementById("sessionTimer"); - setTimeout(function() { - var timeTillSessionEnd = new Date().getTime() + (5 * 60 * 1000); - var x = setInterval(function() { - var now = new Date().getTime(); - var difference = timeTillSessionEnd - now; - var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60)); - var seconds = Math.floor((difference % (1000 * 60)) / 1000); - document.getElementById("timeLeft").innerHTML = + minutes + "m " + seconds + "s"; - showTimer(); - document.getElementById("logOutTimer").addEventListener("click", logoutUser); - document.getElementById("extendSessionTimer").addEventListener("click", extendSession); - if (difference < 0) { - clearInterval(x); - closeTimer(); - logoutUser(); - } - }, 1000); - }, 25 * 60 * 1000); + function checkTimer(timeTillSessionEnd) { + var now = new Date().getTime(); + var difference = timeTillSessionEnd - now; + var minutes = Math.floor((difference % (1000 * 60 * 60)) / (1000 * 60)); + var seconds = Math.floor((difference % (1000 * 60)) / 1000); + document.getElementById("timeLeft").innerHTML = + minutes + "m " + seconds + "s"; + showTimer(); + document.getElementById("logOutTimer").addEventListener("click", logoutUser); + document.getElementById("extendSessionTimer").addEventListener("click", extendSession); + if (difference < 0) { + clearInterval(x); + closeTimer(); + logoutUser(); + } + } function logoutUser() { window.location.href = '/sign-out'; @@ -36,9 +34,17 @@ function closeTimer() { sessionTimer.close(); } - })(window); - - - + global.GOVUK.Modules.TimeoutPopup = function() { + setTimeout(function() { + var timeTillSessionEnd = new Date().getTime() + (5 * 60 * 1000); + var x = setInterval(checkTimer, 1000, timeTillSessionEnd); + }, 25 * 60 * 1000); + }; + global.GOVUK.Modules.TimeoutPopup.checkTimer = checkTimer; + global.GOVUK.Modules.TimeoutPopup.logoutUser = logoutUser; + global.GOVUK.Modules.TimeoutPopup.extendSession = extendSession; + global.GOVUK.Modules.TimeoutPopup.showTimer = showTimer; + global.GOVUK.Modules.TimeoutPopup.closeTimer = closeTimer; +})(window); diff --git a/tests/javascripts/timeoutPopup.test.js b/tests/javascripts/timeoutPopup.test.js index 74373de5a..46d88b7d2 100644 --- a/tests/javascripts/timeoutPopup.test.js +++ b/tests/javascripts/timeoutPopup.test.js @@ -1,18 +1,97 @@ -const sessionTimerWrapper = require('../../app/assets/javascripts/timeoutPopup.js'); +beforeAll(() => { + jest.useFakeTimers(); + jest.spyOn(global, 'setTimeout'); + + document.body.innerHTML = ` + +
+
+

+ Your session will end soon. + Please choose to extend your session or sign out. Your session will expire in 5 minutes or less. +

+
+

You have been inactive for too long. + Your session will expire in . +

+
+ +
+
+
+ ` + + const sessionTimerModule = require('../../app/assets/javascripts/timeoutPopup.js'); + window.GOVUK.modules.start(); +}); + +afterAll(() => { + jest.useRealTimers(); + document.body.innerHTML = ''; +}); -describe('Test popup process', () => { - beforeEach(() => { - jest.useFakeTimers(); - }); - - afterEach(() => { - jest.useRealTimers(); - }); - - it('Test timers work', () => { +describe('When an authenticated user', () => { + test('does whatever', () => { jest.runAllTimers(); }); -}); +}); + +describe('The session timer ', () => { + test('logoutUser method logs the user out', () => { + const logoutUserMethod = window.GOVUK.Modules.TimeoutPopup.logoutUser; + + expect(window.location.href).toEqual(expect.not.stringContaining('/sign-out')); + + logoutUserMethod(); + + expect(window.location.href).toEqual(expect.stringContaining('/sign-out')); + }); + + test('extendSession method reloads the page', () => { + const windowReload = jest.spyOn(window.location, 'reload'); + const extendSessionMethod = window.GOVUK.Modules.TimeoutPopup.extendSession; + + extendSessionMethod(); + + expect(windowReload).toHaveBeenCalled(); + }); + + test('showTimer method shows the session timer modal', () => { + const sessionTimer = document.getElementById("sessionTimer"); + sessionTimer.showModal = jest.fn(); + + const showTimerMock = jest.spyOn(sessionTimer, 'showModal'); + + window.GOVUK.Modules.TimeoutPopup.showTimer(); + + expect(showTimerMock).toHaveBeenCalled(); + }); + + test('closeTimer method closes the session timer modal', () => { + const sessionTimer = document.getElementById("sessionTimer"); + sessionTimer.close = jest.fn(); + + const closeTimerMock = jest.spyOn(sessionTimer, 'close'); + + window.GOVUK.Modules.TimeoutPopup.closeTimer(); + + expect(closeTimerMock).toHaveBeenCalled(); + }); +});