-
Notifications
You must be signed in to change notification settings - Fork 57
refactor: added helper function performSessionEnd #1113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
refactor: added helper function performSessionEnd #1113
Conversation
…376-refactor-endSession-in-sessionManager
a790359 to
0ba2d13
Compare
src/sessionManager.ts
Outdated
| function hasSessionTimedOut(lastEventTimestamp: number): boolean { | ||
| const sessionTimeoutInMilliseconds: number = | ||
| mpInstance._Store.SDKConfig.sessionTimeout * 60000; | ||
| const timeSinceLastEvent: number = | ||
| new Date().getTime() - lastEventTimestamp; | ||
|
|
||
| return timeSinceLastEvent >= sessionTimeoutInMilliseconds; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's avoid pulling in the entire store when we only need a single value.
| function hasSessionTimedOut(lastEventTimestamp: number): boolean { | |
| const sessionTimeoutInMilliseconds: number = | |
| mpInstance._Store.SDKConfig.sessionTimeout * 60000; | |
| const timeSinceLastEvent: number = | |
| new Date().getTime() - lastEventTimestamp; | |
| return timeSinceLastEvent >= sessionTimeoutInMilliseconds; | |
| } | |
| function hasSessionTimedOut(lastEventTimestamp: number, sessionTimeout: number): boolean { | |
| const sessionTimeoutInMilliseconds: number = sessionTimeout * 60000; | |
| const timeSinceLastEvent: number = | |
| new Date().getTime() - lastEventTimestamp; | |
| return timeSinceLastEvent >= sessionTimeoutInMilliseconds; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
src/sessionManager.ts
Outdated
| const sessionTimeoutInMilliseconds: number = | ||
| mpInstance._Store.SDKConfig.sessionTimeout * 60000; | ||
| const timeSinceLastEvent: number = | ||
| new Date().getTime() - lastEventTimestamp; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I agree with SonarCloud. let's use Date.now() instead of new Date().getTime().
src/sessionManager.ts
Outdated
| sessionTimeoutInMilliseconds | ||
| ) | ||
| ) { | ||
| if (hasSessionTimedOut(mpInstance._Store.dateLastEventSent.getTime())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you follow my suggestion below, this can be destructured and cleaned up.
| if (hasSessionTimedOut(mpInstance._Store.dateLastEventSent.getTime())) { | |
| const { dateLastEventSent, SDKConfig } = mpInstance._Store; | |
| const { sessionTimeout } = SDKConfig; | |
| if (hasSessionTimedOut(dateLastEventSent.getTime(), sessionTimeout)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for suggesting this, cleaned up initialize function
src/sessionManager.ts
Outdated
| mpInstance._Events.logEvent({ | ||
| messageType: Types.MessageType.SessionEnd, | ||
| }); | ||
| mpInstance._Store.sessionStartDate = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we just add this line to nullifySession()?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added this.sessionStartDate = null; to Store. nullifySession()
905641c to
b16bdd2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR refactors session management logic by extracting two helper functions to eliminate code duplication and improve maintainability. The refactoring consolidates timeout calculations that previously used different comparison approaches and extracts session end operations into a reusable function.
Key Changes:
- Extracted
hasSessionTimedOut()helper to unify session timeout logic previously duplicated betweeninitialize()andendSession()with different comparison operators - Extracted
performSessionEnd()helper to consolidate session end operations (logging, clearing data, resetting timer) - Standardized on
>=comparison operator for timeout checks (expires at exactly 30 minutes)
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
| src/sessionManager.ts | Refactored session timeout and end logic into two helper functions; simplified initialize() and endSession() by delegating to the new helpers |
| src/store.ts | Updated nullifySession() to include clearing sessionStartDate, consolidating cleanup logic |
| test/src/tests-session-manager.ts | Added comprehensive test coverage for both new helper functions with 11 new test cases covering timeout scenarios, session end operations, and edge cases |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
test/src/tests-session-manager.ts
Outdated
| const now = new Date(); | ||
| const exactlyThirtyMinutesAgo = new Date(); | ||
| exactlyThirtyMinutesAgo.setMinutes(now.getMinutes() - 30); | ||
|
|
||
| mParticle.init(apiKey, window.mParticle.config); | ||
| const mpInstance = mParticle.getInstance(); | ||
|
|
||
| sinon.stub(mpInstance._Persistence, 'getPersistence').returns({ | ||
| gs: { | ||
| les: exactlyThirtyMinutesAgo.getTime(), | ||
| sid: 'TEST-ID', | ||
| }, | ||
| }); | ||
|
|
||
| mpInstance._SessionManager.endSession(); | ||
|
|
||
| // At exactly 30 minutes, session should be expired | ||
| expect(mpInstance._Store.sessionId).to.equal(null); |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test has a potential timing issue. The test creates exactlyThirtyMinutesAgo using the current time, but by the time hasSessionTimedOut() is called internally (which uses Date.now()), a few milliseconds may have passed. This could make the elapsed time slightly more than 30 minutes, causing the test to pass for the wrong reason. Consider using fake timers (sinon.useFakeTimers) to control time precisely, or add a small buffer to ensure the test is deterministic.
| const now = new Date(); | |
| const exactlyThirtyMinutesAgo = new Date(); | |
| exactlyThirtyMinutesAgo.setMinutes(now.getMinutes() - 30); | |
| mParticle.init(apiKey, window.mParticle.config); | |
| const mpInstance = mParticle.getInstance(); | |
| sinon.stub(mpInstance._Persistence, 'getPersistence').returns({ | |
| gs: { | |
| les: exactlyThirtyMinutesAgo.getTime(), | |
| sid: 'TEST-ID', | |
| }, | |
| }); | |
| mpInstance._SessionManager.endSession(); | |
| // At exactly 30 minutes, session should be expired | |
| expect(mpInstance._Store.sessionId).to.equal(null); | |
| const now = Date.now(); | |
| const clock = sinon.useFakeTimers(now); | |
| const thirtyMinutesInMs = 30 * 60 * 1000; | |
| const exactlyThirtyMinutesAgo = new Date(now - thirtyMinutesInMs); | |
| mParticle.init(apiKey, window.mParticle.config); | |
| const mpInstance = mParticle.getInstance(); | |
| const getPersistenceStub = sinon.stub(mpInstance._Persistence, 'getPersistence').returns({ | |
| gs: { | |
| les: exactlyThirtyMinutesAgo.getTime(), | |
| sid: 'TEST-ID', | |
| }, | |
| }); | |
| try { | |
| mpInstance._SessionManager.endSession(); | |
| // At exactly 30 minutes, session should be expired | |
| expect(mpInstance._Store.sessionId).to.equal(null); | |
| } finally { | |
| getPersistenceStub.restore(); | |
| clock.restore(); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaissica12 let's test this in case the robot is telling the truth
src/sessionManager.ts
Outdated
| } | ||
| } | ||
|
|
||
| mpInstance._timeOnSiteTimer?.resetTimer(); |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The timer reset at this line is redundant when the session has timed out, because performSessionEnd() already resets the timer at line 238. This results in the timer being reset twice when a session times out via the endSession() method. Consider removing this line or moving the timer reset logic into the else block at line 170 to avoid the duplication.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaissica12 Can you try making this code change and see if it works? I think it may clean up the rafactor more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
test/src/tests-session-manager.ts
Outdated
| sinon.stub(mpInstance._Persistence, 'getPersistence').returns({ | ||
| gs: { | ||
| les: thirtyOneMinutesAgo.getTime(), | ||
| sid: newSessionId, | ||
| }, | ||
| }); |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sinon.stub is not cleaned up after the test. This stub will persist and could affect subsequent tests in this test suite. Use sinon.stub().returns() and restore it in a cleanup hook, or use sinon.restore() at the end of the test, or better yet, wrap this test in a context with its own beforeEach/afterEach to handle stub lifecycle.
test/src/tests-session-manager.ts
Outdated
| sinon.stub(mpInstance._Persistence, 'getPersistence').returns({ | ||
| gs: { | ||
| les: exactlyThirtyMinutesAgo.getTime(), | ||
| sid: 'TEST-ID', | ||
| }, | ||
| }); |
Copilot
AI
Dec 19, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sinon.stub is not cleaned up after the test. This stub will persist and could affect subsequent tests in this test suite. Use sinon.stub().returns() and restore it in a cleanup hook, or use sinon.restore() at the end of the test, or better yet, wrap this test in a context with its own beforeEach/afterEach to handle stub lifecycle.
src/sessionManager.ts
Outdated
| } | ||
| } | ||
|
|
||
| mpInstance._timeOnSiteTimer?.resetTimer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaissica12 Can you try making this code change and see if it works? I think it may clean up the rafactor more.
test/src/tests-session-manager.ts
Outdated
| const now = new Date(); | ||
| const exactlyThirtyMinutesAgo = new Date(); | ||
| exactlyThirtyMinutesAgo.setMinutes(now.getMinutes() - 30); | ||
|
|
||
| mParticle.init(apiKey, window.mParticle.config); | ||
| const mpInstance = mParticle.getInstance(); | ||
|
|
||
| sinon.stub(mpInstance._Persistence, 'getPersistence').returns({ | ||
| gs: { | ||
| les: exactlyThirtyMinutesAgo.getTime(), | ||
| sid: 'TEST-ID', | ||
| }, | ||
| }); | ||
|
|
||
| mpInstance._SessionManager.endSession(); | ||
|
|
||
| // At exactly 30 minutes, session should be expired | ||
| expect(mpInstance._Store.sessionId).to.equal(null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jaissica12 let's test this in case the robot is telling the truth
| * @param sessionTimeout - Session timeout in minutes | ||
| * @returns true if the session has expired, false otherwise | ||
| */ | ||
| function hasSessionTimedOut(lastEventTimestamp: number, sessionTimeout: number): boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be an edge case, since we lastEventTimestamp and sessionTimeout have default values, but I would add a guard clause here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added!
| messageType: Types.MessageType.SessionEnd, | ||
| }); | ||
|
|
||
| mpInstance._Store.sessionStartDate = null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed we're not including this line in the performSessionEnd function. Can it be used there? If not, can it be safely removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
remove trailing whitespace Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|



Background
initialize()andendSession()methodsWhat Has Changed
performSessionEndhelper - Extracted session end operations into a dedicated functionhasSessionTimedOuthelper - Consolidates duplicate session timeout calculation logicScreenshots/Video
Checklist
Additional Notes
initialize()used>- session expired after 30:00.000endSession()used>=- session expired at 30:00.000As of now I have standardized on
>=, let me know if you think otherwiseReference Issue (For employees only. Ignore if you are an outside contributor)