Files
standardnotes-app-web/app/assets/javascripts/components/NoteView/NoteView.test.ts
Mo 50c92619ce refactor: migrate remaining angular components to react (#833)
* refactor: menuRow directive to MenuRow component

* refactor: migrate footer to react

* refactor: migrate actions menu to react

* refactor: migrate history menu to react

* fix: click outside handler use capture to trigger event before re-render occurs which would otherwise cause node.contains to return incorrect result (specifically for the account menu)

* refactor: migrate revision preview modal to react

* refactor: migrate permissions modal to react

* refactor: migrate password wizard to react

* refactor: remove unused input modal directive

* refactor: remove unused delay hide component

* refactor: remove unused filechange directive

* refactor: remove unused elemReady directive

* refactor: remove unused sn-enter directive

* refactor: remove unused lowercase directive

* refactor: remove unused autofocus directive

* refactor(wip): note view to react

* refactor: use mutation observer to deinit textarea listeners

* refactor: migrate challenge modal to react

* refactor: migrate note group view to react

* refactor(wip): migrate remaining classes

* fix: navigation parent ref

* refactor: fully remove angular assets

* fix: account switcher

* fix: application view state

* refactor: remove unused password wizard type

* fix: revision preview and permissions modal

* fix: remove angular comment

* refactor: react panel resizers for editor

* feat: simple panel resizer

* fix: use simple panel resizer everywhere

* fix: simplify panel resizer state

* chore: rename simple panel resizer to panel resizer

* refactor: simplify column layout

* fix: editor mount safety check

* fix: use inline onLoad callback for iframe, as setting onload after it loads will never call it

* chore: fix note view test

* chore(deps): upgrade snjs
2022-01-30 19:01:30 -06:00

196 lines
5.9 KiB
TypeScript

/**
* @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);
});
});
});
});