/** * @jest-environment jsdom */ import { NoteView } from './NoteView' import { ApplicationEvent, ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction, } from '@standardnotes/snjs/' describe('editor-view', () => { let ctrl: NoteView let setShowProtectedWarningSpy: jest.SpyInstance beforeEach(() => { ctrl = new NoteView({} as any) setShowProtectedWarningSpy = jest.spyOn(ctrl, 'setShowProtectedOverlay') Object.defineProperties(ctrl, { application: { value: { getAppState: () => { return { notes: { setShowProtectedWarning: jest.fn(), }, } }, hasProtectionSources: () => true, authorizeNoteAccess: jest.fn(), }, }, removeComponentsObserver: { value: jest.fn(), writable: true, }, removeTrashKeyObserver: { value: jest.fn(), writable: true, }, unregisterComponent: { value: jest.fn(), writable: true, }, editor: { value: { clearNoteChangeListener: jest.fn(), }, }, }) }) beforeEach(() => { jest.useFakeTimers() }) afterEach(() => { jest.useRealTimers() }) afterEach(() => { ctrl.deinit() }) describe('note is protected', () => { beforeEach(() => { Object.defineProperty(ctrl, 'note', { value: { protected: true, }, }) }) it("should hide the note if at the time of the session expiration the note wasn't edited for longer than the allowed idle time", async () => { jest .spyOn(ctrl, 'getSecondsElapsedSinceLastEdit') .mockImplementation( () => ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction + 5, ) await ctrl.onAppEvent(ApplicationEvent.UnprotectedSessionExpired) expect(setShowProtectedWarningSpy).toHaveBeenCalledWith(true) }) it('should postpone the note hiding by correct time if the time passed after its last modification is less than the allowed idle time', async () => { const secondsElapsedSinceLastEdit = ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction - 3 Object.defineProperty(ctrl.note, 'userModifiedDate', { value: new Date(Date.now() - secondsElapsedSinceLastEdit * 1000), configurable: true, }) await ctrl.onAppEvent(ApplicationEvent.UnprotectedSessionExpired) const secondsAfterWhichTheNoteShouldHide = ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction - secondsElapsedSinceLastEdit jest.advanceTimersByTime((secondsAfterWhichTheNoteShouldHide - 1) * 1000) expect(setShowProtectedWarningSpy).not.toHaveBeenCalled() jest.advanceTimersByTime(1 * 1000) expect(setShowProtectedWarningSpy).toHaveBeenCalledWith(true) }) it('should postpone the note hiding by correct time if the user continued editing it even after the protection session has expired', async () => { const secondsElapsedSinceLastModification = 3 Object.defineProperty(ctrl.note, 'userModifiedDate', { value: new Date(Date.now() - secondsElapsedSinceLastModification * 1000), configurable: true, }) await ctrl.onAppEvent(ApplicationEvent.UnprotectedSessionExpired) let secondsAfterWhichTheNoteShouldHide = ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction - secondsElapsedSinceLastModification jest.advanceTimersByTime((secondsAfterWhichTheNoteShouldHide - 1) * 1000) // A new modification has just happened Object.defineProperty(ctrl.note, 'userModifiedDate', { value: new Date(), configurable: true, }) secondsAfterWhichTheNoteShouldHide = ProposedSecondsToDeferUILevelSessionExpirationDuringActiveInteraction jest.advanceTimersByTime((secondsAfterWhichTheNoteShouldHide - 1) * 1000) expect(setShowProtectedWarningSpy).not.toHaveBeenCalled() jest.advanceTimersByTime(1 * 1000) expect(setShowProtectedWarningSpy).toHaveBeenCalledWith(true) }) }) describe('note is unprotected', () => { it('should not call any hiding logic', async () => { Object.defineProperty(ctrl, 'note', { value: { protected: false, }, }) const hideProtectedNoteIfInactiveSpy = jest.spyOn(ctrl, 'hideProtectedNoteIfInactive') await ctrl.onAppEvent(ApplicationEvent.UnprotectedSessionExpired) expect(hideProtectedNoteIfInactiveSpy).not.toHaveBeenCalled() }) }) describe('dismissProtectedWarning', () => { describe('the note has protection sources', () => { it('should reveal note contents if the authorization has been passed', async () => { jest .spyOn(ctrl['application'], 'authorizeNoteAccess') .mockImplementation(async () => Promise.resolve(true)) await ctrl.dismissProtectedWarning() expect(setShowProtectedWarningSpy).toHaveBeenCalledWith(false) }) it('should not reveal note contents if the authorization has not been passed', async () => { jest .spyOn(ctrl['application'], 'authorizeNoteAccess') .mockImplementation(async () => Promise.resolve(false)) await ctrl.dismissProtectedWarning() expect(setShowProtectedWarningSpy).not.toHaveBeenCalled() }) }) describe('the note does not have protection sources', () => { it('should reveal note contents', async () => { jest.spyOn(ctrl['application'], 'hasProtectionSources').mockImplementation(() => false) await ctrl.dismissProtectedWarning() expect(setShowProtectedWarningSpy).toHaveBeenCalledWith(false) }) }) }) })