diff --git a/packages/sncrypto-web/test/crypto.test.js b/packages/sncrypto-web/test/crypto.test.js
index ced5eb3f9..09ab13a3c 100644
--- a/packages/sncrypto-web/test/crypto.test.js
+++ b/packages/sncrypto-web/test/crypto.test.js
@@ -1,5 +1,4 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
+
import './vendor/chai-as-promised-built.js'
import './vendor/buffer@5.6.0.js'
diff --git a/packages/sncrypto-web/test/memory.test.js b/packages/sncrypto-web/test/memory.test.js
index 8a7909d0c..cd3a2a33f 100644
--- a/packages/sncrypto-web/test/memory.test.js
+++ b/packages/sncrypto-web/test/memory.test.js
@@ -1,5 +1,4 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
+
import './vendor/chai-as-promised-built.js'
chai.use(chaiAsPromised)
diff --git a/packages/sncrypto-web/test/utils.test.js b/packages/sncrypto-web/test/utils.test.js
index c591050d1..55a1649a4 100644
--- a/packages/sncrypto-web/test/utils.test.js
+++ b/packages/sncrypto-web/test/utils.test.js
@@ -1,5 +1,4 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
+
import './vendor/chai-as-promised-built.js'
chai.use(chaiAsPromised)
diff --git a/packages/snjs/mocha/000.test.js b/packages/snjs/mocha/000.test.js
index f612e88ae..705010e87 100644
--- a/packages/snjs/mocha/000.test.js
+++ b/packages/snjs/mocha/000.test.js
@@ -1,19 +1,17 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
-import * as Factory from './lib/factory.js'
chai.use(chaiAsPromised)
const expect = chai.expect
describe('000 legacy protocol operations', () => {
- const application = Factory.createApplicationWithRealCrypto()
- const protocol004 = new SNProtocolOperator004(new SNWebCrypto())
+ let protocol004
- before(async () => {
- await Factory.initializeApplication(application)
+ beforeEach(async () => {
+ localStorage.clear()
+
+ protocol004 = new SNProtocolOperator004(new SNWebCrypto())
})
- after(async () => {
- await Factory.safeDeinit(application)
+ afterEach(async () => {
+ localStorage.clear()
})
it('cannot decode 000 item', function () {
diff --git a/packages/snjs/mocha/001.test.js b/packages/snjs/mocha/001.test.js
index 2d8214eb0..b3f41fbbf 100644
--- a/packages/snjs/mocha/001.test.js
+++ b/packages/snjs/mocha/001.test.js
@@ -1,27 +1,32 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('001 protocol operations', () => {
- const application = Factory.createApplicationWithRealCrypto()
- const protocol001 = new SNProtocolOperator001(new SNWebCrypto())
+ let application
+ let protocol001
- const _identifier = 'hello@test.com'
- const _password = 'password'
+ let _identifier = 'hello@test.com'
+ let _password = 'password'
let _keyParams, _key
- // runs once before all tests in this block
- before(async () => {
+ beforeEach(async () => {
localStorage.clear()
+
+ application = Factory.createApplicationWithRealCrypto()
+ protocol001 = new SNProtocolOperator001(new SNWebCrypto())
+
await Factory.initializeApplication(application)
+
_key = await protocol001.createRootKey(_identifier, _password, KeyParamsOrigination.Registration)
_keyParams = _key.keyParams
})
- after(async () => {
+ afterEach(async () => {
await Factory.safeDeinit(application)
+ localStorage.clear()
+ application = undefined
})
it('generates random key', async () => {
diff --git a/packages/snjs/mocha/002.test.js b/packages/snjs/mocha/002.test.js
index 21d9779fd..ff47fd240 100644
--- a/packages/snjs/mocha/002.test.js
+++ b/packages/snjs/mocha/002.test.js
@@ -1,26 +1,30 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('002 protocol operations', () => {
- const _identifier = 'hello@test.com'
- const _password = 'password'
+ let _identifier = 'hello@test.com'
+ let _password = 'password'
let _keyParams, _key
- const application = Factory.createApplicationWithRealCrypto()
- const protocol002 = new SNProtocolOperator002(new SNWebCrypto())
+ let application
+ let protocol002
- // runs once before all tests in this block
- before(async () => {
+ beforeEach(async () => {
localStorage.clear()
+
+ application = Factory.createApplicationWithRealCrypto()
+ protocol002 = new SNProtocolOperator002(new SNWebCrypto())
+
await Factory.initializeApplication(application)
_key = await protocol002.createRootKey(_identifier, _password, KeyParamsOrigination.Registration)
_keyParams = _key.keyParams
})
- after(async () => {
+ afterEach(async () => {
await Factory.safeDeinit(application)
+ localStorage.clear()
+ application = undefined
})
it('generates random key', async () => {
diff --git a/packages/snjs/mocha/003.test.js b/packages/snjs/mocha/003.test.js
index 25f5cb850..167ee5eea 100644
--- a/packages/snjs/mocha/003.test.js
+++ b/packages/snjs/mocha/003.test.js
@@ -1,34 +1,31 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('003 protocol operations', () => {
- before(async () => {
- localStorage.clear()
- })
-
- after(async () => {
- localStorage.clear()
- })
-
- const _identifier = 'hello@test.com'
- const _password = 'password'
+ let _identifier = 'hello@test.com'
+ let _password = 'password'
let _keyParams, _key
- const sharedApplication = Factory.createApplicationWithRealCrypto()
- const protocol003 = new SNProtocolOperator003(new SNWebCrypto())
+ let application
+ let protocol003
- // runs once before all tests in this block
- before(async () => {
- await Factory.initializeApplication(sharedApplication)
+ beforeEach(async () => {
+ localStorage.clear()
+
+ application = Factory.createApplicationWithRealCrypto()
+ protocol003 = new SNProtocolOperator003(new SNWebCrypto())
+
+ await Factory.initializeApplication(application)
_key = await protocol003.createRootKey(_identifier, _password, KeyParamsOrigination.Registration)
_keyParams = _key.keyParams
})
- after(async () => {
- await Factory.safeDeinit(sharedApplication)
+ afterEach(async () => {
+ await Factory.safeDeinit(application)
+ localStorage.clear()
+ application = undefined
})
it('generates random key', async () => {
@@ -39,7 +36,7 @@ describe('003 protocol operations', () => {
it('cost minimum should throw', () => {
expect(() => {
- sharedApplication.encryption.costMinimumForVersion('003')
+ application.encryption.costMinimumForVersion('003')
}).to.throw('Cost minimums only apply to versions <= 002')
})
@@ -59,7 +56,7 @@ describe('003 protocol operations', () => {
it('computes proper keys for sign in', async () => {
const identifier = 'foo@bar.com'
const password = 'very_secure'
- const keyParams = sharedApplication.encryption.createKeyParams({
+ const keyParams = application.encryption.createKeyParams({
pw_nonce: 'baaec0131d677cf993381367eb082fe377cefe70118c1699cb9b38f0bc850e7b',
identifier: identifier,
version: '003',
@@ -73,7 +70,7 @@ describe('003 protocol operations', () => {
it('can decrypt item generated with web version 3.3.6', async () => {
const identifier = 'demo@standardnotes.org'
const password = 'password'
- const keyParams = sharedApplication.encryption.createKeyParams({
+ const keyParams = application.encryption.createKeyParams({
pw_nonce: '31107837b44d86179140b7c602a55d694243e2e9ced0c4c914ac21ad90215055',
identifier: identifier,
version: '003',
diff --git a/packages/snjs/mocha/004.test.js b/packages/snjs/mocha/004.test.js
index 839fc765b..503fe953a 100644
--- a/packages/snjs/mocha/004.test.js
+++ b/packages/snjs/mocha/004.test.js
@@ -1,26 +1,33 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('004 protocol operations', function () {
- const _identifier = 'hello@test.com'
- const _password = 'password'
+ let _identifier = 'hello@test.com'
+ let _password = 'password'
let rootKeyParams
let rootKey
- const application = Factory.createApplicationWithRealCrypto()
- const protocol004 = new SNProtocolOperator004(new SNWebCrypto())
+ let application
+ let protocol004
+
+ beforeEach(async function () {
+ localStorage.clear()
+
+ application = Factory.createApplicationWithRealCrypto()
+ protocol004 = new SNProtocolOperator004(new SNWebCrypto())
- before(async function () {
await Factory.initializeApplication(application)
+
rootKey = await protocol004.createRootKey(_identifier, _password, KeyParamsOrigination.Registration)
rootKeyParams = rootKey.keyParams
})
- after(async function () {
+ afterEach(async function () {
await Factory.safeDeinit(application)
+ application = undefined
+ localStorage.clear()
})
it('cost minimum should throw', function () {
diff --git a/packages/snjs/mocha/actions.test.js b/packages/snjs/mocha/actions.test.js
index 574bacad3..1c410d7f2 100644
--- a/packages/snjs/mocha/actions.test.js
+++ b/packages/snjs/mocha/actions.test.js
@@ -1,41 +1,46 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
import * as Utils from './lib/Utils.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('actions service', () => {
const errorProcessingActionMessage = 'An issue occurred while processing this action. Please try again.'
- before(async function () {
+ let application
+ let itemManager
+ let actionsManager
+ let email
+ let password
+ let authParams
+ let fakeServer
+ let actionsExtension
+ let extensionItemUuid
+
+ beforeEach(async function () {
this.timeout(20000)
localStorage.clear()
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.itemManager = this.application.items
- this.actionsManager = this.application.actions
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ application = await Factory.createInitAppWithFakeCrypto()
+ itemManager = application.items
+ actionsManager = application.actions
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const rootKey = await this.application.encryption.createRootKey(
- this.email,
- this.password,
- KeyParamsOrigination.Registration,
- )
- this.authParams = rootKey.keyParams.content
+ const rootKey = await application.encryption.createRootKey(email, password, KeyParamsOrigination.Registration)
+ authParams = rootKey.keyParams.content
- this.fakeServer = sinon.fakeServer.create()
- this.fakeServer.respondImmediately = true
+ fakeServer = sinon.fakeServer.create()
+ fakeServer.respondImmediately = true
- this.actionsExtension = {
+ actionsExtension = {
identifier: 'org.standardnotes.testing',
name: 'Test extension',
content_type: 'Extension',
@@ -81,9 +86,9 @@ describe('actions service', () => {
],
}
- this.fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/get_actions\/(.*)/, (request, params) => {
+ fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/get_actions\/(.*)/, (request, params) => {
const urlParams = new URLSearchParams(params)
- const extension = Copy(this.actionsExtension)
+ const extension = Copy(actionsExtension)
if (urlParams.has('item_uuid')) {
extension.actions.push({
@@ -117,31 +122,31 @@ describe('actions service', () => {
})
const encryptedPayload = CreateEncryptedServerSyncPushPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
}),
)
- this.fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/action_[1,2]\/(.*)/, (request) => {
+ fakeServer.respondWith('GET', /http:\/\/my-extension.sn.org\/action_[1,2]\/(.*)/, (request) => {
request.respond(
200,
{ 'Content-Type': 'application/json' },
JSON.stringify({
item: encryptedPayload,
- auth_params: this.authParams,
+ auth_params: authParams,
}),
)
})
- this.fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_3/', [
+ fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_3/', [
200,
{ 'Content-Type': 'text/html; charset=utf-8' },
'
Action #3
',
])
- this.fakeServer.respondWith('POST', /http:\/\/my-extension.sn.org\/action_[4,6]\/(.*)/, (request) => {
+ fakeServer.respondWith('POST', /http:\/\/my-extension.sn.org\/action_[4,6]\/(.*)/, (request) => {
const requestBody = JSON.parse(request.requestBody)
const response = {
@@ -152,7 +157,7 @@ describe('actions service', () => {
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(response))
})
- this.fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_5/', (request) => {
+ fakeServer.respondWith('GET', 'http://my-extension.sn.org/action_5/', (request) => {
const encryptedPayloadClone = Copy(encryptedPayload)
encryptedPayloadClone.items_key_id = undefined
@@ -163,53 +168,56 @@ describe('actions service', () => {
const payload = {
item: encryptedPayloadClone,
- auth_params: this.authParams,
+ auth_params: authParams,
}
request.respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(payload))
})
// Extension item
- const extensionItem = await this.application.mutator.createItem(
- ContentType.TYPES.ActionsExtension,
- this.actionsExtension,
- )
- this.extensionItemUuid = extensionItem.uuid
+ const extensionItem = await application.mutator.createItem(ContentType.TYPES.ActionsExtension, actionsExtension)
+ extensionItemUuid = extensionItem.uuid
})
- after(async function () {
- this.fakeServer.restore()
- await Factory.safeDeinit(this.application)
- this.application = null
+ afterEach(async function () {
+ fakeServer.restore()
+
+ await Factory.safeDeinit(application)
+
+ application = undefined
+ itemManager = undefined
+ actionsManager = undefined
+ fakeServer = undefined
+
localStorage.clear()
})
it('should get extension items', async function () {
- await this.application.mutator.createItem(ContentType.TYPES.Note, {
+ await application.mutator.createItem(ContentType.TYPES.Note, {
title: 'A simple note',
text: 'Standard Notes rocks! lml.',
})
- const extensions = this.actionsManager.getExtensions()
+ const extensions = actionsManager.getExtensions()
expect(extensions.length).to.eq(1)
})
it('should get extensions in context of item', async function () {
- const noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
+ const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
title: 'Another note',
text: 'Whiskey In The Jar',
})
- const noteItemExtensions = this.actionsManager.extensionsInContextOfItem(noteItem)
+ const noteItemExtensions = actionsManager.extensionsInContextOfItem(noteItem)
expect(noteItemExtensions.length).to.eq(1)
expect(noteItemExtensions[0].supported_types).to.include(noteItem.content_type)
})
it('should get actions based on item context', async function () {
- const tagItem = await this.application.mutator.createItem(ContentType.TYPES.Tag, {
+ const tagItem = await application.mutator.createItem(ContentType.TYPES.Tag, {
title: 'Music',
})
- const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
+ const extensionItem = await itemManager.findItem(extensionItemUuid)
const tagActions = extensionItem.actionsWithContextForItem(tagItem)
expect(tagActions.length).to.eq(1)
@@ -217,15 +225,15 @@ describe('actions service', () => {
})
it('should load extension in context of item', async function () {
- const noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
+ const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
title: 'Yet another note',
text: 'And all things will end ♫',
})
- const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
+ const extensionItem = await itemManager.findItem(extensionItemUuid)
expect(extensionItem.actions.length).to.be.eq(5)
- const extensionWithItem = await this.actionsManager.loadExtensionInContextOfItem(extensionItem, noteItem)
+ const extensionWithItem = await actionsManager.loadExtensionInContextOfItem(extensionItem, noteItem)
expect(extensionWithItem.actions.length).to.be.eq(7)
expect(extensionWithItem.actions.map((action) => action.label)).to.include.members([
/**
@@ -237,7 +245,7 @@ describe('actions service', () => {
])
// Actions that are relevant for an item should not be stored.
- const updatedExtensionItem = await this.itemManager.findItem(this.extensionItemUuid)
+ const updatedExtensionItem = await itemManager.findItem(extensionItemUuid)
const expectedActions = extensionItem.actions.map((action) => {
const { id, ...rest } = action
return rest
@@ -248,18 +256,22 @@ describe('actions service', () => {
describe('render action', async function () {
const sandbox = sinon.createSandbox()
- before(async function () {
- this.noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
+ let noteItem
+ let renderAction
+ let alertServiceAlert
+ let windowAlert
+ let httpServiceGetAbsolute
+
+ beforeEach(async function () {
+ noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
title: 'Hey',
text: 'Welcome To Paradise',
})
- const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
- this.renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
- })
+ const extensionItem = await itemManager.findItem(extensionItemUuid)
- beforeEach(async function () {
- this.alertServiceAlert = sandbox.spy(this.actionsManager.alertService, 'alert')
- this.windowAlert = sandbox.stub(window, 'alert').callsFake((message) => message)
+ renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
+ alertServiceAlert = sandbox.spy(actionsManager.alertService, 'alert')
+ windowAlert = sandbox.stub(window, 'alert').callsFake((message) => message)
})
afterEach(async function () {
@@ -267,35 +279,35 @@ describe('actions service', () => {
})
it('should show an alert if the request fails', async function () {
- this.httpServiceGetAbsolute = sandbox
- .stub(this.actionsManager.httpService, 'getAbsolute')
+ httpServiceGetAbsolute = sandbox
+ .stub(actionsManager.httpService, 'getAbsolute')
.callsFake((url) => Promise.reject(new Error('Dummy error.')))
- const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
+ const actionResponse = await actionsManager.runAction(renderAction, noteItem)
- sinon.assert.calledOnceWithExactly(this.httpServiceGetAbsolute, this.renderAction.url)
- sinon.assert.calledOnceWithExactly(this.alertServiceAlert, errorProcessingActionMessage)
+ sinon.assert.calledOnceWithExactly(httpServiceGetAbsolute, renderAction.url)
+ sinon.assert.calledOnceWithExactly(alertServiceAlert, errorProcessingActionMessage)
expect(actionResponse.error.message).to.eq(errorProcessingActionMessage)
})
it('should return a response if payload is valid', async function () {
- const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
+ const actionResponse = await actionsManager.runAction(renderAction, noteItem)
expect(actionResponse).to.have.property('item')
expect(actionResponse.item.payload.content.title).to.eq('Testing')
})
it('should return undefined if payload is invalid', async function () {
- sandbox.stub(this.actionsManager, 'payloadByDecryptingResponse').returns(null)
+ sandbox.stub(actionsManager, 'payloadByDecryptingResponse').returns(null)
- const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
+ const actionResponse = await actionsManager.runAction(renderAction, noteItem)
expect(actionResponse).to.be.undefined
})
it('should return decrypted payload if password is valid', async function () {
- const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
- this.renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
- const actionResponse = await this.actionsManager.runAction(this.renderAction, this.noteItem)
+ const extensionItem = await itemManager.findItem(extensionItemUuid)
+ renderAction = extensionItem.actions.filter((action) => action.verb === 'render')[0]
+ const actionResponse = await actionsManager.runAction(renderAction, noteItem)
expect(actionResponse.item).to.be.ok
expect(actionResponse.item.title).to.be.equal('Testing')
@@ -305,24 +317,24 @@ describe('actions service', () => {
describe('show action', async function () {
const sandbox = sinon.createSandbox()
- before(async function () {
- const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
- this.showAction = extensionItem.actions[2]
- })
+ let showAction
+ let deviceInterfaceOpenUrl
beforeEach(async function () {
- this.actionsManager.device.openUrl = (url) => url
- this.deviceInterfaceOpenUrl = sandbox.spy(this.actionsManager.device, 'openUrl')
+ const extensionItem = await itemManager.findItem(extensionItemUuid)
+ showAction = extensionItem.actions[2]
+ actionsManager.device.openUrl = (url) => url
+ deviceInterfaceOpenUrl = sandbox.spy(actionsManager.device, 'openUrl')
})
- this.afterEach(async function () {
+ afterEach(async function () {
sandbox.restore()
})
it('should open the action url', async function () {
- const response = await this.actionsManager.runAction(this.showAction)
+ const response = await actionsManager.runAction(showAction)
- sandbox.assert.calledOnceWithExactly(this.deviceInterfaceOpenUrl, this.showAction.url)
+ sandbox.assert.calledOnceWithExactly(deviceInterfaceOpenUrl, showAction.url)
expect(response).to.eql({})
})
})
@@ -330,28 +342,32 @@ describe('actions service', () => {
describe('post action', async function () {
const sandbox = sinon.createSandbox()
- before(async function () {
- this.noteItem = await this.application.mutator.createItem(ContentType.TYPES.Note, {
+ let noteItem
+ let extensionItem
+ let decryptedPostAction
+ let encryptedPostAction
+ let alertServiceAlert
+ let httpServicePostAbsolute
+
+ beforeEach(async function () {
+ noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
title: 'Excuse Me',
text: 'Time To Be King 8)',
})
- this.extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
- this.extensionItem = await this.actionsManager.loadExtensionInContextOfItem(this.extensionItem, this.noteItem)
+ extensionItem = await itemManager.findItem(extensionItemUuid)
+ extensionItem = await actionsManager.loadExtensionInContextOfItem(extensionItem, noteItem)
- this.decryptedPostAction = this.extensionItem.actions.filter(
+ decryptedPostAction = extensionItem.actions.filter(
(action) => action.access_type === 'decrypted' && action.verb === 'post',
)[0]
- this.encryptedPostAction = this.extensionItem.actions.filter(
+ encryptedPostAction = extensionItem.actions.filter(
(action) => action.access_type === 'encrypted' && action.verb === 'post',
)[0]
- })
-
- beforeEach(async function () {
- this.alertServiceAlert = sandbox.spy(this.actionsManager.alertService, 'alert')
- this.windowAlert = sandbox.stub(window, 'alert').callsFake((message) => message)
- this.httpServicePostAbsolute = sandbox.stub(this.actionsManager.httpService, 'postAbsolute')
- this.httpServicePostAbsolute.callsFake((url, params) => Promise.resolve(params))
+ alertServiceAlert = sandbox.spy(actionsManager.alertService, 'alert')
+ sandbox.stub(window, 'alert').callsFake((message) => message)
+ httpServicePostAbsolute = sandbox.stub(actionsManager.httpService, 'postAbsolute')
+ httpServicePostAbsolute.callsFake((url, params) => Promise.resolve(params))
})
afterEach(async function () {
@@ -359,52 +375,50 @@ describe('actions service', () => {
})
it('should include generic encrypted payload within request body', async function () {
- const response = await this.actionsManager.runAction(this.encryptedPostAction, this.noteItem)
+ const response = await actionsManager.runAction(encryptedPostAction, noteItem)
expect(response.items[0].enc_item_key).to.satisfy((string) => {
- return string.startsWith(this.application.encryption.getLatestVersion())
+ return string.startsWith(application.encryption.getLatestVersion())
})
- expect(response.items[0].uuid).to.eq(this.noteItem.uuid)
+ expect(response.items[0].uuid).to.eq(noteItem.uuid)
expect(response.items[0].auth_hash).to.not.be.ok
expect(response.items[0].content_type).to.be.ok
expect(response.items[0].created_at).to.be.ok
expect(response.items[0].content).to.satisfy((string) => {
- return string.startsWith(this.application.encryption.getLatestVersion())
+ return string.startsWith(application.encryption.getLatestVersion())
})
})
it('should include generic decrypted payload within request body', async function () {
- const response = await this.actionsManager.runAction(this.decryptedPostAction, this.noteItem)
+ const response = await actionsManager.runAction(decryptedPostAction, noteItem)
- expect(response.items[0].uuid).to.eq(this.noteItem.uuid)
+ expect(response.items[0].uuid).to.eq(noteItem.uuid)
expect(response.items[0].enc_item_key).to.not.be.ok
expect(response.items[0].auth_hash).to.not.be.ok
expect(response.items[0].content_type).to.be.ok
expect(response.items[0].created_at).to.be.ok
- expect(response.items[0].content.title).to.eq(this.noteItem.title)
- expect(response.items[0].content.text).to.eq(this.noteItem.text)
+ expect(response.items[0].content.title).to.eq(noteItem.title)
+ expect(response.items[0].content.text).to.eq(noteItem.text)
})
it('should post to the action url', async function () {
- this.httpServicePostAbsolute.restore()
- const response = await this.actionsManager.runAction(this.decryptedPostAction, this.noteItem)
+ httpServicePostAbsolute.restore()
+ const response = await actionsManager.runAction(decryptedPostAction, noteItem)
expect(response).to.be.ok
- expect(response.uuid).to.eq(this.noteItem.uuid)
+ expect(response.uuid).to.eq(noteItem.uuid)
expect(response.result).to.eq('Action POSTed successfully.')
})
it('should alert if an error occurred while processing the action', async function () {
- this.httpServicePostAbsolute.restore()
+ httpServicePostAbsolute.restore()
const dummyError = new Error('Dummy error.')
- sandbox
- .stub(this.actionsManager.httpService, 'postAbsolute')
- .callsFake((url, params) => Promise.reject(dummyError))
+ sandbox.stub(actionsManager.httpService, 'postAbsolute').callsFake((url, params) => Promise.reject(dummyError))
- const response = await this.actionsManager.runAction(this.decryptedPostAction, this.noteItem)
+ const response = await actionsManager.runAction(decryptedPostAction, noteItem)
- sinon.assert.calledOnceWithExactly(this.alertServiceAlert, errorProcessingActionMessage)
+ sinon.assert.calledOnceWithExactly(alertServiceAlert, errorProcessingActionMessage)
expect(response).to.be.eq(dummyError)
})
})
@@ -412,15 +426,17 @@ describe('actions service', () => {
describe('nested action', async function () {
const sandbox = sinon.createSandbox()
- before(async function () {
- const extensionItem = await this.itemManager.findItem(this.extensionItemUuid)
- this.nestedAction = extensionItem.actions.filter((action) => action.verb === 'nested')[0]
- })
+ let nestedAction
+ let actionsManagerRunAction
+ let httpServiceRunHttp
+ let actionResponse
beforeEach(async function () {
- this.actionsManagerRunAction = sandbox.spy(this.actionsManager, 'runAction')
- this.httpServiceRunHttp = sandbox.spy(this.actionsManager.httpService, 'runHttp')
- this.actionResponse = await this.actionsManager.runAction(this.nestedAction)
+ const extensionItem = await itemManager.findItem(extensionItemUuid)
+ nestedAction = extensionItem.actions.filter((action) => action.verb === 'nested')[0]
+ actionsManagerRunAction = sandbox.spy(actionsManager, 'runAction')
+ httpServiceRunHttp = sandbox.spy(actionsManager.httpService, 'runHttp')
+ actionResponse = await actionsManager.runAction(nestedAction)
})
afterEach(async function () {
@@ -428,15 +444,15 @@ describe('actions service', () => {
})
it('should return undefined', async function () {
- expect(this.actionResponse).to.be.undefined
+ expect(actionResponse).to.be.undefined
})
it('should call runAction once', async function () {
- sandbox.assert.calledOnce(this.actionsManagerRunAction)
+ sandbox.assert.calledOnce(actionsManagerRunAction)
})
it('should not make any http requests', async function () {
- sandbox.assert.notCalled(this.httpServiceRunHttp)
+ sandbox.assert.notCalled(httpServiceRunHttp)
})
})
})
diff --git a/packages/snjs/mocha/app-group.test.js b/packages/snjs/mocha/app-group.test.js
index 4cb7fba6d..49d9789ee 100644
--- a/packages/snjs/mocha/app-group.test.js
+++ b/packages/snjs/mocha/app-group.test.js
@@ -1,23 +1,32 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import WebDeviceInterface from './lib/web_device_interface.js'
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('application group', function () {
- const globalDevice = new WebDeviceInterface(setTimeout.bind(window), setInterval.bind(window))
+ let device
+ let group
beforeEach(async function () {
localStorage.clear()
+
+ device = new WebDeviceInterface(setTimeout.bind(window), setInterval.bind(window))
+ group = new SNApplicationGroup(device)
})
afterEach(async function () {
+ if (group.primaryApplication) {
+ await Factory.safeDeinit(group.primaryApplication)
+ }
+ device.deinit()
+
localStorage.clear()
+
+ group = undefined
})
it('initializing a group should result with primary application', async function () {
- const group = new SNApplicationGroup(globalDevice)
await group.initialize({
applicationCreator: (descriptor, deviceInterface) => {
return Factory.createApplicationWithFakeCrypto(descriptor.identifier, deviceInterface)
@@ -25,12 +34,9 @@ describe('application group', function () {
})
expect(group.primaryApplication).to.be.ok
expect(group.primaryApplication.identifier).to.be.ok
-
- await Factory.safeDeinit(group.primaryApplication)
})
it('initializing a group should result with proper descriptor setup', async function () {
- const group = new SNApplicationGroup(globalDevice)
await group.initialize({
applicationCreator: (descriptor, deviceInterface) => {
return Factory.createApplicationWithFakeCrypto(descriptor.identifier, deviceInterface)
@@ -38,12 +44,9 @@ describe('application group', function () {
})
const identifier = group.primaryApplication.identifier
expect(group.descriptorRecord[identifier].identifier).to.equal(identifier)
-
- await Factory.safeDeinit(group.primaryApplication)
})
it('should persist descriptor record after changes', async function () {
- const group = new SNApplicationGroup(globalDevice)
await group.initialize({
applicationCreator: (descriptor, device) => {
return Factory.createInitAppWithFakeCryptoWithOptions({
@@ -59,14 +62,13 @@ describe('application group', function () {
expect(descriptorRecord[identifier].primary).to.equal(true)
await group.unloadCurrentAndCreateNewDescriptor()
- const descriptorRecord2 = await globalDevice.getJsonParsedRawStorageValue(RawStorageKey.DescriptorRecord)
+ const descriptorRecord2 = await device.getJsonParsedRawStorageValue(RawStorageKey.DescriptorRecord)
expect(Object.keys(descriptorRecord2).length).to.equal(2)
expect(descriptorRecord2[identifier].primary).to.equal(false)
})
it('adding new application should incrememnt total descriptor count', async function () {
- const group = new SNApplicationGroup(globalDevice)
await group.initialize({
applicationCreator: (descriptor, device) => {
return Factory.createInitAppWithFakeCryptoWithOptions({
@@ -82,7 +84,6 @@ describe('application group', function () {
})
it('should be notified when application changes', async function () {
- const group = new SNApplicationGroup(globalDevice)
let notifyCount = 0
const expectedCount = 2
// eslint-disable-next-line no-async-promise-executor
diff --git a/packages/snjs/mocha/application.test.js b/packages/snjs/mocha/application.test.js
index 013c48242..54f4196c1 100644
--- a/packages/snjs/mocha/application.test.js
+++ b/packages/snjs/mocha/application.test.js
@@ -1,7 +1,6 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from './lib/BaseItemCounts.js'
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -133,6 +132,12 @@ describe('application instances', () => {
deinit = sinon.spy(testSNApp, 'deinit')
})
+ afterEach(async () => {
+ await Factory.safeDeinit(testSNApp)
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('shows confirmation dialog when there are unsaved changes', async () => {
await testSNApp.mutator.setItemDirty(testNote1)
await testSNApp.user.signOut()
diff --git a/packages/snjs/mocha/auth-fringe-cases.test.js b/packages/snjs/mocha/auth-fringe-cases.test.js
index aa8039ce2..f78ba7c74 100644
--- a/packages/snjs/mocha/auth-fringe-cases.test.js
+++ b/packages/snjs/mocha/auth-fringe-cases.test.js
@@ -1,14 +1,16 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from './lib/BaseItemCounts.js'
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('auth fringe cases', () => {
- const createContext = async () => {
+ let context
+
+ beforeEach(async function () {
+ localStorage.clear()
const application = await Factory.createInitAppWithFakeCrypto()
- return {
+ context = {
expectedItemCount: BaseItemCounts.DefaultItems,
application: application,
email: UuidGenerator.GenerateUuid(),
@@ -17,10 +19,6 @@ describe('auth fringe cases', () => {
await Factory.safeDeinit(application)
},
}
- }
-
- beforeEach(async function () {
- localStorage.clear()
})
afterEach(async function () {
@@ -40,7 +38,6 @@ describe('auth fringe cases', () => {
describe('localStorage improperly cleared with 1 item', function () {
it('item should be errored', async function () {
- const context = await createContext()
await context.application.register(context.email, context.password)
const note = await Factory.createSyncedNote(context.application)
clearApplicationLocalStorageOfNonItems()
@@ -55,7 +52,6 @@ describe('auth fringe cases', () => {
})
it('signing in again should decrypt item', async function () {
- const context = await createContext()
await context.application.register(context.email, context.password)
const note = await Factory.createSyncedNote(context.application)
clearApplicationLocalStorageOfNonItems()
@@ -76,7 +72,6 @@ describe('auth fringe cases', () => {
describe('having offline item matching remote item uuid', function () {
it('offline item should not overwrite recently updated server item and conflict should be created', async function () {
- const context = await createContext()
await context.application.register(context.email, context.password)
const staleText = 'stale text'
diff --git a/packages/snjs/mocha/auth.test.js b/packages/snjs/mocha/auth.test.js
index 45715bfae..dc3f7e141 100644
--- a/packages/snjs/mocha/auth.test.js
+++ b/packages/snjs/mocha/auth.test.js
@@ -13,11 +13,7 @@ describe('basic auth', function () {
}
let context
-
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
+ let expectedItemCount
beforeEach(async function () {
localStorage.clear()
@@ -26,12 +22,23 @@ describe('basic auth', function () {
await context.launch()
- this.expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
+ expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
+ })
+
+ afterEach(async function () {
+ await context.deinit()
+
+ localStorage.clear()
+
+ context = undefined
+
+ sinon.restore()
})
it('successfully register new account', async function () {
const response = await context.register()
expect(response).to.be.ok
+
expect(await context.application.encryption.getRootKey()).to.be.ok
})
@@ -58,7 +65,7 @@ describe('basic auth', function () {
expect(await context.application.encryption.getRootKey()).to.be.ok
- context.application = await Factory.signOutApplicationAndReturnNew(context.application)
+ await context.signout()
expect(await context.application.encryption.getRootKey()).to.not.be.ok
expect(context.application.encryption.rootKeyManager.getKeyMode()).to.equal(KeyMode.RootKeyNone)
@@ -233,7 +240,7 @@ describe('basic auth', function () {
await specContext.launch()
await specContext.register()
- await specContext.signout()
+ await specContext.deinit()
specContext = await Factory.createAppContextWithFakeCrypto(Math.random(), uppercase, password)
@@ -255,10 +262,11 @@ describe('basic auth', function () {
* with an uppercase email
*/
const password = UuidGenerator.GenerateUuid()
+
let specContext = await Factory.createAppContextWithFakeCrypto(Math.random(), nospace, password)
await specContext.launch()
await specContext.register()
- await specContext.signout()
+ await specContext.deinit()
specContext = await Factory.createAppContextWithFakeCrypto(Math.random(), withspace, password)
await specContext.launch()
@@ -272,7 +280,8 @@ describe('basic auth', function () {
it('fails login with wrong password', async function () {
await context.register()
- context.application = await Factory.signOutApplicationAndReturnNew(context.application)
+ await context.signout()
+
const response = await context.application.signIn(
context.email,
'wrongpassword',
@@ -299,7 +308,8 @@ describe('basic auth', function () {
expect(response.error).to.be.ok
/** Ensure we can still log in */
- context.application = await Factory.signOutAndBackIn(context.application, context.email, context.password)
+ await context.signout()
+ await context.signIn()
}).timeout(20000)
it('registering for new account and completing first after download sync should not put us out of sync', async function () {
@@ -339,23 +349,23 @@ describe('basic auth', function () {
const noteCount = 5
await Factory.createManyMappedNotes(context.application, noteCount)
- this.expectedItemCount += noteCount
+ expectedItemCount += noteCount
await context.sync()
- expect(context.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(context.application.items.items.length).to.equal(expectedItemCount)
const newPassword = 'newpassword'
const response = await context.application.changePassword(context.password, newPassword)
expect(response.error).to.not.be.ok
- this.expectedItemCount += ['new items key'].length
- expect(context.application.items.items.length).to.equal(this.expectedItemCount)
+ expectedItemCount += ['new items key'].length
+ expect(context.application.items.items.length).to.equal(expectedItemCount)
expect(context.application.payloads.invalidPayloads.length).to.equal(0)
await context.application.sync.markAllItemsAsNeedingSyncAndPersist()
await context.sync(syncOptions)
- expect(context.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(context.application.items.items.length).to.equal(expectedItemCount)
}).timeout(40000)
it('should sign into account after changing password', async function () {
@@ -365,7 +375,7 @@ describe('basic auth', function () {
const response = await context.application.changePassword(context.password, newPassword)
expect(response.error).to.not.be.ok
- this.expectedItemCount += ['new items key'].length
+ expectedItemCount += ['new items key'].length
await context.signout()
@@ -382,7 +392,7 @@ describe('basic auth', function () {
expect(signinResponse.data.error).to.not.be.ok
expect(await context.application.encryption.getRootKey()).to.be.ok
- expect(context.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(context.application.items.items.length).to.equal(expectedItemCount)
expect(context.application.payloads.invalidPayloads.length).to.equal(0)
})
@@ -393,7 +403,7 @@ describe('basic auth', function () {
const noteCount = 3
await Factory.createManyMappedNotes(context.application, noteCount)
- this.expectedItemCount += noteCount
+ expectedItemCount += noteCount
await context.sync()
@@ -401,9 +411,9 @@ describe('basic auth', function () {
const response = await context.application.changePassword(context.password, newPassword)
expect(response.error).to.not.be.ok
- this.expectedItemCount += ['new items key'].length
+ expectedItemCount += ['new items key'].length
- expect(context.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(context.application.items.items.length).to.equal(expectedItemCount)
})
it('changes password many times', async function () {
@@ -411,7 +421,7 @@ describe('basic auth', function () {
const noteCount = 10
await Factory.createManyMappedNotes(context.application, noteCount)
- this.expectedItemCount += noteCount
+ expectedItemCount += noteCount
await context.application.sync.sync(syncOptions)
const numTimesToChangePw = 3
@@ -422,12 +432,12 @@ describe('basic auth', function () {
await context.application.changePassword(currentPassword, newPassword)
/** New items key */
- this.expectedItemCount++
+ expectedItemCount++
currentPassword = newPassword
newPassword = Factory.randomString()
- expect(context.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(context.application.items.items.length).to.equal(expectedItemCount)
expect(context.application.payloads.invalidPayloads.length).to.equal(0)
await context.application.sync.markAllItemsAsNeedingSyncAndPersist()
@@ -460,7 +470,7 @@ describe('basic auth', function () {
email: context.email,
password: context.password,
})
- context.application = await Factory.signOutApplicationAndReturnNew(context.application)
+ await context.signout()
const performSignIn = sinon.spy(context.application.sessions, 'performSignIn')
await context.application.signIn(context.email, 'wrong password', undefined, undefined, undefined, true)
expect(performSignIn.callCount).to.equal(1)
diff --git a/packages/snjs/mocha/backups.test.js b/packages/snjs/mocha/backups.test.js
index ab9a5db87..709c83bee 100644
--- a/packages/snjs/mocha/backups.test.js
+++ b/packages/snjs/mocha/backups.test.js
@@ -1,41 +1,38 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from './lib/BaseItemCounts.js'
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('backups', function () {
- before(function () {
- localStorage.clear()
- })
-
- after(function () {
- localStorage.clear()
- })
+ let application
+ let email
+ let password
beforeEach(async function () {
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ localStorage.clear()
+ application = await Factory.createInitAppWithFakeCrypto()
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
- this.application = null
+ await Factory.safeDeinit(application)
+ application = null
+ localStorage.clear()
})
it('backup file should have a version number', async function () {
- let data = await this.application.createDecryptedBackupFile()
- expect(data.version).to.equal(this.application.encryption.getLatestVersion())
- await this.application.addPasscode('passcode')
- data = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
- expect(data.version).to.equal(this.application.encryption.getLatestVersion())
+ let data = await application.createDecryptedBackupFile()
+ expect(data.version).to.equal(application.encryption.getLatestVersion())
+ await application.addPasscode('passcode')
+ data = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ expect(data.version).to.equal(application.encryption.getLatestVersion())
})
it('no passcode + no account backup file should have correct number of items', async function () {
- await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
- const data = await this.application.createDecryptedBackupFile()
+ await Promise.all([Factory.createSyncedNote(application), Factory.createSyncedNote(application)])
+ const data = await application.createDecryptedBackupFile()
const offsetForNewItems = 2
const offsetForNoItemsKey = -1
expect(data.items.length).to.equal(BaseItemCounts.DefaultItems + offsetForNewItems + offsetForNoItemsKey)
@@ -43,68 +40,68 @@ describe('backups', function () {
it('passcode + no account backup file should have correct number of items', async function () {
const passcode = 'passcode'
- await this.application.addPasscode(passcode)
- await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
+ await application.addPasscode(passcode)
+ await Promise.all([Factory.createSyncedNote(application), Factory.createSyncedNote(application)])
// Encrypted backup without authorization
- const encryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ const encryptedData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
expect(encryptedData.items.length).to.equal(BaseItemCounts.DefaultItems + 2)
// Encrypted backup with authorization
- Factory.handlePasswordChallenges(this.application, passcode)
- const authorizedEncryptedData = await this.application.createEncryptedBackupFile()
+ Factory.handlePasswordChallenges(application, passcode)
+ const authorizedEncryptedData = await application.createEncryptedBackupFile()
expect(authorizedEncryptedData.items.length).to.equal(BaseItemCounts.DefaultItems + 2)
})
it('no passcode + account backup file should have correct number of items', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
+ await Promise.all([Factory.createSyncedNote(application), Factory.createSyncedNote(application)])
// Encrypted backup without authorization
- const encryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ const encryptedData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
expect(encryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
- Factory.handlePasswordChallenges(this.application, this.password)
+ Factory.handlePasswordChallenges(application, password)
// Decrypted backup
- const decryptedData = await this.application.createDecryptedBackupFile()
+ const decryptedData = await application.createDecryptedBackupFile()
expect(decryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccountWithoutItemsKey + 2)
// Encrypted backup with authorization
- const authorizedEncryptedData = await this.application.createEncryptedBackupFile()
+ const authorizedEncryptedData = await application.createEncryptedBackupFile()
expect(authorizedEncryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
})
it('passcode + account backup file should have correct number of items', async function () {
const passcode = 'passcode'
- await this.application.register(this.email, this.password)
- Factory.handlePasswordChallenges(this.application, this.password)
- await this.application.addPasscode(passcode)
- await Promise.all([Factory.createSyncedNote(this.application), Factory.createSyncedNote(this.application)])
+ await application.register(email, password)
+ Factory.handlePasswordChallenges(application, password)
+ await application.addPasscode(passcode)
+ await Promise.all([Factory.createSyncedNote(application), Factory.createSyncedNote(application)])
// Encrypted backup without authorization
- const encryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ const encryptedData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
expect(encryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
- Factory.handlePasswordChallenges(this.application, passcode)
+ Factory.handlePasswordChallenges(application, passcode)
// Decrypted backup
- const decryptedData = await this.application.createDecryptedBackupFile()
+ const decryptedData = await application.createDecryptedBackupFile()
expect(decryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccountWithoutItemsKey + 2)
// Encrypted backup with authorization
- const authorizedEncryptedData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ const authorizedEncryptedData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
expect(authorizedEncryptedData.items.length).to.equal(BaseItemCounts.DefaultItemsWithAccount + 2)
}).timeout(10000)
it('backup file item should have correct fields', async function () {
- await Factory.createSyncedNote(this.application)
- let backupData = await this.application.createDecryptedBackupFile()
+ await Factory.createSyncedNote(application)
+ let backupData = await application.createDecryptedBackupFile()
let rawItem = backupData.items.find((i) => i.content_type === ContentType.TYPES.Note)
expect(rawItem.fields).to.not.be.ok
@@ -118,12 +115,12 @@ describe('backups', function () {
expect(rawItem.updated_at).to.be.ok
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- backupData = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
rawItem = backupData.items.find((i) => i.content_type === ContentType.TYPES.Note)
expect(rawItem.fields).to.not.be.ok
@@ -138,11 +135,11 @@ describe('backups', function () {
})
it('downloading backup if item is error decrypting should succeed', async function () {
- await Factory.createSyncedNote(this.application)
+ await Factory.createSyncedNote(application)
- const note = await Factory.createSyncedNote(this.application)
+ const note = await Factory.createSyncedNote(application)
- const encrypted = await this.application.encryption.encryptSplitSingle({
+ const encrypted = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [note.payload],
},
@@ -152,19 +149,19 @@ describe('backups', function () {
errorDecrypting: true,
})
- await this.application.payloads.emitPayload(errored)
+ await application.payloads.emitPayload(errored)
- const erroredItem = this.application.items.findAnyItem(errored.uuid)
+ const erroredItem = application.items.findAnyItem(errored.uuid)
expect(erroredItem.errorDecrypting).to.equal(true)
- const backupData = await this.application.createDecryptedBackupFile()
+ const backupData = await application.createDecryptedBackupFile()
expect(backupData.items.length).to.equal(BaseItemCounts.DefaultItemsNoAccounNoItemsKey + 2)
})
it('decrypted backup file should not have keyParams', async function () {
- const backup = await this.application.createDecryptedBackupFile()
+ const backup = await application.createDecryptedBackupFile()
expect(backup).to.not.haveOwnProperty('keyParams')
})
@@ -187,31 +184,31 @@ describe('backups', function () {
})
it('encrypted backup file should have keyParams', async function () {
- await this.application.addPasscode('passcode')
- const backup = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ await application.addPasscode('passcode')
+ const backup = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
expect(backup).to.haveOwnProperty('keyParams')
})
it('decrypted backup file should not have itemsKeys', async function () {
- const backup = await this.application.createDecryptedBackupFile()
+ const backup = await application.createDecryptedBackupFile()
expect(backup.items.some((item) => item.content_type === ContentType.TYPES.ItemsKey)).to.be.false
})
it('encrypted backup file should have itemsKeys', async function () {
- await this.application.addPasscode('passcode')
- const backup = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ await application.addPasscode('passcode')
+ const backup = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
expect(backup.items.some((item) => item.content_type === ContentType.TYPES.ItemsKey)).to.be.true
})
it('backup file with no account and no passcode should be decrypted', async function () {
- const note = await Factory.createSyncedNote(this.application)
- const backup = await this.application.createDecryptedBackupFile()
+ const note = await Factory.createSyncedNote(application)
+ const backup = await application.createDecryptedBackupFile()
expect(backup).to.not.haveOwnProperty('keyParams')
expect(backup.items.some((item) => item.content_type === ContentType.TYPES.ItemsKey)).to.be.false
expect(backup.items.find((item) => item.content_type === ContentType.TYPES.Note).uuid).to.equal(note.uuid)
let error
try {
- await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ await application.createEncryptedBackupFileForAutomatedDesktopBackups()
} catch (e) {
error = e
}
diff --git a/packages/snjs/mocha/collections.test.js b/packages/snjs/mocha/collections.test.js
index 72f057cdb..3a4eb00d8 100644
--- a/packages/snjs/mocha/collections.test.js
+++ b/packages/snjs/mocha/collections.test.js
@@ -1,16 +1,15 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
import { createRelatedNoteTagPairPayload } from './lib/Items.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('payload collections', () => {
- before(async () => {
+ beforeEach(async () => {
localStorage.clear()
})
- after(async () => {
+ afterEach(async () => {
localStorage.clear()
})
diff --git a/packages/snjs/mocha/device_auth.test.js b/packages/snjs/mocha/device_auth.test.js
index 982ddb90b..230669562 100644
--- a/packages/snjs/mocha/device_auth.test.js
+++ b/packages/snjs/mocha/device_auth.test.js
@@ -1,6 +1,5 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
diff --git a/packages/snjs/mocha/features.test.js b/packages/snjs/mocha/features.test.js
index 334315cb0..a9d95ce4a 100644
--- a/packages/snjs/mocha/features.test.js
+++ b/packages/snjs/mocha/features.test.js
@@ -1,6 +1,6 @@
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
chai.use(chaiAsPromised)
+
const expect = chai.expect
describe('features', () => {
@@ -9,6 +9,7 @@ describe('features', () => {
let password
beforeEach(async function () {
+ localStorage.clear()
application = await Factory.createInitAppWithFakeCrypto()
sinon.spy(application.mutator, 'createItem')
@@ -28,6 +29,8 @@ describe('features', () => {
afterEach(async function () {
Factory.safeDeinit(application)
sinon.restore()
+ localStorage.clear()
+ application = undefined
})
describe('new user roles received on api response meta', () => {
diff --git a/packages/snjs/mocha/files.test.js b/packages/snjs/mocha/files.test.js
index 8b02d9b37..7a266170b 100644
--- a/packages/snjs/mocha/files.test.js
+++ b/packages/snjs/mocha/files.test.js
@@ -17,6 +17,14 @@ describe('files', function () {
localStorage.clear()
})
+ afterEach(async function () {
+ await Factory.safeDeinit(application)
+ localStorage.clear()
+
+ application = undefined
+ context = undefined
+ })
+
const setup = async ({ fakeCrypto, subscription = true }) => {
if (fakeCrypto) {
context = await Factory.createAppContextWithFakeCrypto()
@@ -41,11 +49,6 @@ describe('files', function () {
}
}
- afterEach(async function () {
- await Factory.safeDeinit(application)
- localStorage.clear()
- })
-
it('should create valet token from server', async function () {
await setup({ fakeCrypto: true, subscription: true })
diff --git a/packages/snjs/mocha/history.test.js b/packages/snjs/mocha/history.test.js
index 421a7b54b..7aa52fd4e 100644
--- a/packages/snjs/mocha/history.test.js
+++ b/packages/snjs/mocha/history.test.js
@@ -1,13 +1,14 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
import { createNoteParams } from './lib/Items.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('history manager', () => {
const largeCharacterChange = 25
+ let application, history, email, password
+
const syncOptions = {
checkIntegrity: true,
awaitAll: true,
@@ -23,15 +24,15 @@ describe('history manager', () => {
describe('session', function () {
beforeEach(async function () {
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.history = this.application.dependencies.get(TYPES.HistoryManager)
- this.payloadManager = this.application.payloads
+ application = await Factory.createInitAppWithFakeCrypto()
+ history = application.dependencies.get(TYPES.HistoryManager)
+
/** Automatically optimize after every revision by setting this to 0 */
- this.history.itemRevisionThreshold = 0
+ history.itemRevisionThreshold = 0
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
})
async function setTextAndSync(application, item, text) {
@@ -53,15 +54,15 @@ describe('history manager', () => {
}
it('create basic history entries 1', async function () {
- const item = await Factory.createSyncedNote(this.application)
- expect(this.history.sessionHistoryForItem(item).length).to.equal(0)
+ const item = await Factory.createSyncedNote(application)
+ expect(history.sessionHistoryForItem(item).length).to.equal(0)
/** Sync with same contents, should not create new entry */
- await Factory.markDirtyAndSyncItem(this.application, item)
- expect(this.history.sessionHistoryForItem(item).length).to.equal(0)
+ await Factory.markDirtyAndSyncItem(application, item)
+ expect(history.sessionHistoryForItem(item).length).to.equal(0)
/** Sync with different contents, should create new entry */
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -70,12 +71,12 @@ describe('history manager', () => {
undefined,
syncOptions,
)
- expect(this.history.sessionHistoryForItem(item).length).to.equal(1)
+ expect(history.sessionHistoryForItem(item).length).to.equal(1)
})
it('first change should create revision with previous value', async function () {
- const identifier = this.application.identifier
- const item = await Factory.createSyncedNote(this.application)
+ const identifier = application.identifier
+ const item = await Factory.createSyncedNote(application)
/** Simulate loading new application session */
const context = await Factory.createAppContext({ identifier })
@@ -119,53 +120,41 @@ describe('history manager', () => {
})
it('should optimize basic entries', async function () {
- let item = await Factory.createSyncedNote(this.application)
+ let item = await Factory.createSyncedNote(application)
/**
* Add 1 character. This typically would be discarded as an entry, but it
* won't here because it's the first change, which we want to keep.
*/
- await setTextAndSync(this.application, item, item.content.text + '1')
- expect(this.history.sessionHistoryForItem(item).length).to.equal(1)
+ await setTextAndSync(application, item, item.content.text + '1')
+ expect(history.sessionHistoryForItem(item).length).to.equal(1)
/**
* Changing it by one character should keep this entry,
* since it's now the last (and will keep the first)
*/
- item = await setTextAndSync(this.application, item, item.content.text + '2')
- expect(this.history.sessionHistoryForItem(item).length).to.equal(2)
+ item = await setTextAndSync(application, item, item.content.text + '2')
+ expect(history.sessionHistoryForItem(item).length).to.equal(2)
/**
* Change it over the largeCharacterChange threshold. It should keep this
* revision, but now remove the previous revision, since it's no longer
* the last, and is a small change.
*/
- item = await setTextAndSync(
- this.application,
- item,
- item.content.text + Factory.randomString(largeCharacterChange + 1),
- )
- expect(this.history.sessionHistoryForItem(item).length).to.equal(2)
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(largeCharacterChange + 1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(2)
- item = await setTextAndSync(
- this.application,
- item,
- item.content.text + Factory.randomString(largeCharacterChange + 1),
- )
- expect(this.history.sessionHistoryForItem(item).length).to.equal(2)
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(largeCharacterChange + 1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(2)
/** Delete over threshold text. */
- item = await setTextAndSync(
- this.application,
- item,
- deleteCharsFromString(item.content.text, largeCharacterChange + 1),
- )
- expect(this.history.sessionHistoryForItem(item).length).to.equal(3)
+ item = await setTextAndSync(application, item, deleteCharsFromString(item.content.text, largeCharacterChange + 1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(3)
/**
* Delete just 1 character. It should now retain the previous revision, as well as the
* one previous to that.
*/
- item = await setTextAndSync(this.application, item, deleteCharsFromString(item.content.text, 1))
- expect(this.history.sessionHistoryForItem(item).length).to.equal(4)
- item = await setTextAndSync(this.application, item, deleteCharsFromString(item.content.text, 1))
- expect(this.history.sessionHistoryForItem(item).length).to.equal(5)
+ item = await setTextAndSync(application, item, deleteCharsFromString(item.content.text, 1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(4)
+ item = await setTextAndSync(application, item, deleteCharsFromString(item.content.text, 1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(5)
})
it('should keep the entry right before a large deletion, regardless of its delta', async function () {
@@ -174,27 +163,19 @@ describe('history manager', () => {
text: Factory.randomString(100),
}),
)
- let item = await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
- await this.application.mutator.setItemDirty(item)
- await this.application.sync.sync(syncOptions)
+ let item = await application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
+ await application.mutator.setItemDirty(item)
+ await application.sync.sync(syncOptions)
/** It should keep the first and last by default */
- item = await setTextAndSync(this.application, item, item.content.text)
- item = await setTextAndSync(this.application, item, item.content.text + Factory.randomString(1))
- expect(this.history.sessionHistoryForItem(item).length).to.equal(2)
- item = await setTextAndSync(
- this.application,
- item,
- deleteCharsFromString(item.content.text, largeCharacterChange + 1),
- )
- expect(this.history.sessionHistoryForItem(item).length).to.equal(2)
- item = await setTextAndSync(this.application, item, item.content.text + Factory.randomString(1))
- expect(this.history.sessionHistoryForItem(item).length).to.equal(3)
- item = await setTextAndSync(
- this.application,
- item,
- item.content.text + Factory.randomString(largeCharacterChange + 1),
- )
- expect(this.history.sessionHistoryForItem(item).length).to.equal(4)
+ item = await setTextAndSync(application, item, item.content.text)
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(2)
+ item = await setTextAndSync(application, item, deleteCharsFromString(item.content.text, largeCharacterChange + 1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(2)
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(3)
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(largeCharacterChange + 1))
+ expect(history.sessionHistoryForItem(item).length).to.equal(4)
})
it('entries should be ordered from newest to oldest', async function () {
@@ -204,32 +185,23 @@ describe('history manager', () => {
}),
)
- let item = await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
+ let item = await application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
- await this.application.mutator.setItemDirty(item)
- await this.application.sync.sync(syncOptions)
+ await application.mutator.setItemDirty(item)
+ await application.sync.sync(syncOptions)
- item = await setTextAndSync(this.application, item, item.content.text + Factory.randomString(1))
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(1))
- item = await setTextAndSync(
- this.application,
- item,
- deleteCharsFromString(item.content.text, largeCharacterChange + 1),
- )
+ item = await setTextAndSync(application, item, deleteCharsFromString(item.content.text, largeCharacterChange + 1))
- item = await setTextAndSync(this.application, item, item.content.text + Factory.randomString(1))
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(1))
- item = await setTextAndSync(
- this.application,
- item,
- item.content.text + Factory.randomString(largeCharacterChange + 1),
- )
+ item = await setTextAndSync(application, item, item.content.text + Factory.randomString(largeCharacterChange + 1))
/** First entry should be the latest revision. */
- const latestRevision = this.history.sessionHistoryForItem(item)[0]
+ const latestRevision = history.sessionHistoryForItem(item)[0]
/** Last entry should be the initial revision. */
- const initialRevision =
- this.history.sessionHistoryForItem(item)[this.history.sessionHistoryForItem(item).length - 1]
+ const initialRevision = history.sessionHistoryForItem(item)[history.sessionHistoryForItem(item).length - 1]
expect(latestRevision).to.not.equal(initialRevision)
@@ -243,9 +215,9 @@ describe('history manager', () => {
it('unsynced entries should use payload created_at for preview titles', async function () {
const payload = Factory.createNotePayload()
- await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
- const item = this.application.items.findItem(payload.uuid)
- await this.application.changeAndSaveItem.execute(
+ await application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
+ const item = application.items.findItem(payload.uuid)
+ await application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -254,7 +226,7 @@ describe('history manager', () => {
undefined,
syncOptions,
)
- const historyItem = this.history.sessionHistoryForItem(item)[0]
+ const historyItem = history.sessionHistoryForItem(item)[0]
expect(historyItem.previewTitle()).to.equal(historyItem.payload.created_at.toLocaleString())
})
})
@@ -263,52 +235,54 @@ describe('history manager', () => {
this.timeout(Factory.TwentySecondTimeout)
beforeEach(async function () {
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.history = this.application.dependencies.get(TYPES.HistoryManager)
- this.payloadManager = this.application.payloads
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ localStorage.clear()
+
+ application = await Factory.createInitAppWithFakeCrypto()
+ history = application.dependencies.get(TYPES.HistoryManager)
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
+ localStorage.clear()
})
it('response from server should be failed if not signed in', async function () {
- await this.application.user.signOut()
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.history = this.application.dependencies.get(TYPES.HistoryManager)
- this.payloadManager = this.application.payloads
- const item = await Factory.createSyncedNote(this.application)
- await this.application.sync.sync(syncOptions)
- const itemHistoryOrError = await this.application.listRevisions.execute({ itemUuid: item.uuid })
+ await application.user.signOut()
+ application = await Factory.createInitAppWithFakeCrypto()
+ history = application.dependencies.get(TYPES.HistoryManager)
+
+ const item = await Factory.createSyncedNote(application)
+ await application.sync.sync(syncOptions)
+ const itemHistoryOrError = await application.listRevisions.execute({ itemUuid: item.uuid })
expect(itemHistoryOrError.isFailed()).to.equal(true)
})
it('create basic history entries 2', async function () {
- const item = await Factory.createSyncedNote(this.application)
+ const item = await Factory.createSyncedNote(application)
await Factory.sleep(Factory.ServerRevisionCreationDelay)
- let itemHistoryOrError = await this.application.listRevisions.execute({ itemUuid: item.uuid })
+ let itemHistoryOrError = await application.listRevisions.execute({ itemUuid: item.uuid })
let itemHistory = itemHistoryOrError.getValue()
/** Server history should save initial revision */
expect(itemHistory.length).to.equal(1)
/** Sync within 5 seconds (ENV VAR dependend on self-hosted setup), should not create a new entry */
- await Factory.markDirtyAndSyncItem(this.application, item)
- itemHistoryOrError = await this.application.listRevisions.execute({ itemUuid: item.uuid })
+ await Factory.markDirtyAndSyncItem(application, item)
+ itemHistoryOrError = await application.listRevisions.execute({ itemUuid: item.uuid })
itemHistory = itemHistoryOrError.getValue()
expect(itemHistory.length).to.equal(1)
/** Sync with different contents, should not create a new entry */
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -318,18 +292,18 @@ describe('history manager', () => {
syncOptions,
)
await Factory.sleep(Factory.ServerRevisionCreationDelay)
- itemHistoryOrError = await this.application.listRevisions.execute({ itemUuid: item.uuid })
+ itemHistoryOrError = await application.listRevisions.execute({ itemUuid: item.uuid })
itemHistory = itemHistoryOrError.getValue()
expect(itemHistory.length).to.equal(1)
})
it('returns revisions from server', async function () {
- let item = await Factory.createSyncedNote(this.application)
+ let item = await Factory.createSyncedNote(application)
await Factory.sleep(Factory.ServerRevisionFrequency)
/** Sync with different contents, should create new entry */
const newTitleAfterFirstChange = `The title should be: ${Math.random()}`
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = newTitleAfterFirstChange
@@ -340,12 +314,12 @@ describe('history manager', () => {
)
await Factory.sleep(Factory.ServerRevisionCreationDelay)
- const itemHistoryOrError = await this.application.listRevisions.execute({ itemUuid: item.uuid })
+ const itemHistoryOrError = await application.listRevisions.execute({ itemUuid: item.uuid })
const itemHistory = itemHistoryOrError.getValue()
expect(itemHistory.length).to.equal(2)
const oldestEntry = lastElement(itemHistory)
- let revisionFromServerOrError = await this.application.getRevision.execute({
+ let revisionFromServerOrError = await application.getRevision.execute({
itemUuid: item.uuid,
revisionUuid: oldestEntry.uuid,
})
@@ -357,22 +331,22 @@ describe('history manager', () => {
expect(payloadFromServer.uuid).to.eq(item.payload.uuid)
expect(payloadFromServer.content).to.eql(item.payload.content)
- item = this.application.items.findItem(item.uuid)
+ item = application.items.findItem(item.uuid)
expect(payloadFromServer.content).to.not.eql(item.payload.content)
})
it('duplicate revisions should not have the originals uuid', async function () {
- const note = await Factory.createSyncedNote(this.application)
- await Factory.markDirtyAndSyncItem(this.application, note)
- const dupe = await this.application.mutator.duplicateItem(note, true)
- await Factory.markDirtyAndSyncItem(this.application, dupe)
+ const note = await Factory.createSyncedNote(application)
+ await Factory.markDirtyAndSyncItem(application, note)
+ const dupe = await application.mutator.duplicateItem(note, true)
+ await Factory.markDirtyAndSyncItem(application, dupe)
await Factory.sleep(Factory.ServerRevisionCreationDelay)
- const dupeHistoryOrError = await this.application.listRevisions.execute({ itemUuid: dupe.uuid })
+ const dupeHistoryOrError = await application.listRevisions.execute({ itemUuid: dupe.uuid })
const dupeHistory = dupeHistoryOrError.getValue()
- const dupeRevisionOrError = await this.application.getRevision.execute({
+ const dupeRevisionOrError = await application.getRevision.execute({
itemUuid: dupe.uuid,
revisionUuid: dupeHistory[0].uuid,
})
@@ -381,54 +355,54 @@ describe('history manager', () => {
})
it('revisions count matches original for duplicated items', async function () {
- const note = await Factory.createSyncedNote(this.application)
+ const note = await Factory.createSyncedNote(application)
await Factory.sleep(Factory.ServerRevisionFrequency)
- await Factory.markDirtyAndSyncItem(this.application, note)
+ await Factory.markDirtyAndSyncItem(application, note)
await Factory.sleep(Factory.ServerRevisionFrequency)
- await Factory.markDirtyAndSyncItem(this.application, note)
+ await Factory.markDirtyAndSyncItem(application, note)
await Factory.sleep(Factory.ServerRevisionFrequency)
- await Factory.markDirtyAndSyncItem(this.application, note)
+ await Factory.markDirtyAndSyncItem(application, note)
- const dupe = await this.application.mutator.duplicateItem(note, true)
- await Factory.markDirtyAndSyncItem(this.application, dupe)
+ const dupe = await application.mutator.duplicateItem(note, true)
+ await Factory.markDirtyAndSyncItem(application, dupe)
await Factory.sleep(Factory.ServerRevisionCreationDelay)
const expectedRevisions = 4
- const noteHistoryOrError = await this.application.listRevisions.execute({ itemUuid: note.uuid })
+ const noteHistoryOrError = await application.listRevisions.execute({ itemUuid: note.uuid })
const noteHistory = noteHistoryOrError.getValue()
- const dupeHistoryOrError = await this.application.listRevisions.execute({ itemUuid: dupe.uuid })
+ const dupeHistoryOrError = await application.listRevisions.execute({ itemUuid: dupe.uuid })
const dupeHistory = dupeHistoryOrError.getValue()
expect(noteHistory.length).to.equal(expectedRevisions)
expect(dupeHistory.length).to.equal(expectedRevisions + 1)
- }).timeout(Factory.ThirtySecondTimeout)
+ }).timeout(Factory.SixtySecondTimeout)
it('can decrypt revisions for duplicate_of items', async function () {
- const note = await Factory.createSyncedNote(this.application)
+ const note = await Factory.createSyncedNote(application)
await Factory.sleep(Factory.ServerRevisionFrequency)
const changedText = `${Math.random()}`
- await this.application.changeAndSaveItem.execute(note, (mutator) => {
+ await application.changeAndSaveItem.execute(note, (mutator) => {
mutator.title = changedText
})
- await Factory.markDirtyAndSyncItem(this.application, note)
+ await Factory.markDirtyAndSyncItem(application, note)
- const dupe = await this.application.mutator.duplicateItem(note, true)
- await Factory.markDirtyAndSyncItem(this.application, dupe)
+ const dupe = await application.mutator.duplicateItem(note, true)
+ await Factory.markDirtyAndSyncItem(application, dupe)
await Factory.sleep(Factory.ServerRevisionCreationDelay)
- const itemHistoryOrError = await this.application.listRevisions.execute({ itemUuid: dupe.uuid })
+ const itemHistoryOrError = await application.listRevisions.execute({ itemUuid: dupe.uuid })
const itemHistory = itemHistoryOrError.getValue()
expect(itemHistory.length).to.be.above(1)
const newestRevision = itemHistory[0]
- const fetchedOrError = await this.application.getRevision.execute({
+ const fetchedOrError = await application.getRevision.execute({
itemUuid: dupe.uuid,
revisionUuid: newestRevision.uuid,
})
diff --git a/packages/snjs/mocha/item.test.js b/packages/snjs/mocha/item.test.js
index bbbd58640..4eaed8e1a 100644
--- a/packages/snjs/mocha/item.test.js
+++ b/packages/snjs/mocha/item.test.js
@@ -1,45 +1,43 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
-describe('item', () => {
- beforeEach(async function () {
- this.createBarePayload = () => {
- return new DecryptedPayload({
- uuid: '123',
- content_type: ContentType.TYPES.Note,
- content: {
- title: 'hello',
- },
- })
- }
+const createBarePayload = () => {
+ return new DecryptedPayload({
+ uuid: '123',
+ content_type: ContentType.TYPES.Note,
+ content: {
+ title: 'hello',
+ },
+ })
+}
- this.createNote = () => {
- return new DecryptedItem(this.createBarePayload())
- }
+const createNote = () => {
+ return new DecryptedItem(createBarePayload())
+}
- this.createTag = (notes = []) => {
- const references = notes.map((note) => {
- return {
- uuid: note.uuid,
- content_type: note.content_type,
- }
- })
- return new SNTag(
- new DecryptedPayload({
- uuid: Factory.generateUuidish(),
- content_type: ContentType.TYPES.Tag,
- content: {
- title: 'thoughts',
- references: references,
- },
- }),
- )
+const createTag = (notes = []) => {
+ const references = notes.map((note) => {
+ return {
+ uuid: note.uuid,
+ content_type: note.content_type,
}
})
+ return new SNTag(
+ new DecryptedPayload({
+ uuid: Factory.generateUuidish(),
+ content_type: ContentType.TYPES.Tag,
+ content: {
+ title: 'thoughts',
+ references: references,
+ },
+ }),
+ )
+}
+
+describe('item', () => {
it('constructing without uuid should throw', function () {
let error
@@ -53,40 +51,40 @@ describe('item', () => {
})
it('healthy constructor', function () {
- const item = this.createNote()
+ const item = createNote()
expect(item).to.be.ok
expect(item.payload).to.be.ok
})
it('user modified date should be ok', function () {
- const item = this.createNote()
+ const item = createNote()
expect(item.userModifiedDate).to.be.ok
})
it('has relationship with item true', function () {
- const note = this.createNote()
- const tag = this.createTag()
+ const note = createNote()
+ const tag = createTag()
expect(tag.isReferencingItem(note)).to.equal(false)
})
it('has relationship with item true', function () {
- const note = this.createNote()
- const tag = this.createTag([note])
+ const note = createNote()
+ const tag = createTag([note])
expect(tag.isReferencingItem(note)).to.equal(true)
})
it('getDomainData for random domain should return undefined', function () {
- const note = this.createNote()
+ const note = createNote()
expect(note.getDomainData('random')).to.not.be.ok
})
it('getDomainData for app domain should return object', function () {
- const note = this.createNote()
+ const note = createNote()
expect(note.getDomainData(DecryptedItem.DefaultAppDomain())).to.be.ok
})
diff --git a/packages/snjs/mocha/item_manager.test.js b/packages/snjs/mocha/item_manager.test.js
index 78aa4811b..bf8fa3d40 100644
--- a/packages/snjs/mocha/item_manager.test.js
+++ b/packages/snjs/mocha/item_manager.test.js
@@ -1,5 +1,3 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
import { BaseItemCounts } from './lib/BaseItemCounts.js'
@@ -10,11 +8,6 @@ describe('item manager', function () {
let context
let application
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -24,6 +17,14 @@ describe('item manager', function () {
await context.launch()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+
+ context = undefined
+ application = undefined
+ })
+
const createNote = async () => {
return application.mutator.createItem(ContentType.TYPES.Note, {
title: 'hello',
diff --git a/packages/snjs/mocha/key_params.test.js b/packages/snjs/mocha/key_params.test.js
index 65d739998..3e57e11b6 100644
--- a/packages/snjs/mocha/key_params.test.js
+++ b/packages/snjs/mocha/key_params.test.js
@@ -1,17 +1,17 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
+
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('key params', function () {
this.timeout(Factory.TenSecondTimeout)
- before(async function () {
+ beforeEach(async function () {
localStorage.clear()
})
- after(async function () {
+ afterEach(async function () {
localStorage.clear()
})
diff --git a/packages/snjs/mocha/key_recovery_service.test.js b/packages/snjs/mocha/key_recovery_service.test.js
index 9b94eec5b..ccf4cfec6 100644
--- a/packages/snjs/mocha/key_recovery_service.test.js
+++ b/packages/snjs/mocha/key_recovery_service.test.js
@@ -1,23 +1,18 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('key recovery service', function () {
this.timeout(Factory.TwentySecondTimeout)
- const syncOptions = {
- checkIntegrity: true,
- awaitAll: true,
- }
-
beforeEach(function () {
localStorage.clear()
})
afterEach(function () {
localStorage.clear()
+ sinon.restore()
})
it('when encountering an undecryptable items key, should recover through recovery wizard', async function () {
@@ -433,9 +428,7 @@ describe('key recovery service', function () {
KeyParamsOrigination.Registration,
ProtocolVersion.V003,
)
- const randomItemsKey = await context.operators
- .operatorForVersion(ProtocolVersion.V003)
- .createItemsKey()
+ const randomItemsKey = await context.operators.operatorForVersion(ProtocolVersion.V003).createItemsKey()
const encrypted = await application.encryption.encryptSplitSingle({
usesRootKey: {
diff --git a/packages/snjs/mocha/keys.test.js b/packages/snjs/mocha/keys.test.js
index 024b745be..9e7e87677 100644
--- a/packages/snjs/mocha/keys.test.js
+++ b/packages/snjs/mocha/keys.test.js
@@ -1,35 +1,40 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
import * as Utils from './lib/Utils.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('keys', function () {
this.timeout(Factory.TwentySecondTimeout)
+ let context
+ let application
+ let email
+ let password
+
beforeEach(async function () {
localStorage.clear()
- this.context = await Factory.createAppContext()
- await this.context.launch()
+ context = await Factory.createAppContext()
+ await context.launch()
- this.application = this.context.application
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ application = context.application
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
})
afterEach(async function () {
- if (!this.application.dealloced) {
- await Factory.safeDeinit(this.application)
+ if (!application.dealloced) {
+ await Factory.safeDeinit(application)
}
- this.application = undefined
+ application = undefined
+ context = undefined
localStorage.clear()
})
it('should not have root key by default', async function () {
- expect(await this.application.encryption.getRootKey()).to.not.be.ok
+ expect(await application.encryption.getRootKey()).to.not.be.ok
})
it('validates content types requiring root encryption', function () {
@@ -43,7 +48,7 @@ describe('keys', function () {
/** Items key available by default */
const payload = Factory.createNotePayload()
const processedPayload = CreateEncryptedLocalStorageContextPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -53,45 +58,41 @@ describe('keys', function () {
})
it('has root key and one items key after registering user', async function () {
- await Factory.registerUserToApplication({ application: this.application })
- expect(this.application.encryption.getRootKey()).to.be.ok
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
+ await Factory.registerUserToApplication({ application: application })
+ expect(application.encryption.getRootKey()).to.be.ok
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
})
it('changing root key with passcode should re-wrap root key', async function () {
const email = 'foo'
const password = 'bar'
- const key = await this.application.encryption.createRootKey(email, password, KeyParamsOrigination.Registration)
- await this.application.encryption.setRootKey(key)
- Factory.handlePasswordChallenges(this.application, password)
- await this.application.addPasscode(password)
+ const key = await application.encryption.createRootKey(email, password, KeyParamsOrigination.Registration)
+ await application.encryption.setRootKey(key)
+ Factory.handlePasswordChallenges(application, password)
+ await application.addPasscode(password)
/** We should be able to decrypt wrapped root key with passcode */
- const wrappingKeyParams = await this.application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()
- const wrappingKey = await this.application.encryption.computeRootKey(password, wrappingKeyParams)
- await this.application.encryption.unwrapRootKey(wrappingKey).catch((error) => {
+ const wrappingKeyParams = await application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()
+ const wrappingKey = await application.encryption.computeRootKey(password, wrappingKeyParams)
+ await application.encryption.unwrapRootKey(wrappingKey).catch((error) => {
expect(error).to.not.be.ok
})
const newPassword = 'bar'
- const newKey = await this.application.encryption.createRootKey(
- email,
- newPassword,
- KeyParamsOrigination.Registration,
- )
- await this.application.encryption.setRootKey(newKey, wrappingKey)
- await this.application.encryption.unwrapRootKey(wrappingKey).catch((error) => {
+ const newKey = await application.encryption.createRootKey(email, newPassword, KeyParamsOrigination.Registration)
+ await application.encryption.setRootKey(newKey, wrappingKey)
+ await application.encryption.unwrapRootKey(wrappingKey).catch((error) => {
expect(error).to.not.be.ok
})
})
it('items key should be encrypted with root key', async function () {
- await Factory.registerUserToApplication({ application: this.application })
- const itemsKey = await this.application.encryption.getSureDefaultItemsKey()
- const rootKey = await this.application.encryption.getRootKey()
+ await Factory.registerUserToApplication({ application: application })
+ const itemsKey = await application.encryption.getSureDefaultItemsKey()
+ const rootKey = await application.encryption.getRootKey()
/** Encrypt items key */
- const encryptedPayload = await this.application.encryption.encryptSplitSingle({
+ const encryptedPayload = await application.encryption.encryptSplitSingle({
usesRootKey: {
items: [itemsKey.payloadRepresentation()],
key: rootKey,
@@ -102,7 +103,7 @@ describe('keys', function () {
expect(encryptedPayload.items_key_id).to.not.be.ok
/** Attempt to decrypt with root key. Should succeed. */
- const decryptedPayload = await this.application.encryption.decryptSplitSingle({
+ const decryptedPayload = await application.encryption.decryptSplitSingle({
usesRootKey: {
items: [encryptedPayload],
key: rootKey,
@@ -114,7 +115,7 @@ describe('keys', function () {
})
it('should create random items key if no account and no passcode', async function () {
- const itemsKeys = this.application.items.getDisplayableItemsKeys()
+ const itemsKeys = application.items.getDisplayableItemsKeys()
expect(itemsKeys.length).to.equal(1)
const notePayload = Factory.createNotePayload()
@@ -122,55 +123,55 @@ describe('keys', function () {
dirty: true,
dirtyIndex: getIncrementedDirtyIndex(),
})
- await this.application.payloads.emitPayload(dirtied, PayloadEmitSource.LocalChanged)
- await this.application.sync.sync()
+ await application.payloads.emitPayload(dirtied, PayloadEmitSource.LocalChanged)
+ await application.sync.sync()
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ const rawPayloads = await application.storage.getAllRawPayloads()
const rawNotePayload = rawPayloads.find((r) => r.content_type === ContentType.TYPES.Note)
expect(typeof rawNotePayload.content).to.equal('string')
})
it('should keep offline created items key upon registration', async function () {
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
- const originalItemsKey = this.application.items.getDisplayableItemsKeys()[0]
- await this.application.register(this.email, this.password)
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
+ const originalItemsKey = application.items.getDisplayableItemsKeys()[0]
+ await application.register(email, password)
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
- const newestItemsKey = this.application.items.getDisplayableItemsKeys()[0]
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
+ const newestItemsKey = application.items.getDisplayableItemsKeys()[0]
expect(newestItemsKey.uuid).to.equal(originalItemsKey.uuid)
})
it('should use items key for encryption of note', async function () {
const notePayload = Factory.createNotePayload()
- const keyToUse = await this.application.encryption.itemsEncryption.keyToUseForItemEncryption(notePayload)
+ const keyToUse = await application.encryption.itemsEncryption.keyToUseForItemEncryption(notePayload)
expect(keyToUse.content_type).to.equal(ContentType.TYPES.ItemsKey)
})
it('encrypting an item should associate an items key to it', async function () {
const note = Factory.createNotePayload()
- const encryptedPayload = await this.application.encryption.encryptSplitSingle({
+ const encryptedPayload = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [note],
},
})
- const itemsKey = this.application.encryption.itemsKeyForEncryptedPayload(encryptedPayload)
+ const itemsKey = application.encryption.itemsKeyForEncryptedPayload(encryptedPayload)
expect(itemsKey).to.be.ok
})
it('decrypt encrypted item with associated key', async function () {
const note = Factory.createNotePayload()
const title = note.content.title
- const encryptedPayload = await this.application.encryption.encryptSplitSingle({
+ const encryptedPayload = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [note],
},
})
- const itemsKey = this.application.encryption.itemsKeyForEncryptedPayload(encryptedPayload)
+ const itemsKey = application.encryption.itemsKeyForEncryptedPayload(encryptedPayload)
expect(itemsKey).to.be.ok
- const decryptedPayload = await this.application.encryption.decryptSplitSingle({
+ const decryptedPayload = await application.encryption.decryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [encryptedPayload],
},
@@ -182,30 +183,30 @@ describe('keys', function () {
it('decrypts items waiting for keys', async function () {
const notePayload = Factory.createNotePayload()
const title = notePayload.content.title
- const encryptedPayload = await this.application.encryption.encryptSplitSingle({
+ const encryptedPayload = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [notePayload],
},
})
- const itemsKey = this.application.encryption.itemsKeyForEncryptedPayload(encryptedPayload)
+ const itemsKey = application.encryption.itemsKeyForEncryptedPayload(encryptedPayload)
- await this.application.items.removeItemFromMemory(itemsKey)
+ await application.items.removeItemFromMemory(itemsKey)
- const erroredPayload = await this.application.encryption.decryptSplitSingle({
+ const erroredPayload = await application.encryption.decryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [encryptedPayload],
},
})
- await this.application.mutator.emitItemsFromPayloads([erroredPayload], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([erroredPayload], PayloadEmitSource.LocalChanged)
- const note = this.application.items.findAnyItem(notePayload.uuid)
+ const note = application.items.findAnyItem(notePayload.uuid)
expect(note.errorDecrypting).to.equal(true)
expect(note.waitingForKey).to.equal(true)
const keyPayload = new DecryptedPayload(itemsKey.payload.ejected())
- await this.application.mutator.emitItemsFromPayloads([keyPayload], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([keyPayload], PayloadEmitSource.LocalChanged)
/**
* Sleeping is required to trigger asyncronous encryptionService.decryptItemsWaitingForKeys,
@@ -213,7 +214,7 @@ describe('keys', function () {
*/
await Factory.sleep(0.2)
- const updatedNote = this.application.items.findItem(note.uuid)
+ const updatedNote = application.items.findItem(note.uuid)
expect(updatedNote.errorDecrypting).to.not.be.ok
expect(updatedNote.waitingForKey).to.not.be.ok
@@ -221,9 +222,9 @@ describe('keys', function () {
})
it('attempting to emit errored items key for which there exists a non errored master copy should ignore it', async function () {
- await Factory.registerUserToApplication({ application: this.application })
+ await Factory.registerUserToApplication({ application: application })
- const itemsKey = await this.application.encryption.getSureDefaultItemsKey()
+ const itemsKey = await application.encryption.getSureDefaultItemsKey()
expect(itemsKey.errorDecrypting).to.not.be.ok
@@ -239,44 +240,44 @@ describe('keys', function () {
},
})
- await this.application.sync.handleSuccessServerResponse({ payloadsSavedOrSaving: [], options: {} }, response)
+ await application.sync.handleSuccessServerResponse({ payloadsSavedOrSaving: [], options: {} }, response)
- const refreshedKey = this.application.payloads.findOne(itemsKey.uuid)
+ const refreshedKey = application.payloads.findOne(itemsKey.uuid)
expect(refreshedKey.errorDecrypting).to.not.be.ok
expect(refreshedKey.content.itemsKey).to.be.ok
})
it('generating export params with logged in account should produce encrypted payload', async function () {
- await Factory.registerUserToApplication({ application: this.application })
+ await Factory.registerUserToApplication({ application: application })
const payload = Factory.createNotePayload()
- const encryptedPayload = await this.application.encryption.encryptSplitSingle({
+ const encryptedPayload = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
})
expect(typeof encryptedPayload.content).to.equal('string')
- expect(encryptedPayload.content.substring(0, 3)).to.equal(this.application.encryption.getLatestVersion())
+ expect(encryptedPayload.content.substring(0, 3)).to.equal(application.encryption.getLatestVersion())
})
it('When setting passcode, should encrypt items keys', async function () {
- await this.application.addPasscode('foo')
- const itemsKey = this.application.items.getDisplayableItemsKeys()[0]
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ await application.addPasscode('foo')
+ const itemsKey = application.items.getDisplayableItemsKeys()[0]
+ const rawPayloads = await application.storage.getAllRawPayloads()
const itemsKeyRawPayload = rawPayloads.find((p) => p.uuid === itemsKey.uuid)
const itemsKeyPayload = new EncryptedPayload(itemsKeyRawPayload)
expect(itemsKeyPayload.enc_item_key).to.be.ok
})
it('items key encrypted payload should contain root key params', async function () {
- await this.application.addPasscode('foo')
- const itemsKey = this.application.items.getDisplayableItemsKeys()[0]
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ await application.addPasscode('foo')
+ const itemsKey = application.items.getDisplayableItemsKeys()[0]
+ const rawPayloads = await application.storage.getAllRawPayloads()
const itemsKeyRawPayload = rawPayloads.find((p) => p.uuid === itemsKey.uuid)
const itemsKeyPayload = new EncryptedPayload(itemsKeyRawPayload)
- const authenticatedData = this.context.encryption.getEmbeddedPayloadAuthenticatedData(itemsKeyPayload)
- const rootKeyParams = await this.application.encryption.getRootKeyParams()
+ const authenticatedData = context.encryption.getEmbeddedPayloadAuthenticatedData(itemsKeyPayload)
+ const rootKeyParams = await application.encryption.getRootKeyParams()
expect(authenticatedData.kp).to.be.ok
expect(authenticatedData.kp).to.eql(rootKeyParams.getPortableValue())
@@ -285,9 +286,9 @@ describe('keys', function () {
it('correctly validates local passcode', async function () {
const passcode = 'foo'
- await this.application.addPasscode('foo')
- expect((await this.application.encryption.validatePasscode('wrong')).valid).to.equal(false)
- expect((await this.application.encryption.validatePasscode(passcode)).valid).to.equal(true)
+ await application.addPasscode('foo')
+ expect((await application.encryption.validatePasscode('wrong')).valid).to.equal(false)
+ expect((await application.encryption.validatePasscode(passcode)).valid).to.equal(true)
})
it('signing into 003 account should delete latest offline items key and create 003 items key', async function () {
@@ -296,63 +297,63 @@ describe('keys', function () {
* Upon signing into an 003 account, the application should delete any neverSynced items keys,
* and create a new default items key that is the default for a given protocol version.
*/
- const defaultItemsKey = await this.application.encryption.getSureDefaultItemsKey()
- const latestVersion = this.application.encryption.getLatestVersion()
+ const defaultItemsKey = await application.encryption.getSureDefaultItemsKey()
+ const latestVersion = application.encryption.getLatestVersion()
expect(defaultItemsKey.keyVersion).to.equal(latestVersion)
/** Register with 003 version */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: ProtocolVersion.V003,
})
- const itemsKeys = this.application.items.getDisplayableItemsKeys()
+ const itemsKeys = application.items.getDisplayableItemsKeys()
expect(itemsKeys.length).to.equal(1)
const newestItemsKey = itemsKeys[0]
expect(newestItemsKey.keyVersion).to.equal(ProtocolVersion.V003)
- const rootKey = await this.application.encryption.getRootKey()
+ const rootKey = await application.encryption.getRootKey()
expect(newestItemsKey.itemsKey).to.equal(rootKey.masterKey)
expect(newestItemsKey.dataAuthenticationKey).to.equal(rootKey.dataAuthenticationKey)
})
it('reencrypts existing notes when logging into an 003 account', async function () {
- await Factory.createManyMappedNotes(this.application, 10)
+ await Factory.createManyMappedNotes(application, 10)
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: ProtocolVersion.V003,
})
- expect(this.application.payloads.invalidPayloads.length).to.equal(0)
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
- expect(this.application.items.getDisplayableItemsKeys()[0].dirty).to.equal(false)
+ expect(application.payloads.invalidPayloads.length).to.equal(0)
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
+ expect(application.items.getDisplayableItemsKeys()[0].dirty).to.equal(false)
/** Sign out and back in */
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ await application.signIn(email, password, undefined, undefined, undefined, true)
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
- expect(this.application.items.getDisplayableNotes().length).to.equal(10)
- expect(this.application.payloads.invalidPayloads.length).to.equal(0)
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
+ expect(application.items.getDisplayableNotes().length).to.equal(10)
+ expect(application.payloads.invalidPayloads.length).to.equal(0)
})
it('When root key changes, all items keys must be re-encrypted', async function () {
const passcode = 'foo'
- await this.application.addPasscode(passcode)
- await Factory.createSyncedNote(this.application)
- const itemsKeys = this.application.items.getDisplayableItemsKeys()
+ await application.addPasscode(passcode)
+ await Factory.createSyncedNote(application)
+ const itemsKeys = application.items.getDisplayableItemsKeys()
expect(itemsKeys.length).to.equal(1)
const originalItemsKey = itemsKeys[0]
- const originalRootKey = await this.application.encryption.getRootKey()
+ const originalRootKey = await application.encryption.getRootKey()
/** Expect that we can decrypt raw payload with current root key */
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ const rawPayloads = await application.storage.getAllRawPayloads()
const itemsKeyRawPayload = rawPayloads.find((p) => p.uuid === originalItemsKey.uuid)
const itemsKeyPayload = new EncryptedPayload(itemsKeyRawPayload)
- const decrypted = await this.application.encryption.decryptSplitSingle({
+ const decrypted = await application.encryption.decryptSplitSingle({
usesRootKey: {
items: [itemsKeyPayload],
key: originalRootKey,
@@ -363,10 +364,10 @@ describe('keys', function () {
expect(decrypted.content).to.eql(originalItemsKey.content)
/** Change passcode */
- Factory.handlePasswordChallenges(this.application, passcode)
- await this.application.changePasscode('bar')
+ Factory.handlePasswordChallenges(application, passcode)
+ await application.changePasscode('bar')
- const newRootKey = await this.application.encryption.getRootKey()
+ const newRootKey = await application.encryption.getRootKey()
expect(newRootKey).to.not.equal(originalRootKey)
expect(newRootKey.masterKey).to.not.equal(originalRootKey.masterKey)
@@ -374,12 +375,12 @@ describe('keys', function () {
* Expect that originalRootKey can no longer decrypt originalItemsKey
* as items key has been re-encrypted with new root key
*/
- const rawPayloads2 = await this.application.storage.getAllRawPayloads()
+ const rawPayloads2 = await application.storage.getAllRawPayloads()
const itemsKeyRawPayload2 = rawPayloads2.find((p) => p.uuid === originalItemsKey.uuid)
expect(itemsKeyRawPayload2.content).to.not.equal(itemsKeyRawPayload.content)
const itemsKeyPayload2 = new EncryptedPayload(itemsKeyRawPayload2)
- const decrypted2 = await this.application.encryption.decryptSplitSingle({
+ const decrypted2 = await application.encryption.decryptSplitSingle({
usesRootKey: {
items: [itemsKeyPayload2],
key: originalRootKey,
@@ -388,7 +389,7 @@ describe('keys', function () {
expect(decrypted2.errorDecrypting).to.equal(true)
/** Should be able to decrypt with new root key */
- const decrypted3 = await this.application.encryption.decryptSplitSingle({
+ const decrypted3 = await application.encryption.decryptSplitSingle({
usesRootKey: {
items: [itemsKeyPayload2],
key: newRootKey,
@@ -399,23 +400,23 @@ describe('keys', function () {
it('changing account password should create new items key and encrypt items with that key', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const itemsKeys = this.application.items.getDisplayableItemsKeys()
+ const itemsKeys = application.items.getDisplayableItemsKeys()
expect(itemsKeys.length).to.equal(1)
- const defaultItemsKey = await this.application.encryption.getSureDefaultItemsKey()
+ const defaultItemsKey = await application.encryption.getSureDefaultItemsKey()
- const result = await this.application.changePassword(this.password, 'foobarfoo')
+ const result = await application.changePassword(password, 'foobarfoo')
expect(result.error).to.not.be.ok
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(2)
- const newDefaultItemsKey = await this.application.encryption.getSureDefaultItemsKey()
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(2)
+ const newDefaultItemsKey = await application.encryption.getSureDefaultItemsKey()
expect(newDefaultItemsKey.uuid).to.not.equal(defaultItemsKey.uuid)
- const note = await Factory.createSyncedNote(this.application)
- const payload = await this.application.encryption.encryptSplitSingle({
+ const note = await Factory.createSyncedNote(application)
+ const payload = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [note.payload],
},
@@ -480,29 +481,29 @@ describe('keys', function () {
})
it('loading the keychain root key should also load its key params', async function () {
- await Factory.registerUserToApplication({ application: this.application })
- const rootKey = await this.application.encryption.rootKeyManager.getRootKeyFromKeychain()
+ await Factory.registerUserToApplication({ application: application })
+ const rootKey = await application.encryption.rootKeyManager.getRootKeyFromKeychain()
expect(rootKey.keyParams).to.be.ok
})
it('key params should be persisted separately and not as part of root key', async function () {
- await Factory.registerUserToApplication({ application: this.application })
- const rawKey = await this.application.device.getNamespacedKeychainValue(this.application.identifier)
+ await Factory.registerUserToApplication({ application: application })
+ const rawKey = await application.device.getNamespacedKeychainValue(application.identifier)
expect(rawKey.keyParams).to.not.be.ok
- const rawKeyParams = await this.application.storage.getValue(StorageKey.RootKeyParams, StorageValueModes.Nonwrapped)
+ const rawKeyParams = await application.storage.getValue(StorageKey.RootKeyParams, StorageValueModes.Nonwrapped)
expect(rawKeyParams).to.be.ok
})
it('persisted key params should exactly equal in memory rootKey.keyParams', async function () {
- await Factory.registerUserToApplication({ application: this.application })
- const rootKey = await this.application.encryption.getRootKey()
- const rawKeyParams = await this.application.storage.getValue(StorageKey.RootKeyParams, StorageValueModes.Nonwrapped)
+ await Factory.registerUserToApplication({ application: application })
+ const rootKey = await application.encryption.getRootKey()
+ const rawKeyParams = await application.storage.getValue(StorageKey.RootKeyParams, StorageValueModes.Nonwrapped)
expect(rootKey.keyParams.content).to.eql(rawKeyParams)
})
it('key params should have expected values', async function () {
- await Factory.registerUserToApplication({ application: this.application })
- const keyParamsObject = await this.application.encryption.getRootKeyParams()
+ await Factory.registerUserToApplication({ application: application })
+ const keyParamsObject = await application.encryption.getRootKeyParams()
const keyParams = keyParamsObject.content
expect(keyParams.identifier).to.be.ok
expect(keyParams.pw_nonce).to.be.ok
@@ -515,20 +516,18 @@ describe('keys', function () {
})
it('key params obtained when signing in should have created and origination', async function () {
- const email = this.email
- const password = this.password
await Factory.registerUserToApplication({
- application: this.application,
+ application: application,
email,
password,
})
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ application = await Factory.signOutApplicationAndReturnNew(application)
await Factory.loginToApplication({
- application: this.application,
+ application: application,
email,
password,
})
- const keyParamsObject = await this.application.encryption.getRootKeyParams()
+ const keyParamsObject = await application.encryption.getRootKeyParams()
const keyParams = keyParamsObject.content
expect(keyParams.created).to.be.ok
@@ -541,12 +540,12 @@ describe('keys', function () {
/** Register with 003 version */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: ProtocolVersion.V003,
})
- const keyParamsObject = await this.application.encryption.getRootKeyParams()
+ const keyParamsObject = await application.encryption.getRootKeyParams()
const keyParams = keyParamsObject.content
expect(keyParams.created).to.be.ok
@@ -556,17 +555,17 @@ describe('keys', function () {
it('encryption name should be dependent on key params version', async function () {
/** Register with 003 account */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: ProtocolVersion.V003,
})
- expect(await this.application.encryption.getEncryptionDisplayName()).to.equal('AES-256')
+ expect(await application.encryption.getEncryptionDisplayName()).to.equal('AES-256')
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ application = await Factory.signOutApplicationAndReturnNew(application)
/** Register with 004 account */
- await this.application.register(this.email + 'new', this.password)
- expect(await this.application.encryption.getEncryptionDisplayName()).to.equal('XChaCha20-Poly1305')
+ await application.register(email + 'new', password)
+ expect(await application.encryption.getEncryptionDisplayName()).to.equal('XChaCha20-Poly1305')
})
it('when launching app with no keychain but data, should present account recovery challenge', async function () {
@@ -575,21 +574,21 @@ describe('keys', function () {
* when setting up a new device from restore, the keychain is deleted, but the data persists.
* We want to make sure we're prompting the user to re-authenticate their account.
*/
- const id = this.application.identifier
+ const id = application.identifier
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
/** Simulate empty keychain */
- await this.application.device.clearRawKeychainValue()
+ await application.device.clearRawKeychainValue()
const recreatedApp = await Factory.createApplicationWithFakeCrypto(id)
let totalChallenges = 0
const expectedChallenges = 1
const receiveChallenge = (challenge) => {
totalChallenges++
- recreatedApp.submitValuesForChallenge(challenge, [CreateChallengeValue(challenge.prompts[0], this.password)])
+ recreatedApp.submitValuesForChallenge(challenge, [CreateChallengeValue(challenge.prompts[0], password)])
}
await recreatedApp.prepareForLaunch({ receiveChallenge })
await recreatedApp.launch(true)
@@ -610,13 +609,13 @@ describe('keys', function () {
*/
it.skip('should add new items key', async function () {
this.timeout(Factory.TwentySecondTimeout * 3)
- let oldClient = this.application
+ let oldClient = application
/** Register an 003 account */
await Factory.registerOldUser({
application: oldClient,
- email: this.email,
- password: this.password,
+ email: email,
+ password: password,
version: ProtocolVersion.V003,
})
@@ -626,8 +625,8 @@ describe('keys', function () {
receiveChallenge: (challenge) => {
/** Reauth session challenge */
newClient.submitValuesForChallenge(challenge, [
- CreateChallengeValue(challenge.prompts[0], this.email),
- CreateChallengeValue(challenge.prompts[1], this.password),
+ CreateChallengeValue(challenge.prompts[0], email),
+ CreateChallengeValue(challenge.prompts[1], password),
])
},
})
@@ -636,11 +635,11 @@ describe('keys', function () {
/** Change password through session manager directly instead of application,
* as not to create any items key (to simulate 003 client behavior) */
const currentRootKey = await oldClient.encryption.computeRootKey(
- this.password,
+ password,
await oldClient.encryption.getRootKeyParams(),
)
- const operator = this.context.operators.operatorForVersion(ProtocolVersion.V003)
- const newRootKey = await operator.createRootKey(this.email, this.password)
+ const operator = context.operators.operatorForVersion(ProtocolVersion.V003)
+ const newRootKey = await operator.createRootKey(email, password)
Object.defineProperty(oldClient.legacyApi, 'apiVersion', {
get: function () {
return '20190520'
@@ -650,7 +649,7 @@ describe('keys', function () {
/**
* Sign in as late as possible on new client to prevent session timeouts
*/
- await newClient.signIn(this.email, this.password)
+ await newClient.signIn(email, password)
await oldClient.sessions.changeCredentials({
currentServerPassword: currentRootKey.serverPassword,
@@ -669,28 +668,28 @@ describe('keys', function () {
})
it('should add new items key from migration if pw change already happened', async function () {
- this.context.anticipateConsoleError('Shared vault network errors due to not accepting JWT-based token')
- this.context.anticipateConsoleError(
+ context.anticipateConsoleError('Shared vault network errors due to not accepting JWT-based token')
+ context.anticipateConsoleError(
'Cannot find items key to use for encryption',
'No items keys being created in this test',
)
/** Register an 003 account */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: ProtocolVersion.V003,
})
/** Change password through session manager directly instead of application,
* as not to create any items key (to simulate 003 client behavior) */
- const currentRootKey = await this.application.encryption.computeRootKey(
- this.password,
- await this.application.encryption.getRootKeyParams(),
+ const currentRootKey = await application.encryption.computeRootKey(
+ password,
+ await application.encryption.getRootKeyParams(),
)
- const operator = this.context.operators.operatorForVersion(ProtocolVersion.V003)
- const newRootKeyTemplate = await operator.createRootKey(this.email, this.password)
+ const operator = context.operators.operatorForVersion(ProtocolVersion.V003)
+ const newRootKeyTemplate = await operator.createRootKey(email, password)
const newRootKey = CreateNewRootKey({
...newRootKeyTemplate.content,
...{
@@ -699,28 +698,28 @@ describe('keys', function () {
},
})
- Object.defineProperty(this.application.legacyApi, 'apiVersion', {
+ Object.defineProperty(application.legacyApi, 'apiVersion', {
get: function () {
return '20190520'
},
})
/** Renew session to prevent timeouts */
- this.application = await Factory.signOutAndBackIn(this.application, this.email, this.password)
+ application = await Factory.signOutAndBackIn(application, email, password)
- await this.application.sessions.changeCredentials({
+ await application.sessions.changeCredentials({
currentServerPassword: currentRootKey.serverPassword,
newRootKey,
})
- await this.application.dependencies.get(TYPES.ReencryptTypeAItems).execute()
+ await application.dependencies.get(TYPES.ReencryptTypeAItems).execute()
/** Note: this may result in a deadlock if features_service syncs and results in an error */
- await this.application.sync.sync({ awaitAll: true })
+ await application.sync.sync({ awaitAll: true })
/** Relaunch application and expect new items key to be created */
- const identifier = this.application.identifier
+ const identifier = application.identifier
/** Set to pre 2.0.15 version so migration runs */
- await this.application.device.setRawStorageValue(`${identifier}-snjs_version`, '2.0.14')
- await Factory.safeDeinit(this.application)
+ await application.device.setRawStorageValue(`${identifier}-snjs_version`, '2.0.14')
+ await Factory.safeDeinit(application)
const refreshedApp = await Factory.createApplicationWithFakeCrypto(identifier)
await Factory.initializeApplication(refreshedApp)
@@ -740,16 +739,16 @@ describe('keys', function () {
* The corrective action was to do a final check in encryptionService.handleDownloadFirstSyncCompletion
* to ensure there exists an items key corresponding to the user's account version.
*/
- const promise = this.context.awaitNextSucessfulSync()
- await this.context.sync()
+ const promise = context.awaitNextSucessfulSync()
+ await context.sync()
await promise
- await this.application.items.removeAllItemsFromMemory()
- expect(this.application.encryption.getSureDefaultItemsKey()).to.not.be.ok
+ await application.items.removeAllItemsFromMemory()
+ expect(application.encryption.getSureDefaultItemsKey()).to.not.be.ok
const protocol003 = new SNProtocolOperator003(new SNWebCrypto())
const key = await protocol003.createItemsKey()
- await this.application.mutator.emitItemFromPayload(
+ await application.mutator.emitItemFromPayload(
key.payload.copy({
content: {
...key.payload.content,
@@ -761,30 +760,30 @@ describe('keys', function () {
}),
)
- const defaultKey = this.application.encryption.getSureDefaultItemsKey()
+ const defaultKey = application.encryption.getSureDefaultItemsKey()
expect(defaultKey.keyVersion).to.equal(ProtocolVersion.V003)
expect(defaultKey.uuid).to.equal(key.uuid)
- await Factory.registerUserToApplication({ application: this.application })
+ await Factory.registerUserToApplication({ application: application })
const notePayload = Factory.createNotePayload()
- expect(await this.application.encryption.itemsEncryption.keyToUseForItemEncryption(notePayload)).to.be.ok
+ expect(await application.encryption.itemsEncryption.keyToUseForItemEncryption(notePayload)).to.be.ok
})
it('having unsynced items keys should resync them upon download first sync completion', async function () {
- await Factory.registerUserToApplication({ application: this.application })
- const itemsKey = this.application.items.getDisplayableItemsKeys()[0]
- await this.application.mutator.emitItemFromPayload(
+ await Factory.registerUserToApplication({ application: application })
+ const itemsKey = application.items.getDisplayableItemsKeys()[0]
+ await application.mutator.emitItemFromPayload(
itemsKey.payload.copy({
dirty: false,
updated_at: new Date(0),
deleted: false,
}),
)
- await this.application.sync.sync({
+ await application.sync.sync({
mode: SyncMode.DownloadFirst,
})
- const updatedKey = this.application.items.findItem(itemsKey.uuid)
+ const updatedKey = application.items.findItem(itemsKey.uuid)
expect(updatedKey.neverSynced).to.equal(false)
})
@@ -794,18 +793,18 @@ describe('keys', function () {
otherClient.items.itemsKeyDisplayController.setDisplayOptions({ sortBy: 'dsc' })
/** On client A, create account and note */
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- await Factory.createSyncedNote(this.application)
- const itemsKey = this.application.items.getItems(ContentType.TYPES.ItemsKey)[0]
+ await Factory.createSyncedNote(application)
+ const itemsKey = application.items.getItems(ContentType.TYPES.ItemsKey)[0]
/** Create another client and sign into account */
await Factory.loginToApplication({
application: otherClient,
- email: this.email,
- password: this.password,
+ email: email,
+ password: password,
})
const defaultKeys = otherClient.encryption.itemsEncryption.getItemsKeys().filter((key) => {
return key.isDefault
diff --git a/packages/snjs/mocha/lib/factory.js b/packages/snjs/mocha/lib/factory.js
index afbcdd98e..9cb682d2d 100644
--- a/packages/snjs/mocha/lib/factory.js
+++ b/packages/snjs/mocha/lib/factory.js
@@ -1,5 +1,4 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
+
import FakeWebCrypto from './fake_web_crypto.js'
import { AppContext } from './AppContext.js'
import { VaultsContext } from './VaultsContext.js'
@@ -63,6 +62,10 @@ export async function createVaultsContextWithRealCrypto(identifier) {
return createVaultsContext({ identifier, crypto: new SNWebCrypto() })
}
+export async function createVaultsContextWithFakeCrypto(identifier) {
+ return createVaultsContext({ identifier, crypto: new FakeWebCrypto() })
+}
+
export async function createVaultsContext({ identifier, crypto, email, password, host } = {}) {
const context = new VaultsContext({ identifier, crypto, email, password, host })
await context.initialize()
diff --git a/packages/snjs/mocha/memory.test.js b/packages/snjs/mocha/memory.test.js
index 806b9c10c..e336d243e 100644
--- a/packages/snjs/mocha/memory.test.js
+++ b/packages/snjs/mocha/memory.test.js
@@ -1,6 +1,5 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -9,6 +8,7 @@ const expect = chai.expect
* Then check browser Memory tool to make sure there are no leaks.
*/
describe('memory', function () {
+ let application
before(async function () {
localStorage.clear()
})
@@ -18,12 +18,12 @@ describe('memory', function () {
})
beforeEach(async function () {
- this.application = await Factory.createInitAppWithFakeCrypto()
+ application = await Factory.createInitAppWithFakeCrypto()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
- this.application = null
+ await Factory.safeDeinit(application)
+ application = undefined
})
it('passes', async function () {
diff --git a/packages/snjs/mocha/mfa_service.test.js b/packages/snjs/mocha/mfa_service.test.js
index cb585202a..6cb62b967 100644
--- a/packages/snjs/mocha/mfa_service.test.js
+++ b/packages/snjs/mocha/mfa_service.test.js
@@ -1,68 +1,76 @@
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
-const createApp = async () => Factory.createInitAppWithFakeCrypto(Environment.Web, Platform.MacWeb)
-
const accountPassword = 'password'
-const registerApp = async (snApp) => {
+const registerApp = async (application) => {
const email = UuidGenerator.GenerateUuid()
const password = accountPassword
const ephemeral = false
const mergeLocal = true
- await snApp.register(email, password, ephemeral, mergeLocal)
- return snApp
+ await application.register(email, password, ephemeral, mergeLocal)
+ return application
}
describe('mfa service', () => {
+ let application
+
+ beforeEach(async () => {
+ localStorage.clear()
+ application = await Factory.createInitAppWithFakeCrypto(Environment.Web, Platform.MacWeb)
+ })
+
+ afterEach(async () => {
+ Factory.safeDeinit(application)
+ localStorage.clear()
+ application = undefined
+ sinon.restore()
+ })
+
it('generates 160 bit base32-encoded mfa secret', async () => {
const RFC4648 = /[ABCDEFGHIJKLMNOPQRSTUVWXYZ234567]/g
- const snApp = await createApp()
- const secret = await snApp.generateMfaSecret()
+ const secret = await application.generateMfaSecret()
expect(secret).to.have.lengthOf(32)
expect(secret.replace(RFC4648, '')).to.have.lengthOf(0)
-
- Factory.safeDeinit(snApp)
})
it('activates mfa, checks if enabled, deactivates mfa', async () => {
- const snApp = await createApp().then(registerApp)
- Factory.handlePasswordChallenges(snApp, accountPassword)
+ await registerApp(application)
- expect(await snApp.isMfaActivated()).to.equal(false)
+ Factory.handlePasswordChallenges(application, accountPassword)
- const secret = await snApp.generateMfaSecret()
- const token = await snApp.getOtpToken(secret)
+ expect(await application.isMfaActivated()).to.equal(false)
- await snApp.enableMfa(secret, token)
+ const secret = await application.generateMfaSecret()
+ const token = await application.getOtpToken(secret)
- expect(await snApp.isMfaActivated()).to.equal(true)
+ await application.enableMfa(secret, token)
- await snApp.disableMfa()
+ expect(await application.isMfaActivated()).to.equal(true)
- expect(await snApp.isMfaActivated()).to.equal(false)
+ await application.disableMfa()
- Factory.safeDeinit(snApp)
+ expect(await application.isMfaActivated()).to.equal(false)
}).timeout(Factory.TenSecondTimeout)
it('prompts for account password when disabling mfa', async () => {
- const snApp = await createApp().then(registerApp)
- Factory.handlePasswordChallenges(snApp, accountPassword)
- const secret = await snApp.generateMfaSecret()
- const token = await snApp.getOtpToken(secret)
+ await registerApp(application)
- sinon.spy(snApp.challenges, 'sendChallenge')
- await snApp.enableMfa(secret, token)
- await snApp.disableMfa()
+ Factory.handlePasswordChallenges(application, accountPassword)
+ const secret = await application.generateMfaSecret()
+ const token = await application.getOtpToken(secret)
- const spyCall = snApp.challenges.sendChallenge.getCall(0)
+ sinon.spy(application.challenges, 'sendChallenge')
+ await application.enableMfa(secret, token)
+ await application.disableMfa()
+
+ const spyCall = application.challenges.sendChallenge.getCall(0)
const challenge = spyCall.firstArg
expect(challenge.prompts).to.have.lengthOf(2)
expect(challenge.prompts[0].validation).to.equal(ChallengeValidation.AccountPassword)
-
- Factory.safeDeinit(snApp)
}).timeout(Factory.TenSecondTimeout)
})
diff --git a/packages/snjs/mocha/migrations/migration.test.js b/packages/snjs/mocha/migrations/migration.test.js
index 85f363042..60ce05a03 100644
--- a/packages/snjs/mocha/migrations/migration.test.js
+++ b/packages/snjs/mocha/migrations/migration.test.js
@@ -1,4 +1,5 @@
import * as Factory from '../lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
diff --git a/packages/snjs/mocha/migrations/tags-to-folders.test.js b/packages/snjs/mocha/migrations/tags-to-folders.test.js
index 989a2be42..ec182908c 100644
--- a/packages/snjs/mocha/migrations/tags-to-folders.test.js
+++ b/packages/snjs/mocha/migrations/tags-to-folders.test.js
@@ -1,6 +1,5 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from '../lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -11,25 +10,29 @@ const setupRandomUuid = () => {
}
describe('web native folders migration', () => {
+ let application
+
beforeEach(async function () {
- this.application = await Factory.createInitAppWithFakeCrypto()
+ localStorage.clear()
+ application = await Factory.createInitAppWithFakeCrypto()
setupRandomUuid()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
- // TODO: cleanup uuid behind us or we'll mess other tests.
+ await Factory.safeDeinit(application)
+ application = undefined
+ localStorage.clear()
})
it('migration with flat tag folders', async function () {
const titles = ['a', 'b', 'c']
- await makeTags(this.application, titles)
+ await makeTags(application, titles)
// Run the migration
- await this.application.mutator.migrateTagsToFolders()
+ await application.mutator.migrateTagsToFolders()
// Check new tags
- const result = extractTagHierarchy(this.application)
+ const result = extractTagHierarchy(application)
expect(result).to.deep.equal({
a: { _uuid: 'a' },
@@ -40,13 +43,13 @@ describe('web native folders migration', () => {
it('migration with simple tag folders', async function () {
const titles = ['a.b.c', 'b', 'a.b']
- await makeTags(this.application, titles)
+ await makeTags(application, titles)
// Run the migration
- await this.application.mutator.migrateTagsToFolders()
+ await application.mutator.migrateTagsToFolders()
// Check new tags
- const result = extractTagHierarchy(this.application)
+ const result = extractTagHierarchy(application)
expect(result).to.deep.equal({
a: {
@@ -62,13 +65,13 @@ describe('web native folders migration', () => {
it('migration with more complex cases', async function () {
const titles = ['a.b.c', 'b', 'a.b']
- await makeTags(this.application, titles)
+ await makeTags(application, titles)
// Run the migration
- await this.application.mutator.migrateTagsToFolders()
+ await application.mutator.migrateTagsToFolders()
// Check new tags
- const result = extractTagHierarchy(this.application)
+ const result = extractTagHierarchy(application)
expect(result).to.deep.equal({
a: {
@@ -84,13 +87,13 @@ describe('web native folders migration', () => {
it('should produce a valid hierarchy cases with missing intermediate tags or unordered', async function () {
const titles = ['y.2', 'w.3', 'y']
- await makeTags(this.application, titles)
+ await makeTags(application, titles)
// Run the migration
- await this.application.mutator.migrateTagsToFolders()
+ await application.mutator.migrateTagsToFolders()
// Check new tags
- const result = extractTagHierarchy(this.application)
+ const result = extractTagHierarchy(application)
expect(result).to.deep.equal({
w: {
@@ -105,13 +108,13 @@ describe('web native folders migration', () => {
it('skip prefixed names', async function () {
const titles = ['.something', '.something...something', 'something.a.b.c']
- await makeTags(this.application, titles)
+ await makeTags(application, titles)
// Run the migration
- await this.application.mutator.migrateTagsToFolders()
+ await application.mutator.migrateTagsToFolders()
// Check new tags
- const result = extractTagHierarchy(this.application)
+ const result = extractTagHierarchy(application)
expect(result).to.deep.equal({
'.something': { _uuid: '.something' },
@@ -132,13 +135,13 @@ describe('web native folders migration', () => {
'a',
'something..another.thing..anyway',
]
- await makeTags(this.application, titles)
+ await makeTags(application, titles)
// Run the migration
- await this.application.mutator.migrateTagsToFolders()
+ await application.mutator.migrateTagsToFolders()
// Check new tags
- const result = extractTagHierarchy(this.application)
+ const result = extractTagHierarchy(application)
expect(result).to.deep.equal({
'something.': { _uuid: 'something.' },
diff --git a/packages/snjs/mocha/model_tests/appmodels.test.js b/packages/snjs/mocha/model_tests/appmodels.test.js
index 5e2acd8c5..9ea4d8395 100644
--- a/packages/snjs/mocha/model_tests/appmodels.test.js
+++ b/packages/snjs/mocha/model_tests/appmodels.test.js
@@ -1,37 +1,26 @@
-/* eslint-disable camelcase */
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('app models', () => {
- const sharedApplication = Factory.createApplicationWithFakeCrypto()
-
- before(async function () {
- localStorage.clear()
- await Factory.initializeApplication(sharedApplication)
- })
-
- after(async function () {
- localStorage.clear()
- await Factory.safeDeinit(sharedApplication)
- })
+ let application
+ let expectedItemCount
+ let context
beforeEach(async function () {
- this.expectedItemCount = BaseItemCounts.DefaultItems
- this.context = await Factory.createAppContext()
- this.application = this.context.application
- await this.context.launch()
+ localStorage.clear()
+ expectedItemCount = BaseItemCounts.DefaultItems
+ context = await Factory.createAppContext()
+ application = context.application
+ await context.launch()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
- })
-
- it('payloads should be defined', () => {
- expect(sharedApplication.payloads).to.be.ok
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
})
it('item should be defined', () => {
@@ -72,17 +61,17 @@ describe('app models', () => {
},
})
- await this.application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
- await this.application.mutator.emitItemsFromPayloads([params2], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([params2], PayloadEmitSource.LocalChanged)
- const item1 = this.application.items.findItem(params1.uuid)
- const item2 = this.application.items.findItem(params2.uuid)
+ const item1 = application.items.findItem(params1.uuid)
+ const item2 = application.items.findItem(params2.uuid)
expect(item1.content.references.length).to.equal(1)
expect(item2.content.references.length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(item1).length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(item2).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(item1).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(item2).length).to.equal(1)
})
it('mapping an item twice shouldnt cause problems', async function () {
@@ -95,45 +84,45 @@ describe('app models', () => {
},
})
- let items = await this.application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
+ let items = await application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
let item = items[0]
expect(item).to.be.ok
- items = await this.application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
+ items = await application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
item = items[0]
expect(item.content.foo).to.equal('bar')
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
})
it('mapping item twice should preserve references', async function () {
- const item1 = await Factory.createMappedNote(this.application)
- const item2 = await Factory.createMappedNote(this.application)
+ const item1 = await Factory.createMappedNote(application)
+ const item2 = await Factory.createMappedNote(application)
- await this.application.mutator.changeItem(item1, (mutator) => {
+ await application.mutator.changeItem(item1, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
})
- await this.application.mutator.changeItem(item2, (mutator) => {
+ await application.mutator.changeItem(item2, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item1)
})
- const refreshedItem = this.application.items.findItem(item1.uuid)
+ const refreshedItem = application.items.findItem(item1.uuid)
expect(refreshedItem.content.references.length).to.equal(1)
})
it('fixes relationship integrity', async function () {
- var item1 = await Factory.createMappedNote(this.application)
- var item2 = await Factory.createMappedNote(this.application)
+ var item1 = await Factory.createMappedNote(application)
+ var item2 = await Factory.createMappedNote(application)
- await this.application.mutator.changeItem(item1, (mutator) => {
+ await application.mutator.changeItem(item1, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
})
- await this.application.mutator.changeItem(item2, (mutator) => {
+ await application.mutator.changeItem(item2, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item1)
})
- const refreshedItem1 = this.application.items.findItem(item1.uuid)
- const refreshedItem2 = this.application.items.findItem(item2.uuid)
+ const refreshedItem1 = application.items.findItem(item1.uuid)
+ const refreshedItem2 = application.items.findItem(item2.uuid)
expect(refreshedItem1.content.references.length).to.equal(1)
expect(refreshedItem2.content.references.length).to.equal(1)
@@ -145,54 +134,54 @@ describe('app models', () => {
references: [],
},
})
- await this.application.mutator.emitItemsFromPayloads([damagedPayload], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([damagedPayload], PayloadEmitSource.LocalChanged)
- const refreshedItem1_2 = this.application.items.findItem(item1.uuid)
- const refreshedItem2_2 = this.application.items.findItem(item2.uuid)
+ const refreshedItem1_2 = application.items.findItem(item1.uuid)
+ const refreshedItem2_2 = application.items.findItem(item2.uuid)
expect(refreshedItem1_2.content.references.length).to.equal(0)
expect(refreshedItem2_2.content.references.length).to.equal(1)
})
it('creating and removing relationships between two items should have valid references', async function () {
- var item1 = await Factory.createMappedNote(this.application)
- var item2 = await Factory.createMappedNote(this.application)
- await this.application.mutator.changeItem(item1, (mutator) => {
+ var item1 = await Factory.createMappedNote(application)
+ var item2 = await Factory.createMappedNote(application)
+ await application.mutator.changeItem(item1, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
})
- await this.application.mutator.changeItem(item2, (mutator) => {
+ await application.mutator.changeItem(item2, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item1)
})
- const refreshedItem1 = this.application.items.findItem(item1.uuid)
- const refreshedItem2 = this.application.items.findItem(item2.uuid)
+ const refreshedItem1 = application.items.findItem(item1.uuid)
+ const refreshedItem2 = application.items.findItem(item2.uuid)
expect(refreshedItem1.content.references.length).to.equal(1)
expect(refreshedItem2.content.references.length).to.equal(1)
- expect(this.application.items.itemsReferencingItem(item1)).to.include(refreshedItem2)
- expect(this.application.items.itemsReferencingItem(item2)).to.include(refreshedItem1)
+ expect(application.items.itemsReferencingItem(item1)).to.include(refreshedItem2)
+ expect(application.items.itemsReferencingItem(item2)).to.include(refreshedItem1)
- await this.application.mutator.changeItem(item1, (mutator) => {
+ await application.mutator.changeItem(item1, (mutator) => {
mutator.removeItemAsRelationship(item2)
})
- await this.application.mutator.changeItem(item2, (mutator) => {
+ await application.mutator.changeItem(item2, (mutator) => {
mutator.removeItemAsRelationship(item1)
})
- const refreshedItem1_2 = this.application.items.findItem(item1.uuid)
- const refreshedItem2_2 = this.application.items.findItem(item2.uuid)
+ const refreshedItem1_2 = application.items.findItem(item1.uuid)
+ const refreshedItem2_2 = application.items.findItem(item2.uuid)
expect(refreshedItem1_2.content.references.length).to.equal(0)
expect(refreshedItem2_2.content.references.length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(item1).length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(item2).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(item1).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(item2).length).to.equal(0)
})
it('properly duplicates item with no relationships', async function () {
- const item = await Factory.createMappedNote(this.application)
- const duplicate = await this.application.mutator.duplicateItem(item)
+ const item = await Factory.createMappedNote(application)
+ const duplicate = await application.mutator.duplicateItem(item)
expect(duplicate.uuid).to.not.equal(item.uuid)
expect(item.isItemContentEqualWith(duplicate)).to.equal(true)
expect(item.created_at.toISOString()).to.equal(duplicate.created_at.toISOString())
@@ -200,36 +189,36 @@ describe('app models', () => {
})
it('properly duplicates item with relationships', async function () {
- const item1 = await Factory.createMappedNote(this.application)
- const item2 = await Factory.createMappedNote(this.application)
+ const item1 = await Factory.createMappedNote(application)
+ const item2 = await Factory.createMappedNote(application)
- const refreshedItem1 = await this.application.mutator.changeItem(item1, (mutator) => {
+ const refreshedItem1 = await application.mutator.changeItem(item1, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
})
expect(refreshedItem1.content.references.length).to.equal(1)
- const duplicate = await this.application.mutator.duplicateItem(item1)
+ const duplicate = await application.mutator.duplicateItem(item1)
expect(duplicate.uuid).to.not.equal(item1.uuid)
expect(duplicate.content.references.length).to.equal(1)
- expect(this.application.items.itemsReferencingItem(item1).length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(item2).length).to.equal(2)
+ expect(application.items.itemsReferencingItem(item1).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(item2).length).to.equal(2)
- const refreshedItem1_2 = this.application.items.findItem(item1.uuid)
+ const refreshedItem1_2 = application.items.findItem(item1.uuid)
expect(refreshedItem1_2.isItemContentEqualWith(duplicate)).to.equal(true)
expect(refreshedItem1_2.created_at.toISOString()).to.equal(duplicate.created_at.toISOString())
expect(refreshedItem1_2.content_type).to.equal(duplicate.content_type)
})
it('removing references should update cross-refs', async function () {
- const item1 = await Factory.createMappedNote(this.application)
- const item2 = await Factory.createMappedNote(this.application)
- const refreshedItem1 = await this.application.mutator.changeItem(item1, (mutator) => {
+ const item1 = await Factory.createMappedNote(application)
+ const item2 = await Factory.createMappedNote(application)
+ const refreshedItem1 = await application.mutator.changeItem(item1, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
})
- const refreshedItem1_2 = await this.application.mutator.emitItemFromPayload(
+ const refreshedItem1_2 = await application.mutator.emitItemFromPayload(
refreshedItem1.payloadRepresentation({
deleted: true,
content: {
@@ -240,49 +229,49 @@ describe('app models', () => {
PayloadEmitSource.LocalChanged,
)
- expect(this.application.items.itemsReferencingItem(item2).length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(item1).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(item2).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(item1).length).to.equal(0)
expect(refreshedItem1_2.content.references.length).to.equal(0)
})
it('properly handles single item uuid alternation', async function () {
- const item1 = await Factory.createMappedNote(this.application)
- const item2 = await Factory.createMappedNote(this.application)
+ const item1 = await Factory.createMappedNote(application)
+ const item2 = await Factory.createMappedNote(application)
- const refreshedItem1 = await this.application.mutator.changeItem(item1, (mutator) => {
+ const refreshedItem1 = await application.mutator.changeItem(item1, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
})
expect(refreshedItem1.content.references.length).to.equal(1)
- expect(this.application.items.itemsReferencingItem(item2).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(item2).length).to.equal(1)
- const alternatedItem = await Factory.alternateUuidForItem(this.application, item1.uuid)
- const refreshedItem1_2 = this.application.items.findItem(item1.uuid)
+ const alternatedItem = await Factory.alternateUuidForItem(application, item1.uuid)
+ const refreshedItem1_2 = application.items.findItem(item1.uuid)
expect(refreshedItem1_2).to.not.be.ok
- expect(this.application.items.getDisplayableNotes().length).to.equal(2)
+ expect(application.items.getDisplayableNotes().length).to.equal(2)
expect(alternatedItem.content.references.length).to.equal(1)
- expect(this.application.items.itemsReferencingItem(alternatedItem.uuid).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(alternatedItem.uuid).length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(item2).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(item2).length).to.equal(1)
expect(alternatedItem.isReferencingItem(item2)).to.equal(true)
expect(alternatedItem.dirty).to.equal(true)
})
it('alterating uuid of item should fill its duplicateOf value', async function () {
- const item1 = await Factory.createMappedNote(this.application)
- const alternatedItem = await Factory.alternateUuidForItem(this.application, item1.uuid)
+ const item1 = await Factory.createMappedNote(application)
+ const alternatedItem = await Factory.alternateUuidForItem(application, item1.uuid)
expect(alternatedItem.duplicateOf).to.equal(item1.uuid)
})
it('alterating itemskey uuid should update errored items encrypted with that key', async function () {
- const item1 = await Factory.createMappedNote(this.application)
- const itemsKey = this.application.items.getDisplayableItemsKeys()[0]
+ const item1 = await Factory.createMappedNote(application)
+ const itemsKey = application.items.getDisplayableItemsKeys()[0]
/** Encrypt item1 and emit as errored so it persists with items_key_id */
- const encrypted = await this.application.encryption.encryptSplitSingle({
+ const encrypted = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [item1.payload],
},
@@ -292,46 +281,46 @@ describe('app models', () => {
waitingForKey: true,
})
- await this.application.payloads.emitPayload(errored)
+ await application.payloads.emitPayload(errored)
- expect(this.application.payloads.findOne(item1.uuid).errorDecrypting).to.equal(true)
- expect(this.application.payloads.findOne(item1.uuid).items_key_id).to.equal(itemsKey.uuid)
+ expect(application.payloads.findOne(item1.uuid).errorDecrypting).to.equal(true)
+ expect(application.payloads.findOne(item1.uuid).items_key_id).to.equal(itemsKey.uuid)
- sinon.stub(this.application.encryption.itemsEncryption, 'decryptErroredItemPayloads').callsFake(() => {
+ sinon.stub(application.encryption.itemsEncryption, 'decryptErroredItemPayloads').callsFake(() => {
// prevent auto decryption
})
- const alternatedKey = await Factory.alternateUuidForItem(this.application, itemsKey.uuid)
- const updatedPayload = this.application.payloads.findOne(item1.uuid)
+ const alternatedKey = await Factory.alternateUuidForItem(application, itemsKey.uuid)
+ const updatedPayload = application.payloads.findOne(item1.uuid)
expect(updatedPayload.items_key_id).to.equal(alternatedKey.uuid)
})
it('properly handles mutli item uuid alternation', async function () {
- const item1 = await Factory.createMappedNote(this.application)
- const item2 = await Factory.createMappedNote(this.application)
- this.expectedItemCount += 2
+ const item1 = await Factory.createMappedNote(application)
+ const item2 = await Factory.createMappedNote(application)
+ expectedItemCount += 2
- await this.application.mutator.changeItem(item1, (mutator) => {
+ await application.mutator.changeItem(item1, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
})
- expect(this.application.items.itemsReferencingItem(item2).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(item2).length).to.equal(1)
- const alternatedItem1 = await Factory.alternateUuidForItem(this.application, item1.uuid)
- const alternatedItem2 = await Factory.alternateUuidForItem(this.application, item2.uuid)
+ const alternatedItem1 = await Factory.alternateUuidForItem(application, item1.uuid)
+ const alternatedItem2 = await Factory.alternateUuidForItem(application, item2.uuid)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
expect(item1.uuid).to.not.equal(alternatedItem1.uuid)
expect(item2.uuid).to.not.equal(alternatedItem2.uuid)
- const refreshedAltItem1 = this.application.items.findItem(alternatedItem1.uuid)
+ const refreshedAltItem1 = application.items.findItem(alternatedItem1.uuid)
expect(refreshedAltItem1.content.references.length).to.equal(1)
expect(refreshedAltItem1.content.references[0].uuid).to.equal(alternatedItem2.uuid)
expect(alternatedItem2.content.references.length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(alternatedItem2).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(alternatedItem2).length).to.equal(1)
expect(refreshedAltItem1.isReferencingItem(alternatedItem2)).to.equal(true)
expect(alternatedItem2.isReferencingItem(refreshedAltItem1)).to.equal(false)
@@ -339,39 +328,39 @@ describe('app models', () => {
})
it('maintains referencing relationships when duplicating', async function () {
- const tag = await Factory.createMappedTag(this.application)
- const note = await Factory.createMappedNote(this.application)
- const refreshedTag = await this.application.mutator.changeItem(tag, (mutator) => {
+ const tag = await Factory.createMappedTag(application)
+ const note = await Factory.createMappedNote(application)
+ const refreshedTag = await application.mutator.changeItem(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(note)
})
expect(refreshedTag.content.references.length).to.equal(1)
- const noteCopy = await this.application.mutator.duplicateItem(note)
+ const noteCopy = await application.mutator.duplicateItem(note)
expect(note.uuid).to.not.equal(noteCopy.uuid)
- expect(this.application.items.getDisplayableNotes().length).to.equal(2)
- expect(this.application.items.getDisplayableTags().length).to.equal(1)
+ expect(application.items.getDisplayableNotes().length).to.equal(2)
+ expect(application.items.getDisplayableTags().length).to.equal(1)
expect(note.content.references.length).to.equal(0)
expect(noteCopy.content.references.length).to.equal(0)
- const refreshedTag_2 = this.application.items.findItem(tag.uuid)
+ const refreshedTag_2 = application.items.findItem(tag.uuid)
expect(refreshedTag_2.content.references.length).to.equal(2)
})
it('maintains editor reference when duplicating note', async function () {
- const component = await this.application.mutator.createItem(
+ const component = await application.mutator.createItem(
ContentType.TYPES.Component,
{ area: ComponentArea.Editor, package_info: { identifier: 'foo-editor' } },
true,
)
- const note = await Factory.insertItemWithOverride(this.application, ContentType.TYPES.Note, {
+ const note = await Factory.insertItemWithOverride(application, ContentType.TYPES.Note, {
editorIdentifier: 'foo-editor',
})
- expect(this.application.componentManager.editorForNote(note).uniqueIdentifier.value).to.equal(component.uuid)
+ expect(application.componentManager.editorForNote(note).uniqueIdentifier.value).to.equal(component.uuid)
- const duplicate = await this.application.mutator.duplicateItem(note, true)
- expect(this.application.componentManager.editorForNote(duplicate).uniqueIdentifier.value).to.equal(component.uuid)
+ const duplicate = await application.mutator.duplicateItem(note, true)
+ expect(application.componentManager.editorForNote(duplicate).uniqueIdentifier.value).to.equal(component.uuid)
})
})
diff --git a/packages/snjs/mocha/model_tests/importing.test.js b/packages/snjs/mocha/model_tests/importing.test.js
index 9a9a0a923..f94585a9d 100644
--- a/packages/snjs/mocha/model_tests/importing.test.js
+++ b/packages/snjs/mocha/model_tests/importing.test.js
@@ -1,8 +1,7 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
import { createRelatedNoteTagPairPayload } from '../lib/Items.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -15,869 +14,862 @@ describe('importing', function () {
let password
let context
- beforeEach(function () {
- localStorage.clear()
- })
-
- const setup = async ({ fakeCrypto }) => {
- expectedItemCount = BaseItemCounts.DefaultItems
-
- if (fakeCrypto) {
- context = await Factory.createAppContext()
- } else {
- context = await Factory.createAppContextWithRealCrypto()
- }
-
- await context.launch()
- application = context.application
-
- email = UuidGenerator.GenerateUuid()
- password = UuidGenerator.GenerateUuid()
- Factory.handlePasswordChallenges(application, password)
- }
-
afterEach(async function () {
- await Factory.safeDeinit(application)
- localStorage.clear()
- })
-
- it('should not import backups made from unsupported versions', async function () {
- await setup({ fakeCrypto: true })
- const result = await application.importData({
- version: '-1',
- items: [],
- })
- expect(result.error).to.exist
- })
-
- it('should not import backups made from 004 into 003 account', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerOldUser({
- application,
- email,
- password,
- version: ProtocolVersion.V003,
- })
- const result = await application.importData({
- version: ProtocolVersion.V004,
- items: [],
- })
- expect(result.error).to.exist
- })
-
- it('importing existing data should keep relationships valid', async function () {
- await setup({ fakeCrypto: true })
- const pair = createRelatedNoteTagPairPayload()
- const notePayload = pair[0]
- const tagPayload = pair[1]
-
- await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- expectedItemCount += 2
- const note = application.items.getItems([ContentType.TYPES.Note])[0]
- const tag = application.items.getItems([ContentType.TYPES.Tag])[0]
-
- expect(tag.content.references.length).to.equal(1)
- expect(tag.noteCount).to.equal(1)
-
- expect(note.content.references.length).to.equal(0)
- expect(application.items.itemsReferencingItem(note).length).to.equal(1)
-
- await application.importData(
- {
- items: [notePayload, tagPayload],
- },
- true,
- )
-
- expect(application.items.items.length).to.equal(expectedItemCount)
-
- expect(tag.content.references.length).to.equal(1)
- expect(tag.noteCount).to.equal(1)
-
- expect(note.content.references.length).to.equal(0)
- expect(application.items.itemsReferencingItem(note).length).to.equal(1)
- })
-
- it('importing same note many times should create only one duplicate', async function () {
- /**
- * Used strategy here will be KEEP_LEFT_DUPLICATE_RIGHT
- * which means that new right items will be created with different
- */
- await setup({ fakeCrypto: true })
- const notePayload = Factory.createNotePayload()
- await application.mutator.emitItemFromPayload(notePayload, PayloadEmitSource.LocalChanged)
- expectedItemCount++
- const mutatedNote = new DecryptedPayload({
- ...notePayload,
- content: {
- ...notePayload.content,
- title: `${Math.random()}`,
- },
- })
- await application.importData(
- {
- items: [mutatedNote, mutatedNote, mutatedNote],
- },
- true,
- )
- expectedItemCount++
- expect(application.items.getDisplayableNotes().length).to.equal(2)
- const imported = application.items.getDisplayableNotes().find((n) => n.uuid !== notePayload.uuid)
- expect(imported.content.title).to.equal(mutatedNote.content.title)
- })
-
- it('importing a tag with lesser references should not create duplicate', async function () {
- await setup({ fakeCrypto: true })
- const pair = createRelatedNoteTagPairPayload()
- const tagPayload = pair[1]
- await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
- const mutatedTag = new DecryptedPayload({
- ...tagPayload,
- content: {
- ...tagPayload.content,
- references: [],
- },
- })
- await application.importData(
- {
- items: [mutatedTag],
- },
- true,
- )
- expect(application.items.getDisplayableTags().length).to.equal(1)
- expect(application.items.findItem(tagPayload.uuid).content.references.length).to.equal(1)
- })
-
- it('importing data with differing content should create duplicates', async function () {
- await setup({ fakeCrypto: true })
- const pair = createRelatedNoteTagPairPayload()
- const notePayload = pair[0]
- const tagPayload = pair[1]
- await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
- expectedItemCount += 2
- const note = application.items.getDisplayableNotes()[0]
- const tag = application.items.getDisplayableTags()[0]
- const mutatedNote = new DecryptedPayload({
- ...notePayload,
- content: {
- ...notePayload.content,
- title: `${Math.random()}`,
- },
- })
- const mutatedTag = new DecryptedPayload({
- ...tagPayload,
- content: {
- ...tagPayload.content,
- title: `${Math.random()}`,
- },
- })
- await application.importData(
- {
- items: [mutatedNote, mutatedTag],
- },
- true,
- )
- expectedItemCount += 2
- expect(application.items.items.length).to.equal(expectedItemCount)
-
- const newNote = application.items.getDisplayableNotes().find((n) => n.uuid !== notePayload.uuid)
- const newTag = application.items.getDisplayableTags().find((t) => t.uuid !== tagPayload.uuid)
-
- expect(newNote.uuid).to.not.equal(note.uuid)
- expect(newTag.uuid).to.not.equal(tag.uuid)
-
- const refreshedTag = application.items.findItem(tag.uuid)
- expect(refreshedTag.content.references.length).to.equal(2)
- expect(refreshedTag.noteCount).to.equal(2)
-
- const refreshedNote = application.items.findItem(note.uuid)
- expect(refreshedNote.content.references.length).to.equal(0)
- expect(application.items.itemsReferencingItem(refreshedNote).length).to.equal(2)
-
- expect(newTag.content.references.length).to.equal(1)
- expect(newTag.noteCount).to.equal(1)
-
- expect(newNote.content.references.length).to.equal(0)
- expect(application.items.itemsReferencingItem(newNote).length).to.equal(1)
- })
-
- it('when importing items, imported values should not be used to determine if changed', async function () {
- /**
- * If you have a note and a tag, and the tag has 1 reference to the note,
- * and you import the same two items, except modify the note value so that
- * a duplicate is created, we expect only the note to be duplicated, and the
- * tag not to. However, if only the note changes, and you duplicate the note,
- * which causes the tag's references content to change, then when the incoming
- * tag is being processed, it will also think it has changed, since our local
- * value now doesn't match what's coming in. The solution is to get all values
- * ahead of time before any changes are made.
- */
- await setup({ fakeCrypto: true })
- const note = await Factory.createMappedNote(application)
- const tag = await Factory.createMappedTag(application)
- expectedItemCount += 2
-
- await application.mutator.changeItem(tag, (mutator) => {
- mutator.e2ePendingRefactor_addItemAsRelationship(note)
- })
-
- const externalNote = Object.assign(
- {},
- {
- uuid: note.uuid,
- content: note.getContentCopy(),
- content_type: note.content_type,
- },
- )
- externalNote.content.text = `${Math.random()}`
-
- const externalTag = Object.assign(
- {},
- {
- uuid: tag.uuid,
- content: tag.getContentCopy(),
- content_type: tag.content_type,
- },
- )
-
- await application.importData(
- {
- items: [externalNote, externalTag],
- },
- true,
- )
- expectedItemCount += 1
-
- /** We expect now that the total item count is 3, not 4. */
- expect(application.items.items.length).to.equal(expectedItemCount)
-
- const refreshedTag = application.items.findItem(tag.uuid)
- /** References from both items have merged. */
- expect(refreshedTag.content.references.length).to.equal(2)
- })
-
- it('should import decrypted data and keep items that were previously deleted', async function () {
- await setup({ fakeCrypto: true })
-
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- Factory.handlePasswordChallenges(application, password)
-
- const [note, tag] = await Promise.all([Factory.createMappedNote(application), Factory.createMappedTag(application)])
-
- await application.sync.sync({ awaitAll: true })
-
- await application.mutator.deleteItem(note)
- await application.sync.sync()
- expect(application.items.findItem(note.uuid)).to.not.exist
-
- await application.mutator.deleteItem(tag)
- await application.sync.sync()
- expect(application.items.findItem(tag.uuid)).to.not.exist
-
- await application.importData(
- {
- items: [note, tag],
- },
- true,
- )
-
- expect(application.items.getDisplayableNotes().length).to.equal(1)
- expect(application.items.findItem(note.uuid).deleted).to.not.be.ok
-
- expect(application.items.getDisplayableTags().length).to.equal(1)
- expect(application.items.findItem(tag.uuid).deleted).to.not.be.ok
- })
-
- it('should duplicate notes by alternating UUIDs when dealing with conflicts during importing', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
- const note = await Factory.createSyncedNote(application)
-
- /** Sign into another account and import the same item. It should get a different UUID. */
- application = await Factory.signOutApplicationAndReturnNew(application)
- email = UuidGenerator.GenerateUuid()
- Factory.handlePasswordChallenges(application, password)
-
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- await application.importData(
- {
- items: [note.payload],
- },
- true,
- )
-
- expect(application.items.getDisplayableNotes().length).to.equal(1)
- expect(application.items.getDisplayableNotes()[0].uuid).to.not.equal(note.uuid)
- })
-
- it('should maintain consistency between storage and PayloadManager after an import with conflicts', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
- const note = await Factory.createSyncedNote(application)
-
- /** Sign into another account and import the same items. They should get a different UUID. */
- application = await Factory.signOutApplicationAndReturnNew(application)
- email = UuidGenerator.GenerateUuid()
- Factory.handlePasswordChallenges(application, password)
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- await application.importData(
- {
- items: [note],
- },
- true,
- )
-
- const storedPayloads = await application.storage.getAllRawPayloads()
- expect(application.items.items.length).to.equal(storedPayloads.length)
- const notes = storedPayloads.filter((p) => p.content_type === ContentType.TYPES.Note)
- const itemsKeys = storedPayloads.filter((p) => p.content_type === ContentType.TYPES.ItemsKey)
- expect(notes.length).to.equal(1)
- expect(itemsKeys.length).to.equal(1)
- })
-
- it('should import encrypted data and keep items that were previously deleted', async function () {
- await setup({ fakeCrypto: true })
-
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- const [note, tag] = await Promise.all([Factory.createMappedNote(application), Factory.createMappedTag(application)])
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
-
- await application.sync.sync({ awaitAll: true })
-
- await application.mutator.deleteItem(note)
- await application.sync.sync()
- expect(application.items.findItem(note.uuid)).to.not.exist
-
- await application.mutator.deleteItem(tag)
- await application.sync.sync()
- expect(application.items.findItem(tag.uuid)).to.not.exist
-
- await application.importData(backupData, true)
-
- expect(application.items.getDisplayableNotes().length).to.equal(1)
- expect(application.items.findItem(note.uuid).deleted).to.not.be.ok
-
- expect(application.items.getDisplayableTags().length).to.equal(1)
- expect(application.items.findItem(tag.uuid).deleted).to.not.be.ok
- })
-
- it('should import decrypted data and all items payload source should be FileImport', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- const [note, tag] = await Promise.all([Factory.createMappedNote(application), Factory.createMappedTag(application)])
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- Factory.handlePasswordChallenges(application, password)
-
- await application.importData(backupData, true)
-
- const importedNote = application.items.findItem(note.uuid)
- const importedTag = application.items.findItem(tag.uuid)
-
- expect(importedNote.payload.source).to.be.equal(PayloadSource.FileImport)
- expect(importedTag.payload.source).to.be.equal(PayloadSource.FileImport)
- })
-
- it('should import encrypted data and all items payload source should be FileImport', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- const [note, tag] = await Promise.all([Factory.createMappedNote(application), Factory.createMappedTag(application)])
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- Factory.handlePasswordChallenges(application, password)
-
- await application.importData(backupData, true)
-
- const importedNote = application.items.findItem(note.uuid)
- const importedTag = application.items.findItem(tag.uuid)
- expect(importedNote.payload.source).to.be.equal(PayloadSource.FileImport)
- expect(importedTag.payload.source).to.be.equal(PayloadSource.FileImport)
- })
-
- it('should import data from 003 encrypted payload using client generated backup', async function () {
- await setup({ fakeCrypto: true })
- const oldVersion = ProtocolVersion.V003
- await Factory.registerOldUser({
- application: application,
- email: email,
- password: password,
- version: oldVersion,
- })
-
- const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
- title: 'Encrypted note',
- text: 'On protocol version 003.',
- })
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- Factory.handlePasswordChallenges(application, password)
-
- const result = await application.importData(backupData, true)
- expect(result).to.not.be.undefined
- expect(result.affectedItems.length).to.be.eq(backupData.items.length)
- expect(result.errorCount).to.be.eq(0)
-
- const decryptedNote = application.items.findItem(noteItem.uuid)
- expect(decryptedNote.title).to.be.eq('Encrypted note')
- expect(decryptedNote.text).to.be.eq('On protocol version 003.')
- expect(application.items.getDisplayableNotes().length).to.equal(1)
- })
-
- it('should import data from 003 encrypted payload using server generated backup with 004 key params', async function () {
- await setup({ fakeCrypto: false })
- const backupData = {
- items: [
- {
- uuid: 'eb1b7eed-e43d-48dd-b257-b7fc8ccba3da',
- duplicate_of: null,
- items_key_id: null,
- content:
- '003:618138e365a13f8aed17d4f52e3da47d4b5d6e02004a0f827118e8a981a57c35:eb1b7eed-e43d-48dd-b257-b7fc8ccba3da:9f38642b7a3f57546520a9e32aa7c0ad:qa9rUcaD904m1Knv63dnATEHwfHJjsbq9bWb06zGTsyQxzLaAYT7uRGp2KB2g1eo5Aqxc5FqhvuF0+dE1f4+uQOeiRFNX73V2pJJY0w5Qq7l7ZuhB08ZtOMY4Ctq7evBBSIVZ+PEIfFnACelNJhsB5Uhn3kS4ZBx6qtvQ6ciSQGfYAwc6wSKhjUm1umEINeb08LNgwbP6XAm8U/la1bdtdMO112XjUW7ixkWi3POWcM=:eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X2Nvc3QiOjExMDAwMCwicHdfbm9uY2UiOiJhZmIwYjE3NGJlYjViMmJmZTIyNTk1NDlmMTgxNDI1NzlkMDE1ZmE3ZTBhMjE4YzVmNDIxNmU0Mzg2ZGI3OWFiIiwidmVyc2lvbiI6IjAwMyJ9',
- content_type: 'Note',
- enc_item_key:
- '003:5a01e913c52899ba10c16dbe7e713dd9caf9b9554c82176ddfcf1424f5bfd94f:eb1b7eed-e43d-48dd-b257-b7fc8ccba3da:14721ff8dbdd36fb57ae4bf7414c5eab:odmq91dfaTZG/zeSUA09fD/PdB2OkiDxcQZ0FL06GPstxdvxnU17k1rtsWoA7HoNNnd5494BZ/b7YiKqUb76ddd8x3/+cTZgCa4tYxNINmb1T3wwUX0Ebxc8xynAhg6nTY/BGq+ba6jTyl8zw12dL3kBEGGglRCHnO0ZTeylwQW7asfONN8s0BwrvHdonRlx:eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X2Nvc3QiOjExMDAwMCwicHdfbm9uY2UiOiJhZmIwYjE3NGJlYjViMmJmZTIyNTk1NDlmMTgxNDI1NzlkMDE1ZmE3ZTBhMjE4YzVmNDIxNmU0Mzg2ZGI3OWFiIiwidmVyc2lvbiI6IjAwMyJ9',
- auth_hash: null,
- created_at: '2019-05-12T02:29:21.789000Z',
- updated_at: '2019-11-12T21:47:48.382708Z',
- deleted: false,
- },
- {
- uuid: '10051be7-4ca2-4af3-aae9-021939df4fab',
- duplicate_of: null,
- items_key_id: null,
- content:
- '004:77a986823b8ffdd87164b6f541de6ed420b70ac67e055774:+8cjww1QbyXNX+PSKeCwmnysv0rAoEaKh409VWQJpDbEy/pPZCT6c0rKxLzvyMiSq6EwkOiduZMzokRgCKP7RuRqNPJceWsxNnpIUwa40KR1IP2tdreW4J8v9pFEzPMec1oq40u+c+UI/Y6ChOLV/4ozyWmpQCK3y8Ugm7B1/FzaeDs9Ie6Mvf98+XECoi0fWv9SO2TeBvq1G24LXd4zf0j8jd0sKZbLPXH0+gaUXtBH7A56lHvB0ED9NuiHI8xopTBd9ogKlz/b5+JB4zA2zQCQ3WMEE1qz6WeB2S4FMomgeO1e3trabdU0ICu0WMvDVii4qNlQo/inD41oHXKeV5QwnYoGjPrLJIaP0hiLKhDURTHygCdvWdp63OWI+aGxv0/HI+nfcRsqSE+aYECrWB/kp/c5yTrEqBEafuWZkw==:eyJrcCI6eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X25vbmNlIjoiNjUxYWUxZWM5NTgwMzM5YTM1NjdlZTdmMGY4NjcyNDkyZGUyYzE2NmE1NTZjMTNkMTE5NzI4YTAzYzYwZjc5MyIsInZlcnNpb24iOiIwMDQiLCJvcmlnaW5hdGlvbiI6InByb3RvY29sLXVwZ3JhZGUiLCJjcmVhdGVkIjoiMTYxNDc4NDE5MjQ5NyJ9LCJ1IjoiMTAwNTFiZTctNGNhMi00YWYzLWFhZTktMDIxOTM5ZGY0ZmFiIiwidiI6IjAwNCJ9',
- content_type: 'SN|ItemsKey',
- enc_item_key:
- '004:d25deb224251b4705a44d8ce125a62f6a2f0e0e856603e8f:FEv1pfU/VfY7XhJrTfpcdhaSBfmNySTQtHohFYDm8V84KlyF5YaXRKV7BfXsa77DKTjOCU/EHHsWwhBEEfsNnzNySHxTHNc26bpoz0V8h50=:eyJrcCI6eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X25vbmNlIjoiNjUxYWUxZWM5NTgwMzM5YTM1NjdlZTdmMGY4NjcyNDkyZGUyYzE2NmE1NTZjMTNkMTE5NzI4YTAzYzYwZjc5MyIsInZlcnNpb24iOiIwMDQiLCJvcmlnaW5hdGlvbiI6InByb3RvY29sLXVwZ3JhZGUiLCJjcmVhdGVkIjoiMTYxNDc4NDE5MjQ5NyJ9LCJ1IjoiMTAwNTFiZTctNGNhMi00YWYzLWFhZTktMDIxOTM5ZGY0ZmFiIiwidiI6IjAwNCJ9',
- auth_hash: null,
- created_at: '2020-09-07T12:22:06.562000Z',
- updated_at: '2021-03-03T15:09:55.741107Z',
- deleted: false,
- },
- ],
- auth_params: {
- identifier: 'playground@bitar.io',
- pw_nonce: '651ae1ec9580339a3567ee7f0f8672492de2c166a556c13d119728a03c60f793',
- version: '004',
- },
+ if (application) {
+ await Factory.safeDeinit(application)
}
-
- const password = 'password'
-
- application = await Factory.createInitAppWithRealCrypto()
- Factory.handlePasswordChallenges(application, password)
-
- const result = await application.importData(backupData, true)
- expect(result).to.not.be.undefined
- expect(result.affectedItems.length).to.be.eq(backupData.items.length)
- expect(result.errorCount).to.be.eq(0)
+ localStorage.clear()
+ application = undefined
+ context = undefined
})
- it('should import data from 004 encrypted payload', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
+ describe('fake crypto', function () {
+ beforeEach(async function () {
+ localStorage.clear()
+ expectedItemCount = BaseItemCounts.DefaultItems
+
+ context = await Factory.createAppContext()
+
+ await context.launch()
+ application = context.application
+
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
+ Factory.handlePasswordChallenges(application, password)
})
- const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
- title: 'Encrypted note',
- text: 'On protocol version 004.',
+ it('should not import backups made from unsupported versions', async function () {
+ const result = await application.importData({
+ version: '-1',
+ items: [],
+ })
+ expect(result.error).to.exist
})
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- Factory.handlePasswordChallenges(application, password)
-
- const result = await application.importData(backupData, true)
- expect(result).to.not.be.undefined
- expect(result.affectedItems.length).to.be.eq(backupData.items.length)
- expect(result.errorCount).to.be.eq(0)
-
- const decryptedNote = application.items.findItem(noteItem.uuid)
- expect(decryptedNote.title).to.be.eq('Encrypted note')
- expect(decryptedNote.text).to.be.eq('On protocol version 004.')
- expect(application.items.getDisplayableNotes().length).to.equal(1)
- })
-
- it('should return correct errorCount', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
+ it('should not import backups made from 004 into 003 account', async function () {
+ await Factory.registerOldUser({
+ application,
+ email,
+ password,
+ version: ProtocolVersion.V003,
+ })
+ const result = await application.importData({
+ version: ProtocolVersion.V004,
+ items: [],
+ })
+ expect(result.error).to.exist
})
- const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
- title: 'This is a valid, encrypted note',
- text: 'On protocol version 004.',
- })
+ it('importing existing data should keep relationships valid', async function () {
+ const pair = createRelatedNoteTagPairPayload()
+ const notePayload = pair[0]
+ const tagPayload = pair[1]
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ expectedItemCount += 2
+ const note = application.items.getItems([ContentType.TYPES.Note])[0]
+ const tag = application.items.getItems([ContentType.TYPES.Tag])[0]
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- Factory.handlePasswordChallenges(application, password)
+ expect(tag.content.references.length).to.equal(1)
+ expect(tag.noteCount).to.equal(1)
- const madeUpPayload = JSON.parse(JSON.stringify(noteItem))
+ expect(note.content.references.length).to.equal(0)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(1)
- madeUpPayload.items_key_id = undefined
- madeUpPayload.content = '004:somenonsense'
- madeUpPayload.enc_item_key = '003:anothernonsense'
- madeUpPayload.version = '004'
- madeUpPayload.uuid = 'fake-uuid'
-
- backupData.items = [...backupData.items, madeUpPayload]
-
- const result = await application.importData(backupData, true)
- expect(result).to.not.be.undefined
- expect(result.affectedItems.length).to.be.eq(backupData.items.length - 1)
- expect(result.errorCount).to.be.eq(1)
- })
-
- it('should not import data from 003 encrypted payload if an invalid password is provided', async function () {
- await setup({ fakeCrypto: true })
-
- const oldVersion = ProtocolVersion.V003
- await Factory.registerOldUser({
- application: application,
- email: email,
- password: UuidGenerator.GenerateUuid(),
- version: oldVersion,
- })
-
- await application.mutator.createItem(ContentType.TYPES.Note, {
- title: 'Encrypted note',
- text: 'On protocol version 003.',
- })
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- application.setLaunchCallback({
- receiveChallenge: (challenge) => {
- const values = challenge.prompts.map((prompt) =>
- CreateChallengeValue(
- prompt,
- prompt.validation === ChallengeValidation.None ? 'incorrect password' : password,
- ),
- )
- application.submitValuesForChallenge(challenge, values)
- },
- })
-
- const result = await application.importData(backupData, true)
- expect(result).to.not.be.undefined
-
- expect(result.affectedItems.length).to.be.eq(0)
- expect(result.errorCount).to.be.eq(backupData.items.length)
- expect(application.items.getDisplayableNotes().length).to.equal(0)
- })
-
- it('should not import data from 004 encrypted payload if an invalid password is provided', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- await application.mutator.createItem(ContentType.TYPES.Note, {
- title: 'This is a valid, encrypted note',
- text: 'On protocol version 004.',
- })
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- application.setLaunchCallback({
- receiveChallenge: (challenge) => {
- const values = challenge.prompts.map((prompt) => CreateChallengeValue(prompt, 'incorrect password'))
- application.submitValuesForChallenge(challenge, values)
- },
- })
-
- const result = await application.importData(backupData, true)
- expect(result).to.not.be.undefined
- expect(result.affectedItems.length).to.be.eq(0)
- expect(result.errorCount).to.be.eq(backupData.items.length)
- expect(application.items.getDisplayableNotes().length).to.equal(0)
- })
-
- it('should not import encrypted data with no keyParams or auth_params', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
-
- await application.mutator.createItem(ContentType.TYPES.Note, {
- title: 'Encrypted note',
- text: 'On protocol version 004.',
- })
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
- delete backupData.keyParams
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
-
- const result = await application.importData(backupData)
-
- expect(result.error).to.be.ok
- })
-
- it('should not import payloads if the corresponding ItemsKey is not present within the backup file', async function () {
- await setup({ fakeCrypto: true })
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
- })
- Factory.handlePasswordChallenges(application, password)
-
- await application.mutator.createItem(ContentType.TYPES.Note, {
- title: 'Encrypted note',
- text: 'On protocol version 004.',
- })
-
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
- backupData.items = backupData.items.filter((payload) => payload.content_type !== ContentType.TYPES.ItemsKey)
-
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- Factory.handlePasswordChallenges(application, password)
-
- const result = await application.importData(backupData, true)
-
- expect(result).to.not.be.undefined
-
- expect(result.affectedItems.length).to.equal(BaseItemCounts.BackupFileRootKeyEncryptedItems)
-
- expect(result.errorCount).to.be.eq(backupData.items.length - BaseItemCounts.BackupFileRootKeyEncryptedItems)
- expect(application.items.getDisplayableNotes().length).to.equal(0)
- })
-
- it('importing data with no items key should use the root key generated by the file password', async function () {
- await setup({ fakeCrypto: false })
- /**
- * In SNJS 2.0.12, this file import would fail with "incorrect password" on file.
- * The reason was that we would use the default items key we had for the current account
- * instead of using the password generated root key for the file.
- *
- * Note this test will not be able to properly sync as the credentials are invalid.
- * This test is only meant to test successful local importing.
- */
- const identifier = 'standardnotes'
- const application = await Factory.createApplicationWithRealCrypto(identifier)
- /** Create legacy migrations value so that base migration detects old app */
- await application.device.setRawStorageValue(
- 'keychain',
- JSON.stringify({
- [identifier]: {
- version: '003',
- masterKey: '30bae65687b45b20100be219df983bded23868baa44f4bbef1026403daee0a9d',
- dataAuthenticationKey: 'c9b382ff1f7adb5c6cad620605ad139cd9f1e7700f507345ef1a1d46a6413712',
+ await application.importData(
+ {
+ items: [notePayload, tagPayload],
},
- }),
- )
- await application.device.setRawStorageValue(
- 'descriptors',
- JSON.stringify({
- [identifier]: {
- identifier: 'standardnotes',
- label: 'Main Application',
- primary: true,
- },
- }),
- )
- await application.device.setRawStorageValue('standardnotes-snjs_version', '2.0.11')
- await application.device.saveDatabaseEntry(
- {
- content:
- '003:9f2c7527eb8b2a1f8bfb3ea6b885403b6886bce2640843ebd57a6c479cbf7597:58e3322b-269a-4be3-a658-b035dffcd70f:9140b23a0fa989e224e292049f133154:SESTNOgIGf2+ZqmJdFnGU4EMgQkhKOzpZNoSzx76SJaImsayzctAgbUmJ+UU2gSQAHADS3+Z5w11bXvZgIrStTsWriwvYkNyyKmUPadKHNSBwOk4WeBZpWsA9gtI5zgI04Q5pvb8hS+kNW2j1DjM4YWqd0JQxMOeOrMIrxr/6Awn5TzYE+9wCbXZdYHyvRQcp9ui/G02ZJ67IA86vNEdjTTBAAWipWqTqKH9VDZbSQ2W/IOKfIquB373SFDKZb1S1NmBFvcoG2G7w//fAl/+ehYiL6UdiNH5MhXCDAOTQRFNfOh57HFDWVnz1VIp8X+VAPy6d9zzQH+8aws1JxHq/7BOhXrFE8UCueV6kERt9njgQxKJzd9AH32ShSiUB9X/sPi0fUXbS178xAZMJrNx3w==:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
- content_type: 'SN|ItemsKey',
- created_at: new Date(),
- enc_item_key:
- '003:d7267919b07864ccc1da87a48db6c6192e2e892be29ce882e981c36f673b3847:58e3322b-269a-4be3-a658-b035dffcd70f:2384a22d8f8bf671ba6517c6e1d0be30:0qXjBDPLCcMlNTnuUDcFiJPIXU9OP6b4ttTVE58n2Jn7971xMhx6toLbAZWWLPk/ezX/19EYE9xmRngWsG4jJaZMxGZIz/melU08K7AHH3oahQpHwZvSM3iV2ufsN7liQywftdVH6NNzULnZnFX+FgEfpDquru++R4aWDLvsSegWYmde9zD62pPNUB9Kik6P:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
- updated_at: new Date(),
- uuid: '58e3322b-269a-4be3-a658-b035dffcd70f',
- },
- identifier,
- )
- /**
- * Note that this storage contains "sync.standardnotes.org" as the API Host param.
- */
- await application.device.setRawStorageValue(
- 'standardnotes-storage',
- JSON.stringify({
- wrapped: {
- uuid: '15af096f-4e9d-4cde-8d67-f132218fa757',
- content_type: 'SN|EncryptedStorage',
- enc_item_key:
- '003:2fb0c55859ddf0c16982b91d6202a6fb8174f711d820f8b785c558538cda5048:15af096f-4e9d-4cde-8d67-f132218fa757:09a4da52d5214e76642f0363246daa99:zt5fnmxYSZOqC+uA08oAKdtjfTdAoX1lPnbTe98CYQSlIvaePIpG5c9tAN5QzZbECkj4Lm9txwSA2O6Y4Y25rqO4lIerKjxxNqPwDze9mtPOGeoR48csUPiMIHiH78bLGZZs4VoBwYKAP+uEygXEFYRuscGnDOrFV7fnwGDL/nkhr6xpM159OTUKBgiBpVMS:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
- content:
- '003:70a02948696e09211cfd34cd312dbbf85751397189da06d7acc7c46dafa9aeeb:15af096f-4e9d-4cde-8d67-f132218fa757:b92fb4b030ac51f4d3eef0ada35f3d5f:r3gdrawyd069qOQQotD5EtabTwjs4IiLFWotK0Ygbt9oAT09xILx7v92z8YALJ6i6EKHOT7zyCytR5l2B9b1J7Tls00uVgfEKs3zX7n3F6ne+ju0++WsJuy0Gre5+Olov6lqQrY3I8hWQShxaG84huZaFTIPU5+LP0JAseWWDENqUQ+Vxr+w0wqNYO6TLtr/YAqk2yOY7DLQ0WhGzK+WH9JfvS8MCccJVeBD99ebM8lKVVfTaUfrk2AlbMv47TFSjTeCDblQuU68joE45HV8Y0g2CF4nkTvdr3wn0HhdDp07YuXditX9NGtBhI8oFkstwKEksblyX9dGpn7of4ctdvNOom3Vjw/m4x9mE0lCIbjxQVAiDyy+Hg0HDtVt1j205ycg1RS7cT7+Sn746Z06S8TixcVUUUQh+MGRIulIE5utOE81Lv/p+jb2vmv+TGHUV4kZJPluG7A9IEphMZrMWwiU56FdSlSDD82qd9iG+C3Pux+X/GYCMiWS2T/BoyI6a9OERSARuTUuom2bv59hqD1yUoj7VQXhqXmverSwLE1zDeF+dc0tMwuTNCNOTk08A6wRKTR9ZjuFlLcxHsg/VZyfIdCkElFh1FrliMbW2ZsgsPFaZAI+YN8pid1tTw+Ou1cOfyD85aki98DDvg/cTi8ahrrm8UvxRQwhIW17Cm1RnKxhIvaq5HRjEN76Y46ubkZv7/HjhNwJt9vPEr9wyOrMH6XSxCnSIFD1kbVHI33q444xyUWa/EQju8SoEGGU92HhpMWd1kIz37SJRJTC7u2ah2Xg60JGcUcCNtHG3IHMPVP+UKUjx5nKP6t/NVSa+xsjIvM/ZkSL37W0TMZykC1cKfzeUmlZhGQPCIqad3b4ognZ48LGCgwBP87rWn8Ln8Cqcz7X0Ze22HoouKBPAtWlYJ8fmvg2HiW6nX/L9DqoxK4OXt/LnC2BTEvtP4PUzBqx8WoqmVNNnYp+FgYptLcgxmgckle41w1eMr6NYGeaaC1Jk3i/e9Piw0w0XjV/lB+yn03gEMYPTT2yiXMQrfPmkUNYNN7/xfhY3bqqwfER7iXdr/80Lc+x9byywChXLvg8VCjHWGd+Sky3NHyMdxLY8IqefyyZWMeXtt1aNYH6QW9DeK5KvK3DI+MK3kWwMCySe51lkE9jzcqrxpYMZjb2Za9VDZNBgdwQYXfOlxFEje0so0LlMJmmxRfbMU06bYt0vszT2szAkOnVuyi6TBRiGLyjMxYI0csM0SHZWZUQK0z7ZoQAWR5D+adX29tOvrKc2kJA8Lrzgeqw/rJIh6zPg3kmsd2rFbo+Qfe3J6XrlZU+J+N96I98i0FU0quI6HwG1zFg6UOmfRjaCML8rSAPtMaNhlO7M2sgRmDCtsNcpU06Fua6F2fEHPiXs4+9:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
- created_at: '2020-11-24T00:53:42.057Z',
- updated_at: '1970-01-01T00:00:00.000Z',
- },
- nonwrapped: {
- ROOT_KEY_PARAMS: {
- pw_nonce: '4cb103aa89cff4563a911d3f396583cefc6833c66f880fbee06bda94c31f868b',
- pw_cost: 110000,
- identifier: 'nov2322@bitar.io',
- version: '003',
- },
- },
- }),
- )
- const password = 'password'
+ true,
+ )
- await application.prepareForLaunch({
- receiveChallenge: (challenge) => {
- if (challenge.reason === ChallengeReason.Custom) {
- return
- }
+ expect(application.items.items.length).to.equal(expectedItemCount)
- if (
- challenge.reason === ChallengeReason.DecryptEncryptedFile ||
- challenge.reason === ChallengeReason.ImportFile
- ) {
- application.submitValuesForChallenge(
- challenge,
- challenge.prompts.map((prompt) =>
- CreateChallengeValue(
- prompt,
- prompt.validation !== ChallengeValidation.ProtectionSessionDuration
- ? password
- : UnprotectedAccessSecondsDuration.OneMinute,
- ),
+ expect(tag.content.references.length).to.equal(1)
+ expect(tag.noteCount).to.equal(1)
+
+ expect(note.content.references.length).to.equal(0)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(1)
+ })
+
+ it('importing same note many times should create only one duplicate', async function () {
+ /**
+ * Used strategy here will be KEEP_LEFT_DUPLICATE_RIGHT
+ * which means that new right items will be created with different
+ */
+
+ const notePayload = Factory.createNotePayload()
+ await application.mutator.emitItemFromPayload(notePayload, PayloadEmitSource.LocalChanged)
+ expectedItemCount++
+ const mutatedNote = new DecryptedPayload({
+ ...notePayload,
+ content: {
+ ...notePayload.content,
+ title: `${Math.random()}`,
+ },
+ })
+ await application.importData(
+ {
+ items: [mutatedNote, mutatedNote, mutatedNote],
+ },
+ true,
+ )
+ expectedItemCount++
+ expect(application.items.getDisplayableNotes().length).to.equal(2)
+ const imported = application.items.getDisplayableNotes().find((n) => n.uuid !== notePayload.uuid)
+ expect(imported.content.title).to.equal(mutatedNote.content.title)
+ })
+
+ it('importing a tag with lesser references should not create duplicate', async function () {
+ const pair = createRelatedNoteTagPairPayload()
+ const tagPayload = pair[1]
+ await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
+ const mutatedTag = new DecryptedPayload({
+ ...tagPayload,
+ content: {
+ ...tagPayload.content,
+ references: [],
+ },
+ })
+ await application.importData(
+ {
+ items: [mutatedTag],
+ },
+ true,
+ )
+ expect(application.items.getDisplayableTags().length).to.equal(1)
+ expect(application.items.findItem(tagPayload.uuid).content.references.length).to.equal(1)
+ })
+
+ it('importing data with differing content should create duplicates', async function () {
+ const pair = createRelatedNoteTagPairPayload()
+ const notePayload = pair[0]
+ const tagPayload = pair[1]
+ await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
+ expectedItemCount += 2
+ const note = application.items.getDisplayableNotes()[0]
+ const tag = application.items.getDisplayableTags()[0]
+ const mutatedNote = new DecryptedPayload({
+ ...notePayload,
+ content: {
+ ...notePayload.content,
+ title: `${Math.random()}`,
+ },
+ })
+ const mutatedTag = new DecryptedPayload({
+ ...tagPayload,
+ content: {
+ ...tagPayload.content,
+ title: `${Math.random()}`,
+ },
+ })
+ await application.importData(
+ {
+ items: [mutatedNote, mutatedTag],
+ },
+ true,
+ )
+ expectedItemCount += 2
+ expect(application.items.items.length).to.equal(expectedItemCount)
+
+ const newNote = application.items.getDisplayableNotes().find((n) => n.uuid !== notePayload.uuid)
+ const newTag = application.items.getDisplayableTags().find((t) => t.uuid !== tagPayload.uuid)
+
+ expect(newNote.uuid).to.not.equal(note.uuid)
+ expect(newTag.uuid).to.not.equal(tag.uuid)
+
+ const refreshedTag = application.items.findItem(tag.uuid)
+ expect(refreshedTag.content.references.length).to.equal(2)
+ expect(refreshedTag.noteCount).to.equal(2)
+
+ const refreshedNote = application.items.findItem(note.uuid)
+ expect(refreshedNote.content.references.length).to.equal(0)
+ expect(application.items.itemsReferencingItem(refreshedNote).length).to.equal(2)
+
+ expect(newTag.content.references.length).to.equal(1)
+ expect(newTag.noteCount).to.equal(1)
+
+ expect(newNote.content.references.length).to.equal(0)
+ expect(application.items.itemsReferencingItem(newNote).length).to.equal(1)
+ })
+
+ it('when importing items, imported values should not be used to determine if changed', async function () {
+ /**
+ * If you have a note and a tag, and the tag has 1 reference to the note,
+ * and you import the same two items, except modify the note value so that
+ * a duplicate is created, we expect only the note to be duplicated, and the
+ * tag not to. However, if only the note changes, and you duplicate the note,
+ * which causes the tag's references content to change, then when the incoming
+ * tag is being processed, it will also think it has changed, since our local
+ * value now doesn't match what's coming in. The solution is to get all values
+ * ahead of time before any changes are made.
+ */
+
+ const note = await Factory.createMappedNote(application)
+ const tag = await Factory.createMappedTag(application)
+ expectedItemCount += 2
+
+ await application.mutator.changeItem(tag, (mutator) => {
+ mutator.e2ePendingRefactor_addItemAsRelationship(note)
+ })
+
+ const externalNote = Object.assign(
+ {},
+ {
+ uuid: note.uuid,
+ content: note.getContentCopy(),
+ content_type: note.content_type,
+ },
+ )
+ externalNote.content.text = `${Math.random()}`
+
+ const externalTag = Object.assign(
+ {},
+ {
+ uuid: tag.uuid,
+ content: tag.getContentCopy(),
+ content_type: tag.content_type,
+ },
+ )
+
+ await application.importData(
+ {
+ items: [externalNote, externalTag],
+ },
+ true,
+ )
+ expectedItemCount += 1
+
+ /** We expect now that the total item count is 3, not 4. */
+ expect(application.items.items.length).to.equal(expectedItemCount)
+
+ const refreshedTag = application.items.findItem(tag.uuid)
+ /** References from both items have merged. */
+ expect(refreshedTag.content.references.length).to.equal(2)
+ })
+
+ it('should import decrypted data and keep items that were previously deleted', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ Factory.handlePasswordChallenges(application, password)
+
+ const [note, tag] = await Promise.all([
+ Factory.createMappedNote(application),
+ Factory.createMappedTag(application),
+ ])
+
+ await application.sync.sync({ awaitAll: true })
+
+ await application.mutator.deleteItem(note)
+ await application.sync.sync()
+ expect(application.items.findItem(note.uuid)).to.not.exist
+
+ await application.mutator.deleteItem(tag)
+ await application.sync.sync()
+ expect(application.items.findItem(tag.uuid)).to.not.exist
+
+ await application.importData(
+ {
+ items: [note, tag],
+ },
+ true,
+ )
+
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.findItem(note.uuid).deleted).to.not.be.ok
+
+ expect(application.items.getDisplayableTags().length).to.equal(1)
+ expect(application.items.findItem(tag.uuid).deleted).to.not.be.ok
+ })
+
+ it('should duplicate notes by alternating UUIDs when dealing with conflicts during importing', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+ const note = await Factory.createSyncedNote(application)
+
+ /** Sign into another account and import the same item. It should get a different UUID. */
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ email = UuidGenerator.GenerateUuid()
+ Factory.handlePasswordChallenges(application, password)
+
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ await application.importData(
+ {
+ items: [note.payload],
+ },
+ true,
+ )
+
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableNotes()[0].uuid).to.not.equal(note.uuid)
+ })
+
+ it('should maintain consistency between storage and PayloadManager after an import with conflicts', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+ const note = await Factory.createSyncedNote(application)
+
+ /** Sign into another account and import the same items. They should get a different UUID. */
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ email = UuidGenerator.GenerateUuid()
+ Factory.handlePasswordChallenges(application, password)
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ await application.importData(
+ {
+ items: [note],
+ },
+ true,
+ )
+
+ const storedPayloads = await application.storage.getAllRawPayloads()
+ expect(application.items.items.length).to.equal(storedPayloads.length)
+ const notes = storedPayloads.filter((p) => p.content_type === ContentType.TYPES.Note)
+ const itemsKeys = storedPayloads.filter((p) => p.content_type === ContentType.TYPES.ItemsKey)
+ expect(notes.length).to.equal(1)
+ expect(itemsKeys.length).to.equal(1)
+ })
+
+ it('should import encrypted data and keep items that were previously deleted', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ const [note, tag] = await Promise.all([
+ Factory.createMappedNote(application),
+ Factory.createMappedTag(application),
+ ])
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await application.sync.sync({ awaitAll: true })
+
+ await application.mutator.deleteItem(note)
+ await application.sync.sync()
+ expect(application.items.findItem(note.uuid)).to.not.exist
+
+ await application.mutator.deleteItem(tag)
+ await application.sync.sync()
+ expect(application.items.findItem(tag.uuid)).to.not.exist
+
+ await application.importData(backupData, true)
+
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.findItem(note.uuid).deleted).to.not.be.ok
+
+ expect(application.items.getDisplayableTags().length).to.equal(1)
+ expect(application.items.findItem(tag.uuid).deleted).to.not.be.ok
+ })
+
+ it('should import decrypted data and all items payload source should be FileImport', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ const [note, tag] = await Promise.all([
+ Factory.createMappedNote(application),
+ Factory.createMappedTag(application),
+ ])
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.handlePasswordChallenges(application, password)
+
+ await application.importData(backupData, true)
+
+ const importedNote = application.items.findItem(note.uuid)
+ const importedTag = application.items.findItem(tag.uuid)
+
+ expect(importedNote.payload.source).to.be.equal(PayloadSource.FileImport)
+ expect(importedTag.payload.source).to.be.equal(PayloadSource.FileImport)
+ })
+
+ it('should import encrypted data and all items payload source should be FileImport', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ const [note, tag] = await Promise.all([
+ Factory.createMappedNote(application),
+ Factory.createMappedTag(application),
+ ])
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.handlePasswordChallenges(application, password)
+
+ await application.importData(backupData, true)
+
+ const importedNote = application.items.findItem(note.uuid)
+ const importedTag = application.items.findItem(tag.uuid)
+ expect(importedNote.payload.source).to.be.equal(PayloadSource.FileImport)
+ expect(importedTag.payload.source).to.be.equal(PayloadSource.FileImport)
+ })
+
+ it('should import data from 003 encrypted payload using client generated backup', async function () {
+ const oldVersion = ProtocolVersion.V003
+ await Factory.registerOldUser({
+ application: application,
+ email: email,
+ password: password,
+ version: oldVersion,
+ })
+
+ const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
+ title: 'Encrypted note',
+ text: 'On protocol version 003.',
+ })
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.handlePasswordChallenges(application, password)
+
+ const result = await application.importData(backupData, true)
+ expect(result).to.not.be.undefined
+ expect(result.affectedItems.length).to.be.eq(backupData.items.length)
+ expect(result.errorCount).to.be.eq(0)
+
+ const decryptedNote = application.items.findItem(noteItem.uuid)
+ expect(decryptedNote.title).to.be.eq('Encrypted note')
+ expect(decryptedNote.text).to.be.eq('On protocol version 003.')
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ })
+
+ it('should import data from 004 encrypted payload', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
+ title: 'Encrypted note',
+ text: 'On protocol version 004.',
+ })
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.handlePasswordChallenges(application, password)
+
+ const result = await application.importData(backupData, true)
+ expect(result).to.not.be.undefined
+ expect(result.affectedItems.length).to.be.eq(backupData.items.length)
+ expect(result.errorCount).to.be.eq(0)
+
+ const decryptedNote = application.items.findItem(noteItem.uuid)
+ expect(decryptedNote.title).to.be.eq('Encrypted note')
+ expect(decryptedNote.text).to.be.eq('On protocol version 004.')
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ })
+
+ it('should return correct errorCount', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ const noteItem = await application.mutator.createItem(ContentType.TYPES.Note, {
+ title: 'This is a valid, encrypted note',
+ text: 'On protocol version 004.',
+ })
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.handlePasswordChallenges(application, password)
+
+ const madeUpPayload = JSON.parse(JSON.stringify(noteItem))
+
+ madeUpPayload.items_key_id = undefined
+ madeUpPayload.content = '004:somenonsense'
+ madeUpPayload.enc_item_key = '003:anothernonsense'
+ madeUpPayload.version = '004'
+ madeUpPayload.uuid = 'fake-uuid'
+
+ backupData.items = [...backupData.items, madeUpPayload]
+
+ const result = await application.importData(backupData, true)
+ expect(result).to.not.be.undefined
+ expect(result.affectedItems.length).to.be.eq(backupData.items.length - 1)
+ expect(result.errorCount).to.be.eq(1)
+ })
+
+ it('should not import data from 003 encrypted payload if an invalid password is provided', async function () {
+ const oldVersion = ProtocolVersion.V003
+ await Factory.registerOldUser({
+ application: application,
+ email: email,
+ password: UuidGenerator.GenerateUuid(),
+ version: oldVersion,
+ })
+
+ await application.mutator.createItem(ContentType.TYPES.Note, {
+ title: 'Encrypted note',
+ text: 'On protocol version 003.',
+ })
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ application.setLaunchCallback({
+ receiveChallenge: (challenge) => {
+ const values = challenge.prompts.map((prompt) =>
+ CreateChallengeValue(
+ prompt,
+ prompt.validation === ChallengeValidation.None ? 'incorrect password' : password,
),
)
- }
- },
- })
- await application.launch(false)
- await application.setHost.execute(Factory.getDefaultHost())
-
- const backupFile = {
- items: [
- {
- uuid: '11204d02-5a8b-47c0-ab94-ae0727d656b5',
- content_type: 'Note',
- created_at: '2020-11-23T17:11:06.322Z',
- enc_item_key:
- '003:111edcff9ed3432b9e11c4a64bef9e810ed2b9147790963caf6886511c46bbc4:11204d02-5a8b-47c0-ab94-ae0727d656b5:62de2b95cca4d7948f70516d12f5cb3a:lhUF/EoQP2DC8CSVrXyLp1yXsiJUXxwmtkwXtLUJ5sm4E0+ZNzMCO9U9ho+q6i9V+777dSbfTqODz4ZSt6hj3gtYxi9ZlOM/VrTtmJ2YcxiMaRTVl5sVZPG+YTpQPMuugN5/0EfuT/SJ9IqVbjgYhKA5xt/lMgw4JSbiW8ZkVQ5tVDfgt0omhDRLlkh758ou:eyJwd19ub25jZSI6IjNlMzU3YzQxZmI1YWU2MTUyYmZmMzY2ZjBhOGE3ZjRmZDk2NDQxZDZhNWViYzY3MDA4OTk2ZWY2YzU1YTg3ZjIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzVAYml0YXIuaW8iLCJ2ZXJzaW9uIjoiMDAzIn0=',
- content:
- '003:d43c6d2dc9465796e01145843cf1b95031030c15cc79a73f14d941d15e28147a:11204d02-5a8b-47c0-ab94-ae0727d656b5:84a2b760019a62d7ad9c314bc7a5564a:G8Mm9fy9ybuo92VbV4NUERruJ1VA7garv1+fBg4KRDRjsRGoLvORhHldQHRfUQmSR6PkrG6ol/jOn1gjIH5gtgGczB5NgbKau7amYZHsQJPr1UleJVsLrjMJgiYGqbEDmXPtJSX2tLGFhAbYcVX4xrHKbkiuLQnu9bZp9zbR6txB1NtLoNFvwDZTMko7Q+28fM4TKBbQCCw3NufLHVUnfEwS7tLLFFPdEyyMXOerKP93u8X+7NG2eDmsUetPsPOq:eyJwd19ub25jZSI6IjNlMzU3YzQxZmI1YWU2MTUyYmZmMzY2ZjBhOGE3ZjRmZDk2NDQxZDZhNWViYzY3MDA4OTk2ZWY2YzU1YTg3ZjIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzVAYml0YXIuaW8iLCJ2ZXJzaW9uIjoiMDAzIn0=',
- auth_hash: null,
- updated_at: '2020-11-23T17:11:40.399Z',
+ application.submitValuesForChallenge(challenge, values)
},
- ],
- auth_params: {
- pw_nonce: '3e357c41fb5ae6152bff366f0a8a7f4fd96441d6a5ebc67008996ef6c55a87f2',
- pw_cost: 110000,
- identifier: 'nov235@bitar.io',
- version: '003',
- },
- }
+ })
- const result = await application.importData(backupFile, false)
- expect(result.errorCount).to.equal(0)
- await Factory.safeDeinit(application)
+ const result = await application.importData(backupData, true)
+ expect(result).to.not.be.undefined
+
+ expect(result.affectedItems.length).to.be.eq(0)
+ expect(result.errorCount).to.be.eq(backupData.items.length)
+ expect(application.items.getDisplayableNotes().length).to.equal(0)
+ })
+
+ it('should not import data from 004 encrypted payload if an invalid password is provided', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ await application.mutator.createItem(ContentType.TYPES.Note, {
+ title: 'This is a valid, encrypted note',
+ text: 'On protocol version 004.',
+ })
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ application.setLaunchCallback({
+ receiveChallenge: (challenge) => {
+ const values = challenge.prompts.map((prompt) => CreateChallengeValue(prompt, 'incorrect password'))
+ application.submitValuesForChallenge(challenge, values)
+ },
+ })
+
+ const result = await application.importData(backupData, true)
+ expect(result).to.not.be.undefined
+ expect(result.affectedItems.length).to.be.eq(0)
+ expect(result.errorCount).to.be.eq(backupData.items.length)
+ expect(application.items.getDisplayableNotes().length).to.equal(0)
+ })
+
+ it('should not import encrypted data with no keyParams or auth_params', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ await application.mutator.createItem(ContentType.TYPES.Note, {
+ title: 'Encrypted note',
+ text: 'On protocol version 004.',
+ })
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ delete backupData.keyParams
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+
+ const result = await application.importData(backupData)
+
+ expect(result.error).to.be.ok
+ })
+
+ it('should not import payloads if the corresponding ItemsKey is not present within the backup file', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+ Factory.handlePasswordChallenges(application, password)
+
+ await application.mutator.createItem(ContentType.TYPES.Note, {
+ title: 'Encrypted note',
+ text: 'On protocol version 004.',
+ })
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ backupData.items = backupData.items.filter((payload) => payload.content_type !== ContentType.TYPES.ItemsKey)
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.handlePasswordChallenges(application, password)
+
+ const result = await application.importData(backupData, true)
+
+ expect(result).to.not.be.undefined
+
+ expect(result.affectedItems.length).to.equal(BaseItemCounts.BackupFileRootKeyEncryptedItems)
+
+ expect(result.errorCount).to.be.eq(backupData.items.length - BaseItemCounts.BackupFileRootKeyEncryptedItems)
+ expect(application.items.getDisplayableNotes().length).to.equal(0)
+ })
+
+ it('importing another accounts notes/tags should correctly keep relationships', async function () {
+ await Factory.registerUserToApplication({
+ application: application,
+ email: email,
+ password: password,
+ })
+
+ Factory.handlePasswordChallenges(application, password)
+
+ const pair = createRelatedNoteTagPairPayload()
+ await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
+
+ await application.sync.sync()
+
+ const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+
+ await Factory.safeDeinit(application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.handlePasswordChallenges(application, password)
+
+ await Factory.registerUserToApplication({
+ application: application,
+ email: `${Math.random()}`,
+ password: password,
+ })
+
+ await application.importData(backupData, true)
+
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableTags().length).to.equal(1)
+
+ const importedNote = application.items.getDisplayableNotes()[0]
+ const importedTag = application.items.getDisplayableTags()[0]
+ expect(application.items.referencesForItem(importedTag).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(importedNote).length).to.equal(1)
+
+ await Factory.safeDeinit(application)
+ }).timeout(Factory.TwentySecondTimeout)
})
- it('importing another accounts notes/tags should correctly keep relationships', async function () {
- await setup({ fakeCrypto: true })
+ describe('real crypto', function () {
+ let identifier = 'standardnotes'
- await Factory.registerUserToApplication({
- application: application,
- email: email,
- password: password,
+ it('should import data from 003 encrypted payload using server generated backup with 004 key params', async function () {
+ context = await Factory.createAppContextWithRealCrypto(identifier)
+
+ await context.launch()
+ application = context.application
+
+ const backupData = {
+ items: [
+ {
+ uuid: 'eb1b7eed-e43d-48dd-b257-b7fc8ccba3da',
+ duplicate_of: null,
+ items_key_id: null,
+ content:
+ '003:618138e365a13f8aed17d4f52e3da47d4b5d6e02004a0f827118e8a981a57c35:eb1b7eed-e43d-48dd-b257-b7fc8ccba3da:9f38642b7a3f57546520a9e32aa7c0ad:qa9rUcaD904m1Knv63dnATEHwfHJjsbq9bWb06zGTsyQxzLaAYT7uRGp2KB2g1eo5Aqxc5FqhvuF0+dE1f4+uQOeiRFNX73V2pJJY0w5Qq7l7ZuhB08ZtOMY4Ctq7evBBSIVZ+PEIfFnACelNJhsB5Uhn3kS4ZBx6qtvQ6ciSQGfYAwc6wSKhjUm1umEINeb08LNgwbP6XAm8U/la1bdtdMO112XjUW7ixkWi3POWcM=:eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X2Nvc3QiOjExMDAwMCwicHdfbm9uY2UiOiJhZmIwYjE3NGJlYjViMmJmZTIyNTk1NDlmMTgxNDI1NzlkMDE1ZmE3ZTBhMjE4YzVmNDIxNmU0Mzg2ZGI3OWFiIiwidmVyc2lvbiI6IjAwMyJ9',
+ content_type: 'Note',
+ enc_item_key:
+ '003:5a01e913c52899ba10c16dbe7e713dd9caf9b9554c82176ddfcf1424f5bfd94f:eb1b7eed-e43d-48dd-b257-b7fc8ccba3da:14721ff8dbdd36fb57ae4bf7414c5eab:odmq91dfaTZG/zeSUA09fD/PdB2OkiDxcQZ0FL06GPstxdvxnU17k1rtsWoA7HoNNnd5494BZ/b7YiKqUb76ddd8x3/+cTZgCa4tYxNINmb1T3wwUX0Ebxc8xynAhg6nTY/BGq+ba6jTyl8zw12dL3kBEGGglRCHnO0ZTeylwQW7asfONN8s0BwrvHdonRlx:eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X2Nvc3QiOjExMDAwMCwicHdfbm9uY2UiOiJhZmIwYjE3NGJlYjViMmJmZTIyNTk1NDlmMTgxNDI1NzlkMDE1ZmE3ZTBhMjE4YzVmNDIxNmU0Mzg2ZGI3OWFiIiwidmVyc2lvbiI6IjAwMyJ9',
+ auth_hash: null,
+ created_at: '2019-05-12T02:29:21.789000Z',
+ updated_at: '2019-11-12T21:47:48.382708Z',
+ deleted: false,
+ },
+ {
+ uuid: '10051be7-4ca2-4af3-aae9-021939df4fab',
+ duplicate_of: null,
+ items_key_id: null,
+ content:
+ '004:77a986823b8ffdd87164b6f541de6ed420b70ac67e055774:+8cjww1QbyXNX+PSKeCwmnysv0rAoEaKh409VWQJpDbEy/pPZCT6c0rKxLzvyMiSq6EwkOiduZMzokRgCKP7RuRqNPJceWsxNnpIUwa40KR1IP2tdreW4J8v9pFEzPMec1oq40u+c+UI/Y6ChOLV/4ozyWmpQCK3y8Ugm7B1/FzaeDs9Ie6Mvf98+XECoi0fWv9SO2TeBvq1G24LXd4zf0j8jd0sKZbLPXH0+gaUXtBH7A56lHvB0ED9NuiHI8xopTBd9ogKlz/b5+JB4zA2zQCQ3WMEE1qz6WeB2S4FMomgeO1e3trabdU0ICu0WMvDVii4qNlQo/inD41oHXKeV5QwnYoGjPrLJIaP0hiLKhDURTHygCdvWdp63OWI+aGxv0/HI+nfcRsqSE+aYECrWB/kp/c5yTrEqBEafuWZkw==:eyJrcCI6eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X25vbmNlIjoiNjUxYWUxZWM5NTgwMzM5YTM1NjdlZTdmMGY4NjcyNDkyZGUyYzE2NmE1NTZjMTNkMTE5NzI4YTAzYzYwZjc5MyIsInZlcnNpb24iOiIwMDQiLCJvcmlnaW5hdGlvbiI6InByb3RvY29sLXVwZ3JhZGUiLCJjcmVhdGVkIjoiMTYxNDc4NDE5MjQ5NyJ9LCJ1IjoiMTAwNTFiZTctNGNhMi00YWYzLWFhZTktMDIxOTM5ZGY0ZmFiIiwidiI6IjAwNCJ9',
+ content_type: 'SN|ItemsKey',
+ enc_item_key:
+ '004:d25deb224251b4705a44d8ce125a62f6a2f0e0e856603e8f:FEv1pfU/VfY7XhJrTfpcdhaSBfmNySTQtHohFYDm8V84KlyF5YaXRKV7BfXsa77DKTjOCU/EHHsWwhBEEfsNnzNySHxTHNc26bpoz0V8h50=:eyJrcCI6eyJpZGVudGlmaWVyIjoicGxheWdyb3VuZEBiaXRhci5pbyIsInB3X25vbmNlIjoiNjUxYWUxZWM5NTgwMzM5YTM1NjdlZTdmMGY4NjcyNDkyZGUyYzE2NmE1NTZjMTNkMTE5NzI4YTAzYzYwZjc5MyIsInZlcnNpb24iOiIwMDQiLCJvcmlnaW5hdGlvbiI6InByb3RvY29sLXVwZ3JhZGUiLCJjcmVhdGVkIjoiMTYxNDc4NDE5MjQ5NyJ9LCJ1IjoiMTAwNTFiZTctNGNhMi00YWYzLWFhZTktMDIxOTM5ZGY0ZmFiIiwidiI6IjAwNCJ9',
+ auth_hash: null,
+ created_at: '2020-09-07T12:22:06.562000Z',
+ updated_at: '2021-03-03T15:09:55.741107Z',
+ deleted: false,
+ },
+ ],
+ auth_params: {
+ identifier: 'playground@bitar.io',
+ pw_nonce: '651ae1ec9580339a3567ee7f0f8672492de2c166a556c13d119728a03c60f793',
+ version: '004',
+ },
+ }
+
+ Factory.handlePasswordChallenges(application, 'password')
+
+ const result = await application.importData(backupData, true)
+ expect(result).to.not.be.undefined
+ expect(result.affectedItems.length).to.be.eq(backupData.items.length)
+ expect(result.errorCount).to.be.eq(0)
})
- Factory.handlePasswordChallenges(application, password)
+ it('importing data with no items key should use the root key generated by the file password', async function () {
+ /**
+ * In SNJS 2.0.12, this file import would fail with "incorrect password" on file.
+ * The reason was that we would use the default items key we had for the current account
+ * instead of using the password generated root key for the file.
+ *
+ * Note this test will not be able to properly sync as the credentials are invalid.
+ * This test is only meant to test successful local importing.
+ */
+ const application = await Factory.createApplicationWithRealCrypto(identifier)
+ /** Create legacy migrations value so that base migration detects old app */
+ await application.device.setRawStorageValue(
+ 'keychain',
+ JSON.stringify({
+ [identifier]: {
+ version: '003',
+ masterKey: '30bae65687b45b20100be219df983bded23868baa44f4bbef1026403daee0a9d',
+ dataAuthenticationKey: 'c9b382ff1f7adb5c6cad620605ad139cd9f1e7700f507345ef1a1d46a6413712',
+ },
+ }),
+ )
+ await application.device.setRawStorageValue(
+ 'descriptors',
+ JSON.stringify({
+ [identifier]: {
+ identifier: 'standardnotes',
+ label: 'Main Application',
+ primary: true,
+ },
+ }),
+ )
+ await application.device.setRawStorageValue('standardnotes-snjs_version', '2.0.11')
+ await application.device.saveDatabaseEntry(
+ {
+ content:
+ '003:9f2c7527eb8b2a1f8bfb3ea6b885403b6886bce2640843ebd57a6c479cbf7597:58e3322b-269a-4be3-a658-b035dffcd70f:9140b23a0fa989e224e292049f133154:SESTNOgIGf2+ZqmJdFnGU4EMgQkhKOzpZNoSzx76SJaImsayzctAgbUmJ+UU2gSQAHADS3+Z5w11bXvZgIrStTsWriwvYkNyyKmUPadKHNSBwOk4WeBZpWsA9gtI5zgI04Q5pvb8hS+kNW2j1DjM4YWqd0JQxMOeOrMIrxr/6Awn5TzYE+9wCbXZdYHyvRQcp9ui/G02ZJ67IA86vNEdjTTBAAWipWqTqKH9VDZbSQ2W/IOKfIquB373SFDKZb1S1NmBFvcoG2G7w//fAl/+ehYiL6UdiNH5MhXCDAOTQRFNfOh57HFDWVnz1VIp8X+VAPy6d9zzQH+8aws1JxHq/7BOhXrFE8UCueV6kERt9njgQxKJzd9AH32ShSiUB9X/sPi0fUXbS178xAZMJrNx3w==:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
+ content_type: 'SN|ItemsKey',
+ created_at: new Date(),
+ enc_item_key:
+ '003:d7267919b07864ccc1da87a48db6c6192e2e892be29ce882e981c36f673b3847:58e3322b-269a-4be3-a658-b035dffcd70f:2384a22d8f8bf671ba6517c6e1d0be30:0qXjBDPLCcMlNTnuUDcFiJPIXU9OP6b4ttTVE58n2Jn7971xMhx6toLbAZWWLPk/ezX/19EYE9xmRngWsG4jJaZMxGZIz/melU08K7AHH3oahQpHwZvSM3iV2ufsN7liQywftdVH6NNzULnZnFX+FgEfpDquru++R4aWDLvsSegWYmde9zD62pPNUB9Kik6P:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
+ updated_at: new Date(),
+ uuid: '58e3322b-269a-4be3-a658-b035dffcd70f',
+ },
+ identifier,
+ )
+ /**
+ * Note that this storage contains "sync.standardnotes.org" as the API Host param.
+ */
+ await application.device.setRawStorageValue(
+ 'standardnotes-storage',
+ JSON.stringify({
+ wrapped: {
+ uuid: '15af096f-4e9d-4cde-8d67-f132218fa757',
+ content_type: 'SN|EncryptedStorage',
+ enc_item_key:
+ '003:2fb0c55859ddf0c16982b91d6202a6fb8174f711d820f8b785c558538cda5048:15af096f-4e9d-4cde-8d67-f132218fa757:09a4da52d5214e76642f0363246daa99:zt5fnmxYSZOqC+uA08oAKdtjfTdAoX1lPnbTe98CYQSlIvaePIpG5c9tAN5QzZbECkj4Lm9txwSA2O6Y4Y25rqO4lIerKjxxNqPwDze9mtPOGeoR48csUPiMIHiH78bLGZZs4VoBwYKAP+uEygXEFYRuscGnDOrFV7fnwGDL/nkhr6xpM159OTUKBgiBpVMS:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
+ content:
+ '003:70a02948696e09211cfd34cd312dbbf85751397189da06d7acc7c46dafa9aeeb:15af096f-4e9d-4cde-8d67-f132218fa757:b92fb4b030ac51f4d3eef0ada35f3d5f:r3gdrawyd069qOQQotD5EtabTwjs4IiLFWotK0Ygbt9oAT09xILx7v92z8YALJ6i6EKHOT7zyCytR5l2B9b1J7Tls00uVgfEKs3zX7n3F6ne+ju0++WsJuy0Gre5+Olov6lqQrY3I8hWQShxaG84huZaFTIPU5+LP0JAseWWDENqUQ+Vxr+w0wqNYO6TLtr/YAqk2yOY7DLQ0WhGzK+WH9JfvS8MCccJVeBD99ebM8lKVVfTaUfrk2AlbMv47TFSjTeCDblQuU68joE45HV8Y0g2CF4nkTvdr3wn0HhdDp07YuXditX9NGtBhI8oFkstwKEksblyX9dGpn7of4ctdvNOom3Vjw/m4x9mE0lCIbjxQVAiDyy+Hg0HDtVt1j205ycg1RS7cT7+Sn746Z06S8TixcVUUUQh+MGRIulIE5utOE81Lv/p+jb2vmv+TGHUV4kZJPluG7A9IEphMZrMWwiU56FdSlSDD82qd9iG+C3Pux+X/GYCMiWS2T/BoyI6a9OERSARuTUuom2bv59hqD1yUoj7VQXhqXmverSwLE1zDeF+dc0tMwuTNCNOTk08A6wRKTR9ZjuFlLcxHsg/VZyfIdCkElFh1FrliMbW2ZsgsPFaZAI+YN8pid1tTw+Ou1cOfyD85aki98DDvg/cTi8ahrrm8UvxRQwhIW17Cm1RnKxhIvaq5HRjEN76Y46ubkZv7/HjhNwJt9vPEr9wyOrMH6XSxCnSIFD1kbVHI33q444xyUWa/EQju8SoEGGU92HhpMWd1kIz37SJRJTC7u2ah2Xg60JGcUcCNtHG3IHMPVP+UKUjx5nKP6t/NVSa+xsjIvM/ZkSL37W0TMZykC1cKfzeUmlZhGQPCIqad3b4ognZ48LGCgwBP87rWn8Ln8Cqcz7X0Ze22HoouKBPAtWlYJ8fmvg2HiW6nX/L9DqoxK4OXt/LnC2BTEvtP4PUzBqx8WoqmVNNnYp+FgYptLcgxmgckle41w1eMr6NYGeaaC1Jk3i/e9Piw0w0XjV/lB+yn03gEMYPTT2yiXMQrfPmkUNYNN7/xfhY3bqqwfER7iXdr/80Lc+x9byywChXLvg8VCjHWGd+Sky3NHyMdxLY8IqefyyZWMeXtt1aNYH6QW9DeK5KvK3DI+MK3kWwMCySe51lkE9jzcqrxpYMZjb2Za9VDZNBgdwQYXfOlxFEje0so0LlMJmmxRfbMU06bYt0vszT2szAkOnVuyi6TBRiGLyjMxYI0csM0SHZWZUQK0z7ZoQAWR5D+adX29tOvrKc2kJA8Lrzgeqw/rJIh6zPg3kmsd2rFbo+Qfe3J6XrlZU+J+N96I98i0FU0quI6HwG1zFg6UOmfRjaCML8rSAPtMaNhlO7M2sgRmDCtsNcpU06Fua6F2fEHPiXs4+9:eyJwd19ub25jZSI6IjRjYjEwM2FhODljZmY0NTYzYTkxMWQzZjM5NjU4M2NlZmM2ODMzYzY2Zjg4MGZiZWUwNmJkYTk0YzMxZjg2OGIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzIyQGJpdGFyLmlvIiwidmVyc2lvbiI6IjAwMyIsIm9yaWdpbmF0aW9uIjoicmVnaXN0cmF0aW9uIn0=',
+ created_at: '2020-11-24T00:53:42.057Z',
+ updated_at: '1970-01-01T00:00:00.000Z',
+ },
+ nonwrapped: {
+ ROOT_KEY_PARAMS: {
+ pw_nonce: '4cb103aa89cff4563a911d3f396583cefc6833c66f880fbee06bda94c31f868b',
+ pw_cost: 110000,
+ identifier: 'nov2322@bitar.io',
+ version: '003',
+ },
+ },
+ }),
+ )
+ const password = 'password'
- const pair = createRelatedNoteTagPairPayload()
- await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
+ await application.prepareForLaunch({
+ receiveChallenge: (challenge) => {
+ if (challenge.reason === ChallengeReason.Custom) {
+ return
+ }
- await application.sync.sync()
+ if (
+ challenge.reason === ChallengeReason.DecryptEncryptedFile ||
+ challenge.reason === ChallengeReason.ImportFile
+ ) {
+ application.submitValuesForChallenge(
+ challenge,
+ challenge.prompts.map((prompt) =>
+ CreateChallengeValue(
+ prompt,
+ prompt.validation !== ChallengeValidation.ProtectionSessionDuration
+ ? password
+ : UnprotectedAccessSecondsDuration.OneMinute,
+ ),
+ ),
+ )
+ }
+ },
+ })
+ await application.launch(false)
+ await application.setHost.execute(Factory.getDefaultHost())
- const backupData = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ const backupFile = {
+ items: [
+ {
+ uuid: '11204d02-5a8b-47c0-ab94-ae0727d656b5',
+ content_type: 'Note',
+ created_at: '2020-11-23T17:11:06.322Z',
+ enc_item_key:
+ '003:111edcff9ed3432b9e11c4a64bef9e810ed2b9147790963caf6886511c46bbc4:11204d02-5a8b-47c0-ab94-ae0727d656b5:62de2b95cca4d7948f70516d12f5cb3a:lhUF/EoQP2DC8CSVrXyLp1yXsiJUXxwmtkwXtLUJ5sm4E0+ZNzMCO9U9ho+q6i9V+777dSbfTqODz4ZSt6hj3gtYxi9ZlOM/VrTtmJ2YcxiMaRTVl5sVZPG+YTpQPMuugN5/0EfuT/SJ9IqVbjgYhKA5xt/lMgw4JSbiW8ZkVQ5tVDfgt0omhDRLlkh758ou:eyJwd19ub25jZSI6IjNlMzU3YzQxZmI1YWU2MTUyYmZmMzY2ZjBhOGE3ZjRmZDk2NDQxZDZhNWViYzY3MDA4OTk2ZWY2YzU1YTg3ZjIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzVAYml0YXIuaW8iLCJ2ZXJzaW9uIjoiMDAzIn0=',
+ content:
+ '003:d43c6d2dc9465796e01145843cf1b95031030c15cc79a73f14d941d15e28147a:11204d02-5a8b-47c0-ab94-ae0727d656b5:84a2b760019a62d7ad9c314bc7a5564a:G8Mm9fy9ybuo92VbV4NUERruJ1VA7garv1+fBg4KRDRjsRGoLvORhHldQHRfUQmSR6PkrG6ol/jOn1gjIH5gtgGczB5NgbKau7amYZHsQJPr1UleJVsLrjMJgiYGqbEDmXPtJSX2tLGFhAbYcVX4xrHKbkiuLQnu9bZp9zbR6txB1NtLoNFvwDZTMko7Q+28fM4TKBbQCCw3NufLHVUnfEwS7tLLFFPdEyyMXOerKP93u8X+7NG2eDmsUetPsPOq:eyJwd19ub25jZSI6IjNlMzU3YzQxZmI1YWU2MTUyYmZmMzY2ZjBhOGE3ZjRmZDk2NDQxZDZhNWViYzY3MDA4OTk2ZWY2YzU1YTg3ZjIiLCJwd19jb3N0IjoxMTAwMDAsImlkZW50aWZpZXIiOiJub3YyMzVAYml0YXIuaW8iLCJ2ZXJzaW9uIjoiMDAzIn0=',
+ auth_hash: null,
+ updated_at: '2020-11-23T17:11:40.399Z',
+ },
+ ],
+ auth_params: {
+ pw_nonce: '3e357c41fb5ae6152bff366f0a8a7f4fd96441d6a5ebc67008996ef6c55a87f2',
+ pw_cost: 110000,
+ identifier: 'nov235@bitar.io',
+ version: '003',
+ },
+ }
- await Factory.safeDeinit(application)
- application = await Factory.createInitAppWithFakeCrypto()
- Factory.handlePasswordChallenges(application, password)
-
- await Factory.registerUserToApplication({
- application: application,
- email: `${Math.random()}`,
- password: password,
+ const result = await application.importData(backupFile, false)
+ expect(result.errorCount).to.equal(0)
+ await Factory.safeDeinit(application)
})
-
- await application.importData(backupData, true)
-
- expect(application.items.getDisplayableNotes().length).to.equal(1)
- expect(application.items.getDisplayableTags().length).to.equal(1)
-
- const importedNote = application.items.getDisplayableNotes()[0]
- const importedTag = application.items.getDisplayableTags()[0]
- expect(application.items.referencesForItem(importedTag).length).to.equal(1)
- expect(application.items.itemsReferencingItem(importedNote).length).to.equal(1)
- }).timeout(Factory.TwentySecondTimeout)
+ })
})
diff --git a/packages/snjs/mocha/model_tests/items.test.js b/packages/snjs/mocha/model_tests/items.test.js
index a466887ed..ea30d8d27 100644
--- a/packages/snjs/mocha/model_tests/items.test.js
+++ b/packages/snjs/mocha/model_tests/items.test.js
@@ -1,7 +1,6 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -11,47 +10,52 @@ describe('items', () => {
awaitAll: true,
}
+ let application
+ let expectedItemCount
+
beforeEach(async function () {
- this.expectedItemCount = BaseItemCounts.DefaultItems
- this.application = await Factory.createInitAppWithFakeCrypto()
+ localStorage.clear()
+ expectedItemCount = BaseItemCounts.DefaultItems
+ application = await Factory.createInitAppWithFakeCrypto()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
+ localStorage.clear()
})
it('setting an item as dirty should update its client updated at', async function () {
const params = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([params], PayloadEmitSource.LocalChanged)
- const item = this.application.items.items[0]
+ await application.mutator.emitItemsFromPayloads([params], PayloadEmitSource.LocalChanged)
+ const item = application.items.items[0]
const prevDate = item.userModifiedDate.getTime()
await Factory.sleep(0.1)
- await this.application.mutator.setItemDirty(item, true)
- const refreshedItem = this.application.items.findItem(item.uuid)
+ await application.mutator.setItemDirty(item, true)
+ const refreshedItem = application.items.findItem(item.uuid)
const newDate = refreshedItem.userModifiedDate.getTime()
expect(prevDate).to.not.equal(newDate)
})
it('setting an item as dirty with option to skip client updated at', async function () {
const params = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([params], PayloadEmitSource.LocalChanged)
- const item = this.application.items.items[0]
+ await application.mutator.emitItemsFromPayloads([params], PayloadEmitSource.LocalChanged)
+ const item = application.items.items[0]
const prevDate = item.userModifiedDate.getTime()
await Factory.sleep(0.1)
- await this.application.mutator.setItemDirty(item)
+ await application.mutator.setItemDirty(item)
const newDate = item.userModifiedDate.getTime()
expect(prevDate).to.equal(newDate)
})
it('properly pins, archives, and locks', async function () {
const params = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([params], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([params], PayloadEmitSource.LocalChanged)
- const item = this.application.items.items[0]
+ const item = application.items.items[0]
expect(item.pinned).to.not.be.ok
const refreshedItem = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.pinned = true
@@ -71,16 +75,16 @@ describe('items', () => {
it('properly compares item equality', async function () {
const params1 = Factory.createNotePayload()
const params2 = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([params1, params2], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([params1, params2], PayloadEmitSource.LocalChanged)
- let item1 = this.application.items.getDisplayableNotes()[0]
- let item2 = this.application.items.getDisplayableNotes()[1]
+ let item1 = application.items.getDisplayableNotes()[0]
+ let item2 = application.items.getDisplayableNotes()[1]
expect(item1.isItemContentEqualWith(item2)).to.equal(true)
// items should ignore this field when checking for equality
item1 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.userModifiedDate = new Date()
@@ -91,7 +95,7 @@ describe('items', () => {
)
).getValue()
item2 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.userModifiedDate = undefined
@@ -105,7 +109,7 @@ describe('items', () => {
expect(item1.isItemContentEqualWith(item2)).to.equal(true)
item1 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.mutableContent.foo = 'bar'
@@ -119,7 +123,7 @@ describe('items', () => {
expect(item1.isItemContentEqualWith(item2)).to.equal(false)
item2 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.mutableContent.foo = 'bar'
@@ -134,7 +138,7 @@ describe('items', () => {
expect(item2.isItemContentEqualWith(item1)).to.equal(true)
item1 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
@@ -145,7 +149,7 @@ describe('items', () => {
)
).getValue()
item2 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item1)
@@ -162,7 +166,7 @@ describe('items', () => {
expect(item1.isItemContentEqualWith(item2)).to.equal(false)
item1 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.removeItemAsRelationship(item2)
@@ -173,7 +177,7 @@ describe('items', () => {
)
).getValue()
item2 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.removeItemAsRelationship(item1)
@@ -192,13 +196,13 @@ describe('items', () => {
it('content equality should not have side effects', async function () {
const params1 = Factory.createNotePayload()
const params2 = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([params1, params2], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([params1, params2], PayloadEmitSource.LocalChanged)
- let item1 = this.application.items.getDisplayableNotes()[0]
- const item2 = this.application.items.getDisplayableNotes()[1]
+ let item1 = application.items.getDisplayableNotes()[0]
+ const item2 = application.items.getDisplayableNotes()[1]
item1 = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.mutableContent.foo = 'bar'
@@ -223,7 +227,7 @@ describe('items', () => {
// There was an issue where calling that function would modify values directly to omit keys
// in contentKeysToIgnoreWhenCheckingEquality.
- await this.application.mutator.setItemsDirty([item1, item2])
+ await application.mutator.setItemsDirty([item1, item2])
expect(item1.userModifiedDate).to.be.ok
expect(item2.userModifiedDate).to.be.ok
diff --git a/packages/snjs/mocha/model_tests/mapping.test.js b/packages/snjs/mocha/model_tests/mapping.test.js
index f1707bf50..3a69cbf70 100644
--- a/packages/snjs/mocha/model_tests/mapping.test.js
+++ b/packages/snjs/mocha/model_tests/mapping.test.js
@@ -1,28 +1,35 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
import { createNoteParams } from '../lib/Items.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('model manager mapping', () => {
+ let application
+ let expectedItemCount
+ let context
+
beforeEach(async function () {
- this.expectedItemCount = BaseItemCounts.DefaultItems
- this.context = await Factory.createAppContext()
- await this.context.launch()
- this.application = this.context.application
+ localStorage.clear()
+ expectedItemCount = BaseItemCounts.DefaultItems
+ context = await Factory.createAppContext()
+ await context.launch()
+ application = context.application
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
+ application = undefined
+ context = undefined
+ localStorage.clear()
})
it('mapping nonexistent item creates it', async function () {
const payload = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
- this.expectedItemCount++
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ await application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
+ expectedItemCount++
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
it('mapping nonexistent deleted item doesnt create it', async function () {
@@ -31,17 +38,17 @@ describe('model manager mapping', () => {
dirty: false,
deleted: true,
})
- await this.application.payloads.emitPayload(payload, PayloadEmitSource.LocalChanged)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ await application.payloads.emitPayload(payload, PayloadEmitSource.LocalChanged)
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
it('mapping and deleting nonexistent item creates and deletes it', async function () {
const payload = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
- this.expectedItemCount++
+ expectedItemCount++
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
const changedParams = new DeletedPayload({
...payload,
@@ -49,32 +56,32 @@ describe('model manager mapping', () => {
deleted: true,
})
- this.expectedItemCount--
+ expectedItemCount--
- await this.application.mutator.emitItemsFromPayloads([changedParams], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([changedParams], PayloadEmitSource.LocalChanged)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
it('mapping deleted but dirty item should not delete it', async function () {
const payload = Factory.createNotePayload()
- const [item] = await this.application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
+ const [item] = await application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
- this.expectedItemCount++
+ expectedItemCount++
- await this.application.payloads.emitPayload(new DeleteItemMutator(item).getDeletedResult())
+ await application.payloads.emitPayload(new DeleteItemMutator(item).getDeletedResult())
- const payload2 = new DeletedPayload(this.application.payloads.findOne(payload.uuid).ejected())
+ const payload2 = new DeletedPayload(application.payloads.findOne(payload.uuid).ejected())
- await this.application.payloads.emitPayloads([payload2], PayloadEmitSource.LocalChanged)
+ await application.payloads.emitPayloads([payload2], PayloadEmitSource.LocalChanged)
- expect(this.application.payloads.collection.all().length).to.equal(this.expectedItemCount)
+ expect(application.payloads.collection.all().length).to.equal(expectedItemCount)
})
it('mapping existing item updates its properties', async function () {
const payload = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
const newTitle = 'updated title'
const mutated = new DecryptedPayload({
@@ -84,45 +91,45 @@ describe('model manager mapping', () => {
title: newTitle,
},
})
- await this.application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
- const item = this.application.items.getDisplayableNotes()[0]
+ await application.mutator.emitItemsFromPayloads([mutated], PayloadEmitSource.LocalChanged)
+ const item = application.items.getDisplayableNotes()[0]
expect(item.content.title).to.equal(newTitle)
})
it('setting an item dirty should retrieve it in dirty items', async function () {
const payload = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
- const note = this.application.items.getDisplayableNotes()[0]
- await this.application.mutator.setItemDirty(note)
- const dirtyItems = this.application.items.getDirtyItems()
+ await application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
+ const note = application.items.getDisplayableNotes()[0]
+ await application.mutator.setItemDirty(note)
+ const dirtyItems = application.items.getDirtyItems()
expect(Uuids(dirtyItems).includes(note.uuid))
})
it('set all items dirty', async function () {
const count = 10
- this.expectedItemCount += count
+ expectedItemCount += count
const payloads = []
for (let i = 0; i < count; i++) {
payloads.push(Factory.createNotePayload())
}
- await this.application.mutator.emitItemsFromPayloads(payloads, PayloadEmitSource.LocalChanged)
- await this.application.sync.markAllItemsAsNeedingSyncAndPersist()
+ await application.mutator.emitItemsFromPayloads(payloads, PayloadEmitSource.LocalChanged)
+ await application.sync.markAllItemsAsNeedingSyncAndPersist()
- const dirtyItems = this.application.items.getDirtyItems()
- expect(dirtyItems.length).to.equal(this.expectedItemCount)
+ const dirtyItems = application.items.getDirtyItems()
+ expect(dirtyItems.length).to.equal(expectedItemCount)
})
it('sync observers should be notified of changes', async function () {
const payload = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
- const item = this.application.items.items[0]
+ await application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
+ const item = application.items.items[0]
return new Promise((resolve) => {
- this.application.items.addObserver(ContentType.TYPES.Any, ({ changed }) => {
+ application.items.addObserver(ContentType.TYPES.Any, ({ changed }) => {
expect(changed[0].uuid === item.uuid)
resolve()
})
- this.application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
+ application.mutator.emitItemsFromPayloads([payload], PayloadEmitSource.LocalChanged)
})
})
})
diff --git a/packages/snjs/mocha/model_tests/notes_smart_tags.test.js b/packages/snjs/mocha/model_tests/notes_smart_tags.test.js
index b16700250..65ebf1410 100644
--- a/packages/snjs/mocha/model_tests/notes_smart_tags.test.js
+++ b/packages/snjs/mocha/model_tests/notes_smart_tags.test.js
@@ -1,5 +1,3 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from '../lib/factory.js'
chai.use(chaiAsPromised)
@@ -26,48 +24,53 @@ const titles = (items) => {
}
describe('notes and smart views', () => {
+ let application
+
beforeEach(async function () {
- this.application = await Factory.createInitAppWithFakeCrypto()
+ localStorage.clear()
+ application = await Factory.createInitAppWithFakeCrypto()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
+ localStorage.clear()
+ application = undefined
})
it('lets me create a smart view and use it', async function () {
// ## The user creates 3 notes
const [note_1, note_2, note_3] = await Promise.all([
- Factory.createMappedNote(this.application, 'long & pinned', generateLongString()),
- Factory.createMappedNote(this.application, 'long & !pinned', generateLongString()),
- Factory.createMappedNote(this.application, 'pinned', 'this is a pinned note'),
+ Factory.createMappedNote(application, 'long & pinned', generateLongString()),
+ Factory.createMappedNote(application, 'long & !pinned', generateLongString()),
+ Factory.createMappedNote(application, 'pinned', 'this is a pinned note'),
])
// The user pin 2 notes
- await Promise.all([Factory.pinNote(this.application, note_1), Factory.pinNote(this.application, note_3)])
+ await Promise.all([Factory.pinNote(application, note_1), Factory.pinNote(application, note_3)])
// ## The user creates smart views (long & pinned)
const not_pinned = '!["Not Pinned", "pinned", "=", false]'
const long = '!["Long", "text.length", ">", 500]'
- const tag_not_pinned = await this.application.mutator.createTagOrSmartView(not_pinned)
- const tag_long = await this.application.mutator.createTagOrSmartView(long)
+ const tag_not_pinned = await application.mutator.createTagOrSmartView(not_pinned)
+ const tag_long = await application.mutator.createTagOrSmartView(long)
// ## The user can filter and see the pinned notes
- const notes_not_pinned = getFilteredNotes(this.application, {
+ const notes_not_pinned = getFilteredNotes(application, {
views: [tag_not_pinned],
})
expect(titles(notes_not_pinned)).to.eql(['long & !pinned'])
// ## The user can filter and see the long notes
- const notes_long = getFilteredNotes(this.application, { views: [tag_long] })
+ const notes_long = getFilteredNotes(application, { views: [tag_long] })
expect(titles(notes_long)).to.eql(['long & !pinned', 'long & pinned'])
// ## The user creates a new long note
- await Factory.createMappedNote(this.application, 'new long', generateLongString())
+ await Factory.createMappedNote(application, 'new long', generateLongString())
// ## The user can filter and see the new long note
- const notes_long2 = getFilteredNotes(this.application, {
+ const notes_long2 = getFilteredNotes(application, {
views: [tag_long],
})
expect(titles(notes_long2)).to.eql(['long & !pinned', 'long & pinned', 'new long'])
diff --git a/packages/snjs/mocha/model_tests/notes_tags.test.js b/packages/snjs/mocha/model_tests/notes_tags.test.js
index ad0d2fa06..aefae49ff 100644
--- a/packages/snjs/mocha/model_tests/notes_tags.test.js
+++ b/packages/snjs/mocha/model_tests/notes_tags.test.js
@@ -1,39 +1,44 @@
-/* eslint-disable no-undef */
import * as Factory from '../lib/factory.js'
import * as Utils from '../lib/Utils.js'
import { createRelatedNoteTagPairPayload } from '../lib/Items.js'
-import { BaseItemCounts } from '../lib/BaseItemCounts.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('notes and tags', () => {
+ let application
+ let context
+
const syncOptions = {
checkIntegrity: true,
awaitAll: true,
}
beforeEach(async function () {
- this.expectedItemCount = BaseItemCounts.DefaultItems
- this.context = await Factory.createAppContext()
- await this.context.launch()
- this.application = this.context.application
+ localStorage.clear()
+ context = await Factory.createAppContext()
+ await context.launch()
+ application = context.application
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
+ localStorage.clear()
+ application = undefined
+ context = undefined
})
it('uses proper class for note', async function () {
const payload = Factory.createNotePayload()
- await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
- const note = this.application.items.getItems([ContentType.TYPES.Note])[0]
+ await application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
+ const note = application.items.getItems([ContentType.TYPES.Note])[0]
expect(note.constructor === SNNote).to.equal(true)
})
it('properly constructs syncing params', async function () {
const title = 'Foo'
const text = 'Bar'
- const note = await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const note = await application.items.createTemplateItem(ContentType.TYPES.Note, {
title,
text,
})
@@ -41,7 +46,7 @@ describe('notes and tags', () => {
expect(note.content.title).to.equal(title)
expect(note.content.text).to.equal(text)
- const tag = await this.application.items.createTemplateItem(ContentType.TYPES.Tag, {
+ const tag = await application.items.createTemplateItem(ContentType.TYPES.Tag, {
title,
})
@@ -73,12 +78,12 @@ describe('notes and tags', () => {
},
})
- await this.application.mutator.emitItemsFromPayloads([mutatedNote, mutatedTag], PayloadEmitSource.LocalChanged)
- const note = this.application.items.getItems([ContentType.TYPES.Note])[0]
- const tag = this.application.items.getItems([ContentType.TYPES.Tag])[0]
+ await application.mutator.emitItemsFromPayloads([mutatedNote, mutatedTag], PayloadEmitSource.LocalChanged)
+ const note = application.items.getItems([ContentType.TYPES.Note])[0]
+ const tag = application.items.getItems([ContentType.TYPES.Tag])[0]
expect(note.content.references.length).to.equal(1)
- expect(this.application.items.itemsReferencingItem(tag).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(tag).length).to.equal(1)
})
it('creates relationship between note and tag', async function () {
@@ -89,9 +94,9 @@ describe('notes and tags', () => {
expect(notePayload.content.references.length).to.equal(0)
expect(tagPayload.content.references.length).to.equal(1)
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- let note = this.application.items.getDisplayableNotes()[0]
- let tag = this.application.items.getDisplayableTags()[0]
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ let note = application.items.getDisplayableNotes()[0]
+ let tag = application.items.getDisplayableTags()[0]
expect(note.dirty).to.not.be.ok
expect(tag.dirty).to.not.be.ok
@@ -102,26 +107,26 @@ describe('notes and tags', () => {
expect(note.isReferencingItem(tag)).to.equal(false)
expect(tag.isReferencingItem(note)).to.equal(true)
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(1)
expect(note.payload.references.length).to.equal(0)
expect(tag.noteCount).to.equal(1)
- await this.application.mutator.setItemToBeDeleted(note)
+ await application.mutator.setItemToBeDeleted(note)
- tag = this.application.items.getDisplayableTags()[0]
+ tag = application.items.getDisplayableTags()[0]
- const deletedNotePayload = this.application.payloads.findOne(note.uuid)
+ const deletedNotePayload = application.payloads.findOne(note.uuid)
expect(deletedNotePayload.dirty).to.be.true
expect(tag.dirty).to.be.true
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
expect(tag.content.references.length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(0)
expect(tag.noteCount).to.equal(0)
- tag = this.application.items.getDisplayableTags()[0]
- expect(this.application.items.getDisplayableNotes().length).to.equal(0)
+ tag = application.items.getDisplayableTags()[0]
+ expect(application.items.getDisplayableNotes().length).to.equal(0)
expect(tag.dirty).to.be.false
})
@@ -130,14 +135,14 @@ describe('notes and tags', () => {
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
- let note = this.application.items.getItems([ContentType.TYPES.Note])[0]
- let tag = this.application.items.getItems([ContentType.TYPES.Tag])[0]
+ await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
+ let note = application.items.getItems([ContentType.TYPES.Note])[0]
+ let tag = application.items.getItems([ContentType.TYPES.Tag])[0]
expect(note.content.references.length).to.equal(0)
expect(tag.content.references.length).to.equal(1)
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
const mutatedTag = new DecryptedPayload({
...tagPayload,
@@ -147,13 +152,13 @@ describe('notes and tags', () => {
references: [],
},
})
- await this.application.mutator.emitItemsFromPayloads([mutatedTag], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([mutatedTag], PayloadEmitSource.LocalChanged)
- note = this.application.items.findItem(note.uuid)
- tag = this.application.items.findItem(tag.uuid)
+ note = application.items.findItem(note.uuid)
+ tag = application.items.findItem(tag.uuid)
expect(tag.content.references.length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(0)
expect(tag.noteCount).to.equal(0)
// expect to be false
@@ -162,13 +167,13 @@ describe('notes and tags', () => {
})
it('creating basic note should have text set', async function () {
- const note = await Factory.createMappedNote(this.application)
+ const note = await Factory.createMappedNote(application)
expect(note.title).to.be.ok
expect(note.text).to.be.ok
})
it('creating basic tag should have title', async function () {
- const tag = await Factory.createMappedTag(this.application)
+ const tag = await Factory.createMappedTag(application)
expect(tag.title).to.be.ok
})
@@ -177,15 +182,15 @@ describe('notes and tags', () => {
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- const note = this.application.items.getItems([ContentType.TYPES.Note])[0]
- let tag = this.application.items.getItems([ContentType.TYPES.Tag])[0]
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ const note = application.items.getItems([ContentType.TYPES.Note])[0]
+ let tag = application.items.getItems([ContentType.TYPES.Tag])[0]
expect(note.content.references.length).to.equal(0)
expect(tag.content.references.length).to.equal(1)
tag = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
tag,
(mutator) => {
mutator.removeItemAsRelationship(note)
@@ -196,21 +201,21 @@ describe('notes and tags', () => {
)
).getValue()
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(0)
expect(tag.noteCount).to.equal(0)
})
it('properly handles tag duplication', async function () {
const pair = createRelatedNoteTagPairPayload()
- await this.application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
- let note = this.application.items.getDisplayableNotes()[0]
- let tag = this.application.items.getDisplayableTags()[0]
+ await application.mutator.emitItemsFromPayloads(pair, PayloadEmitSource.LocalChanged)
+ let note = application.items.getDisplayableNotes()[0]
+ let tag = application.items.getDisplayableTags()[0]
- const duplicateTag = await this.application.mutator.duplicateItem(tag, true)
- await this.application.sync.sync(syncOptions)
+ const duplicateTag = await application.mutator.duplicateItem(tag, true)
+ await application.sync.sync(syncOptions)
- note = this.application.items.findItem(note.uuid)
- tag = this.application.items.findItem(tag.uuid)
+ note = application.items.findItem(note.uuid)
+ tag = application.items.findItem(tag.uuid)
expect(tag.uuid).to.not.equal(duplicateTag.uuid)
expect(tag.content.references.length).to.equal(1)
@@ -218,7 +223,7 @@ describe('notes and tags', () => {
expect(duplicateTag.content.references.length).to.equal(1)
expect(duplicateTag.noteCount).to.equal(1)
- const noteTags = this.application.items.itemsReferencingItem(note)
+ const noteTags = application.items.itemsReferencingItem(note)
expect(noteTags.length).to.equal(2)
const noteTag1 = noteTags[0]
@@ -234,13 +239,13 @@ describe('notes and tags', () => {
const pair = createRelatedNoteTagPairPayload()
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- const note = this.application.items.getItems([ContentType.TYPES.Note])[0]
- const duplicateNote = await this.application.mutator.duplicateItem(note, true)
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ const note = application.items.getItems([ContentType.TYPES.Note])[0]
+ const duplicateNote = await application.mutator.duplicateItem(note, true)
expect(note.uuid).to.not.equal(duplicateNote.uuid)
- expect(this.application.items.itemsReferencingItem(duplicateNote).length).to.equal(
- this.application.items.itemsReferencingItem(note).length,
+ expect(application.items.itemsReferencingItem(duplicateNote).length).to.equal(
+ application.items.itemsReferencingItem(note).length,
)
})
@@ -248,27 +253,27 @@ describe('notes and tags', () => {
const pair = createRelatedNoteTagPairPayload()
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- const note = this.application.items.getItems([ContentType.TYPES.Note])[0]
- let tag = this.application.items.getItems([ContentType.TYPES.Tag])[0]
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ const note = application.items.getItems([ContentType.TYPES.Note])[0]
+ let tag = application.items.getItems([ContentType.TYPES.Tag])[0]
expect(tag.content.references.length).to.equal(1)
expect(tag.noteCount).to.equal(1)
expect(note.content.references.length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(1)
- await this.application.mutator.setItemToBeDeleted(tag)
- tag = this.application.items.findItem(tag.uuid)
+ await application.mutator.setItemToBeDeleted(tag)
+ tag = application.items.findItem(tag.uuid)
expect(tag).to.not.be.ok
})
it('modifying item content should not modify payload content', async function () {
const notePayload = Factory.createNotePayload()
- await this.application.mutator.emitItemsFromPayloads([notePayload], PayloadEmitSource.LocalChanged)
- let note = this.application.items.getItems([ContentType.TYPES.Note])[0]
+ await application.mutator.emitItemsFromPayloads([notePayload], PayloadEmitSource.LocalChanged)
+ let note = application.items.getItems([ContentType.TYPES.Note])[0]
note = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
note,
(mutator) => {
mutator.mutableContent.title = Math.random()
@@ -289,15 +294,15 @@ describe('notes and tags', () => {
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- let note = this.application.items.getItems([ContentType.TYPES.Note])[0]
- let tag = this.application.items.getItems([ContentType.TYPES.Tag])[0]
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ let note = application.items.getItems([ContentType.TYPES.Note])[0]
+ let tag = application.items.getItems([ContentType.TYPES.Tag])[0]
- await this.application.sync.sync(syncOptions)
- await this.application.mutator.setItemToBeDeleted(tag)
+ await application.sync.sync(syncOptions)
+ await application.mutator.setItemToBeDeleted(tag)
- note = this.application.items.findItem(note.uuid)
- this.application.items.findItem(tag.uuid)
+ note = application.items.findItem(note.uuid)
+ application.items.findItem(tag.uuid)
expect(note.dirty).to.not.be.ok
})
@@ -305,26 +310,26 @@ describe('notes and tags', () => {
it('should sort notes', async function () {
await Promise.all(
['Y', 'Z', 'A', 'B'].map(async (title) => {
- return this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, { title }),
+ return application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, { title }),
)
}),
)
- this.application.items.setPrimaryItemDisplayOptions({
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'dsc',
})
- const titles = this.application.items.getDisplayableNotes().map((note) => note.title)
+ const titles = application.items.getDisplayableNotes().map((note) => note.title)
/** setPrimaryItemDisplayOptions inverses sort for title */
expect(titles).to.deep.equal(['A', 'B', 'Y', 'Z'])
})
it('setting a note dirty should collapse its properties into content', async function () {
- let note = await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ let note = await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'Foo',
})
- await this.application.mutator.insertItem(note)
- note = this.application.items.findItem(note.uuid)
+ await application.mutator.insertItem(note)
+ note = application.items.findItem(note.uuid)
expect(note.content.title).to.equal('Foo')
})
@@ -332,49 +337,49 @@ describe('notes and tags', () => {
it('should sort tags in ascending alphabetical order by default', async function () {
const titles = ['1', 'A', 'b', '2']
const sortedTitles = titles.sort((a, b) => a.localeCompare(b))
- await Promise.all(titles.map((title) => this.application.mutator.findOrCreateTag(title)))
- expect(this.application.items.tagDisplayController.items().map((t) => t.title)).to.deep.equal(sortedTitles)
+ await Promise.all(titles.map((title) => application.mutator.findOrCreateTag(title)))
+ expect(application.items.tagDisplayController.items().map((t) => t.title)).to.deep.equal(sortedTitles)
})
it('should match a tag', async function () {
- const taggedNote = await Factory.createMappedNote(this.application)
- const tag = await this.application.mutator.findOrCreateTag('A')
- await this.application.mutator.changeItem(tag, (mutator) => {
+ const taggedNote = await Factory.createMappedNote(application)
+ const tag = await application.mutator.findOrCreateTag('A')
+ await application.mutator.changeItem(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(taggedNote)
})
- await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- this.application.items.setPrimaryItemDisplayOptions({
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'dsc',
tags: [tag],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes.length).to.equal(1)
expect(displayedNotes[0].uuid).to.equal(taggedNote.uuid)
})
it('should not show trashed notes when displaying a tag', async function () {
- const taggedNote = await Factory.createMappedNote(this.application)
- const trashedNote = await Factory.createMappedNote(this.application)
- const tag = await this.application.mutator.findOrCreateTag('A')
- await this.application.mutator.changeItem(tag, (mutator) => {
+ const taggedNote = await Factory.createMappedNote(application)
+ const trashedNote = await Factory.createMappedNote(application)
+ const tag = await application.mutator.findOrCreateTag('A')
+ await application.mutator.changeItem(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(taggedNote)
mutator.e2ePendingRefactor_addItemAsRelationship(trashedNote)
})
- await this.application.mutator.changeItem(trashedNote, (mutator) => {
+ await application.mutator.changeItem(trashedNote, (mutator) => {
mutator.trashed = true
})
- this.application.items.setPrimaryItemDisplayOptions({
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'dsc',
tags: [tag],
includeTrashed: false,
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes.length).to.equal(1)
expect(displayedNotes[0].uuid).to.equal(taggedNote.uuid)
})
@@ -382,31 +387,31 @@ describe('notes and tags', () => {
it('should sort notes when displaying tag', async function () {
await Promise.all(
['Y', 'Z', 'A', 'B'].map(async (title) => {
- return this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ return application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title,
}),
)
}),
)
- const pinnedNote = this.application.items.getDisplayableNotes().find((note) => note.title === 'B')
- await this.application.mutator.changeItem(pinnedNote, (mutator) => {
+ const pinnedNote = application.items.getDisplayableNotes().find((note) => note.title === 'B')
+ await application.mutator.changeItem(pinnedNote, (mutator) => {
mutator.pinned = true
})
- const tag = await this.application.mutator.findOrCreateTag('A')
- await this.application.mutator.changeItem(tag, (mutator) => {
- for (const note of this.application.items.getDisplayableNotes()) {
+ const tag = await application.mutator.findOrCreateTag('A')
+ await application.mutator.changeItem(tag, (mutator) => {
+ for (const note of application.items.getDisplayableNotes()) {
mutator.e2ePendingRefactor_addItemAsRelationship(note)
}
})
- this.application.items.setPrimaryItemDisplayOptions({
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'dsc',
tags: [tag],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.have.length(4)
/** setPrimaryItemDisplayOptions inverses sort for title */
expect(displayedNotes[0].title).to.equal('B')
@@ -416,18 +421,18 @@ describe('notes and tags', () => {
describe('Smart views', function () {
it('"title", "startsWith", "Foo"', async function () {
- const note = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const note = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'Foo 🎲',
}),
)
- await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'Not Foo 🎲',
}),
)
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'Foo Notes',
predicate: {
keypath: 'title',
@@ -436,36 +441,36 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(note.uuid)
})
it('"pinned", "=", true', async function () {
- const note = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const note = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.pinned = true
})
- await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'B',
pinned: false,
}),
)
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'Pinned',
predicate: {
keypath: 'pinned',
@@ -474,35 +479,35 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(note.uuid)
})
it('"pinned", "=", false', async function () {
- const pinnedNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const pinnedNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- await this.application.mutator.changeItem(pinnedNote, (mutator) => {
+ await application.mutator.changeItem(pinnedNote, (mutator) => {
mutator.pinned = true
})
- const unpinnedNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const unpinnedNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'B',
}),
)
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'Not pinned',
predicate: {
keypath: 'pinned',
@@ -511,34 +516,34 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(unpinnedNote.uuid)
})
it('"text.length", ">", 500', async function () {
- const longNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const longNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
text: Array(501).fill(0).join(''),
}),
)
- await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'B',
text: 'b',
}),
)
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'Long',
predicate: {
keypath: 'text.length',
@@ -547,13 +552,13 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(longNote.uuid)
@@ -561,22 +566,22 @@ describe('notes and tags', () => {
it('"updated_at", ">", "1.days.ago"', async function () {
await Factory.registerUserToApplication({
- application: this.application,
+ application: application,
email: Utils.generateUuid(),
password: Utils.generateUuid(),
})
- const recentNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const recentNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
true,
)
- await this.application.sync.sync()
+ await application.sync.sync()
- const olderNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const olderNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'B',
text: 'b',
}),
@@ -584,17 +589,17 @@ describe('notes and tags', () => {
)
const threeDays = 3 * 24 * 60 * 60 * 1000
- await Factory.changePayloadUpdatedAt(this.application, olderNote.payload, new Date(Date.now() - threeDays))
+ await Factory.changePayloadUpdatedAt(application, olderNote.payload, new Date(Date.now() - threeDays))
/** Create an unsynced note which shouldn't get an updated_at */
- await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'B',
text: 'b',
}),
)
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'One day ago',
predicate: {
keypath: 'serverUpdatedAt',
@@ -603,33 +608,33 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
+ const matches = application.items.notesMatchingSmartView(view)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(recentNote.uuid)
- this.application.items.setPrimaryItemDisplayOptions({
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
})
it('"tags.length", "=", 0', async function () {
- const untaggedNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const untaggedNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- const taggedNote = await Factory.createMappedNote(this.application)
- const tag = await this.application.mutator.findOrCreateTag('A')
- await this.application.mutator.changeItem(tag, (mutator) => {
+ const taggedNote = await Factory.createMappedNote(application)
+ const tag = await application.mutator.findOrCreateTag('A')
+ await application.mutator.changeItem(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(taggedNote)
})
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'Untagged',
predicate: {
keypath: 'tags.length',
@@ -638,32 +643,32 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(untaggedNote.uuid)
})
it('"tags", "includes", ["title", "startsWith", "b"]', async function () {
- const taggedNote = await Factory.createMappedNote(this.application)
- const tag = await this.application.mutator.findOrCreateTag('B')
- await this.application.mutator.changeItem(tag, (mutator) => {
+ const taggedNote = await Factory.createMappedNote(application)
+ const tag = await application.mutator.findOrCreateTag('B')
+ await application.mutator.changeItem(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(taggedNote)
})
- await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'B-tags',
predicate: {
keypath: 'tags',
@@ -672,45 +677,45 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(taggedNote.uuid)
})
it('"ignored", "and", [["pinned", "=", true], ["locked", "=", true]]', async function () {
- const pinnedAndLockedNote = await Factory.createMappedNote(this.application)
- await this.application.mutator.changeItem(pinnedAndLockedNote, (mutator) => {
+ const pinnedAndLockedNote = await Factory.createMappedNote(application)
+ await application.mutator.changeItem(pinnedAndLockedNote, (mutator) => {
mutator.pinned = true
mutator.locked = true
})
- const pinnedNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const pinnedNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- await this.application.mutator.changeItem(pinnedNote, (mutator) => {
+ await application.mutator.changeItem(pinnedNote, (mutator) => {
mutator.pinned = true
})
- const lockedNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const lockedNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- await this.application.mutator.changeItem(lockedNote, (mutator) => {
+ await application.mutator.changeItem(lockedNote, (mutator) => {
mutator.locked = true
})
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'Pinned & Locked',
predicate: {
operator: 'and',
@@ -721,51 +726,51 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes).to.deep.equal(matches)
expect(matches.length).to.equal(1)
expect(matches[0].uuid).to.equal(pinnedAndLockedNote.uuid)
})
it('"ignored", "or", [["content.protected", "=", true], ["pinned", "=", true]]', async function () {
- const protectedNote = await Factory.createMappedNote(this.application)
- await this.application.mutator.changeItem(protectedNote, (mutator) => {
+ const protectedNote = await Factory.createMappedNote(application)
+ await application.mutator.changeItem(protectedNote, (mutator) => {
mutator.protected = true
})
- const pinnedNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const pinnedNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- await this.application.mutator.changeItem(pinnedNote, (mutator) => {
+ await application.mutator.changeItem(pinnedNote, (mutator) => {
mutator.pinned = true
})
- const pinnedAndProtectedNote = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ const pinnedAndProtectedNote = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- await this.application.mutator.changeItem(pinnedAndProtectedNote, (mutator) => {
+ await application.mutator.changeItem(pinnedAndProtectedNote, (mutator) => {
mutator.pinned = true
mutator.protected = true
})
- await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.Note, {
+ await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.Note, {
title: 'A',
}),
)
- const view = await this.application.mutator.insertItem(
- await this.application.items.createTemplateItem(ContentType.TYPES.SmartView, {
+ const view = await application.mutator.insertItem(
+ await application.items.createTemplateItem(ContentType.TYPES.SmartView, {
title: 'Protected or Pinned',
predicate: {
operator: 'or',
@@ -776,13 +781,13 @@ describe('notes and tags', () => {
},
}),
)
- const matches = this.application.items.notesMatchingSmartView(view)
- this.application.items.setPrimaryItemDisplayOptions({
+ const matches = application.items.notesMatchingSmartView(view)
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'created_at',
sortDirection: 'asc',
views: [view],
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes.length).to.equal(matches.length)
expect(matches.length).to.equal(3)
expect(matches.find((note) => note.uuid === protectedNote.uuid)).to.exist
@@ -801,12 +806,12 @@ describe('notes and tags', () => {
const notePayload3 = Factory.createNotePayload('Bar')
const notePayload4 = Factory.createNotePayload('Testing')
- await this.application.mutator.emitItemsFromPayloads(
+ await application.mutator.emitItemsFromPayloads(
[notePayload1, notePayload2, notePayload3, notePayload4, tagPayload1],
PayloadEmitSource.LocalChanged,
)
- this.application.items.setPrimaryItemDisplayOptions({
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'dsc',
searchQuery: {
@@ -814,7 +819,7 @@ describe('notes and tags', () => {
},
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes.length).to.equal(2)
/** setPrimaryItemDisplayOptions inverses sort for title */
expect(displayedNotes[0].uuid).to.equal(notePayload1.uuid)
@@ -831,12 +836,12 @@ describe('notes and tags', () => {
const notePayload3 = Factory.createNotePayload('Testing FOO (Bar)')
const notePayload4 = Factory.createNotePayload('This should not match')
- await this.application.mutator.emitItemsFromPayloads(
+ await application.mutator.emitItemsFromPayloads(
[notePayload1, notePayload2, notePayload3, notePayload4, tagPayload1],
PayloadEmitSource.LocalChanged,
)
- this.application.items.setPrimaryItemDisplayOptions({
+ application.items.setPrimaryItemDisplayOptions({
sortBy: 'title',
sortDirection: 'dsc',
searchQuery: {
@@ -844,7 +849,7 @@ describe('notes and tags', () => {
},
})
- const displayedNotes = this.application.items.getDisplayableNotes()
+ const displayedNotes = application.items.getDisplayableNotes()
expect(displayedNotes.length).to.equal(3)
/** setPrimaryItemDisplayOptions inverses sort for title */
expect(displayedNotes[0].uuid).to.equal(notePayload1.uuid)
diff --git a/packages/snjs/mocha/model_tests/notes_tags_folders.test.js b/packages/snjs/mocha/model_tests/notes_tags_folders.test.js
index ffa239153..5bbbac98a 100644
--- a/packages/snjs/mocha/model_tests/notes_tags_folders.test.js
+++ b/packages/snjs/mocha/model_tests/notes_tags_folders.test.js
@@ -1,86 +1,91 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from '../lib/factory.js'
chai.use(chaiAsPromised)
const expect = chai.expect
describe('tags as folders', () => {
+ let context
+ let application
+
beforeEach(async function () {
- this.context = await Factory.createAppContext()
- await this.context.launch()
- this.application = this.context.application
+ localStorage.clear()
+ context = await Factory.createAppContext()
+ await context.launch()
+ application = context.application
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
+ context = undefined
+ application = undefined
+ localStorage.clear()
})
it('lets me create a tag, add relationships, move a note to a children, and query data all along', async function () {
// ## The user creates four tags
- let tagChildren = await Factory.createMappedTag(this.application, {
+ let tagChildren = await Factory.createMappedTag(application, {
title: 'children',
})
- let tagParent = await Factory.createMappedTag(this.application, {
+ let tagParent = await Factory.createMappedTag(application, {
title: 'parent',
})
- let tagGrandParent = await Factory.createMappedTag(this.application, {
+ let tagGrandParent = await Factory.createMappedTag(application, {
title: 'grandparent',
})
- let tagGrandParent2 = await Factory.createMappedTag(this.application, {
+ let tagGrandParent2 = await Factory.createMappedTag(application, {
title: 'grandparent2',
})
// ## Now the users moves the tag children into the parent
- await this.application.mutator.setTagParent(tagParent, tagChildren)
+ await application.mutator.setTagParent(tagParent, tagChildren)
- expect(this.application.items.getTagParent(tagChildren)).to.equal(tagParent)
- expect(Uuids(this.application.items.getTagChildren(tagParent))).deep.to.equal(Uuids([tagChildren]))
+ expect(application.items.getTagParent(tagChildren)).to.equal(tagParent)
+ expect(Uuids(application.items.getTagChildren(tagParent))).deep.to.equal(Uuids([tagChildren]))
// ## Now the user moves the tag parent into the grand parent
- await this.application.mutator.setTagParent(tagGrandParent, tagParent)
+ await application.mutator.setTagParent(tagGrandParent, tagParent)
- expect(this.application.items.getTagParent(tagParent)).to.equal(tagGrandParent)
- expect(Uuids(this.application.items.getTagChildren(tagGrandParent))).deep.to.equal(Uuids([tagParent]))
+ expect(application.items.getTagParent(tagParent)).to.equal(tagGrandParent)
+ expect(Uuids(application.items.getTagChildren(tagGrandParent))).deep.to.equal(Uuids([tagParent]))
// ## Now the user moves the tag parent into another grand parent
- await this.application.mutator.setTagParent(tagGrandParent2, tagParent)
+ await application.mutator.setTagParent(tagGrandParent2, tagParent)
- expect(this.application.items.getTagParent(tagParent)).to.equal(tagGrandParent2)
- expect(this.application.items.getTagChildren(tagGrandParent)).deep.to.equal([])
- expect(Uuids(this.application.items.getTagChildren(tagGrandParent2))).deep.to.equal(Uuids([tagParent]))
+ expect(application.items.getTagParent(tagParent)).to.equal(tagGrandParent2)
+ expect(application.items.getTagChildren(tagGrandParent)).deep.to.equal([])
+ expect(Uuids(application.items.getTagChildren(tagGrandParent2))).deep.to.equal(Uuids([tagParent]))
// ## Now the user tries to move the tag into one of its children
- await expect(this.application.mutator.setTagParent(tagChildren, tagParent)).to.eventually.be.rejected
+ await expect(application.mutator.setTagParent(tagChildren, tagParent)).to.eventually.be.rejected
- expect(this.application.items.getTagParent(tagParent)).to.equal(tagGrandParent2)
- expect(this.application.items.getTagChildren(tagGrandParent)).deep.to.equal([])
- expect(Uuids(this.application.items.getTagChildren(tagGrandParent2))).deep.to.equal(Uuids([tagParent]))
+ expect(application.items.getTagParent(tagParent)).to.equal(tagGrandParent2)
+ expect(application.items.getTagChildren(tagGrandParent)).deep.to.equal([])
+ expect(Uuids(application.items.getTagChildren(tagGrandParent2))).deep.to.equal(Uuids([tagParent]))
// ## Now the user move the tag outside any hierarchy
- await this.application.mutator.unsetTagParent(tagParent)
+ await application.mutator.unsetTagParent(tagParent)
- expect(this.application.items.getTagParent(tagParent)).to.equal(undefined)
- expect(this.application.items.getTagChildren(tagGrandParent2)).deep.to.equals([])
+ expect(application.items.getTagParent(tagParent)).to.equal(undefined)
+ expect(application.items.getTagChildren(tagGrandParent2)).deep.to.equals([])
})
it('lets me add a note to a tag hierarchy', async function () {
// ## The user creates four tags hierarchy
- const tags = await Factory.createTags(this.application, {
+ const tags = await Factory.createTags(application, {
grandparent: { parent: { child: true } },
another: true,
})
- const note1 = await Factory.createMappedNote(this.application, 'my first note')
- const note2 = await Factory.createMappedNote(this.application, 'my second note')
+ const note1 = await Factory.createMappedNote(application, 'my first note')
+ const note2 = await Factory.createMappedNote(application, 'my second note')
// ## The user add a note to the child tag
- await this.application.mutator.addTagToNote(note1, tags.child, true)
- await this.application.mutator.addTagToNote(note2, tags.another, true)
+ await application.mutator.addTagToNote(note1, tags.child, true)
+ await application.mutator.addTagToNote(note2, tags.another, true)
// ## The note has been added to other tags
- const note1Tags = await this.application.items.getSortedTagsForItem(note1)
- const note2Tags = await this.application.items.getSortedTagsForItem(note2)
+ const note1Tags = await application.items.getSortedTagsForItem(note1)
+ const note2Tags = await application.items.getSortedTagsForItem(note2)
expect(note1Tags.length).to.equal(3)
expect(note2Tags.length).to.equal(1)
diff --git a/packages/snjs/mocha/model_tests/performance.test.js b/packages/snjs/mocha/model_tests/performance.test.js
index ab6e6391c..87b4ee847 100644
--- a/packages/snjs/mocha/model_tests/performance.test.js
+++ b/packages/snjs/mocha/model_tests/performance.test.js
@@ -1,10 +1,17 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from '../lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('mapping performance', () => {
+ beforeEach(function () {
+ localStorage.clear()
+ })
+
+ afterEach(async function () {
+ localStorage.clear()
+ })
+
it('shouldnt take a long time', async () => {
/*
There was an issue with mapping where we were using arrays for everything instead of hashes (like items, missedReferences),
diff --git a/packages/snjs/mocha/mutator.test.js b/packages/snjs/mocha/mutator.test.js
index 59bae15c4..ebe8c5bd1 100644
--- a/packages/snjs/mocha/mutator.test.js
+++ b/packages/snjs/mocha/mutator.test.js
@@ -1,47 +1,44 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('item mutator', () => {
- beforeEach(async function () {
- this.createBarePayload = () => {
- return new DecryptedPayload({
- uuid: '123',
- content_type: ContentType.TYPES.Note,
+ const createBarePayload = () => {
+ return new DecryptedPayload({
+ uuid: '123',
+ content_type: ContentType.TYPES.Note,
+ content: {
+ title: 'hello',
+ },
+ })
+ }
+
+ const createNote = () => {
+ return new DecryptedItem(createBarePayload())
+ }
+
+ const createTag = (notes = []) => {
+ const references = notes.map((note) => {
+ return {
+ uuid: note.uuid,
+ content_type: note.content_type,
+ }
+ })
+ return new SNTag(
+ new DecryptedPayload({
+ uuid: Factory.generateUuidish(),
+ content_type: ContentType.TYPES.Tag,
content: {
- title: 'hello',
+ title: 'thoughts',
+ references: references,
},
- })
- }
-
- this.createNote = () => {
- return new DecryptedItem(this.createBarePayload())
- }
-
- this.createTag = (notes = []) => {
- const references = notes.map((note) => {
- return {
- uuid: note.uuid,
- content_type: note.content_type,
- }
- })
- return new SNTag(
- new DecryptedPayload({
- uuid: Factory.generateUuidish(),
- content_type: ContentType.TYPES.Tag,
- content: {
- title: 'thoughts',
- references: references,
- },
- }),
- )
- }
- })
+ }),
+ )
+ }
it('mutate set domain data key', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
mutator.setDomainDataKey('somekey', 'somevalue', 'somedomain')
const payload = mutator.getResult()
@@ -50,7 +47,7 @@ describe('item mutator', () => {
})
it('mutate set pinned', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
mutator.pinned = true
const payload = mutator.getResult()
@@ -59,7 +56,7 @@ describe('item mutator', () => {
})
it('mutate set archived', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
mutator.archived = true
const payload = mutator.getResult()
@@ -68,7 +65,7 @@ describe('item mutator', () => {
})
it('mutate set locked', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
mutator.locked = true
const payload = mutator.getResult()
@@ -77,7 +74,7 @@ describe('item mutator', () => {
})
it('mutate set protected', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
mutator.protected = true
const payload = mutator.getResult()
@@ -86,7 +83,7 @@ describe('item mutator', () => {
})
it('mutate set trashed', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
mutator.trashed = true
const payload = mutator.getResult()
@@ -95,7 +92,7 @@ describe('item mutator', () => {
})
it('calling get result should set us dirty', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
const payload = mutator.getResult()
@@ -103,7 +100,7 @@ describe('item mutator', () => {
})
it('get result should always have userModifiedDate', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item)
const payload = mutator.getResult()
const resultItem = CreateDecryptedItemFromPayload(payload)
@@ -111,7 +108,7 @@ describe('item mutator', () => {
})
it('mutate set deleted', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DeleteItemMutator(item)
const payload = mutator.getDeletedResult()
@@ -121,7 +118,7 @@ describe('item mutator', () => {
})
it('mutate app data', function () {
- const item = this.createNote()
+ const item = createNote()
const mutator = new DecryptedItemMutator(item, MutationType.UpdateUserTimestamps)
mutator.setAppDataItem('foo', 'bar')
mutator.setAppDataItem('bar', 'foo')
@@ -131,8 +128,8 @@ describe('item mutator', () => {
})
it('mutate add item as relationship', function () {
- const note = this.createNote()
- const tag = this.createTag()
+ const note = createNote()
+ const tag = createTag()
const mutator = new DecryptedItemMutator(tag)
mutator.e2ePendingRefactor_addItemAsRelationship(note)
const payload = mutator.getResult()
@@ -142,8 +139,8 @@ describe('item mutator', () => {
})
it('mutate remove item as relationship', function () {
- const note = this.createNote()
- const tag = this.createTag([note])
+ const note = createNote()
+ const tag = createTag([note])
const mutator = new DecryptedItemMutator(tag)
mutator.removeItemAsRelationship(note)
const payload = mutator.getResult()
diff --git a/packages/snjs/mocha/mutator_service.test.js b/packages/snjs/mocha/mutator_service.test.js
index dc93ecab9..cff5d36e0 100644
--- a/packages/snjs/mocha/mutator_service.test.js
+++ b/packages/snjs/mocha/mutator_service.test.js
@@ -1,7 +1,6 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
import { BaseItemCounts } from './lib/BaseItemCounts.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -12,11 +11,6 @@ describe('mutator service', function () {
let application
let mutator
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -27,6 +21,12 @@ describe('mutator service', function () {
await context.launch()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ context = undefined
+ })
+
const createNote = async () => {
return mutator.createItem(ContentType.TYPES.Note, {
title: 'hello',
@@ -154,8 +154,10 @@ describe('mutator service', function () {
describe('duplicateItem', async function () {
const sandbox = sinon.createSandbox()
+ let emitPayloads
+
beforeEach(async function () {
- this.emitPayloads = sandbox.spy(application.payloads, 'emitPayloads')
+ emitPayloads = sandbox.spy(application.payloads, 'emitPayloads')
})
afterEach(async function () {
@@ -165,7 +167,7 @@ describe('mutator service', function () {
it('should duplicate the item and set the duplicate_of property', async function () {
const note = await createNote()
await mutator.duplicateItem(note)
- sinon.assert.calledTwice(this.emitPayloads)
+ sinon.assert.calledTwice(emitPayloads)
const originalNote = application.items.getDisplayableNotes()[0]
const duplicatedNote = application.items.getDisplayableNotes()[1]
@@ -182,7 +184,7 @@ describe('mutator service', function () {
it('should duplicate the item and set the duplicate_of and conflict_of properties', async function () {
const note = await createNote()
await mutator.duplicateItem(note, true)
- sinon.assert.calledTwice(this.emitPayloads)
+ sinon.assert.calledTwice(emitPayloads)
const originalNote = application.items.getDisplayableNotes()[0]
const duplicatedNote = application.items.getDisplayableNotes()[1]
diff --git a/packages/snjs/mocha/note_display_criteria.test.js b/packages/snjs/mocha/note_display_criteria.test.js
index d8df0fae5..65b627d6c 100644
--- a/packages/snjs/mocha/note_display_criteria.test.js
+++ b/packages/snjs/mocha/note_display_criteria.test.js
@@ -1,30 +1,36 @@
-/* eslint-disable no-undef */
chai.use(chaiAsPromised)
const expect = chai.expect
describe('note display criteria', function () {
+ let payloadManager
+ let itemManager
+ let mutator
+
+ let createNote
+ let createTag
+
beforeEach(async function () {
const logger = new Logger('test')
- this.payloadManager = new PayloadManager(logger)
- this.itemManager = new ItemManager(this.payloadManager)
- this.mutator = new MutatorService(this.itemManager, this.payloadManager)
+ payloadManager = new PayloadManager(logger)
+ itemManager = new ItemManager(payloadManager)
+ mutator = new MutatorService(itemManager, payloadManager)
- this.createNote = async (title = 'hello', text = 'world') => {
- return this.mutator.createItem(ContentType.TYPES.Note, {
+ createNote = async (title = 'hello', text = 'world') => {
+ return mutator.createItem(ContentType.TYPES.Note, {
title: title,
text: text,
})
}
- this.createTag = async (notes = [], title = 'thoughts') => {
+ createTag = async (notes = [], title = 'thoughts') => {
const references = notes.map((note) => {
return {
uuid: note.uuid,
content_type: note.content_type,
}
})
- return this.mutator.createItem(ContentType.TYPES.Tag, {
+ return mutator.createItem(ContentType.TYPES.Tag, {
title: title,
references: references,
})
@@ -32,177 +38,147 @@ describe('note display criteria', function () {
})
it('includePinned off', async function () {
- await this.createNote()
- const pendingPin = await this.createNote()
- await this.mutator.changeItem(pendingPin, (mutator) => {
+ await createNote()
+ const pendingPin = await createNote()
+ await mutator.changeItem(pendingPin, (mutator) => {
mutator.pinned = true
})
const criteria = {
includePinned: false,
}
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(1)
})
it('includePinned on', async function () {
- await this.createNote()
- const pendingPin = await this.createNote()
- await this.mutator.changeItem(pendingPin, (mutator) => {
+ await createNote()
+ const pendingPin = await createNote()
+ await mutator.changeItem(pendingPin, (mutator) => {
mutator.pinned = true
})
const criteria = { includePinned: true }
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(2)
})
it('includeTrashed off', async function () {
- await this.createNote()
- const pendingTrash = await this.createNote()
- await this.mutator.changeItem(pendingTrash, (mutator) => {
+ await createNote()
+ const pendingTrash = await createNote()
+ await mutator.changeItem(pendingTrash, (mutator) => {
mutator.trashed = true
})
const criteria = { includeTrashed: false }
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(1)
})
it('includeTrashed on', async function () {
- await this.createNote()
- const pendingTrash = await this.createNote()
- await this.mutator.changeItem(pendingTrash, (mutator) => {
+ await createNote()
+ const pendingTrash = await createNote()
+ await mutator.changeItem(pendingTrash, (mutator) => {
mutator.trashed = true
})
const criteria = { includeTrashed: true }
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(2)
})
it('includeArchived off', async function () {
- await this.createNote()
- const pendingArchive = await this.createNote()
- await this.mutator.changeItem(pendingArchive, (mutator) => {
+ await createNote()
+ const pendingArchive = await createNote()
+ await mutator.changeItem(pendingArchive, (mutator) => {
mutator.archived = true
})
const criteria = { includeArchived: false }
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(1)
})
it('includeArchived on', async function () {
- await this.createNote()
- const pendingArchive = await this.createNote()
- await this.mutator.changeItem(pendingArchive, (mutator) => {
+ await createNote()
+ const pendingArchive = await createNote()
+ await mutator.changeItem(pendingArchive, (mutator) => {
mutator.archived = true
})
const criteria = {
includeArchived: true,
}
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(2)
})
it('includeProtected off', async function () {
- await this.createNote()
- const pendingProtected = await this.createNote()
- await this.mutator.changeItem(pendingProtected, (mutator) => {
+ await createNote()
+ const pendingProtected = await createNote()
+ await mutator.changeItem(pendingProtected, (mutator) => {
mutator.protected = true
})
const criteria = { includeProtected: false }
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(1)
})
it('includeProtected on', async function () {
- await this.createNote()
- const pendingProtected = await this.createNote()
- await this.mutator.changeItem(pendingProtected, (mutator) => {
+ await createNote()
+ const pendingProtected = await createNote()
+ await mutator.changeItem(pendingProtected, (mutator) => {
mutator.protected = true
})
const criteria = {
includeProtected: true,
}
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(2)
})
it('protectedSearchEnabled false', async function () {
- const normal = await this.createNote('hello', 'world')
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote('hello', 'world')
+ await mutator.changeItem(normal, (mutator) => {
mutator.protected = true
})
const criteria = {
searchQuery: { query: 'world', includeProtectedNoteText: false },
}
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(0)
})
it('protectedSearchEnabled true', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.protected = true
})
const criteria = {
searchQuery: { query: 'world', includeProtectedNoteText: true },
}
expect(
- notesAndFilesMatchingOptions(
- criteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
- ).length,
+ notesAndFilesMatchingOptions(criteria, itemManager.collection.all(ContentType.TYPES.Note), itemManager.collection)
+ .length,
).to.equal(1)
})
it('tags', async function () {
- const note = await this.createNote()
- const tag = await this.createTag([note])
- const looseTag = await this.createTag([], 'loose')
+ const note = await createNote()
+ const tag = await createTag([note])
+ const looseTag = await createTag([], 'loose')
const matchingCriteria = {
tags: [tag],
@@ -210,8 +186,8 @@ describe('note display criteria', function () {
expect(
notesAndFilesMatchingOptions(
matchingCriteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
@@ -221,125 +197,125 @@ describe('note display criteria', function () {
expect(
notesAndFilesMatchingOptions(
nonmatchingCriteria,
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
describe('smart views', function () {
it('normal note', async function () {
- await this.createNote()
+ await createNote()
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
it('trashed note', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.trashed = true
})
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeTrashed: false,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
it('archived note', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.trashed = false
mutator.archived = true
})
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: false,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
})
it('archived + trashed note', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.trashed = true
mutator.archived = true
})
@@ -347,30 +323,30 @@ describe('note display criteria', function () {
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
})
@@ -378,87 +354,87 @@ describe('note display criteria', function () {
describe('includeTrash', function () {
it('normal note', async function () {
- await this.createNote()
+ await createNote()
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeTrashed: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
includeTrashed: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
it('trashed note', async function () {
- const normal = await this.createNote()
+ const normal = await createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ await mutator.changeItem(normal, (mutator) => {
mutator.trashed = true
})
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeTrashed: false,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeTrashed: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
includeTrashed: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
includeTrashed: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
it('archived + trashed note', async function () {
- const normal = await this.createNote()
+ const normal = await createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ await mutator.changeItem(normal, (mutator) => {
mutator.trashed = true
mutator.archived = true
})
@@ -466,30 +442,30 @@ describe('note display criteria', function () {
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
})
@@ -497,85 +473,85 @@ describe('note display criteria', function () {
describe('includeArchived', function () {
it('normal note', async function () {
- await this.createNote()
+ await createNote()
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
it('archived note', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.archived = true
})
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: false,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
includeArchived: false,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
})
it('archived + trashed note', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.trashed = true
mutator.archived = true
})
@@ -583,33 +559,33 @@ describe('note display criteria', function () {
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
})
@@ -617,7 +593,7 @@ describe('note display criteria', function () {
describe.skip('multiple tags', function () {
it('normal note', async function () {
- await this.createNote()
+ await createNote()
/**
* This test presently fails because the compound predicate created
* when using multiple views is an AND predicate instead of OR
@@ -625,82 +601,78 @@ describe('note display criteria', function () {
expect(
notesAndFilesMatchingOptions(
{
- views: [
- this.itemManager.allNotesSmartView,
- this.itemManager.archivedSmartView,
- this.itemManager.trashSmartView,
- ],
+ views: [itemManager.allNotesSmartView, itemManager.archivedSmartView, itemManager.trashSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
it('archived note', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.archived = true
})
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: false,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
includeArchived: false,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
})
it('archived + trashed note', async function () {
- const normal = await this.createNote()
- await this.mutator.changeItem(normal, (mutator) => {
+ const normal = await createNote()
+ await mutator.changeItem(normal, (mutator) => {
mutator.trashed = true
mutator.archived = true
})
@@ -708,33 +680,33 @@ describe('note display criteria', function () {
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.allNotesSmartView],
+ views: [itemManager.allNotesSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.trashSmartView],
+ views: [itemManager.trashSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(1)
expect(
notesAndFilesMatchingOptions(
{
- views: [this.itemManager.archivedSmartView],
+ views: [itemManager.archivedSmartView],
includeArchived: true,
},
- this.itemManager.collection.all(ContentType.TYPES.Note),
- this.itemManager.collection,
+ itemManager.collection.all(ContentType.TYPES.Note),
+ itemManager.collection,
).length,
).to.equal(0)
})
diff --git a/packages/snjs/mocha/payload.test.js b/packages/snjs/mocha/payload.test.js
index 4773e311b..97195b849 100644
--- a/packages/snjs/mocha/payload.test.js
+++ b/packages/snjs/mocha/payload.test.js
@@ -1,32 +1,29 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
-chai.use(chaiAsPromised)
-const expect = chai.expect
import * as Factory from './lib/factory.js'
-describe('payload', () => {
- beforeEach(async function () {
- this.createBarePayload = () => {
- return new DecryptedPayload({
- uuid: '123',
- content_type: ContentType.TYPES.Note,
- content: {
- title: 'hello',
- },
- })
- }
+chai.use(chaiAsPromised)
+const expect = chai.expect
- this.createEncryptedPayload = () => {
- return new EncryptedPayload({
- uuid: '123',
- content_type: ContentType.TYPES.Note,
- content: '004:foo:bar',
- })
- }
- })
+describe('payload', () => {
+ const createBarePayload = () => {
+ return new DecryptedPayload({
+ uuid: '123',
+ content_type: ContentType.TYPES.Note,
+ content: {
+ title: 'hello',
+ },
+ })
+ }
+
+ const createEncryptedPayload = () => {
+ return new EncryptedPayload({
+ uuid: '123',
+ content_type: ContentType.TYPES.Note,
+ content: '004:foo:bar',
+ })
+ }
it('constructor should set expected fields', function () {
- const payload = this.createBarePayload()
+ const payload = createBarePayload()
expect(payload.uuid).to.be.ok
expect(payload.content_type).to.be.ok
@@ -46,25 +43,25 @@ describe('payload', () => {
})
it('created at should default to present', function () {
- const payload = this.createBarePayload()
+ const payload = createBarePayload()
expect(payload.created_at - new Date()).to.be.below(1)
})
it('updated at should default to epoch', function () {
- const payload = this.createBarePayload()
+ const payload = createBarePayload()
expect(payload.updated_at.getTime()).to.equal(0)
})
it('payload format bare', function () {
- const payload = this.createBarePayload()
+ const payload = createBarePayload()
expect(isDecryptedPayload(payload)).to.equal(true)
})
it('payload format encrypted string', function () {
- const payload = this.createEncryptedPayload()
+ const payload = createEncryptedPayload()
expect(isEncryptedPayload(payload)).to.equal(true)
})
@@ -92,13 +89,13 @@ describe('payload', () => {
})
it('payload version 004', function () {
- const payload = this.createEncryptedPayload()
+ const payload = createEncryptedPayload()
expect(payload.version).to.equal('004')
})
it('merged with absent content', function () {
- const payload = this.createBarePayload()
+ const payload = createBarePayload()
const merged = payload.copy({
uuid: '123',
content_type: ContentType.TYPES.Note,
@@ -125,7 +122,7 @@ describe('payload', () => {
})
it('should be immutable', async function () {
- const payload = this.createBarePayload()
+ const payload = createBarePayload()
await Factory.sleep(0.1)
diff --git a/packages/snjs/mocha/payload_encryption.test.js b/packages/snjs/mocha/payload_encryption.test.js
index dc24b387d..86e9afb8f 100644
--- a/packages/snjs/mocha/payload_encryption.test.js
+++ b/packages/snjs/mocha/payload_encryption.test.js
@@ -1,31 +1,33 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
import { createRelatedNoteTagPairPayload } from './lib/Items.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('payload encryption', function () {
+ let application
+
beforeEach(async function () {
this.timeout(Factory.TenSecondTimeout)
localStorage.clear()
- this.application = await Factory.createInitAppWithFakeCrypto()
+ application = await Factory.createInitAppWithFakeCrypto()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
localStorage.clear()
+ application = undefined
})
it('creating payload from item should create copy not by reference', async function () {
- const item = await Factory.createMappedNote(this.application)
+ const item = await Factory.createMappedNote(application)
const payload = new DecryptedPayload(item.payload.ejected())
expect(item.content === payload.content).to.equal(false)
expect(item.content.references === payload.content.references).to.equal(false)
})
it('creating payload from item should preserve appData', async function () {
- const item = await Factory.createMappedNote(this.application)
+ const item = await Factory.createMappedNote(application)
const payload = new DecryptedPayload(item.payload.ejected())
expect(item.content.appData).to.be.ok
expect(JSON.stringify(item.content)).to.equal(JSON.stringify(payload.content))
@@ -40,7 +42,7 @@ describe('payload encryption', function () {
lastSyncBegan: new Date(),
})
- const encryptedPayload = await this.application.encryption.encryptSplitSingle({
+ const encryptedPayload = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [notePayload],
},
@@ -85,7 +87,7 @@ describe('payload encryption', function () {
})
it('copying payload with override content should override completely', async function () {
- const item = await Factory.createMappedNote(this.application)
+ const item = await Factory.createMappedNote(application)
const payload = new DecryptedPayload(item.payload.ejected())
const mutated = new DecryptedPayload({
...payload,
@@ -114,7 +116,7 @@ describe('payload encryption', function () {
it('returns valid encrypted params for syncing', async function () {
const payload = Factory.createNotePayload()
const encryptedPayload = CreateEncryptedServerSyncPushPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -126,7 +128,7 @@ describe('payload encryption', function () {
expect(encryptedPayload.content_type).to.be.ok
expect(encryptedPayload.created_at).to.be.ok
expect(encryptedPayload.content).to.satisfy((string) => {
- return string.startsWith(this.application.encryption.getLatestVersion())
+ return string.startsWith(application.encryption.getLatestVersion())
})
}).timeout(5000)
@@ -134,7 +136,7 @@ describe('payload encryption', function () {
const payload = Factory.createNotePayload()
const encryptedPayload = CreateEncryptedLocalStorageContextPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -150,14 +152,14 @@ describe('payload encryption', function () {
expect(encryptedPayload.deleted).to.not.be.ok
expect(encryptedPayload.errorDecrypting).to.not.be.ok
expect(encryptedPayload.content).to.satisfy((string) => {
- return string.startsWith(this.application.encryption.getLatestVersion())
+ return string.startsWith(application.encryption.getLatestVersion())
})
})
it('omits deleted for export file', async function () {
const payload = Factory.createNotePayload()
const encryptedPayload = CreateEncryptedBackupFileContextPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -170,7 +172,7 @@ describe('payload encryption', function () {
expect(encryptedPayload.created_at).to.be.ok
expect(encryptedPayload.deleted).to.not.be.ok
expect(encryptedPayload.content).to.satisfy((string) => {
- return string.startsWith(this.application.encryption.getLatestVersion())
+ return string.startsWith(application.encryption.getLatestVersion())
})
})
diff --git a/packages/snjs/mocha/payload_manager.test.js b/packages/snjs/mocha/payload_manager.test.js
index 95a03db49..d25eb0899 100644
--- a/packages/snjs/mocha/payload_manager.test.js
+++ b/packages/snjs/mocha/payload_manager.test.js
@@ -1,14 +1,17 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('payload manager', () => {
+ let payloadManager
+ let createNotePayload
+
beforeEach(async function () {
const logger = new Logger('test')
- this.payloadManager = new PayloadManager(logger)
- this.createNotePayload = async () => {
+ payloadManager = new PayloadManager(logger)
+
+ createNotePayload = async () => {
return new DecryptedPayload({
uuid: Factory.generateUuidish(),
content_type: ContentType.TYPES.Note,
@@ -21,15 +24,15 @@ describe('payload manager', () => {
})
it('emit payload should create local record', async function () {
- const payload = await this.createNotePayload()
- await this.payloadManager.emitPayload(payload)
+ const payload = await createNotePayload()
+ await payloadManager.emitPayload(payload)
- expect(this.payloadManager.collection.find(payload.uuid)).to.be.ok
+ expect(payloadManager.collection.find(payload.uuid)).to.be.ok
})
it('merge payloads onto master', async function () {
- const payload = await this.createNotePayload()
- await this.payloadManager.emitPayload(payload)
+ const payload = await createNotePayload()
+ await payloadManager.emitPayload(payload)
const newTitle = `${Math.random()}`
const changedPayload = payload.copy({
@@ -38,19 +41,19 @@ describe('payload manager', () => {
title: newTitle,
},
})
- const { changed, inserted } = await this.payloadManager.applyPayloads([changedPayload])
+ const { changed, inserted } = await payloadManager.applyPayloads([changedPayload])
expect(changed.length).to.equal(1)
expect(inserted.length).to.equal(0)
- expect(this.payloadManager.collection.find(payload.uuid).content.title).to.equal(newTitle)
+ expect(payloadManager.collection.find(payload.uuid).content.title).to.equal(newTitle)
})
it('insertion observer', async function () {
const observations = []
- this.payloadManager.addObserver(ContentType.TYPES.Any, ({ inserted }) => {
+ payloadManager.addObserver(ContentType.TYPES.Any, ({ inserted }) => {
observations.push({ inserted })
})
- const payload = await this.createNotePayload()
- await this.payloadManager.emitPayload(payload)
+ const payload = await createNotePayload()
+ await payloadManager.emitPayload(payload)
expect(observations.length).equal(1)
expect(observations[0].inserted[0]).equal(payload)
@@ -58,14 +61,14 @@ describe('payload manager', () => {
it('change observer', async function () {
const observations = []
- this.payloadManager.addObserver(ContentType.TYPES.Any, ({ changed }) => {
+ payloadManager.addObserver(ContentType.TYPES.Any, ({ changed }) => {
if (changed.length > 0) {
observations.push({ changed })
}
})
- const payload = await this.createNotePayload()
- await this.payloadManager.emitPayload(payload)
- await this.payloadManager.emitPayload(
+ const payload = await createNotePayload()
+ await payloadManager.emitPayload(payload)
+ await payloadManager.emitPayload(
payload.copy({
content: {
...payload.content,
@@ -79,12 +82,12 @@ describe('payload manager', () => {
})
it('reset state', async function () {
- this.payloadManager.addObserver(ContentType.TYPES.Any, ({}) => {})
- const payload = await this.createNotePayload()
- await this.payloadManager.emitPayload(payload)
- await this.payloadManager.resetState()
+ payloadManager.addObserver(ContentType.TYPES.Any, ({}) => {})
+ const payload = await createNotePayload()
+ await payloadManager.emitPayload(payload)
+ await payloadManager.resetState()
- expect(this.payloadManager.collection.all().length).to.equal(0)
- expect(this.payloadManager.changeObservers.length).equal(1)
+ expect(payloadManager.collection.all().length).to.equal(0)
+ expect(payloadManager.changeObservers.length).equal(1)
})
})
diff --git a/packages/snjs/mocha/preferences.test.js b/packages/snjs/mocha/preferences.test.js
index ac82ccce3..63879c716 100644
--- a/packages/snjs/mocha/preferences.test.js
+++ b/packages/snjs/mocha/preferences.test.js
@@ -1,111 +1,116 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('preferences', function () {
+ let application
+ let email
+ let password
+ let context
+
beforeEach(async function () {
localStorage.clear()
- this.context = await Factory.createAppContext()
- await this.context.launch()
- this.application = this.context.application
+ context = await Factory.createAppContext()
+ await context.launch()
+ application = context.application
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
localStorage.clear()
+ context = undefined
})
function register() {
return Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
}
it('sets preference', async function () {
- await this.application.setPreference('editorLeft', 300)
- expect(this.application.getPreference('editorLeft')).to.equal(300)
+ await application.setPreference('editorLeft', 300)
+ expect(application.getPreference('editorLeft')).to.equal(300)
})
it('saves preference', async function () {
await register.call(this)
- await this.application.setPreference('editorLeft', 300)
- await this.application.sync.sync()
- this.application = await Factory.signOutAndBackIn(this.application, this.email, this.password)
- const editorLeft = this.application.getPreference('editorLeft')
+ await application.setPreference('editorLeft', 300)
+ await application.sync.sync()
+ application = await Factory.signOutAndBackIn(application, email, password)
+ const editorLeft = application.getPreference('editorLeft')
expect(editorLeft).to.equal(300)
}).timeout(10000)
it('clears preferences on signout', async function () {
await register.call(this)
- await this.application.setPreference('editorLeft', 300)
- await this.application.sync.sync()
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- expect(this.application.getPreference('editorLeft')).to.equal(undefined)
+ await application.setPreference('editorLeft', 300)
+ await application.sync.sync()
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ expect(application.getPreference('editorLeft')).to.equal(undefined)
})
it('returns default value for non-existent preference', async function () {
await register.call(this)
- const editorLeft = this.application.getPreference('editorLeft', 100)
+ const editorLeft = application.getPreference('editorLeft', 100)
expect(editorLeft).to.equal(100)
})
it('emits an event when preferences change', async function () {
const promise = new Promise((resolve) => {
- this.application.addEventObserver(() => {
+ application.addEventObserver(() => {
resolve()
}, ApplicationEvent.PreferencesChanged)
})
- await this.application.setPreference('editorLeft', 300)
+ await application.setPreference('editorLeft', 300)
await promise
expect(promise).to.be.fulfilled
})
it('discards existing preferences when signing in', async function () {
await register.call(this)
- await this.application.setPreference('editorLeft', 300)
- await this.application.sync.sync()
+ await application.setPreference('editorLeft', 300)
+ await application.sync.sync()
- this.application = await this.context.signout()
+ application = await context.signout()
- await this.application.setPreference('editorLeft', 200)
- await this.application.signIn(this.email, this.password)
+ await application.setPreference('editorLeft', 200)
+ await application.signIn(email, password)
- const promise = this.context.awaitUserPrefsSingletonResolution()
- await this.application.sync.sync({ awaitAll: true })
+ const promise = context.awaitUserPrefsSingletonResolution()
+ await application.sync.sync({ awaitAll: true })
await promise
- const editorLeft = this.application.getPreference('editorLeft')
+ const editorLeft = application.getPreference('editorLeft')
expect(editorLeft).to.equal(300)
})
it('reads stored preferences on start without waiting for syncing to complete', async function () {
const prefKey = 'editorLeft'
const prefValue = 300
- const identifier = this.application.identifier
+ const identifier = application.identifier
await register.call(this)
- await this.application.setPreference(prefKey, prefValue)
- await this.application.sync.sync()
+ await application.setPreference(prefKey, prefValue)
+ await application.sync.sync()
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
- this.application = Factory.createApplicationWithFakeCrypto(identifier)
+ application = Factory.createApplicationWithFakeCrypto(identifier)
const willSyncPromise = new Promise((resolve) => {
- this.application.addEventObserver(resolve, ApplicationEvent.WillSync)
+ application.addEventObserver(resolve, ApplicationEvent.WillSync)
})
- Factory.initializeApplication(this.application)
+ Factory.initializeApplication(application)
await willSyncPromise
- expect(this.application.preferences.preferences).to.exist
- expect(this.application.getPreference(prefKey)).to.equal(prefValue)
+ expect(application.preferences.preferences).to.exist
+ expect(application.getPreference(prefKey)).to.equal(prefValue)
})
})
diff --git a/packages/snjs/mocha/protection.test.js b/packages/snjs/mocha/protection.test.js
index 0ea3892ac..faa1ef3d6 100644
--- a/packages/snjs/mocha/protection.test.js
+++ b/packages/snjs/mocha/protection.test.js
@@ -1,6 +1,6 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
+
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
diff --git a/packages/snjs/mocha/protocol.test.js b/packages/snjs/mocha/protocol.test.js
index 90bcfafea..6ce021926 100644
--- a/packages/snjs/mocha/protocol.test.js
+++ b/packages/snjs/mocha/protocol.test.js
@@ -1,61 +1,60 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('protocol', function () {
+ let application
+
beforeEach(async function () {
localStorage.clear()
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ application = await Factory.createInitAppWithFakeCrypto()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
- this.application = null
+ await Factory.safeDeinit(application)
+ application = null
localStorage.clear()
})
it('checks version to make sure its 004', function () {
- expect(this.application.encryption.getLatestVersion()).to.equal('004')
+ expect(application.encryption.getLatestVersion()).to.equal('004')
})
it('checks supported versions to make sure it includes 001, 002, 003, 004', function () {
- expect(this.application.encryption.supportedVersions()).to.eql(['001', '002', '003', '004'])
+ expect(application.encryption.supportedVersions()).to.eql(['001', '002', '003', '004'])
})
it('platform derivation support', function () {
expect(
- this.application.encryption.platformSupportsKeyDerivation({
+ application.encryption.platformSupportsKeyDerivation({
version: '001',
}),
).to.equal(true)
expect(
- this.application.encryption.platformSupportsKeyDerivation({
+ application.encryption.platformSupportsKeyDerivation({
version: '002',
}),
).to.equal(true)
expect(
- this.application.encryption.platformSupportsKeyDerivation({
+ application.encryption.platformSupportsKeyDerivation({
version: '003',
}),
).to.equal(true)
expect(
- this.application.encryption.platformSupportsKeyDerivation({
+ application.encryption.platformSupportsKeyDerivation({
version: '004',
}),
).to.equal(true)
expect(
- this.application.encryption.platformSupportsKeyDerivation({
+ application.encryption.platformSupportsKeyDerivation({
version: '005',
}),
).to.equal(true)
})
it('key params versions <= 002 should include pw_cost in portable value', function () {
- const keyParams002 = this.application.encryption.createKeyParams({
+ const keyParams002 = application.encryption.createKeyParams({
version: '002',
pw_cost: 5000,
})
@@ -63,15 +62,15 @@ describe('protocol', function () {
})
it('version comparison of 002 should be older than library version', function () {
- expect(this.application.encryption.isVersionNewerThanLibraryVersion('002')).to.equal(false)
+ expect(application.encryption.isVersionNewerThanLibraryVersion('002')).to.equal(false)
})
it('version comparison of 005 should be newer than library version', function () {
- expect(this.application.encryption.isVersionNewerThanLibraryVersion('005')).to.equal(true)
+ expect(application.encryption.isVersionNewerThanLibraryVersion('005')).to.equal(true)
})
it('library version should not be outdated', function () {
- var currentVersion = this.application.encryption.getLatestVersion()
+ var currentVersion = application.encryption.getLatestVersion()
expect(isProtocolVersionExpired(currentVersion)).to.equal(false)
})
@@ -91,7 +90,7 @@ describe('protocol', function () {
const payload = Factory.createNotePayload()
let error
try {
- await this.application.encryption.decryptSplitSingle({
+ await application.encryption.decryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -103,10 +102,10 @@ describe('protocol', function () {
})
it('ejected payload should not have meta fields', async function () {
- await this.application.addPasscode('123')
+ await application.addPasscode('123')
const payload = Factory.createNotePayload()
const result = CreateEncryptedServerSyncPushPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -121,7 +120,7 @@ describe('protocol', function () {
it('encrypted payload for server should include duplicate_of field', async function () {
const payload = Factory.createNotePayload('Test')
const encryptedPayload = CreateEncryptedServerSyncPushPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -134,7 +133,7 @@ describe('protocol', function () {
it('ejected payload for server should include duplicate_of field', async function () {
const payload = Factory.createNotePayload('Test')
const encryptedPayload = CreateEncryptedServerSyncPushPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -147,7 +146,7 @@ describe('protocol', function () {
it('encrypted payload for storage should include duplicate_of field', async function () {
const payload = Factory.createNotePayload('Test')
const encryptedPayload = CreateEncryptedLocalStorageContextPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -160,7 +159,7 @@ describe('protocol', function () {
it('ejected payload for storage should include duplicate_of field', async function () {
const payload = Factory.createNotePayload('Test')
const encryptedPayload = CreateEncryptedLocalStorageContextPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -173,7 +172,7 @@ describe('protocol', function () {
it('encrypted payload for file should include duplicate_of field', async function () {
const payload = Factory.createNotePayload('Test')
const encryptedPayload = CreateEncryptedBackupFileContextPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
@@ -186,7 +185,7 @@ describe('protocol', function () {
it('ejected payload for file should include duplicate_of field', async function () {
const payload = Factory.createNotePayload('Test')
const encryptedPayload = CreateEncryptedBackupFileContextPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [payload],
},
diff --git a/packages/snjs/mocha/session.test.js b/packages/snjs/mocha/session.test.js
index 7acba2e13..cb21d4670 100644
--- a/packages/snjs/mocha/session.test.js
+++ b/packages/snjs/mocha/session.test.js
@@ -1,14 +1,17 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
-import { BaseItemCounts } from './lib/BaseItemCounts.js'
import * as Factory from './lib/factory.js'
import WebDeviceInterface from './lib/web_device_interface.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('server session', function () {
this.timeout(Factory.TenSecondTimeout)
+ let application
+ let email
+ let password
+ let newPassword
+
const syncOptions = {
checkIntegrity: true,
awaitAll: true,
@@ -16,16 +19,15 @@ describe('server session', function () {
beforeEach(async function () {
localStorage.clear()
- this.expectedItemCount = BaseItemCounts.DefaultItems
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
- this.newPassword = Factory.randomString()
+ application = await Factory.createInitAppWithFakeCrypto()
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
+ newPassword = Factory.randomString()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
- this.application = null
+ await Factory.safeDeinit(application)
+ application = null
localStorage.clear()
})
@@ -47,26 +49,26 @@ describe('server session', function () {
it('should succeed when a sync request is perfomed with an expired access token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- await sleepUntilSessionExpires(this.application)
+ await sleepUntilSessionExpires(application)
- const response = await this.application.legacyApi.sync([])
+ const response = await application.legacyApi.sync([])
expect(response.status).to.equal(200)
}).timeout(Factory.TwentySecondTimeout)
it('should return the new session in the response when refreshed', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const response = await this.application.legacyApi.refreshSession()
+ const response = await application.legacyApi.refreshSession()
expect(response.status).to.equal(200)
expect(response.data.session.access_token).to.be.a('string')
@@ -77,22 +79,22 @@ describe('server session', function () {
it('should be refreshed on any api call if access token is expired', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
// Saving the current session information for later...
- const sessionBeforeSync = this.application.legacyApi.getSession()
+ const sessionBeforeSync = application.legacyApi.getSession()
// Waiting enough time for the access token to expire, before performing a new sync request.
- await sleepUntilSessionExpires(this.application)
+ await sleepUntilSessionExpires(application)
// Performing a sync request with an expired access token.
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
// After the above sync request is completed, we obtain the session information.
- const sessionAfterSync = this.application.legacyApi.getSession()
+ const sessionAfterSync = application.legacyApi.getSession()
expect(sessionBeforeSync.accessToken.value).to.not.equal(sessionAfterSync.accessToken.value)
expect(sessionBeforeSync.refreshToken.value).to.not.equal(sessionAfterSync.refreshToken.value)
@@ -103,59 +105,59 @@ describe('server session', function () {
it('should not deadlock while renewing session', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- await sleepUntilSessionExpires(this.application)
+ await sleepUntilSessionExpires(application)
- // Apply a latency simulation so that ` this.inProgressRefreshSessionPromise = this.refreshSession()` does
+ // Apply a latency simulation so that ` inProgressRefreshSessionPromise = refreshSession()` does
// not have the chance to complete before it is assigned to the variable. This test came along with a fix
// where runHttp does not await a pending refreshSession promise if the request being made is itself a refreshSession request.
- this.application.http.__latencySimulatorMs = 1000
- await this.application.sync.sync(syncOptions)
+ application.http.__latencySimulatorMs = 1000
+ await application.sync.sync(syncOptions)
- const sessionAfterSync = this.application.legacyApi.getSession()
+ const sessionAfterSync = application.legacyApi.getSession()
expect(sessionAfterSync.accessToken.expiresAt).to.be.greaterThan(Date.now())
}).timeout(Factory.TwentySecondTimeout)
it('should succeed when a sync request is perfomed after signing into an ephemeral session', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ application = await Factory.signOutApplicationAndReturnNew(application)
- await this.application.signIn(this.email, this.password, false, true)
+ await application.signIn(email, password, false, true)
- const response = await this.application.legacyApi.sync([])
+ const response = await application.legacyApi.sync([])
expect(response.status).to.equal(200)
})
it('should succeed when a sync request is perfomed after registering into an ephemeral session', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: true,
})
- const response = await this.application.legacyApi.sync([])
+ const response = await application.legacyApi.sync([])
expect(response.status).to.equal(200)
})
it('should be consistent between storage and apiService', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const sessionFromStorage = await getSessionFromStorage(this.application)
- const sessionFromApiService = this.application.legacyApi.getSession()
+ const sessionFromStorage = await getSessionFromStorage(application)
+ const sessionFromApiService = application.legacyApi.getSession()
expect(sessionFromStorage.accessToken).to.equal(sessionFromApiService.accessToken.value)
expect(sessionFromStorage.refreshToken).to.equal(sessionFromApiService.refreshToken.value)
@@ -163,10 +165,10 @@ describe('server session', function () {
expect(sessionFromStorage.refreshExpiration).to.equal(sessionFromApiService.refreshToken.expiresAt)
expect(sessionFromStorage.readonlyAccess).to.equal(sessionFromApiService.isReadOnly())
- await this.application.legacyApi.refreshSession()
+ await application.legacyApi.refreshSession()
- const updatedSessionFromStorage = await getSessionFromStorage(this.application)
- const updatedSessionFromApiService = this.application.legacyApi.getSession()
+ const updatedSessionFromStorage = await getSessionFromStorage(application)
+ const updatedSessionFromApiService = application.legacyApi.getSession()
expect(updatedSessionFromStorage.accessToken).to.equal(updatedSessionFromApiService.accessToken.value)
expect(updatedSessionFromStorage.refreshToken).to.equal(updatedSessionFromApiService.refreshToken.value)
@@ -177,16 +179,16 @@ describe('server session', function () {
it('should be performed successfully and terminate session with a valid access token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const signOutResponse = await this.application.legacyApi.signOut()
+ const signOutResponse = await application.legacyApi.signOut()
expect(signOutResponse.status).to.equal(204)
- Factory.ignoreChallenges(this.application)
- const syncResponse = await this.application.legacyApi.sync([])
+ Factory.ignoreChallenges(application)
+ const syncResponse = await application.legacyApi.sync([])
expect(syncResponse.status).to.equal(401)
expect(syncResponse.data.error.tag).to.equal('invalid-auth')
expect(syncResponse.data.error.message).to.equal('Invalid login credentials.')
@@ -194,19 +196,19 @@ describe('server session', function () {
it('sign out request should be performed successfully and terminate session with expired access token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
// Waiting enough time for the access token to expire, before performing a sign out request.
- await sleepUntilSessionExpires(this.application)
+ await sleepUntilSessionExpires(application)
- const signOutResponse = await this.application.legacyApi.signOut()
+ const signOutResponse = await application.legacyApi.signOut()
expect(signOutResponse.status).to.equal(204)
- Factory.ignoreChallenges(this.application)
- const syncResponse = await this.application.legacyApi.sync([])
+ Factory.ignoreChallenges(application)
+ const syncResponse = await application.legacyApi.sync([])
expect(syncResponse.status).to.equal(401)
expect(syncResponse.data.error.tag).to.equal('invalid-auth')
expect(syncResponse.data.error.message).to.equal('Invalid login credentials.')
@@ -276,20 +278,20 @@ describe('server session', function () {
it('change password request should be successful with a valid access token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const changePasswordResponse = await this.application.changePassword(this.password, this.newPassword)
+ const changePasswordResponse = await application.changePassword(password, newPassword)
expect(changePasswordResponse.error).to.not.be.ok
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ application = await Factory.signOutApplicationAndReturnNew(application)
const loginResponse = await Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.newPassword,
+ application: application,
+ email: email,
+ password: newPassword,
})
expect(loginResponse).to.be.ok
@@ -298,23 +300,23 @@ describe('server session', function () {
it('change password request should be successful after the expired access token is refreshed', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
// Waiting enough time for the access token to expire.
- await sleepUntilSessionExpires(this.application)
+ await sleepUntilSessionExpires(application)
- const changePasswordResponse = await this.application.changePassword(this.password, this.newPassword)
+ const changePasswordResponse = await application.changePassword(password, newPassword)
expect(changePasswordResponse.error).to.not.be.ok
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ application = await Factory.signOutApplicationAndReturnNew(application)
const loginResponse = await Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.newPassword,
+ application: application,
+ email: email,
+ password: newPassword,
})
expect(loginResponse).to.be.ok
@@ -323,39 +325,39 @@ describe('server session', function () {
it('change password request should fail with an invalid access token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- this.application.storage.setValue(StorageKey.Session, {
+ application.storage.setValue(StorageKey.Session, {
accessToken: 'this-is-a-fake-token-1234',
refreshToken: 'this-is-a-fake-token-1234',
accessExpiration: 999999999999999,
refreshExpiration: 99999999999999,
readonlyAccess: false,
})
- this.application.sessions.initializeFromDisk()
+ application.sessions.initializeFromDisk()
- Factory.ignoreChallenges(this.application)
- const changePasswordResponse = await this.application.changePassword(this.password, this.newPassword)
+ Factory.ignoreChallenges(application)
+ const changePasswordResponse = await application.changePassword(password, newPassword)
expect(changePasswordResponse.error.message).to.equal('Invalid login credentials.')
})
it('change password request should fail with an expired refresh token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- this.application.sync.lockSyncing()
+ application.sync.lockSyncing()
/** Waiting for the refresh token to expire. */
- await sleepUntilSessionExpires(this.application, false)
+ await sleepUntilSessionExpires(application, false)
- Factory.ignoreChallenges(this.application)
- const changePasswordResponse = await this.application.changePassword(this.password, this.newPassword)
+ Factory.ignoreChallenges(application)
+ const changePasswordResponse = await application.changePassword(password, newPassword)
expect(changePasswordResponse).to.be.ok
expect(changePasswordResponse.error.message).to.equal('Invalid login credentials.')
@@ -363,17 +365,17 @@ describe('server session', function () {
it('should sign in successfully after signing out', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- await this.application.legacyApi.signOut()
- this.application.legacyApi.session = undefined
+ await application.legacyApi.signOut()
+ application.legacyApi.session = undefined
- await this.application.sessions.signIn(this.email, this.password)
+ await application.sessions.signIn(email, password)
- const currentSession = this.application.legacyApi.getSession()
+ const currentSession = application.legacyApi.getSession()
expect(currentSession).to.be.ok
expect(currentSession.accessToken).to.be.ok
@@ -383,16 +385,16 @@ describe('server session', function () {
it('should fail when renewing a session with an expired refresh token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- this.application.sync.lockSyncing()
+ application.sync.lockSyncing()
- await sleepUntilSessionExpires(this.application, false)
+ await sleepUntilSessionExpires(application, false)
- const refreshSessionResponse = await this.application.legacyApi.refreshSession()
+ const refreshSessionResponse = await application.legacyApi.refreshSession()
expect(refreshSessionResponse.status).to.equal(400)
expect(refreshSessionResponse.data.error.tag).to.equal('expired-refresh-token')
@@ -402,8 +404,8 @@ describe('server session', function () {
The access token and refresh token should be expired up to this point.
Here we make sure that any subsequent requests will fail.
*/
- Factory.ignoreChallenges(this.application)
- const syncResponse = await this.application.legacyApi.sync([])
+ Factory.ignoreChallenges(application)
+ const syncResponse = await application.legacyApi.sync([])
expect(syncResponse.status).to.equal(401)
expect(syncResponse.data.error.tag).to.equal('invalid-auth')
expect(syncResponse.data.error.message).to.equal('Invalid login credentials.')
@@ -411,42 +413,42 @@ describe('server session', function () {
it('should fail when renewing a session with an invalid refresh token', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const originalSession = this.application.legacyApi.getSession()
+ const originalSession = application.legacyApi.getSession()
- this.application.storage.setValue(StorageKey.Session, {
+ application.storage.setValue(StorageKey.Session, {
accessToken: originalSession.accessToken.value,
refreshToken: 'this-is-a-fake-token-1234',
accessExpiration: originalSession.accessToken.expiresAt,
refreshExpiration: originalSession.refreshToken.expiresAt,
readonlyAccess: false,
})
- this.application.sessions.initializeFromDisk()
+ application.sessions.initializeFromDisk()
- const refreshSessionResponse = await this.application.legacyApi.refreshSession()
+ const refreshSessionResponse = await application.legacyApi.refreshSession()
expect(refreshSessionResponse.status).to.equal(400)
expect(refreshSessionResponse.data.error.tag).to.equal('invalid-refresh-token')
expect(refreshSessionResponse.data.error.message).to.equal('The refresh token is not valid.')
// Access token should remain valid.
- const syncResponse = await this.application.legacyApi.sync([])
+ const syncResponse = await application.legacyApi.sync([])
expect(syncResponse.status).to.equal(200)
})
it('should fail if syncing while a session refresh is in progress', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const refreshPromise = this.application.legacyApi.refreshSession()
- const syncResponse = await this.application.legacyApi.sync([])
+ const refreshPromise = application.legacyApi.refreshSession()
+ const syncResponse = await application.legacyApi.sync([])
expect(syncResponse.data.error).to.be.ok
@@ -458,40 +460,40 @@ describe('server session', function () {
it('notes should be synced as expected after refreshing a session', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const notesBeforeSync = await Factory.createManyMappedNotes(this.application, 5)
+ const notesBeforeSync = await Factory.createManyMappedNotes(application, 5)
- await sleepUntilSessionExpires(this.application)
- await this.application.sync.sync(syncOptions)
- expect(this.application.sync.isOutOfSync()).to.equal(false)
+ await sleepUntilSessionExpires(application)
+ await application.sync.sync(syncOptions)
+ expect(application.sync.isOutOfSync()).to.equal(false)
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ await application.signIn(email, password, undefined, undefined, undefined, true)
const expectedNotesUuids = notesBeforeSync.map((n) => n.uuid)
- const notesResults = await this.application.items.findItems(expectedNotesUuids)
+ const notesResults = await application.items.findItems(expectedNotesUuids)
expect(notesResults.length).to.equal(notesBeforeSync.length)
for (const aNoteBeforeSync of notesBeforeSync) {
- const noteResult = await this.application.items.findItem(aNoteBeforeSync.uuid)
+ const noteResult = await application.items.findItem(aNoteBeforeSync.uuid)
expect(aNoteBeforeSync.isItemContentEqualWith(noteResult)).to.equal(true)
}
}).timeout(Factory.TwentySecondTimeout)
it('should prompt user for account password and sign back in on invalid session', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const email = `${Math.random()}`
- const password = `${Math.random()}`
+ email = `${Math.random()}`
+ password = `${Math.random()}`
let didPromptForSignIn = false
const receiveChallenge = async (challenge) => {
didPromptForSignIn = true
@@ -541,55 +543,55 @@ describe('server session', function () {
it('should return current session in list of sessions', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const response = await this.application.legacyApi.getSessionsList()
+ const response = await application.legacyApi.getSessionsList()
expect(response.data[0].current).to.equal(true)
})
it('signing out should delete session from all list', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
/** Create new session aside from existing one */
const app2 = await Factory.createAndInitializeApplication('app2')
- await app2.signIn(this.email, this.password)
+ await app2.signIn(email, password)
- const response = await this.application.legacyApi.getSessionsList()
+ const response = await application.legacyApi.getSessionsList()
expect(response.data.length).to.equal(2)
await app2.user.signOut()
- const response2 = await this.application.legacyApi.getSessionsList()
+ const response2 = await application.legacyApi.getSessionsList()
expect(response2.data.length).to.equal(1)
})
it('revoking a session should destroy local data', async function () {
- Factory.handlePasswordChallenges(this.application, this.password)
+ Factory.handlePasswordChallenges(application, password)
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
const app2identifier = 'app2'
const app2 = await Factory.createAndInitializeApplication(app2identifier)
- await app2.signIn(this.email, this.password)
+ await app2.signIn(email, password)
const app2Deinit = new Promise((resolve) => {
app2.setOnDeinit(() => {
resolve()
})
})
- const { data: sessions } = await this.application.getSessions()
+ const { data: sessions } = await application.getSessions()
const app2session = sessions.find((session) => !session.current)
- await this.application.revokeSession(app2session.uuid)
+ await application.revokeSession(app2session.uuid)
void app2.sync.sync()
await app2Deinit
@@ -599,23 +601,23 @@ describe('server session', function () {
}).timeout(Factory.TwentySecondTimeout)
it('revoking other sessions should destroy their local data', async function () {
- Factory.handlePasswordChallenges(this.application, this.password)
+ Factory.handlePasswordChallenges(application, password)
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
const app2identifier = 'app2'
const app2 = await Factory.createAndInitializeApplication(app2identifier)
- await app2.signIn(this.email, this.password)
+ await app2.signIn(email, password)
const app2Deinit = new Promise((resolve) => {
app2.setOnDeinit(() => {
resolve()
})
})
- await this.application.revokeAllOtherSessions()
+ await application.revokeAllOtherSessions()
void app2.sync.sync()
await app2Deinit
@@ -626,24 +628,24 @@ describe('server session', function () {
it('signing out with invalid session token should still delete local data', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- this.application.storage.setValue(StorageKey.Session, {
+ application.storage.setValue(StorageKey.Session, {
accessToken: undefined,
refreshToken: undefined,
accessExpiration: 999999999999999,
refreshExpiration: 999999999999999,
readonlyAccess: false,
})
- this.application.sessions.initializeFromDisk()
+ application.sessions.initializeFromDisk()
- const storageKey = this.application.storage.getPersistenceKey()
+ const storageKey = application.storage.getPersistenceKey()
expect(localStorage.getItem(storageKey)).to.be.ok
- await this.application.user.signOut()
+ await application.user.signOut()
expect(localStorage.getItem(storageKey)).to.not.be.ok
})
})
diff --git a/packages/snjs/mocha/settings.test.js b/packages/snjs/mocha/settings.test.js
index 587295294..115541510 100644
--- a/packages/snjs/mocha/settings.test.js
+++ b/packages/snjs/mocha/settings.test.js
@@ -30,6 +30,11 @@ describe('settings service', function () {
})
})
+ afterEach(async function () {
+ await Factory.safeDeinit(application)
+ localStorage.clear()
+ })
+
const reInitializeApplicationWithRealCrypto = async () => {
await Factory.safeDeinit(application)
@@ -46,11 +51,6 @@ describe('settings service', function () {
})
}
- afterEach(async function () {
- await Factory.safeDeinit(application)
- localStorage.clear()
- })
-
it('creates and reads a setting', async function () {
await application.settings.updateSetting(validSetting, fakePayload)
const responseCreate = await application.settings.getSetting(validSetting)
diff --git a/packages/snjs/mocha/singletons.test.js b/packages/snjs/mocha/singletons.test.js
index f84bf5456..f5898bf7a 100644
--- a/packages/snjs/mocha/singletons.test.js
+++ b/packages/snjs/mocha/singletons.test.js
@@ -1,8 +1,6 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from './lib/BaseItemCounts.js'
import * as Factory from './lib/factory.js'
-import WebDeviceInterface from './lib/web_device_interface.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -28,48 +26,60 @@ describe('singletons', function () {
return context.singletons.findOrCreateContentTypeSingleton(ContentType.TYPES.UserPrefs, FillItemContent({}))
}
+ let expectedItemCount
+ let application
+ let context
+ let email
+ let password
+ let registerUser
+ let signIn
+ let signOut
+ let extManagerId
+ let extPred
+ let createExtMgr
+
beforeEach(async function () {
localStorage.clear()
- this.expectedItemCount = BaseItemCounts.DefaultItems
+ expectedItemCount = BaseItemCounts.DefaultItems
- this.context = await Factory.createAppContext()
- await this.context.launch()
- this.application = this.context.application
+ context = await Factory.createAppContext()
+ await context.launch()
+ application = context.application
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
- this.registerUser = async () => {
- this.expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
+ registerUser = async () => {
+ expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
}
- this.signOut = async () => {
- this.application = await this.context.signout()
+ signOut = async () => {
+ application = await context.signout()
}
- this.signIn = async () => {
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
+ signIn = async () => {
+ await application.signIn(email, password, undefined, undefined, undefined, true)
}
- this.extManagerId = 'org.standardnotes.extensions-manager'
+ extManagerId = 'org.standardnotes.extensions-manager'
- this.extPred = new CompoundPredicate('and', [
+ extPred = new CompoundPredicate('and', [
new Predicate('content_type', '=', ContentType.TYPES.Component),
- new Predicate('package_info.identifier', '=', this.extManagerId),
+ new Predicate('package_info.identifier', '=', extManagerId),
])
- this.createExtMgr = () => {
- return this.application.mutator.createItem(
+ createExtMgr = () => {
+ return application.mutator.createItem(
ContentType.TYPES.Component,
{
package_info: {
name: 'Extensions',
- identifier: this.extManagerId,
+ identifier: extManagerId,
},
},
true,
@@ -78,13 +88,13 @@ describe('singletons', function () {
})
afterEach(async function () {
- expect(this.application.sync.isOutOfSync()).to.equal(false)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.sync.isOutOfSync()).to.equal(false)
+ expect(application.items.items.length).to.equal(expectedItemCount)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
localStorage.clear()
})
@@ -95,99 +105,99 @@ describe('singletons', function () {
const prefs2 = createPrefsPayload()
const prefs3 = createPrefsPayload()
- const items = await this.application.mutator.emitItemsFromPayloads(
+ const items = await application.mutator.emitItemsFromPayloads(
[prefs1, prefs2, prefs3],
PayloadEmitSource.LocalChanged,
)
- await this.application.mutator.setItemsDirty(items)
- await this.application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ await application.mutator.setItemsDirty(items)
+ await application.sync.sync(syncOptions)
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
it('duplicate components should auto-resolve to 1', async function () {
- const extManager = await this.createExtMgr()
- this.expectedItemCount += 1
+ const extManager = await createExtMgr()
+ expectedItemCount += 1
/** Call needlessly */
- await this.createExtMgr()
- await this.createExtMgr()
- await this.createExtMgr()
+ await createExtMgr()
+ await createExtMgr()
+ await createExtMgr()
expect(extManager).to.be.ok
- const refreshedExtMgr = this.application.items.findItem(extManager.uuid)
+ const refreshedExtMgr = application.items.findItem(extManager.uuid)
expect(refreshedExtMgr).to.be.ok
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
- expect(this.application.items.itemsMatchingPredicate(ContentType.TYPES.Component, this.extPred).length).to.equal(1)
+ expect(application.items.itemsMatchingPredicate(ContentType.TYPES.Component, extPred).length).to.equal(1)
})
it('resolves via find or create', async function () {
/* Set to never synced as singleton manager will attempt to sync before resolving */
- this.application.sync.ut_clearLastSyncDate()
- this.application.sync.ut_setDatabaseLoaded(false)
+ application.sync.ut_clearLastSyncDate()
+ application.sync.ut_setDatabaseLoaded(false)
const contentType = ContentType.TYPES.UserPrefs
const predicate = new Predicate('content_type', '=', contentType)
/* Start a sync right after we await singleton resolve below */
setTimeout(() => {
- this.application.sync.ut_setDatabaseLoaded(true)
- this.application.sync.sync({
+ application.sync.ut_setDatabaseLoaded(true)
+ application.sync.sync({
/* Simulate the first sync occuring as that is handled specially by sync service */
mode: SyncMode.DownloadFirst,
})
})
- const userPreferences = await this.context.singletons.findOrCreateContentTypeSingleton(contentType, {})
+ const userPreferences = await context.singletons.findOrCreateContentTypeSingleton(contentType, {})
expect(userPreferences).to.be.ok
- const refreshedUserPrefs = this.application.items.findItem(userPreferences.uuid)
+ const refreshedUserPrefs = application.items.findItem(userPreferences.uuid)
expect(refreshedUserPrefs).to.be.ok
- await this.application.sync.sync(syncOptions)
- expect(this.application.items.itemsMatchingPredicate(contentType, predicate).length).to.equal(1)
+ await application.sync.sync(syncOptions)
+ expect(application.items.itemsMatchingPredicate(contentType, predicate).length).to.equal(1)
})
it('resolves registered predicate with signing in/out', async function () {
- await this.registerUser()
+ await registerUser()
- await this.signOut()
+ await signOut()
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
- await this.createExtMgr()
+ await createExtMgr()
- this.expectedItemCount += 1
+ expectedItemCount += 1
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- await this.signOut()
+ await signOut()
- await this.createExtMgr()
+ await createExtMgr()
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
- const extraSync = this.application.sync.sync(syncOptions)
+ const extraSync = application.sync.sync(syncOptions)
- await this.signIn()
+ await signIn()
await extraSync
}).timeout(15000)
it('singletons that are deleted after download first sync should not sync to server', async function () {
- await this.registerUser()
- await this.createExtMgr()
- await this.createExtMgr()
- await this.createExtMgr()
- this.expectedItemCount++
+ await registerUser()
+ await createExtMgr()
+ await createExtMgr()
+ await createExtMgr()
+ expectedItemCount++
let didCompleteRelevantSync = false
let beginCheckingResponse = false
- this.application.sync.addEventObserver(async (eventName, data) => {
+ application.sync.addEventObserver(async (eventName, data) => {
if (eventName === SyncEvent.DownloadFirstSyncCompleted) {
beginCheckingResponse = true
}
@@ -202,59 +212,59 @@ describe('singletons', function () {
expect(matching).to.not.be.ok
}
})
- await this.application.sync.sync({ mode: SyncMode.DownloadFirst })
+ await application.sync.sync({ mode: SyncMode.DownloadFirst })
expect(didCompleteRelevantSync).to.equal(true)
}).timeout(10000)
it('signing into account and retrieving singleton shouldnt put us in deadlock', async function () {
- await this.registerUser()
+ await registerUser()
/** Create prefs */
- const ogPrefs = await findOrCreatePrefsSingleton(this.context)
- await this.application.sync.sync(syncOptions)
+ const ogPrefs = await findOrCreatePrefsSingleton(context)
+ await application.sync.sync(syncOptions)
- this.application = await this.context.signout()
+ application = await context.signout()
/** Create another instance while signed out */
- await findOrCreatePrefsSingleton(this.context)
+ await findOrCreatePrefsSingleton(context)
await Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
/** After signing in, the instance retrieved from the server should be the one kept */
- const latestPrefs = await findOrCreatePrefsSingleton(this.context)
+ const latestPrefs = await findOrCreatePrefsSingleton(context)
expect(latestPrefs.uuid).to.equal(ogPrefs.uuid)
- const allPrefs = this.application.items.getItems(ogPrefs.content_type)
+ const allPrefs = application.items.getItems(ogPrefs.content_type)
expect(allPrefs.length).to.equal(1)
})
it('resolving singleton before first sync, then signing in, should result in correct number of instances', async function () {
- await this.registerUser()
+ await registerUser()
/** Create prefs and associate them with account */
- const ogPrefs = await findOrCreatePrefsSingleton(this.context)
- await this.application.sync.sync(syncOptions)
- this.application = await this.context.signout()
+ const ogPrefs = await findOrCreatePrefsSingleton(context)
+ await application.sync.sync(syncOptions)
+ application = await context.signout()
/** Create another instance while signed out */
- await findOrCreatePrefsSingleton(this.context)
+ await findOrCreatePrefsSingleton(context)
await Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
/** After signing in, the instance retrieved from the server should be the one kept */
- const latestPrefs = await findOrCreatePrefsSingleton(this.context)
+ const latestPrefs = await findOrCreatePrefsSingleton(context)
expect(latestPrefs.uuid).to.equal(ogPrefs.uuid)
- const allPrefs = this.application.items.getItems(ogPrefs.content_type)
+ const allPrefs = application.items.getItems(ogPrefs.content_type)
expect(allPrefs.length).to.equal(1)
})
it('if only result is errorDecrypting, create new item', async function () {
- const item = this.application.items.items.find((item) => item.content_type === ContentType.TYPES.UserPrefs)
+ const item = application.items.items.find((item) => item.content_type === ContentType.TYPES.UserPrefs)
const erroredPayload = new EncryptedPayload({
...item.payload.ejected(),
@@ -262,13 +272,13 @@ describe('singletons', function () {
errorDecrypting: true,
})
- await this.application.payloads.emitPayload(erroredPayload)
+ await application.payloads.emitPayload(erroredPayload)
- const resolvedItem = await this.context.singletons.findOrCreateContentTypeSingleton(item.content_type, item.content)
+ const resolvedItem = await context.singletons.findOrCreateContentTypeSingleton(item.content_type, item.content)
- await this.application.sync.sync({ awaitAll: true })
+ await application.sync.sync({ awaitAll: true })
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
expect(resolvedItem.uuid).to.not.equal(item.uuid)
expect(resolvedItem.errorDecrypting).to.not.be.ok
})
@@ -284,13 +294,13 @@ describe('singletons', function () {
const sharedContent = {
package_info: {
name: 'Extensions',
- identifier: this.extManagerId,
+ identifier: extManagerId,
},
}
const errorDecryptingFalse = false
await Factory.insertItemWithOverride(
- this.application,
+ application,
ContentType.TYPES.Component,
sharedContent,
true,
@@ -299,16 +309,16 @@ describe('singletons', function () {
const errorDecryptingTrue = true
const errored = await Factory.insertItemWithOverride(
- this.application,
+ application,
ContentType.TYPES.Component,
sharedContent,
true,
errorDecryptingTrue,
)
- this.expectedItemCount += 1
+ expectedItemCount += 1
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
/** Now mark errored as not errorDecrypting and sync */
const notErrored = new DecryptedPayload({
@@ -317,34 +327,31 @@ describe('singletons', function () {
errorDecrypting: false,
})
- await this.application.payloads.emitPayload(notErrored)
+ await application.payloads.emitPayload(notErrored)
/** Item will get decrypted on current tick, so wait one before syncing */
await Factory.sleep(0)
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
- expect(this.application.items.itemsMatchingPredicate(ContentType.TYPES.Component, this.extPred).length).to.equal(1)
+ expect(application.items.itemsMatchingPredicate(ContentType.TYPES.Component, extPred).length).to.equal(1)
})
it('alternating the uuid of a singleton should return correct result', async function () {
const payload = createPrefsPayload()
- const item = await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
- await this.application.sync.sync(syncOptions)
+ const item = await application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
+ await application.sync.sync(syncOptions)
const predicate = new Predicate('content_type', '=', item.content_type)
- let resolvedItem = await this.context.singletons.findOrCreateContentTypeSingleton(
- payload.content_type,
- payload.content,
- )
+ let resolvedItem = await context.singletons.findOrCreateContentTypeSingleton(payload.content_type, payload.content)
const originalUuid = resolvedItem.uuid
- await Factory.alternateUuidForItem(this.application, resolvedItem.uuid)
- await this.application.sync.sync(syncOptions)
- const resolvedItem2 = await this.context.singletons.findOrCreateContentTypeSingleton(
+ await Factory.alternateUuidForItem(application, resolvedItem.uuid)
+ await application.sync.sync(syncOptions)
+ const resolvedItem2 = await context.singletons.findOrCreateContentTypeSingleton(
payload.content_type,
payload.content,
)
- resolvedItem = this.application.items.findItem(resolvedItem.uuid)
+ resolvedItem = application.items.findItem(resolvedItem.uuid)
expect(resolvedItem).to.not.be.ok
expect(resolvedItem2.uuid).to.not.equal(originalUuid)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
})
diff --git a/packages/snjs/mocha/storage.test.js b/packages/snjs/mocha/storage.test.js
index 72edf1bbc..f4654d84a 100644
--- a/packages/snjs/mocha/storage.test.js
+++ b/packages/snjs/mocha/storage.test.js
@@ -1,7 +1,6 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from './lib/BaseItemCounts.js'
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
@@ -13,128 +12,137 @@ describe('storage manager', function () {
*/
const BASE_KEY_COUNT = ['storage', 'snjs_version', 'keychain'].length
+ let application
+ let email
+ let password
+ let expectedKeyCount
+
beforeEach(async function () {
localStorage.clear()
- this.expectedKeyCount = BASE_KEY_COUNT
+ expectedKeyCount = BASE_KEY_COUNT
- this.context = await Factory.createAppContext()
- await this.context.launch()
+ context = await Factory.createAppContext()
+ await context.launch()
- this.application = this.context.application
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ application = context.application
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await context.deinit()
+
+ application = undefined
+ context = undefined
+
localStorage.clear()
})
it('should set and retrieve values', async function () {
const key = 'foo'
const value = 'bar'
- await this.application.storage.setValue(key, value)
- expect(await this.application.storage.getValue(key)).to.eql(value)
+ await application.storage.setValue(key, value)
+ expect(await application.storage.getValue(key)).to.eql(value)
})
it('should set and retrieve items', async function () {
const payload = Factory.createNotePayload()
- await this.application.storage.savePayload(payload)
- const payloads = await this.application.storage.getAllRawPayloads()
+ await application.storage.savePayload(payload)
+ const payloads = await application.storage.getAllRawPayloads()
expect(payloads.length).to.equal(BaseItemCounts.DefaultItems + 1)
})
it('should clear values', async function () {
const key = 'foo'
const value = 'bar'
- await this.application.storage.setValue(key, value)
- await this.application.storage.clearAllData()
- expect(await this.application.storage.getValue(key)).to.not.be.ok
+ await application.storage.setValue(key, value)
+ await application.storage.clearAllData()
+ expect(await application.storage.getValue(key)).to.not.be.ok
})
it('serverPassword should not be saved to keychain', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: false,
})
- const keychainValue = await this.application.device.getNamespacedKeychainValue(this.application.identifier)
+ const keychainValue = await application.device.getNamespacedKeychainValue(application.identifier)
expect(keychainValue.masterKey).to.be.ok
expect(keychainValue.serverPassword).to.not.be.ok
})
it('regular session should persist data', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: false,
})
const key = 'foo'
const value = 'bar'
- await this.application.storage.setValue(key, value)
+ await application.storage.setValue(key, value)
- expect(Object.keys(localStorage).length).to.equal(this.expectedKeyCount + BaseItemCounts.DefaultItemsWithAccount)
- const retrievedValue = await this.application.storage.getValue(key)
+ expect(Object.keys(localStorage).length).to.equal(expectedKeyCount + BaseItemCounts.DefaultItemsWithAccount)
+ const retrievedValue = await application.storage.getValue(key)
expect(retrievedValue).to.equal(value)
})
it('ephemeral session should not persist data', async function () {
this.retries(2)
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: true,
})
const key = 'foo'
const value = 'bar'
- await this.application.storage.setValueAndAwaitPersist(key, value)
+ await application.storage.setValueAndAwaitPersist(key, value)
const expectedKeys = ['keychain']
expect(Object.keys(localStorage).length).to.equal(expectedKeys.length)
- const retrievedValue = await this.application.storage.getValue(key)
+ const retrievedValue = await application.storage.getValue(key)
expect(retrievedValue).to.equal(value)
})
it('ephemeral session should not persist to database', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: true,
})
- await Factory.createSyncedNote(this.application)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ await Factory.createSyncedNote(application)
+ const rawPayloads = await application.storage.getAllRawPayloads()
expect(rawPayloads.length).to.equal(0)
})
it('storage with no account and no passcode should not be encrypted', async function () {
- await this.application.storage.setValueAndAwaitPersist('foo', 'bar')
- const wrappedValue = this.application.storage.values[ValueModesKeys.Wrapped]
+ await application.storage.setValueAndAwaitPersist('foo', 'bar')
+ const wrappedValue = application.storage.values[ValueModesKeys.Wrapped]
const payload = new DecryptedPayload(wrappedValue)
expect(payload.content).to.be.an.instanceof(Object)
})
it('storage aftering adding passcode should be encrypted', async function () {
- await this.application.storage.setValueAndAwaitPersist('foo', 'bar')
- await this.application.addPasscode('123')
- const wrappedValue = this.application.storage.values[ValueModesKeys.Wrapped]
+ await application.storage.setValueAndAwaitPersist('foo', 'bar')
+ await application.addPasscode('123')
+ const wrappedValue = application.storage.values[ValueModesKeys.Wrapped]
const payload = new EncryptedPayload(wrappedValue)
expect(payload.content).to.be.a('string')
})
it('storage after adding passcode then removing passcode should not be encrypted', async function () {
const passcode = '123'
- Factory.handlePasswordChallenges(this.application, passcode)
- await this.application.storage.setValueAndAwaitPersist('foo', 'bar')
- await this.application.addPasscode(passcode)
- await this.application.storage.setValueAndAwaitPersist('bar', 'foo')
- await this.application.removePasscode()
- const wrappedValue = this.application.storage.values[ValueModesKeys.Wrapped]
+ Factory.handlePasswordChallenges(application, passcode)
+ await application.storage.setValueAndAwaitPersist('foo', 'bar')
+ await application.addPasscode(passcode)
+ await application.storage.setValueAndAwaitPersist('bar', 'foo')
+ await application.removePasscode()
+ const wrappedValue = application.storage.values[ValueModesKeys.Wrapped]
const payload = new DecryptedPayload(wrappedValue)
expect(payload.content).to.be.an.instanceof(Object)
})
@@ -147,80 +155,85 @@ describe('storage manager', function () {
* the account keys to be moved to the keychain.
* */
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- expect(await this.application.device.getNamespacedKeychainValue(this.application.identifier)).to.be.ok
- await this.application.storage.setValueAndAwaitPersist('foo', 'bar')
- Factory.handlePasswordChallenges(this.application, this.password)
- await this.application.addPasscode(passcode)
- expect(await this.application.device.getNamespacedKeychainValue(this.application.identifier)).to.not.be.ok
- await this.application.storage.setValueAndAwaitPersist('bar', 'foo')
- Factory.handlePasswordChallenges(this.application, passcode)
- await this.application.removePasscode()
- expect(await this.application.device.getNamespacedKeychainValue(this.application.identifier)).to.be.ok
+ expect(await application.device.getNamespacedKeychainValue(application.identifier)).to.be.ok
+ await application.storage.setValueAndAwaitPersist('foo', 'bar')
+ Factory.handlePasswordChallenges(application, password)
+ await application.addPasscode(passcode)
+ expect(await application.device.getNamespacedKeychainValue(application.identifier)).to.not.be.ok
+ await application.storage.setValueAndAwaitPersist('bar', 'foo')
+ Factory.handlePasswordChallenges(application, passcode)
+ await application.removePasscode()
+ expect(await application.device.getNamespacedKeychainValue(application.identifier)).to.be.ok
- const wrappedValue = this.application.storage.values[ValueModesKeys.Wrapped]
+ const wrappedValue = application.storage.values[ValueModesKeys.Wrapped]
const payload = new EncryptedPayload(wrappedValue)
expect(payload.content).to.be.a('string')
})
it('adding account should encrypt storage with account keys', async function () {
- await this.application.storage.setValueAndAwaitPersist('foo', 'bar')
+ await application.storage.setValueAndAwaitPersist('foo', 'bar')
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: true,
})
- const accountKey = await this.application.encryption.getRootKey()
- expect(await this.application.storage.canDecryptWithKey(accountKey)).to.equal(true)
+ const accountKey = await application.encryption.getRootKey()
+ expect(await application.storage.canDecryptWithKey(accountKey)).to.equal(true)
})
it('signing out of account should decrypt storage', async function () {
- await this.application.storage.setValueAndAwaitPersist('foo', 'bar')
+ await application.storage.setValueAndAwaitPersist('foo', 'bar')
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: true,
})
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- await this.application.storage.setValueAndAwaitPersist('bar', 'foo')
- const wrappedValue = this.application.storage.values[ValueModesKeys.Wrapped]
+
+ application = await Factory.signOutApplicationAndReturnNew(application)
+
+ await application.storage.setValueAndAwaitPersist('bar', 'foo')
+ const wrappedValue = application.storage.values[ValueModesKeys.Wrapped]
const payload = new DecryptedPayload(wrappedValue)
+
expect(payload.content).to.be.an.instanceof(Object)
+
+ await Factory.safeDeinit(application)
})
it('adding account then passcode should encrypt storage with account keys', async function () {
/** Should encrypt storage with account keys and encrypt account keys with passcode */
- await this.application.storage.setValueAndAwaitPersist('foo', 'bar')
+ await application.storage.setValueAndAwaitPersist('foo', 'bar')
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: true,
})
/** Should not be wrapped root key yet */
- expect(await this.application.encryption.rootKeyManager.getWrappedRootKey()).to.not.be.ok
+ expect(await application.encryption.rootKeyManager.getWrappedRootKey()).to.not.be.ok
const passcode = '123'
- Factory.handlePasswordChallenges(this.application, this.password)
- await this.application.addPasscode(passcode)
- await this.application.storage.setValueAndAwaitPersist('bar', 'foo')
+ Factory.handlePasswordChallenges(application, password)
+ await application.addPasscode(passcode)
+ await application.storage.setValueAndAwaitPersist('bar', 'foo')
/** Root key should now be wrapped */
- expect(await this.application.encryption.rootKeyManager.getWrappedRootKey()).to.be.ok
+ expect(await application.encryption.rootKeyManager.getWrappedRootKey()).to.be.ok
- const accountKey = await this.application.encryption.getRootKey()
- expect(await this.application.storage.canDecryptWithKey(accountKey)).to.equal(true)
- const passcodeKey = await this.application.encryption.computeWrappingKey(passcode)
- const wrappedRootKey = await this.application.encryption.rootKeyManager.getWrappedRootKey()
+ const accountKey = await application.encryption.getRootKey()
+ expect(await application.storage.canDecryptWithKey(accountKey)).to.equal(true)
+ const passcodeKey = await application.encryption.computeWrappingKey(passcode)
+ const wrappedRootKey = await application.encryption.rootKeyManager.getWrappedRootKey()
/** Expect that we can decrypt wrapped root key with passcode key */
const payload = new EncryptedPayload(wrappedRootKey)
- const decrypted = await this.application.encryption.decryptSplitSingle({
+ const decrypted = await application.encryption.decryptSplitSingle({
usesRootKey: {
items: [payload],
key: passcodeKey,
@@ -230,9 +243,9 @@ describe('storage manager', function () {
})
it('stored payloads should not contain metadata fields', async function () {
- await this.application.addPasscode('123')
- await Factory.createSyncedNote(this.application)
- const payloads = await this.application.storage.getAllRawPayloads()
+ await application.addPasscode('123')
+ await Factory.createSyncedNote(application)
+ const payloads = await application.storage.getAllRawPayloads()
const payload = payloads[0]
expect(payload.fields).to.not.be.ok
expect(payload.source).to.not.be.ok
@@ -240,9 +253,9 @@ describe('storage manager', function () {
})
it('storing an offline synced payload should not include dirty flag', async function () {
- await this.application.addPasscode('123')
- await Factory.createSyncedNote(this.application)
- const payloads = await this.application.storage.getAllRawPayloads()
+ await application.addPasscode('123')
+ await Factory.createSyncedNote(application)
+ const payloads = await application.storage.getAllRawPayloads()
const payload = payloads[0]
expect(payload.dirty).to.not.be.ok
@@ -250,14 +263,14 @@ describe('storage manager', function () {
it('storing an online synced payload should not include dirty flag', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: false,
})
- await Factory.createSyncedNote(this.application)
- const payloads = await this.application.storage.getAllRawPayloads()
+ await Factory.createSyncedNote(application)
+ const payloads = await application.storage.getAllRawPayloads()
const payload = payloads[0]
expect(payload.dirty).to.not.be.ok
@@ -265,29 +278,36 @@ describe('storage manager', function () {
it('signing out should clear unwrapped value store', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: false,
})
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- const values = this.application.storage.values[ValueModesKeys.Unwrapped]
+ application = await Factory.signOutApplicationAndReturnNew(application)
+
+ const values = application.storage.values[ValueModesKeys.Unwrapped]
expect(Object.keys(values).length).to.equal(0)
+
+ await Factory.safeDeinit(application)
})
it('signing out should clear payloads', async function () {
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
ephemeral: false,
})
- await Factory.createSyncedNote(this.application)
- expect(await Factory.storagePayloadCount(this.application)).to.equal(BaseItemCounts.DefaultItemsWithAccount + 1)
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ await Factory.createSyncedNote(application)
+ expect(await Factory.storagePayloadCount(application)).to.equal(BaseItemCounts.DefaultItemsWithAccount + 1)
+
+ application = await Factory.signOutApplicationAndReturnNew(application)
+
await Factory.sleep(0.1, 'Allow all untrackable singleton syncs to complete')
- expect(await Factory.storagePayloadCount(this.application)).to.equal(BaseItemCounts.DefaultItems)
+ expect(await Factory.storagePayloadCount(application)).to.equal(BaseItemCounts.DefaultItems)
+
+ await Factory.safeDeinit(application)
})
})
diff --git a/packages/snjs/mocha/subscriptions.test.js b/packages/snjs/mocha/subscriptions.test.js
index cd56e947a..8fb0862de 100644
--- a/packages/snjs/mocha/subscriptions.test.js
+++ b/packages/snjs/mocha/subscriptions.test.js
@@ -10,11 +10,6 @@ describe('subscriptions', function () {
let context
let subscriptionManager
- afterEach(async function () {
- await Factory.safeDeinit(application)
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -34,6 +29,11 @@ describe('subscriptions', function () {
await context.activatePaidSubscriptionForUser()
})
+ afterEach(async function () {
+ await Factory.safeDeinit(application)
+ localStorage.clear()
+ })
+
it('should invite a user by email to a shared subscription', async () => {
await subscriptionManager.inviteToSubscription('test@test.te')
diff --git a/packages/snjs/mocha/sync_tests/conflicting.test.js b/packages/snjs/mocha/sync_tests/conflicting.test.js
index d25211693..0a4dc5dd9 100644
--- a/packages/snjs/mocha/sync_tests/conflicting.test.js
+++ b/packages/snjs/mocha/sync_tests/conflicting.test.js
@@ -3,44 +3,48 @@ import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
import { createSyncedNoteWithTag } from '../lib/Items.js'
import * as Utils from '../lib/Utils.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('online conflict handling', function () {
this.timeout(Factory.TenSecondTimeout)
+ let context
+ let application
+ let sharedFinalAssertions
+ let expectedItemCount
+
const syncOptions = {
checkIntegrity: true,
awaitAll: true,
}
- beforeEach(async function () {
+ beforeEach(async () => {
localStorage.clear()
- this.expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
+ expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
- this.context = await Factory.createAppContextWithFakeCrypto('AppA')
- await this.context.launch()
+ context = await Factory.createAppContextWithFakeCrypto('AppA')
+ await context.launch()
- this.application = this.context.application
- this.email = this.context.email
- this.password = this.context.password
+ application = context.application
- Factory.disableIntegrityAutoHeal(this.application)
+ Factory.disableIntegrityAutoHeal(application)
- await this.context.register()
+ await context.register()
- this.sharedFinalAssertions = async function () {
- expect(this.application.sync.isOutOfSync()).to.equal(false)
- const items = this.application.items.items
- expect(items.length).to.equal(this.expectedItemCount)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ sharedFinalAssertions = async () => {
+ expect(application.sync.isOutOfSync()).to.equal(false)
+ const items = application.items.items
+ expect(items.length).to.equal(expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
}
})
- afterEach(async function () {
- if (!this.application.dealloced) {
- await this.context.deinit()
+ afterEach(async () => {
+ if (!application.dealloced) {
+ await context.deinit()
}
localStorage.clear()
})
@@ -61,22 +65,22 @@ describe('online conflict handling', function () {
return payload
}
- it('components should not be duplicated under any circumstances', async function () {
+ it('components should not be duplicated under any circumstances', async () => {
const payload = createDirtyPayload(ContentType.TYPES.Component)
- const item = await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
+ const item = await application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
- this.expectedItemCount++
+ expectedItemCount++
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
/** First modify the item without saving so that our local contents digress from the server's */
- await this.application.mutator.changeItem(item, (mutator) => {
+ await application.mutator.changeItem(item, (mutator) => {
mutator.mutableContent.foo = `${Math.random()}`
})
await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
item.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -85,23 +89,23 @@ describe('online conflict handling', function () {
syncOptions,
)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('items keys should not be duplicated under any circumstances', async function () {
+ it('items keys should not be duplicated under any circumstances', async () => {
const payload = createDirtyPayload(ContentType.TYPES.ItemsKey)
- const item = await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
- this.expectedItemCount++
- await this.application.sync.sync(syncOptions)
+ const item = await application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
+ expectedItemCount++
+ await application.sync.sync(syncOptions)
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(item, (mutator) => {
+ await application.mutator.changeItem(item, (mutator) => {
mutator.title = `${Math.random()}`
})
await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
item.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -110,29 +114,29 @@ describe('online conflict handling', function () {
syncOptions,
)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('should create conflicted copy if incoming server item attempts to overwrite local dirty item', async function () {
+ it('should create conflicted copy if incoming server item attempts to overwrite local dirty item', async () => {
// create an item and sync it
- const note = await Factory.createMappedNote(this.application)
- this.expectedItemCount++
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
+ const note = await Factory.createMappedNote(application)
+ expectedItemCount++
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
const originalValue = note.title
const dirtyValue = `${Math.random()}`
/** Modify nonsense first to get around strategyWhenConflictingWithItem with previousRevision check */
- await this.application.mutator.changeNote(note, (mutator) => {
+ await application.mutator.changeNote(note, (mutator) => {
mutator.title = 'any'
})
- await this.application.mutator.changeNote(note, (mutator) => {
+ await application.mutator.changeNote(note, (mutator) => {
// modify this item locally to have differing contents from server
mutator.title = dirtyValue
// Intentionally don't change updated_at. We want to simulate a chaotic case where
@@ -141,47 +145,47 @@ describe('online conflict handling', function () {
})
// Download all items from the server, which will include this note.
- await this.application.sync.clearSyncPositionTokens()
- await this.application.sync.sync({
+ await application.sync.clearSyncPositionTokens()
+ await application.sync.sync({
...syncOptions,
awaitAll: true,
})
// We expect this item to be duplicated
- this.expectedItemCount++
- expect(this.application.items.getDisplayableNotes().length).to.equal(2)
+ expectedItemCount++
+ expect(application.items.getDisplayableNotes().length).to.equal(2)
- const allItems = this.application.items.items
- expect(allItems.length).to.equal(this.expectedItemCount)
+ const allItems = application.items.items
+ expect(allItems.length).to.equal(expectedItemCount)
- const originalItem = this.application.items.findItem(note.uuid)
+ const originalItem = application.items.findItem(note.uuid)
const duplicateItem = allItems.find((i) => i.content.conflict_of === note.uuid)
expect(originalItem.title).to.equal(dirtyValue)
expect(duplicateItem.title).to.equal(originalValue)
expect(originalItem.title).to.not.equal(duplicateItem.title)
- const newRawPayloads = await this.application.storage.getAllRawPayloads()
- expect(newRawPayloads.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ const newRawPayloads = await application.storage.getAllRawPayloads()
+ expect(newRawPayloads.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('should handle sync conflicts by duplicating differing data', async function () {
+ it('should handle sync conflicts by duplicating differing data', async () => {
// create an item and sync it
- const note = await Factory.createMappedNote(this.application)
- await Factory.markDirtyAndSyncItem(this.application, note)
- this.expectedItemCount++
+ const note = await Factory.createMappedNote(application)
+ await Factory.markDirtyAndSyncItem(application, note)
+ expectedItemCount++
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -191,28 +195,28 @@ describe('online conflict handling', function () {
)
// We expect this item to be duplicated
- this.expectedItemCount++
- const allItems = this.application.items.items
- expect(allItems.length).to.equal(this.expectedItemCount)
+ expectedItemCount++
+ const allItems = application.items.items
+ expect(allItems.length).to.equal(expectedItemCount)
- const note1 = this.application.items.getDisplayableNotes()[0]
- const note2 = this.application.items.getDisplayableNotes()[1]
+ const note1 = application.items.getDisplayableNotes()[0]
+ const note2 = application.items.getDisplayableNotes()[1]
expect(note1.content.title).to.not.equal(note2.content.title)
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
})
- it('basic conflict with clearing local state', async function () {
- const note = await Factory.createMappedNote(this.application)
- await Factory.markDirtyAndSyncItem(this.application, note)
- this.expectedItemCount += 1
+ it('basic conflict with clearing local state', async () => {
+ const note = await Factory.createMappedNote(application)
+ await Factory.markDirtyAndSyncItem(application, note)
+ expectedItemCount += 1
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -221,37 +225,37 @@ describe('online conflict handling', function () {
syncOptions,
)
- this.expectedItemCount++
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expectedItemCount++
+ expect(application.items.items.length).to.equal(expectedItemCount)
// clear sync token, clear storage, download all items, and ensure none of them have error decrypting
- await this.application.sync.clearSyncPositionTokens()
- await this.application.storage.clearAllPayloads()
- await this.application.payloads.resetState()
- await this.application.items.resetState()
- await this.application.sync.sync(syncOptions)
+ await application.sync.clearSyncPositionTokens()
+ await application.storage.clearAllPayloads()
+ await application.payloads.resetState()
+ await application.items.resetState()
+ await application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('should duplicate item if saving a modified item and clearing our sync token', async function () {
- let note = await Factory.createMappedNote(this.application)
+ it('should duplicate item if saving a modified item and clearing our sync token', async () => {
+ let note = await Factory.createMappedNote(application)
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
- this.expectedItemCount++
+ expectedItemCount++
const newTitle = `${Math.random()}`
/** First modify the item without saving so that our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
await Factory.changePayloadTimeStamp(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -261,44 +265,44 @@ describe('online conflict handling', function () {
)
// We expect this item to be duplicated
- this.expectedItemCount++
+ expectedItemCount++
- await this.application.sync.clearSyncPositionTokens()
- await this.application.sync.sync(syncOptions)
+ await application.sync.clearSyncPositionTokens()
+ await application.sync.sync(syncOptions)
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
// We expect the item title to be the new title, and not rolled back to original value
expect(note.content.title).to.equal(newTitle)
- const allItems = this.application.items.items
- expect(allItems.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ const allItems = application.items.items
+ expect(allItems.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('should handle sync conflicts by not duplicating same data', async function () {
- const note = await Factory.createMappedNote(this.application)
- this.expectedItemCount++
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
+ it('should handle sync conflicts by not duplicating same data', async () => {
+ const note = await Factory.createMappedNote(application)
+ expectedItemCount++
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
// keep item as is and set dirty
- await this.application.mutator.setItemDirty(note)
+ await application.mutator.setItemDirty(note)
// clear sync token so that all items are retrieved on next sync
- this.application.sync.clearSyncPositionTokens()
+ application.sync.clearSyncPositionTokens()
- await this.application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ await application.sync.sync(syncOptions)
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('clearing conflict_of on two clients simultaneously should keep us in sync', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- this.expectedItemCount++
+ it('clearing conflict_of on two clients simultaneously should keep us in sync', async () => {
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ expectedItemCount++
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
note,
(mutator) => {
// client A
@@ -310,8 +314,8 @@ describe('online conflict handling', function () {
)
// client B
- await this.application.sync.clearSyncPositionTokens()
- await this.application.mutator.changeItem(
+ await application.sync.clearSyncPositionTokens()
+ await application.mutator.changeItem(
note,
(mutator) => {
mutator.mutableContent.conflict_of = 'bar'
@@ -323,16 +327,16 @@ describe('online conflict handling', function () {
// conflict_of is a key to ignore when comparing content, so item should
// not be duplicated.
- await this.application.sync.sync(syncOptions)
- await this.sharedFinalAssertions()
+ await application.sync.sync(syncOptions)
+ await sharedFinalAssertions()
})
- it('setting property on two clients simultaneously should create conflict', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- this.expectedItemCount++
+ it('setting property on two clients simultaneously should create conflict', async () => {
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ expectedItemCount++
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
note,
(mutator) => {
// client A
@@ -344,14 +348,14 @@ describe('online conflict handling', function () {
)
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
// client B
- await this.application.sync.clearSyncPositionTokens()
+ await application.sync.clearSyncPositionTokens()
await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -360,85 +364,85 @@ describe('online conflict handling', function () {
syncOptions,
)
- this.expectedItemCount++
+ expectedItemCount++
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
})
- it('if server says deleted but client says not deleted, keep server state', async function () {
- const note = await Factory.createMappedNote(this.application)
+ it('if server says deleted but client says not deleted, keep server state', async () => {
+ const note = await Factory.createMappedNote(application)
const originalPayload = note.payloadRepresentation()
- this.expectedItemCount++
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expectedItemCount++
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
+ expect(application.items.items.length).to.equal(expectedItemCount)
// client A
- await this.application.mutator.setItemToBeDeleted(note)
- await this.application.sync.sync(syncOptions)
- this.expectedItemCount--
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ await application.mutator.setItemToBeDeleted(note)
+ await application.sync.sync(syncOptions)
+ expectedItemCount--
+ expect(application.items.items.length).to.equal(expectedItemCount)
// client B
- await this.application.sync.clearSyncPositionTokens()
+ await application.sync.clearSyncPositionTokens()
// Add the item back and say it's not deleted
const mutatedPayload = new DecryptedPayload({
...originalPayload,
deleted: false,
updated_at: Factory.yesterday(),
})
- await this.application.mutator.emitItemsFromPayloads([mutatedPayload], PayloadEmitSource.LocalChanged)
- const resultNote = this.application.items.findItem(note.uuid)
+ await application.mutator.emitItemsFromPayloads([mutatedPayload], PayloadEmitSource.LocalChanged)
+ const resultNote = application.items.findItem(note.uuid)
expect(resultNote.uuid).to.equal(note.uuid)
- await this.application.mutator.setItemDirty(resultNote)
- await this.application.sync.sync(syncOptions)
+ await application.mutator.setItemDirty(resultNote)
+ await application.sync.sync(syncOptions)
// We expect that this item is now gone for good, and a duplicate has not been created.
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('if server says not deleted but client says deleted, keep server state', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- this.expectedItemCount++
+ it('if server says not deleted but client says deleted, keep server state', async () => {
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ expectedItemCount++
// client A
- await this.application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ await application.sync.sync(syncOptions)
+ expect(application.items.items.length).to.equal(expectedItemCount)
// client B
- await this.application.sync.clearSyncPositionTokens()
+ await application.sync.clearSyncPositionTokens()
// This client says this item is deleted, but the server is saying its not deleted.
// In this case, we want to keep the server copy.
await Factory.changePayloadTimeStampDeleteAndSync(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
syncOptions,
)
// We expect that this item maintained.
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
- it('should create conflict if syncing an item that is stale', async function () {
- let note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
- note = this.application.items.findItem(note.uuid)
+ it('should create conflict if syncing an item that is stale', async () => {
+ let note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
+ note = application.items.findItem(note.uuid)
expect(note.dirty).to.equal(false)
- this.expectedItemCount++
+ expectedItemCount++
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
note = await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -450,111 +454,111 @@ describe('online conflict handling', function () {
expect(note.dirty).to.equal(false)
// We expect now that the item was conflicted
- this.expectedItemCount++
+ expectedItemCount++
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
for (const payload of rawPayloads) {
expect(payload.dirty).to.not.be.ok
}
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
})
- it('creating conflict with exactly equal content should keep us in sync', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- this.expectedItemCount++
+ it('creating conflict with exactly equal content should keep us in sync', async () => {
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ expectedItemCount++
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{},
syncOptions,
)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- await this.sharedFinalAssertions()
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ await sharedFinalAssertions()
})
/**
* This test takes over 60s in a CI environment when running in Docker server.
* It's much faster in a home server environment but should still be skipped for now.
*/
- it.skip('handles stale data in bulk', async function () {
+ it.skip('handles stale data in bulk', async () => {
/** This number must be greater than the pagination limit per sync request.
* For example if the limit per request is 150 items sent/received, this number should
* be something like 160. */
const largeItemCount = SyncUpDownLimit + 10
- await Factory.createManyMappedNotes(this.application, largeItemCount)
+ await Factory.createManyMappedNotes(application, largeItemCount)
/** Upload */
- this.application.sync.sync(syncOptions)
- await this.context.awaitNextSucessfulSync()
+ application.sync.sync(syncOptions)
+ await context.awaitNextSucessfulSync()
- this.expectedItemCount += largeItemCount
- const items = this.application.items.items
- expect(items.length).to.equal(this.expectedItemCount)
+ expectedItemCount += largeItemCount
+ const items = application.items.items
+ expect(items.length).to.equal(expectedItemCount)
/**
* We want to see what will happen if we upload everything we have to
* the server as dirty, with no sync token, so that the server also
* gives us everything it has.
*/
- this.application.sync.lockSyncing()
+ application.sync.lockSyncing()
const yesterday = Factory.yesterday()
- for (const note of this.application.items.getDisplayableNotes()) {
+ for (const note of application.items.getDisplayableNotes()) {
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.text = '1'
})
- await Factory.changePayloadTimeStamp(this.application, note.payload, Factory.dateToMicroseconds(yesterday), {
+ await Factory.changePayloadTimeStamp(application, note.payload, Factory.dateToMicroseconds(yesterday), {
text: '2',
})
// We expect all the notes to be duplicated.
- this.expectedItemCount++
+ expectedItemCount++
}
- this.application.sync.unlockSyncing()
+ application.sync.unlockSyncing()
- await this.application.sync.clearSyncPositionTokens()
- this.application.sync.sync(syncOptions)
- await this.context.awaitNextSucessfulSync()
+ await application.sync.clearSyncPositionTokens()
+ application.sync.sync(syncOptions)
+ await context.awaitNextSucessfulSync()
- expect(this.application.items.getDisplayableNotes().length).to.equal(largeItemCount * 2)
- await this.sharedFinalAssertions()
+ expect(application.items.getDisplayableNotes().length).to.equal(largeItemCount * 2)
+ await sharedFinalAssertions()
}).timeout(60000)
- it('duplicating an item should maintian its relationships', async function () {
+ it('duplicating an item should maintian its relationships', async () => {
const payload1 = Factory.createStorageItemPayload(ContentType.TYPES.Tag)
const payload2 = Factory.createStorageItemPayload(ContentType.TYPES.UserPrefs)
- this.expectedItemCount -= 1 /** auto-created user preferences */
- await this.application.mutator.emitItemsFromPayloads([payload1, payload2], PayloadEmitSource.LocalChanged)
- this.expectedItemCount += 2
- let tag = this.application.items.getItems(ContentType.TYPES.Tag)[0]
- let userPrefs = this.application.items.getItems(ContentType.TYPES.UserPrefs)[0]
+ expectedItemCount -= 1 /** auto-created user preferences */
+ await application.mutator.emitItemsFromPayloads([payload1, payload2], PayloadEmitSource.LocalChanged)
+ expectedItemCount += 2
+ let tag = application.items.getItems(ContentType.TYPES.Tag)[0]
+ let userPrefs = application.items.getItems(ContentType.TYPES.UserPrefs)[0]
expect(tag).to.be.ok
expect(userPrefs).to.be.ok
- tag = await this.application.mutator.changeItem(tag, (mutator) => {
+ tag = await application.mutator.changeItem(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(userPrefs)
})
- await this.application.mutator.setItemDirty(userPrefs)
- userPrefs = this.application.items.findItem(userPrefs.uuid)
+ await application.mutator.setItemDirty(userPrefs)
+ userPrefs = application.items.findItem(userPrefs.uuid)
- expect(this.application.items.itemsReferencingItem(userPrefs).length).to.equal(1)
- expect(this.application.items.itemsReferencingItem(userPrefs)).to.include(tag)
+ expect(application.items.itemsReferencingItem(userPrefs).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(userPrefs)).to.include(tag)
- await this.application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ await application.sync.sync(syncOptions)
+ expect(application.items.items.length).to.equal(expectedItemCount)
tag = await Factory.changePayloadTimeStamp(
- this.application,
+ application,
tag.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -562,48 +566,48 @@ describe('online conflict handling', function () {
},
)
- await this.application.sync.sync({ ...syncOptions, awaitAll: true })
+ await application.sync.sync({ ...syncOptions, awaitAll: true })
// fooItem should now be conflicted and a copy created
- this.expectedItemCount++
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ expectedItemCount++
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
- const fooItems = this.application.items.getItems(ContentType.TYPES.Tag)
+ const fooItems = application.items.getItems(ContentType.TYPES.Tag)
const fooItem2 = fooItems[1]
expect(fooItem2.content.conflict_of).to.equal(tag.uuid)
// Two items now link to this original object
- const referencingItems = this.application.items.itemsReferencingItem(userPrefs)
+ const referencingItems = application.items.itemsReferencingItem(userPrefs)
expect(referencingItems.length).to.equal(2)
expect(referencingItems[0]).to.not.equal(referencingItems[1])
- expect(this.application.items.itemsReferencingItem(tag).length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(fooItem2).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(tag).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(fooItem2).length).to.equal(0)
expect(tag.content.references.length).to.equal(1)
expect(fooItem2.content.references.length).to.equal(1)
expect(userPrefs.content.references.length).to.equal(0)
- expect(this.application.items.getDirtyItems().length).to.equal(0)
- for (const item of this.application.items.items) {
+ expect(application.items.getDirtyItems().length).to.equal(0)
+ for (const item of application.items.items) {
expect(item.dirty).to.not.be.ok
}
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
})
- it('when a note is conflicted, its tags should not be duplicated.', async function () {
+ it('when a note is conflicted, its tags should not be duplicated.', async () => {
/**
* If you have a note and a tag, and the tag has 1 reference to the note,
* and you import the same two items, except modify the note value so that
* a duplicate is created, we expect only the note to be duplicated,
* and the tag not to.
*/
- let tag = await Factory.createMappedTag(this.application)
- let note = await Factory.createMappedNote(this.application)
+ let tag = await Factory.createMappedTag(application)
+ let note = await Factory.createMappedNote(application)
tag = (
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
tag,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(note)
@@ -613,21 +617,21 @@ describe('online conflict handling', function () {
syncOptions,
)
).getValue()
- await this.application.mutator.setItemDirty(note)
- this.expectedItemCount += 2
+ await application.mutator.setItemDirty(note)
+ expectedItemCount += 2
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
// conflict the note
const newText = `${Math.random()}`
/** First modify the item without saving so that our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
note = await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
note.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -638,7 +642,7 @@ describe('online conflict handling', function () {
// conflict the tag but keep its content the same
tag = await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
tag.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{},
@@ -649,13 +653,13 @@ describe('online conflict handling', function () {
* We expect now that the total item count has went up by just 1 (the note),
* and not 2 (the note and tag)
*/
- this.expectedItemCount += 1
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expectedItemCount += 1
+ expect(application.items.items.length).to.equal(expectedItemCount)
expect(tag.content.references.length).to.equal(2)
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
})
- it('succesful server side saving but dropped packet response should not create sync conflict', async function () {
+ it('succesful server side saving but dropped packet response should not create sync conflict', async () => {
/**
* 1. Initiate a change locally that is successfully saved by the server, but the client
* drops the server response.
@@ -663,35 +667,35 @@ describe('online conflict handling', function () {
*
* Expected result: no sync conflict is created
*/
- const note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
+ const note = await Factory.createSyncedNote(application)
+ expectedItemCount++
const baseTitle = 'base title'
/** Change the note */
- const noteAfterChange = await this.application.mutator.changeItem(note, (mutator) => {
+ const noteAfterChange = await application.mutator.changeItem(note, (mutator) => {
mutator.title = baseTitle
})
- await this.application.sync.sync()
+ await application.sync.sync()
/** Simulate a dropped response by reverting the note back its post-change, pre-sync state */
- const retroNote = await this.application.mutator.emitItemFromPayload(noteAfterChange.payload)
+ const retroNote = await application.mutator.emitItemFromPayload(noteAfterChange.payload)
expect(retroNote.serverUpdatedAt.getTime()).to.equal(noteAfterChange.serverUpdatedAt.getTime())
/** Change the item to its final title and sync */
const finalTitle = 'final title'
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = finalTitle
})
- await this.application.sync.sync()
+ await application.sync.sync()
/** Expect that no duplicates have been created, and that the note's title is now finalTitle */
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- const finalNote = this.application.items.findItem(note.uuid)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ const finalNote = application.items.findItem(note.uuid)
expect(finalNote.title).to.equal(finalTitle)
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
})
- it('receiving a decrypted item while the current local item is errored and dirty should overwrite local value', async function () {
+ it('receiving a decrypted item while the current local item is errored and dirty should overwrite local value', async () => {
/**
* An item can be marked as dirty (perhaps via a bulk dirtying operation) even if it is errored,
* but it can never be sent to the server if errored. If we retrieve an item from the server
@@ -701,8 +705,8 @@ describe('online conflict handling', function () {
/**
* Create a note and sync it with the server while its valid
*/
- const note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
+ const note = await Factory.createSyncedNote(application)
+ expectedItemCount++
/**
* Mark the item as dirty and errored
@@ -713,13 +717,13 @@ describe('online conflict handling', function () {
errorDecrypting: true,
dirty: true,
})
- await this.application.mutator.emitItemsFromPayloads([errorred], PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads([errorred], PayloadEmitSource.LocalChanged)
/**
* Retrieve this note from the server by clearing sync token
*/
- await this.application.sync.clearSyncPositionTokens()
- await this.application.sync.sync({
+ await application.sync.clearSyncPositionTokens()
+ await application.sync.sync({
...syncOptions,
awaitAll: true,
})
@@ -727,16 +731,16 @@ describe('online conflict handling', function () {
/**
* Expect that the final result is just 1 note that is not errored
*/
- const resultNote = await this.application.items.findItem(note.uuid)
+ const resultNote = await application.items.findItem(note.uuid)
expect(resultNote.errorDecrypting).to.not.be.ok
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- await this.sharedFinalAssertions()
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ await sharedFinalAssertions()
})
/** This test takes too long on Docker CI */
it.skip(
'registering for account with bulk offline data belonging to another account should be error-free',
- async function () {
+ async () => {
/**
* When performing a multi-page sync request where we are uploading data imported from a backup,
* if the first page of the sync request returns conflicted items keys, we rotate their UUID.
@@ -752,12 +756,12 @@ describe('online conflict handling', function () {
/** Create bulk data belonging to another account and sync */
const largeItemCount = SyncUpDownLimit + 10
- await Factory.createManyMappedNotes(this.application, largeItemCount)
- await this.application.sync.sync(syncOptions)
- const priorData = this.application.items.items
+ await Factory.createManyMappedNotes(application, largeItemCount)
+ await application.sync.sync(syncOptions)
+ const priorData = application.items.items
/** Register new account and import this same data */
- const newApp = await Factory.signOutApplicationAndReturnNew(this.application)
+ const newApp = await Factory.signOutApplicationAndReturnNew(application)
await Factory.registerUserToApplication({
application: newApp,
email: Utils.generateUuid(),
@@ -771,10 +775,10 @@ describe('online conflict handling', function () {
},
).timeout(80000)
- it('importing data belonging to another account should not result in duplication', async function () {
+ it('importing data belonging to another account should not result in duplication', async () => {
/** Create primary account and export data */
- await createSyncedNoteWithTag(this.application)
- let backupFile = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ await createSyncedNoteWithTag(application)
+ let backupFile = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
/** Sort matters, and is the cause of the original issue, where tag comes before the note */
backupFile.items = [
backupFile.items.find((i) => i.content_type === ContentType.TYPES.ItemsKey),
@@ -783,8 +787,8 @@ describe('online conflict handling', function () {
]
backupFile = JSON.parse(JSON.stringify(backupFile))
/** Register new account and import this same data */
- const newApp = await Factory.signOutApplicationAndReturnNew(this.application)
- const password = this.password
+ const newApp = await Factory.signOutApplicationAndReturnNew(application)
+ const password = context.password
await Factory.registerUserToApplication({
application: newApp,
email: Utils.generateUuid(),
@@ -797,19 +801,19 @@ describe('online conflict handling', function () {
await Factory.safeDeinit(newApp)
}).timeout(10000)
- it('importing notes + tags belonging to another account should keep correct associations', async function () {
+ it('importing notes + tags belonging to another account should keep correct associations', async () => {
/**
* The original issue can be replicated when an export contains a tag with two notes,
* where the two notes are first listed in the backup, then the tag.
*/
/** Create primary account and export data */
- await createSyncedNoteWithTag(this.application)
- const tag = this.application.items.getDisplayableTags()[0]
- const note2 = await Factory.createMappedNote(this.application)
- await this.application.changeAndSaveItem.execute(tag, (mutator) => {
+ await createSyncedNoteWithTag(application)
+ const tag = application.items.getDisplayableTags()[0]
+ const note2 = await Factory.createMappedNote(application)
+ await application.changeAndSaveItem.execute(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(note2)
})
- let backupFile = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()
+ let backupFile = await application.createEncryptedBackupFileForAutomatedDesktopBackups()
backupFile.items = [
backupFile.items.find((i) => i.content_type === ContentType.TYPES.ItemsKey),
backupFile.items.filter((i) => i.content_type === ContentType.TYPES.Note)[0],
@@ -818,8 +822,8 @@ describe('online conflict handling', function () {
]
backupFile = JSON.parse(JSON.stringify(backupFile))
/** Register new account and import this same data */
- const newApp = await Factory.signOutApplicationAndReturnNew(this.application)
- const password = this.password
+ const newApp = await Factory.signOutApplicationAndReturnNew(application)
+ const password = context.password
await Factory.registerUserToApplication({
application: newApp,
email: Utils.generateUuid(),
@@ -833,18 +837,18 @@ describe('online conflict handling', function () {
await Factory.safeDeinit(newApp)
}).timeout(10000)
- it('server should prioritize updated_at_timestamp over updated_at for sync, if provided', async function () {
+ it('server should prioritize updated_at_timestamp over updated_at for sync, if provided', async () => {
/**
* As part of SSRB to SSJS migration, server should prefer to use updated_at_timestamp
* over updated_at for sync conflict logic. The timestamps are more accurate and support
* microsecond precision, versus date objects which only go up to milliseconds.
*/
- const note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
+ const note = await Factory.createSyncedNote(application)
+ expectedItemCount++
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
/**
@@ -860,19 +864,19 @@ describe('online conflict handling', function () {
},
dirty: true,
})
- await this.application.mutator.emitItemFromPayload(modified)
- await this.application.sync.sync()
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- await this.sharedFinalAssertions()
+ await application.mutator.emitItemFromPayload(modified)
+ await application.sync.sync()
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ await sharedFinalAssertions()
})
- it('conflict should be created if updated_at_timestamp is not exactly equal to servers', async function () {
- const note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
+ it('conflict should be created if updated_at_timestamp is not exactly equal to servers', async () => {
+ const note = await Factory.createSyncedNote(application)
+ expectedItemCount++
/** First modify the item without saving so that
* our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
const modified = note.payload.copy({
@@ -883,14 +887,14 @@ describe('online conflict handling', function () {
},
dirty: true,
})
- this.expectedItemCount++
- await this.application.mutator.emitItemFromPayload(modified)
- await this.application.sync.sync()
- expect(this.application.items.getDisplayableNotes().length).to.equal(2)
- await this.sharedFinalAssertions()
+ expectedItemCount++
+ await application.mutator.emitItemFromPayload(modified)
+ await application.sync.sync()
+ expect(application.items.getDisplayableNotes().length).to.equal(2)
+ await sharedFinalAssertions()
})
- it('conflict where server updated_at_timestamp is less than base updated_at should not result in infinite loop', async function () {
+ it('conflict where server updated_at_timestamp is less than base updated_at should not result in infinite loop', async () => {
/**
* While this shouldn't happen, I've seen this happen locally where a single UserPrefs object has a timestamp of A
* on the server, and A + 10 on the client side. Somehow the client had a newer timestamp than the server. The
@@ -900,11 +904,11 @@ describe('online conflict handling', function () {
* Because this was not the case, the client kept sending up its own base timestamp and the server kept rejecting it,
* and it never resolved. The fix made here was to take the server's timestamp no matter what, even if it is less than client's.
*/
- const note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
+ const note = await Factory.createSyncedNote(application)
+ expectedItemCount++
/** First modify the item without saving so that our local contents digress from the server's */
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}`
})
const modified = note.payload.copy({
@@ -915,21 +919,21 @@ describe('online conflict handling', function () {
},
dirty: true,
})
- this.expectedItemCount++
- await this.application.mutator.emitItemFromPayload(modified)
- await this.application.sync.sync()
- expect(this.application.items.getDisplayableNotes().length).to.equal(2)
- await this.sharedFinalAssertions()
+ expectedItemCount++
+ await application.mutator.emitItemFromPayload(modified)
+ await application.sync.sync()
+ expect(application.items.getDisplayableNotes().length).to.equal(2)
+ await sharedFinalAssertions()
})
- it('conflicting should not over resolve', async function () {
+ it('conflicting should not over resolve', async () => {
/**
* Before refactoring to use dirtyIndex instead of dirtiedDate, sometimes an item could be dirtied
* and begin sync at the exact same millisecond count (at least in the tests). In which case, the item
* would be stillDirty after sync and would sync again. This test ensures that an item is only synced once
* after it saves changes from conflicted items.
*/
- const contextA = this.context
+ const contextA = context
const contextB = await Factory.createAppContextWithFakeCrypto('AppB', contextA.email, contextA.password)
contextA.disableIntegrityAutoHeal()
@@ -944,7 +948,7 @@ describe('online conflict handling', function () {
await contextA.changeNoteTitleAndSync(note, 'title-A')
await contextB.changeNoteTitleAndSync(note, 'title-B')
- this.expectedItemCount += 2
+ expectedItemCount += 2
const noteAExpectedTimestamp = contextB.findNoteByTitle('title-A').payload.updated_at_timestamp
const noteBExpectedTimestamp = contextB.findNoteByTitle('title-B').payload.updated_at_timestamp
@@ -954,12 +958,12 @@ describe('online conflict handling', function () {
expect(contextA.findNoteByTitle('title-A').payload.updated_at_timestamp).to.equal(noteAExpectedTimestamp)
expect(contextA.findNoteByTitle('title-B').payload.updated_at_timestamp).to.equal(noteBExpectedTimestamp)
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
await contextB.deinit()
}).timeout(20000)
- it('editing original note many times after conflict on other client should only result in 2 cumulative notes', async function () {
- const contextA = this.context
+ it('editing original note many times after conflict on other client should only result in 2 cumulative notes', async () => {
+ const contextA = context
const contextB = await Factory.createAppContextWithFakeCrypto('AppB', contextA.email, contextA.password)
contextA.disableIntegrityAutoHeal()
contextB.disableIntegrityAutoHeal()
@@ -968,7 +972,7 @@ describe('online conflict handling', function () {
await contextB.signIn()
const { original } = await contextA.createConflictedNotes(contextB)
- this.expectedItemCount += 2
+ expectedItemCount += 2
expect(contextA.noteCount).to.equal(2)
expect(contextB.noteCount).to.equal(2)
@@ -984,7 +988,7 @@ describe('online conflict handling', function () {
expect(contextA.noteCount).to.equal(2)
expect(contextB.noteCount).to.equal(2)
- await this.sharedFinalAssertions()
+ await sharedFinalAssertions()
await contextB.deinit()
}).timeout(20000)
})
diff --git a/packages/snjs/mocha/sync_tests/integrity.test.js b/packages/snjs/mocha/sync_tests/integrity.test.js
index 704ec3095..1c32cf9c4 100644
--- a/packages/snjs/mocha/sync_tests/integrity.test.js
+++ b/packages/snjs/mocha/sync_tests/integrity.test.js
@@ -1,31 +1,37 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('sync integrity', () => {
- before(function () {
- localStorage.clear()
- })
-
- after(function () {
- localStorage.clear()
- })
+ let application
+ let email
+ let password
+ let expectedItemCount
beforeEach(async function () {
- this.expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
- this.application = await Factory.createInitAppWithFakeCrypto()
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
+ localStorage.clear()
+ expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
+ application = await Factory.createInitAppWithFakeCrypto()
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
})
+ afterEach(async function () {
+ expect(application.sync.isOutOfSync()).to.equal(false)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
+ await Factory.safeDeinit(application)
+ localStorage.clear()
+ application = undefined
+ })
+
const awaitSyncEventPromise = (application, targetEvent) => {
return new Promise((resolve) => {
application.sync.addEventObserver((event) => {
@@ -36,44 +42,37 @@ describe('sync integrity', () => {
})
}
- afterEach(async function () {
- expect(this.application.sync.isOutOfSync()).to.equal(false)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
- await Factory.safeDeinit(this.application)
- })
-
it('should detect when out of sync', async function () {
- const item = await this.application.mutator.emitItemFromPayload(
+ const item = await application.mutator.emitItemFromPayload(
Factory.createNotePayload(),
PayloadEmitSource.LocalChanged,
)
- this.expectedItemCount++
+ expectedItemCount++
- const didEnterOutOfSync = awaitSyncEventPromise(this.application, SyncEvent.EnterOutOfSync)
- await this.application.sync.sync({ checkIntegrity: true })
+ const didEnterOutOfSync = awaitSyncEventPromise(application, SyncEvent.EnterOutOfSync)
+ await application.sync.sync({ checkIntegrity: true })
- await this.application.items.removeItemFromMemory(item)
- await this.application.sync.sync({ checkIntegrity: true, awaitAll: true })
+ await application.items.removeItemFromMemory(item)
+ await application.sync.sync({ checkIntegrity: true, awaitAll: true })
await didEnterOutOfSync
})
it('should self heal after out of sync', async function () {
- const item = await this.application.mutator.emitItemFromPayload(
+ const item = await application.mutator.emitItemFromPayload(
Factory.createNotePayload(),
PayloadEmitSource.LocalChanged,
)
- this.expectedItemCount++
+ expectedItemCount++
- const didEnterOutOfSync = awaitSyncEventPromise(this.application, SyncEvent.EnterOutOfSync)
- const didExitOutOfSync = awaitSyncEventPromise(this.application, SyncEvent.ExitOutOfSync)
+ const didEnterOutOfSync = awaitSyncEventPromise(application, SyncEvent.EnterOutOfSync)
+ const didExitOutOfSync = awaitSyncEventPromise(application, SyncEvent.ExitOutOfSync)
- await this.application.sync.sync({ checkIntegrity: true })
- await this.application.items.removeItemFromMemory(item)
- await this.application.sync.sync({ checkIntegrity: true, awaitAll: true })
+ await application.sync.sync({ checkIntegrity: true })
+ await application.items.removeItemFromMemory(item)
+ await application.sync.sync({ checkIntegrity: true, awaitAll: true })
await Promise.all([didEnterOutOfSync, didExitOutOfSync])
- expect(this.application.sync.isOutOfSync()).to.equal(false)
+ expect(application.sync.isOutOfSync()).to.equal(false)
})
})
diff --git a/packages/snjs/mocha/sync_tests/notes_tags.test.js b/packages/snjs/mocha/sync_tests/notes_tags.test.js
index 8e234d588..db6f57e51 100644
--- a/packages/snjs/mocha/sync_tests/notes_tags.test.js
+++ b/packages/snjs/mocha/sync_tests/notes_tags.test.js
@@ -1,11 +1,12 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from '../lib/factory.js'
import { createRelatedNoteTagPairPayload } from '../lib/Items.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('notes + tags syncing', function () {
+ let application
+
const syncOptions = {
checkIntegrity: true,
awaitAll: true,
@@ -16,30 +17,31 @@ describe('notes + tags syncing', function () {
})
beforeEach(async function () {
- this.application = await Factory.createInitAppWithFakeCrypto()
- Factory.disableIntegrityAutoHeal(this.application)
+ application = await Factory.createInitAppWithFakeCrypto()
+ Factory.disableIntegrityAutoHeal(application)
const email = UuidGenerator.GenerateUuid()
const password = UuidGenerator.GenerateUuid()
await Factory.registerUserToApplication({
- application: this.application,
+ application: application,
email,
password,
})
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
+ application = undefined
})
it('syncing an item then downloading it should include items_key_id', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
- await this.application.payloads.resetState()
- await this.application.items.resetState()
- await this.application.sync.clearSyncPositionTokens()
- await this.application.sync.sync(syncOptions)
- const downloadedNote = this.application.items.getDisplayableNotes()[0]
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
+ await application.payloads.resetState()
+ await application.items.resetState()
+ await application.sync.clearSyncPositionTokens()
+ await application.sync.sync(syncOptions)
+ const downloadedNote = application.items.getDisplayableNotes()[0]
expect(downloadedNote.items_key_id).to.not.be.ok
// Allow time for waitingForKey
await Factory.sleep(0.1)
@@ -52,21 +54,21 @@ describe('notes + tags syncing', function () {
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- const note = this.application.items.getItems([ContentType.TYPES.Note])[0]
- const tag = this.application.items.getItems([ContentType.TYPES.Tag])[0]
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- expect(this.application.items.getDisplayableTags().length).to.equal(1)
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ const note = application.items.getItems([ContentType.TYPES.Note])[0]
+ const tag = application.items.getItems([ContentType.TYPES.Tag])[0]
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableTags().length).to.equal(1)
for (let i = 0; i < 9; i++) {
- await this.application.mutator.setItemsDirty([note, tag])
- await this.application.sync.sync(syncOptions)
- this.application.sync.clearSyncPositionTokens()
+ await application.mutator.setItemsDirty([note, tag])
+ await application.sync.sync(syncOptions)
+ application.sync.clearSyncPositionTokens()
expect(tag.content.references.length).to.equal(1)
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(1)
expect(tag.noteCount).to.equal(1)
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- expect(this.application.items.getDisplayableTags().length).to.equal(1)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableTags().length).to.equal(1)
console.warn('Waiting 0.1s...')
await Factory.sleep(0.1)
}
@@ -76,59 +78,59 @@ describe('notes + tags syncing', function () {
const pair = createRelatedNoteTagPairPayload()
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- const originalNote = this.application.items.getDisplayableNotes()[0]
- const originalTag = this.application.items.getDisplayableTags()[0]
- await this.application.mutator.setItemsDirty([originalNote, originalTag])
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ const originalNote = application.items.getDisplayableNotes()[0]
+ const originalTag = application.items.getDisplayableTags()[0]
+ await application.mutator.setItemsDirty([originalNote, originalTag])
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
expect(originalTag.content.references.length).to.equal(1)
expect(originalTag.noteCount).to.equal(1)
- expect(this.application.items.itemsReferencingItem(originalNote).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(originalNote).length).to.equal(1)
// when signing in, all local items are cleared from storage (but kept in memory; to clear desktop logs),
// then resaved with alternated uuids.
- await this.application.storage.clearAllPayloads()
- await this.application.sync.markAllItemsAsNeedingSyncAndPersist()
+ await application.storage.clearAllPayloads()
+ await application.sync.markAllItemsAsNeedingSyncAndPersist()
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- expect(this.application.items.getDisplayableTags().length).to.equal(1)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableTags().length).to.equal(1)
- const note = this.application.items.getDisplayableNotes()[0]
- const tag = this.application.items.getDisplayableTags()[0]
+ const note = application.items.getDisplayableNotes()[0]
+ const tag = application.items.getDisplayableTags()[0]
expect(tag.content.references.length).to.equal(1)
expect(note.content.references.length).to.equal(0)
expect(tag.noteCount).to.equal(1)
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(1)
+ expect(application.items.itemsReferencingItem(note).length).to.equal(1)
})
it('duplicating a tag should maintian its relationships', async function () {
const pair = createRelatedNoteTagPairPayload()
const notePayload = pair[0]
const tagPayload = pair[1]
- await this.application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
- let note = this.application.items.getDisplayableNotes()[0]
- let tag = this.application.items.getDisplayableTags()[0]
- expect(this.application.items.itemsReferencingItem(note).length).to.equal(1)
+ await application.mutator.emitItemsFromPayloads([notePayload, tagPayload], PayloadEmitSource.LocalChanged)
+ let note = application.items.getDisplayableNotes()[0]
+ let tag = application.items.getDisplayableTags()[0]
+ expect(application.items.itemsReferencingItem(note).length).to.equal(1)
- await this.application.mutator.setItemsDirty([note, tag])
- await this.application.sync.sync(syncOptions)
- await this.application.sync.clearSyncPositionTokens()
+ await application.mutator.setItemsDirty([note, tag])
+ await application.sync.sync(syncOptions)
+ await application.sync.clearSyncPositionTokens()
- note = this.application.items.findItem(note.uuid)
- tag = this.application.items.findItem(tag.uuid)
+ note = application.items.findItem(note.uuid)
+ tag = application.items.findItem(tag.uuid)
expect(note.dirty).to.equal(false)
expect(tag.dirty).to.equal(false)
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- expect(this.application.items.getDisplayableTags().length).to.equal(1)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableTags().length).to.equal(1)
await Factory.changePayloadTimeStampAndSync(
- this.application,
+ application,
tag.payload,
Factory.dateToMicroseconds(Factory.yesterday()),
{
@@ -137,13 +139,13 @@ describe('notes + tags syncing', function () {
syncOptions,
)
- tag = this.application.items.findItem(tag.uuid)
+ tag = application.items.findItem(tag.uuid)
// tag should now be conflicted and a copy created
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- expect(this.application.items.getDisplayableTags().length).to.equal(2)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableTags().length).to.equal(2)
- const tags = this.application.items.getDisplayableTags()
+ const tags = application.items.getDisplayableTags()
const conflictedTag = tags.find((tag) => {
return !!tag.content.conflict_of
})
@@ -157,11 +159,11 @@ describe('notes + tags syncing', function () {
expect(conflictedTag.content.conflict_of).to.equal(originalTag.uuid)
expect(conflictedTag.noteCount).to.equal(originalTag.noteCount)
- expect(this.application.items.itemsReferencingItem(conflictedTag).length).to.equal(0)
- expect(this.application.items.itemsReferencingItem(originalTag).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(conflictedTag).length).to.equal(0)
+ expect(application.items.itemsReferencingItem(originalTag).length).to.equal(0)
// Two tags now link to this note
- const referencingItems = this.application.items.itemsReferencingItem(note)
+ const referencingItems = application.items.itemsReferencingItem(note)
expect(referencingItems.length).to.equal(2)
expect(referencingItems[0]).to.not.equal(referencingItems[1])
}).timeout(10000)
diff --git a/packages/snjs/mocha/sync_tests/offline.test.js b/packages/snjs/mocha/sync_tests/offline.test.js
index 6456f13a5..c236f0c3e 100644
--- a/packages/snjs/mocha/sync_tests/offline.test.js
+++ b/packages/snjs/mocha/sync_tests/offline.test.js
@@ -1,71 +1,70 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('offline syncing', () => {
+ let context
+ let application
+ let expectedItemCount
+
const syncOptions = {
checkIntegrity: true,
awaitAll: true,
}
beforeEach(async function () {
- this.expectedItemCount = BaseItemCounts.DefaultItems
- this.context = await Factory.createAppContext()
- await this.context.launch()
- this.application = this.context.application
+ localStorage.clear()
+ expectedItemCount = BaseItemCounts.DefaultItems
+ context = await Factory.createAppContext()
+ await context.launch()
+ application = context.application
})
afterEach(async function () {
- expect(this.application.sync.isOutOfSync()).to.equal(false)
- await Factory.safeDeinit(this.application)
- })
-
- before(async function () {
- localStorage.clear()
- })
-
- after(async function () {
+ expect(application.sync.isOutOfSync()).to.equal(false)
+ await Factory.safeDeinit(application)
localStorage.clear()
+ application = undefined
+ context = undefined
})
it('uuid alternation should delete original payload', async function () {
- const note = await Factory.createMappedNote(this.application)
- this.expectedItemCount++
+ const note = await Factory.createMappedNote(application)
+ expectedItemCount++
- await Factory.alternateUuidForItem(this.application, note.uuid)
- await this.application.sync.sync(syncOptions)
+ await Factory.alternateUuidForItem(application, note.uuid)
+ await application.sync.sync(syncOptions)
- const notes = this.application.items.getDisplayableNotes()
+ const notes = application.items.getDisplayableNotes()
expect(notes.length).to.equal(1)
expect(notes[0].uuid).to.not.equal(note.uuid)
- const items = this.application.items.allTrackedItems()
- expect(items.length).to.equal(this.expectedItemCount)
+ const items = application.items.allTrackedItems()
+ expect(items.length).to.equal(expectedItemCount)
})
it('should sync item with no passcode', async function () {
- let note = await Factory.createMappedNote(this.application)
- expect(Uuids(this.application.items.getDirtyItems()).includes(note.uuid))
+ let note = await Factory.createMappedNote(application)
+ expect(Uuids(application.items.getDirtyItems()).includes(note.uuid))
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
/** In rare cases a sync can complete so fast that the dates are equal; this is ok. */
expect(note.lastSyncEnd).to.be.at.least(note.lastSyncBegan)
- this.expectedItemCount++
+ expectedItemCount++
- expect(this.application.items.getDirtyItems().length).to.equal(0)
+ expect(application.items.getDirtyItems().length).to.equal(0)
- const rawPayloads2 = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads2.length).to.equal(this.expectedItemCount)
+ const rawPayloads2 = await application.storage.getAllRawPayloads()
+ expect(rawPayloads2.length).to.equal(expectedItemCount)
- const itemsKeyRaw = (await Factory.getStoragePayloadsOfType(this.application, ContentType.TYPES.ItemsKey))[0]
- const noteRaw = (await Factory.getStoragePayloadsOfType(this.application, ContentType.TYPES.Note))[0]
+ const itemsKeyRaw = (await Factory.getStoragePayloadsOfType(application, ContentType.TYPES.ItemsKey))[0]
+ const noteRaw = (await Factory.getStoragePayloadsOfType(application, ContentType.TYPES.Note))[0]
/** Encrypts with default items key */
expect(typeof noteRaw.content).to.equal('string')
@@ -75,30 +74,30 @@ describe('offline syncing', () => {
})
it('should sync item encrypted with passcode', async function () {
- await this.application.addPasscode('foobar')
- await Factory.createMappedNote(this.application)
- expect(this.application.items.getDirtyItems().length).to.equal(1)
- const rawPayloads1 = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads1.length).to.equal(this.expectedItemCount)
+ await application.addPasscode('foobar')
+ await Factory.createMappedNote(application)
+ expect(application.items.getDirtyItems().length).to.equal(1)
+ const rawPayloads1 = await application.storage.getAllRawPayloads()
+ expect(rawPayloads1.length).to.equal(expectedItemCount)
- await this.application.sync.sync(syncOptions)
- this.expectedItemCount++
+ await application.sync.sync(syncOptions)
+ expectedItemCount++
- expect(this.application.items.getDirtyItems().length).to.equal(0)
- const rawPayloads2 = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads2.length).to.equal(this.expectedItemCount)
+ expect(application.items.getDirtyItems().length).to.equal(0)
+ const rawPayloads2 = await application.storage.getAllRawPayloads()
+ expect(rawPayloads2.length).to.equal(expectedItemCount)
const payload = rawPayloads2[0]
expect(typeof payload.content).to.equal('string')
- expect(payload.content.startsWith(this.application.encryption.getLatestVersion())).to.equal(true)
+ expect(payload.content.startsWith(application.encryption.getLatestVersion())).to.equal(true)
})
it('signing out while offline should succeed', async function () {
- await Factory.createMappedNote(this.application)
- this.expectedItemCount++
- await this.application.sync.sync(syncOptions)
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- expect(this.application.sessions.isSignedIn()).to.equal(false)
- expect(this.application.sessions.getUser()).to.not.be.ok
+ await Factory.createMappedNote(application)
+ expectedItemCount++
+ await application.sync.sync(syncOptions)
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ expect(application.sessions.isSignedIn()).to.equal(false)
+ expect(application.sessions.getUser()).to.not.be.ok
})
})
diff --git a/packages/snjs/mocha/sync_tests/online.test.js b/packages/snjs/mocha/sync_tests/online.test.js
index ff7d8220b..2dd6c639e 100644
--- a/packages/snjs/mocha/sync_tests/online.test.js
+++ b/packages/snjs/mocha/sync_tests/online.test.js
@@ -1,13 +1,19 @@
-/* eslint-disable no-undef */
import { BaseItemCounts } from '../lib/BaseItemCounts.js'
import * as Factory from '../lib/factory.js'
import * as Utils from '../lib/Utils.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('online syncing', function () {
this.timeout(Factory.TenSecondTimeout)
+ let application
+ let email
+ let password
+ let expectedItemCount
+ let context
+
const syncOptions = {
checkIntegrity: true,
awaitAll: true,
@@ -15,42 +21,37 @@ describe('online syncing', function () {
beforeEach(async function () {
localStorage.clear()
- this.expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
+ expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
- this.context = await Factory.createAppContext()
- await this.context.launch()
+ context = await Factory.createAppContext()
+ await context.launch()
- this.application = this.context.application
- this.email = this.context.email
- this.password = this.context.password
+ application = context.application
+ email = context.email
+ password = context.password
- Factory.disableIntegrityAutoHeal(this.application)
+ Factory.disableIntegrityAutoHeal(application)
await Factory.registerUserToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
-
- this.signOut = async () => {
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- }
-
- this.signIn = async () => {
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
- }
})
afterEach(async function () {
- expect(this.application.sync.isOutOfSync()).to.equal(false)
+ expect(application.sync.isOutOfSync()).to.equal(false)
- const items = this.application.items.allTrackedItems()
- expect(items.length).to.equal(this.expectedItemCount)
+ const items = application.items.allTrackedItems()
+ expect(items.length).to.equal(expectedItemCount)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
- await Factory.safeDeinit(this.application)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
+ await Factory.safeDeinit(application)
localStorage.clear()
+
+ application = undefined
+ context = undefined
})
function noteObjectsFromObjects(items) {
@@ -58,13 +59,13 @@ describe('online syncing', function () {
}
it('should register and sync basic model online', async function () {
- let note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
- expect(this.application.items.getDirtyItems().length).to.equal(0)
- note = this.application.items.findItem(note.uuid)
+ let note = await Factory.createSyncedNote(application)
+ expectedItemCount++
+ expect(application.items.getDirtyItems().length).to.equal(0)
+ note = application.items.findItem(note.uuid)
expect(note.dirty).to.not.be.ok
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ const rawPayloads = await application.storage.getAllRawPayloads()
const notePayloads = noteObjectsFromObjects(rawPayloads)
expect(notePayloads.length).to.equal(1)
for (const rawNote of notePayloads) {
@@ -73,17 +74,17 @@ describe('online syncing', function () {
})
it('should login and retrieve synced item', async function () {
- const note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ const note = await Factory.createSyncedNote(application)
+ expectedItemCount++
+ application = await Factory.signOutApplicationAndReturnNew(application)
await Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- const notes = this.application.items.getDisplayableNotes()
+ const notes = application.items.getDisplayableNotes()
expect(notes.length).to.equal(1)
expect(notes[0].title).to.equal(note.title)
})
@@ -91,27 +92,27 @@ describe('online syncing', function () {
it('can complete multipage sync on sign in', async function () {
const count = 0
- await Factory.createManyMappedNotes(this.application, count)
+ await Factory.createManyMappedNotes(application, count)
- this.expectedItemCount += count
+ expectedItemCount += count
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
- this.application = await this.context.signout()
+ application = await context.signout()
- expect(this.application.items.items.length).to.equal(BaseItemCounts.DefaultItems)
+ expect(application.items.items.length).to.equal(BaseItemCounts.DefaultItems)
const promise = Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
/** Throw in some random syncs to cause trouble */
const syncCount = 30
for (let i = 0; i < syncCount; i++) {
- this.application.sync.sync(syncOptions)
+ application.sync.sync(syncOptions)
await Factory.sleep(0.01)
}
await promise
@@ -122,17 +123,17 @@ describe('online syncing', function () {
}).timeout(20000)
it('having offline data then signing in should not alternate uuid and merge with account', async function () {
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- const note = await Factory.createMappedNote(this.application)
- this.expectedItemCount++
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ const note = await Factory.createMappedNote(application)
+ expectedItemCount++
await Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
mergeLocal: true,
})
- const notes = this.application.items.getDisplayableNotes()
+ const notes = application.items.getDisplayableNotes()
expect(notes.length).to.equal(1)
/** uuid should have been alternated */
expect(notes[0].uuid).to.equal(note.uuid)
@@ -143,8 +144,8 @@ describe('online syncing', function () {
let successes = 0
let events = 0
- this.application.sync.ut_beginLatencySimulator(250)
- this.application.sync.addEventObserver((event, data) => {
+ application.sync.ut_beginLatencySimulator(250)
+ application.sync.addEventObserver((event, data) => {
if (event === SyncEvent.SyncCompletedWithAllItemsUploaded) {
events++
}
@@ -153,7 +154,7 @@ describe('online syncing', function () {
const promises = []
for (let i = 0; i < syncCount; i++) {
promises.push(
- this.application.sync
+ application.sync
.sync({
queueStrategy: SyncQueueStrategy.ResolveOnNext,
})
@@ -169,7 +170,7 @@ describe('online syncing', function () {
// We don't know how many will execute above.
expect(events).to.be.at.least(1)
- this.application.sync.ut_endLatencySimulator()
+ application.sync.ut_endLatencySimulator()
// Since the syncs all happen after one another, extra syncs may be queued on that we are not awaiting.
await Factory.sleep(0.5)
})
@@ -179,9 +180,9 @@ describe('online syncing', function () {
let successes = 0
let events = 0
- this.application.sync.ut_beginLatencySimulator(250)
+ application.sync.ut_beginLatencySimulator(250)
- this.application.sync.addEventObserver((event, data) => {
+ application.sync.addEventObserver((event, data) => {
if (event === SyncEvent.SyncCompletedWithAllItemsUploaded) {
events++
}
@@ -190,7 +191,7 @@ describe('online syncing', function () {
const promises = []
for (let i = 0; i < syncCount; i++) {
promises.push(
- this.application.sync
+ application.sync
.sync({
queueStrategy: SyncQueueStrategy.ForceSpawnNew,
})
@@ -202,18 +203,18 @@ describe('online syncing', function () {
await Promise.all(promises)
expect(successes).to.equal(syncCount)
expect(events).to.equal(syncCount)
- this.application.sync.ut_endLatencySimulator()
+ application.sync.ut_endLatencySimulator()
})
it('retrieving new items should not mark them as dirty', async function () {
- const originalNote = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
+ const originalNote = await Factory.createSyncedNote(application)
+ expectedItemCount++
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
+ application = await Factory.signOutApplicationAndReturnNew(application)
const promise = new Promise((resolve) => {
- this.application.sync.addEventObserver(async (event) => {
+ application.sync.addEventObserver(async (event) => {
if (event === SyncEvent.PaginatedSyncRequestCompleted) {
- const note = this.application.items.findItem(originalNote.uuid)
+ const note = application.items.findItem(originalNote.uuid)
if (note) {
expect(note.dirty).to.not.be.ok
resolve()
@@ -221,45 +222,45 @@ describe('online syncing', function () {
}
})
})
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
+ await application.signIn(email, password, undefined, undefined, undefined, true)
await promise
})
it('allows saving of data after sign out', async function () {
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
- const note = await Factory.createMappedNote(this.application)
- this.expectedItemCount++
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
+ const note = await Factory.createMappedNote(application)
+ expectedItemCount++
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
+ const rawPayloads = await application.storage.getAllRawPayloads()
const notePayload = noteObjectsFromObjects(rawPayloads)
expect(notePayload.length).to.equal(1)
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
// set item to be merged for when sign in occurs
- await this.application.sync.markAllItemsAsNeedingSyncAndPersist()
- expect(this.application.sync.isOutOfSync()).to.equal(false)
- expect(this.application.items.getDirtyItems().length).to.equal(BaseItemCounts.DefaultItems + 1)
+ await application.sync.markAllItemsAsNeedingSyncAndPersist()
+ expect(application.sync.isOutOfSync()).to.equal(false)
+ expect(application.items.getDirtyItems().length).to.equal(BaseItemCounts.DefaultItems + 1)
// Sign back in for next tests
await Factory.loginToApplication({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
})
- expect(this.application.items.getDirtyItems().length).to.equal(0)
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
- expect(this.application.sync.isOutOfSync()).to.equal(false)
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.items.getDirtyItems().length).to.equal(0)
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
+ expect(application.sync.isOutOfSync()).to.equal(false)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
- for (const item of this.application.items.getDisplayableNotes()) {
+ for (const item of application.items.getDisplayableNotes()) {
expect(item.content.title).to.be.ok
}
- const updatedRawPayloads = await this.application.storage.getAllRawPayloads()
+ const updatedRawPayloads = await application.storage.getAllRawPayloads()
for (const payload of updatedRawPayloads) {
// if an item comes back from the server, it is saved to disk immediately without a dirty value.
expect(payload.dirty).to.not.be.ok
@@ -267,17 +268,17 @@ describe('online syncing', function () {
})
it('mapping should not mutate items with error decrypting state', async function () {
- const note = await Factory.createMappedNote(this.application)
+ const note = await Factory.createMappedNote(application)
- this.expectedItemCount++
+ expectedItemCount++
const originalTitle = note.content.title
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
const encrypted = CreateEncryptedServerSyncPushPayload(
- await this.application.encryption.encryptSplitSingle({
+ await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [note.payloadRepresentation()],
},
@@ -289,19 +290,19 @@ describe('online syncing', function () {
errorDecrypting: true,
})
- const items = await this.application.mutator.emitItemsFromPayloads([errorred], PayloadEmitSource.LocalChanged)
+ const items = await application.mutator.emitItemsFromPayloads([errorred], PayloadEmitSource.LocalChanged)
- const mappedItem = this.application.items.findAnyItem(errorred.uuid)
+ const mappedItem = application.items.findAnyItem(errorred.uuid)
expect(typeof mappedItem.content).to.equal('string')
- const decryptedPayload = await this.application.encryption.decryptSplitSingle({
+ const decryptedPayload = await application.encryption.decryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [errorred],
},
})
- const mappedItems2 = await this.application.mutator.emitItemsFromPayloads(
+ const mappedItems2 = await application.mutator.emitItemsFromPayloads(
[decryptedPayload],
PayloadEmitSource.LocalChanged,
)
@@ -312,135 +313,135 @@ describe('online syncing', function () {
})
it('signing into account with pre-existing items', async function () {
- const note = await Factory.createMappedNote(this.application)
- await Factory.markDirtyAndSyncItem(this.application, note)
- this.expectedItemCount += 1
+ const note = await Factory.createMappedNote(application)
+ await Factory.markDirtyAndSyncItem(application, note)
+ expectedItemCount += 1
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ await application.signIn(email, password, undefined, undefined, undefined, true)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
it('removes item from storage upon deletion', async function () {
- let note = await Factory.createMappedNote(this.application)
- this.expectedItemCount++
+ let note = await Factory.createMappedNote(application)
+ expectedItemCount++
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
expect(note.dirty).to.equal(false)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
- await this.application.mutator.setItemToBeDeleted(note)
- note = this.application.items.findAnyItem(note.uuid)
+ await application.mutator.setItemToBeDeleted(note)
+ note = application.items.findAnyItem(note.uuid)
expect(note.dirty).to.equal(true)
- this.expectedItemCount--
+ expectedItemCount--
- await this.application.sync.sync(syncOptions)
- note = this.application.items.findItem(note.uuid)
+ await application.sync.sync(syncOptions)
+ note = application.items.findItem(note.uuid)
expect(note).to.not.be.ok
// We expect that this item is now gone for good, and no duplicate has been created.
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
await Factory.sleep(0.5)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
})
it('retrieving item with no content should correctly map local state', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
- const syncToken = await this.application.sync.getLastSyncToken()
+ const syncToken = await application.sync.getLastSyncToken()
- this.expectedItemCount++
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expectedItemCount++
+ expect(application.items.items.length).to.equal(expectedItemCount)
// client A
- await this.application.mutator.setItemToBeDeleted(note)
- await this.application.sync.sync(syncOptions)
+ await application.mutator.setItemToBeDeleted(note)
+ await application.sync.sync(syncOptions)
// Subtract 1
- this.expectedItemCount--
+ expectedItemCount--
// client B
// Clearing sync tokens wont work as server wont return deleted items.
// Set saved sync token instead
- await this.application.sync.setLastSyncToken(syncToken)
- await this.application.sync.sync(syncOptions)
+ await application.sync.setLastSyncToken(syncToken)
+ await application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
it('changing an item while it is being synced should sync again', async function () {
- const note = await Factory.createMappedNote(this.application)
+ const note = await Factory.createMappedNote(application)
- this.expectedItemCount++
+ expectedItemCount++
/** Begin syncing it with server but introduce latency so we can sneak in a delete */
- this.application.sync.ut_beginLatencySimulator(500)
+ application.sync.ut_beginLatencySimulator(500)
- const sync = this.application.sync.sync()
+ const sync = application.sync.sync()
/** Sleep so sync call can begin preparations but not fully begin */
await Factory.sleep(0.1)
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.title = 'latest title'
})
await sync
- this.application.sync.ut_endLatencySimulator()
+ application.sync.ut_endLatencySimulator()
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
- const latestNote = this.application.items.findItem(note.uuid)
+ const latestNote = application.items.findItem(note.uuid)
expect(latestNote.title).to.equal('latest title')
})
it('deleting an item while it is being synced should keep deletion state', async function () {
- const note = await Factory.createMappedNote(this.application)
+ const note = await Factory.createMappedNote(application)
- this.expectedItemCount++
+ expectedItemCount++
/** Begin syncing it with server but introduce latency so we can sneak in a delete */
- this.application.sync.ut_beginLatencySimulator(500)
+ application.sync.ut_beginLatencySimulator(500)
- const sync = this.application.sync.sync()
+ const sync = application.sync.sync()
/** Sleep so sync call can begin preparations but not fully begin */
await Factory.sleep(0.1)
- await this.application.mutator.setItemToBeDeleted(note)
+ await application.mutator.setItemToBeDeleted(note)
- this.expectedItemCount--
+ expectedItemCount--
await sync
- this.application.sync.ut_endLatencySimulator()
+ application.sync.ut_endLatencySimulator()
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
/** We expect that item has been deleted */
- const allItems = this.application.items.items
- expect(allItems.length).to.equal(this.expectedItemCount)
+ const allItems = application.items.items
+ expect(allItems.length).to.equal(expectedItemCount)
})
it('items that are never synced and deleted should not be uploaded to server', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- await this.application.mutator.setItemToBeDeleted(note)
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ await application.mutator.setItemToBeDeleted(note)
let success = true
let didCompleteRelevantSync = false
let beginCheckingResponse = false
- this.application.sync.addEventObserver((eventName, data) => {
+ application.sync.addEventObserver((eventName, data) => {
if (eventName === SyncEvent.DownloadFirstSyncCompleted) {
beginCheckingResponse = true
}
@@ -456,22 +457,22 @@ describe('online syncing', function () {
}
}
})
- await this.application.sync.sync({ mode: SyncMode.DownloadFirst })
+ await application.sync.sync({ mode: SyncMode.DownloadFirst })
expect(didCompleteRelevantSync).to.equal(true)
expect(success).to.equal(true)
})
it('items that are deleted after download first sync complete should not be uploaded to server', async function () {
/** The singleton manager may delete items are download first. We dont want those uploaded to server. */
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
let success = true
let didCompleteRelevantSync = false
let beginCheckingResponse = false
- this.application.sync.addEventObserver(async (eventName, data) => {
+ application.sync.addEventObserver(async (eventName, data) => {
if (eventName === SyncEvent.DownloadFirstSyncCompleted) {
- await this.application.mutator.setItemToBeDeleted(note)
+ await application.mutator.setItemToBeDeleted(note)
beginCheckingResponse = true
}
if (!beginCheckingResponse) {
@@ -486,26 +487,26 @@ describe('online syncing', function () {
}
}
})
- await this.application.sync.sync({ mode: SyncMode.DownloadFirst })
+ await application.sync.sync({ mode: SyncMode.DownloadFirst })
expect(didCompleteRelevantSync).to.equal(true)
expect(success).to.equal(true)
})
it('marking an item dirty then saving to disk should retain that dirty state when restored', async function () {
- const note = await Factory.createMappedNote(this.application)
+ const note = await Factory.createMappedNote(application)
- this.expectedItemCount++
+ expectedItemCount++
- await this.application.sync.markAllItemsAsNeedingSyncAndPersist()
+ await application.sync.markAllItemsAsNeedingSyncAndPersist()
- this.application.items.resetState()
- this.application.payloads.resetState()
+ application.items.resetState()
+ application.payloads.resetState()
- await this.application.sync.clearSyncPositionTokens()
+ await application.sync.clearSyncPositionTokens()
- expect(this.application.items.items.length).to.equal(0)
+ expect(application.items.items.length).to.equal(0)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ const rawPayloads = await application.storage.getAllRawPayloads()
const encryptedPayloads = rawPayloads.map((rawPayload) => {
return new EncryptedPayload(rawPayload)
@@ -515,92 +516,92 @@ describe('online syncing', function () {
const keyedSplit = CreateDecryptionSplitWithKeyLookup(encryptionSplit)
- const decryptionResults = await this.application.encryption.decryptSplit(keyedSplit)
+ const decryptionResults = await application.encryption.decryptSplit(keyedSplit)
- await this.application.mutator.emitItemsFromPayloads(decryptionResults, PayloadEmitSource.LocalChanged)
+ await application.mutator.emitItemsFromPayloads(decryptionResults, PayloadEmitSource.LocalChanged)
- expect(this.application.items.allTrackedItems().length).to.equal(this.expectedItemCount)
+ expect(application.items.allTrackedItems().length).to.equal(expectedItemCount)
- const foundNote = this.application.items.findAnyItem(note.uuid)
+ const foundNote = application.items.findAnyItem(note.uuid)
expect(foundNote.dirty).to.equal(true)
- await this.application.sync.sync(syncOptions)
+ await application.sync.sync(syncOptions)
})
/** This test takes 30s+ on a Docker server environment and should be skipped for now */
it.skip('should handle uploading with sync pagination', async function () {
const largeItemCount = SyncUpDownLimit + 10
for (let i = 0; i < largeItemCount; i++) {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
}
- this.expectedItemCount += largeItemCount
+ expectedItemCount += largeItemCount
- await this.application.sync.sync(syncOptions)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ await application.sync.sync(syncOptions)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
}).timeout(Factory.SixtySecondTimeout)
/** This test takes 30s+ on a Docker server environment and should be skipped for now */
it.skip('should handle downloading with sync pagination', async function () {
const largeItemCount = SyncUpDownLimit + 10
for (let i = 0; i < largeItemCount; i++) {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
}
/** Upload */
- this.application.sync.sync({ awaitAll: true, checkIntegrity: false })
- await this.context.awaitNextSucessfulSync()
- this.expectedItemCount += largeItemCount
+ application.sync.sync({ awaitAll: true, checkIntegrity: false })
+ await context.awaitNextSucessfulSync()
+ expectedItemCount += largeItemCount
/** Clear local data */
- await this.application.payloads.resetState()
- await this.application.items.resetState()
- await this.application.sync.clearSyncPositionTokens()
- await this.application.storage.clearAllPayloads()
- expect(this.application.items.items.length).to.equal(0)
+ await application.payloads.resetState()
+ await application.items.resetState()
+ await application.sync.clearSyncPositionTokens()
+ await application.storage.clearAllPayloads()
+ expect(application.items.items.length).to.equal(0)
/** Download all data */
- this.application.sync.sync(syncOptions)
- await this.context.awaitNextSucessfulSync()
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ application.sync.sync(syncOptions)
+ await context.awaitNextSucessfulSync()
+ expect(application.items.items.length).to.equal(expectedItemCount)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
}).timeout(Factory.SixtySecondTimeout)
it('syncing an item should storage it encrypted', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- await this.application.sync.sync(syncOptions)
- this.expectedItemCount++
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ await application.sync.sync(syncOptions)
+ expectedItemCount++
+ const rawPayloads = await application.storage.getAllRawPayloads()
const notePayload = rawPayloads.find((p) => p.content_type === ContentType.TYPES.Note)
expect(typeof notePayload.content).to.equal('string')
})
it('syncing an item before data load should storage it encrypted', async function () {
- const note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- this.expectedItemCount++
+ const note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ expectedItemCount++
/** Simulate database not loaded */
- await this.application.sync.clearSyncPositionTokens()
- this.application.sync.ut_setDatabaseLoaded(false)
- this.application.sync.sync(syncOptions)
+ await application.sync.clearSyncPositionTokens()
+ application.sync.ut_setDatabaseLoaded(false)
+ application.sync.sync(syncOptions)
await Factory.sleep(0.3)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ const rawPayloads = await application.storage.getAllRawPayloads()
const notePayload = rawPayloads.find((p) => p.content_type === ContentType.TYPES.Note)
expect(typeof notePayload.content).to.equal('string')
})
it('saving an item after sync should persist it with content property', async function () {
- const note = await Factory.createMappedNote(this.application)
+ const note = await Factory.createMappedNote(application)
const text = Factory.randomString(10000)
- await this.application.changeAndSaveItem.execute(
+ await application.changeAndSaveItem.execute(
note,
(mutator) => {
mutator.text = text
@@ -609,52 +610,52 @@ describe('online syncing', function () {
undefined,
syncOptions,
)
- this.expectedItemCount++
- const rawPayloads = await this.application.storage.getAllRawPayloads()
+ expectedItemCount++
+ const rawPayloads = await application.storage.getAllRawPayloads()
const notePayload = rawPayloads.find((p) => p.content_type === ContentType.TYPES.Note)
expect(typeof notePayload.content).to.equal('string')
expect(notePayload.content.length).to.be.above(text.length)
})
it('syncing a new item before local data has loaded should still persist the item to disk', async function () {
- this.application.sync.ut_setDatabaseLoaded(false)
+ application.sync.ut_setDatabaseLoaded(false)
/** You don't want to clear model manager state as we'll lose encrypting items key */
- // await this.application.payloads.resetState();
- await this.application.sync.clearSyncPositionTokens()
- expect(this.application.items.getDirtyItems().length).to.equal(0)
+ // await application.payloads.resetState();
+ await application.sync.clearSyncPositionTokens()
+ expect(application.items.getDirtyItems().length).to.equal(0)
- let note = await Factory.createMappedNote(this.application)
- note = await this.application.mutator.changeItem(note, (mutator) => {
+ let note = await Factory.createMappedNote(application)
+ note = await application.mutator.changeItem(note, (mutator) => {
mutator.text = `${Math.random()}`
})
/** This sync request should exit prematurely as we called ut_setDatabaseNotLoaded */
/** Do not await. Sleep instead. */
- this.application.sync.sync(syncOptions)
+ application.sync.sync(syncOptions)
await Factory.sleep(0.3)
- this.expectedItemCount++
+ expectedItemCount++
/** Item should still be dirty */
expect(note.dirty).to.equal(true)
- expect(this.application.items.getDirtyItems().length).to.equal(1)
+ expect(application.items.getDirtyItems().length).to.equal(1)
- const rawPayloads = await this.application.storage.getAllRawPayloads()
- expect(rawPayloads.length).to.equal(this.expectedItemCount)
+ const rawPayloads = await application.storage.getAllRawPayloads()
+ expect(rawPayloads.length).to.equal(expectedItemCount)
const rawPayload = rawPayloads.find((p) => p.uuid === note.uuid)
expect(rawPayload.uuid).to.equal(note.uuid)
expect(rawPayload.dirty).equal(true)
expect(typeof rawPayload.content).to.equal('string')
/** Clear state data and upload item from storage to server */
- await this.application.sync.clearSyncPositionTokens()
- await this.application.payloads.resetState()
- await this.application.items.resetState()
- await this.application.sync.loadDatabasePayloads()
- await this.application.sync.sync(syncOptions)
+ await application.sync.clearSyncPositionTokens()
+ await application.payloads.resetState()
+ await application.items.resetState()
+ await application.sync.loadDatabasePayloads()
+ await application.sync.sync(syncOptions)
- const newRawPayloads = await this.application.storage.getAllRawPayloads()
- expect(newRawPayloads.length).to.equal(this.expectedItemCount)
+ const newRawPayloads = await application.storage.getAllRawPayloads()
+ expect(newRawPayloads.length).to.equal(expectedItemCount)
- const currentItem = this.application.items.findItem(note.uuid)
+ const currentItem = application.items.findItem(note.uuid)
expect(currentItem.content.text).to.equal(note.content.text)
expect(currentItem.text).to.equal(note.text)
expect(currentItem.dirty).to.not.be.ok
@@ -678,38 +679,38 @@ describe('online syncing', function () {
it('should sign in and retrieve large number of items', async function () {
const largeItemCount = 50
- await Factory.createManyMappedNotes(this.application, largeItemCount)
- this.expectedItemCount += largeItemCount
- await this.application.sync.sync(syncOptions)
+ await Factory.createManyMappedNotes(application, largeItemCount)
+ expectedItemCount += largeItemCount
+ await application.sync.sync(syncOptions)
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ await application.signIn(email, password, undefined, undefined, undefined, true)
- this.application.sync.ut_setDatabaseLoaded(false)
- await this.application.sync.loadDatabasePayloads()
- await this.application.sync.sync(syncOptions)
+ application.sync.ut_setDatabaseLoaded(false)
+ await application.sync.loadDatabasePayloads()
+ await application.sync.sync(syncOptions)
- const items = await this.application.items.items
- expect(items.length).to.equal(this.expectedItemCount)
+ const items = await application.items.items
+ expect(items.length).to.equal(expectedItemCount)
}).timeout(20000)
it('valid sync date tracking', async function () {
- let note = await Factory.createMappedNote(this.application)
- note = await this.application.mutator.setItemDirty(note)
- this.expectedItemCount++
+ let note = await Factory.createMappedNote(application)
+ note = await application.mutator.setItemDirty(note)
+ expectedItemCount++
expect(note.dirty).to.equal(true)
expect(note.payload.dirtyIndex).to.be.at.most(getCurrentDirtyIndex())
- note = await this.application.mutator.changeItem(note, (mutator) => {
+ note = await application.mutator.changeItem(note, (mutator) => {
mutator.text = `${Math.random()}`
})
- const sync = this.application.sync.sync(syncOptions)
+ const sync = application.sync.sync(syncOptions)
await Factory.sleep(0.1)
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
expect(note.lastSyncBegan).to.be.below(new Date())
await sync
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
expect(note.dirty).to.equal(false)
expect(note.lastSyncEnd).to.be.at.least(note.lastSyncBegan)
})
@@ -717,13 +718,13 @@ describe('online syncing', function () {
it('syncing twice without waiting should only execute 1 online sync', async function () {
const expectedEvents = 1
let actualEvents = 0
- this.application.sync.addEventObserver((event, data) => {
+ application.sync.addEventObserver((event, data) => {
if (event === SyncEvent.SyncCompletedWithAllItemsUploaded && data.source === SyncSource.External) {
actualEvents++
}
})
- const first = this.application.sync.sync()
- const second = this.application.sync.sync()
+ const first = application.sync.sync()
+ const second = application.sync.sync()
await Promise.all([first, second])
/** Sleep so that any automatic syncs that are triggered are also sent to handler above */
await Factory.sleep(0.5)
@@ -737,47 +738,47 @@ describe('online syncing', function () {
* When that completes, it will decide whether an item is still dirty or not.
* It will do based on comparing whether item.dirtyIndex > item.globalDirtyIndexAtLastSync
*/
- let note = await Factory.createMappedNote(this.application)
- await this.application.mutator.setItemDirty(note)
- this.expectedItemCount++
+ let note = await Factory.createMappedNote(application)
+ await application.mutator.setItemDirty(note)
+ expectedItemCount++
// client A. Don't await, we want to do other stuff.
- this.application.sync.ut_beginLatencySimulator(1500)
- const slowSync = this.application.sync.sync(syncOptions)
+ application.sync.ut_beginLatencySimulator(1500)
+ const slowSync = application.sync.sync(syncOptions)
await Factory.sleep(0.1)
expect(note.dirty).to.equal(true)
// While that sync is going on, we want to modify this item many times.
const text = `${Math.random()}`
- note = await this.application.mutator.changeItem(note, (mutator) => {
+ note = await application.mutator.changeItem(note, (mutator) => {
mutator.text = text
})
- await this.application.mutator.setItemDirty(note)
- await this.application.mutator.setItemDirty(note)
- await this.application.mutator.setItemDirty(note)
+ await application.mutator.setItemDirty(note)
+ await application.mutator.setItemDirty(note)
+ await application.mutator.setItemDirty(note)
expect(note.payload.dirtyIndex).to.be.above(note.payload.globalDirtyIndexAtLastSync)
// Now do a regular sync with no latency.
- this.application.sync.ut_endLatencySimulator()
- const midSync = this.application.sync.sync(syncOptions)
+ application.sync.ut_endLatencySimulator()
+ const midSync = application.sync.sync(syncOptions)
await slowSync
await midSync
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
expect(note.dirty).to.equal(false)
expect(note.lastSyncEnd).to.be.above(note.lastSyncBegan)
expect(note.content.text).to.equal(text)
// client B
- await this.application.payloads.resetState()
- await this.application.items.resetState()
- await this.application.sync.clearSyncPositionTokens()
- await this.application.sync.sync(syncOptions)
+ await application.payloads.resetState()
+ await application.items.resetState()
+ await application.sync.clearSyncPositionTokens()
+ await application.sync.sync(syncOptions)
// Expect that the server value and client value match, and no conflicts are created.
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
- const foundItem = this.application.items.findItem(note.uuid)
+ expect(application.items.items.length).to.equal(expectedItemCount)
+ const foundItem = application.items.findItem(note.uuid)
expect(foundItem.content.text).to.equal(text)
expect(foundItem.text).to.equal(text)
})
@@ -788,26 +789,26 @@ describe('online syncing', function () {
let actualSaveCount = 0
/** Create an item and sync it */
- let note = await Factory.createMappedNote(this.application)
+ let note = await Factory.createMappedNote(application)
- this.application.items.addObserver(ContentType.TYPES.Note, ({ source }) => {
+ application.items.addObserver(ContentType.TYPES.Note, ({ source }) => {
if (source === PayloadEmitSource.RemoteSaved) {
actualSaveCount++
}
})
- this.expectedItemCount++
- this.application.sync.ut_beginLatencySimulator(150)
+ expectedItemCount++
+ application.sync.ut_beginLatencySimulator(150)
/** Dont await */
- const syncRequest = this.application.sync.sync(syncOptions)
+ const syncRequest = application.sync.sync(syncOptions)
/** Dirty the item 100ms into 150ms request */
const newText = `${Math.random()}`
setTimeout(
async function () {
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.text = newText
})
}.bind(this),
@@ -820,7 +821,7 @@ describe('online syncing', function () {
*/
await syncRequest
expect(actualSaveCount).to.equal(expectedSaveCount)
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
expect(note.text).to.equal(newText)
})
@@ -835,26 +836,26 @@ describe('online syncing', function () {
let actualSaveCount = 0
/** Create an item and sync it */
- let note = await Factory.createMappedNote(this.application)
+ let note = await Factory.createMappedNote(application)
- this.application.items.addObserver(ContentType.TYPES.Note, ({ source }) => {
+ application.items.addObserver(ContentType.TYPES.Note, ({ source }) => {
if (source === PayloadEmitSource.RemoteSaved) {
actualSaveCount++
}
})
- this.expectedItemCount++
+ expectedItemCount++
/** Dont await */
- const syncRequest = this.application.sync.sync(syncOptions)
+ const syncRequest = application.sync.sync(syncOptions)
/** Dirty the item before lastSyncBegan is set */
let didPerformMutatation = false
const newText = `${Math.random()}`
- this.application.sync.addEventObserver(async (eventName) => {
+ application.sync.addEventObserver(async (eventName) => {
if (eventName === SyncEvent.SyncDidBeginProcessing && !didPerformMutatation) {
didPerformMutatation = true
- await this.application.mutator.changeItem(note, (mutator) => {
+ await application.mutator.changeItem(note, (mutator) => {
mutator.text = newText
})
}
@@ -863,7 +864,7 @@ describe('online syncing', function () {
await syncRequest
expect(actualSaveCount).to.equal(expectedSaveCount)
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
expect(note.text).to.equal(newText)
})
@@ -872,11 +873,11 @@ describe('online syncing', function () {
let actualSaveCount = 0
/** Create an item and sync it */
- let note = await Factory.createMappedNote(this.application)
+ let note = await Factory.createMappedNote(application)
let didPerformMutatation = false
const newText = `${Math.random()}`
- this.application.items.addObserver(ContentType.TYPES.Note, async ({ changed, source }) => {
+ application.items.addObserver(ContentType.TYPES.Note, async ({ changed, source }) => {
if (source === PayloadEmitSource.RemoteSaved) {
actualSaveCount++
} else if (source === PayloadEmitSource.PreSyncSave && !didPerformMutatation) {
@@ -888,37 +889,37 @@ describe('online syncing', function () {
dirtyIndex: changed[0].payload.globalDirtyIndexAtLastSync + 1,
})
- await this.application.mutator.emitItemFromPayload(mutated)
+ await application.mutator.emitItemFromPayload(mutated)
}
})
- this.expectedItemCount++
+ expectedItemCount++
/** Dont await */
- const syncRequest = this.application.sync.sync(syncOptions)
+ const syncRequest = application.sync.sync(syncOptions)
await syncRequest
expect(actualSaveCount).to.equal(expectedSaveCount)
- note = this.application.items.findItem(note.uuid)
+ note = application.items.findItem(note.uuid)
expect(note.text).to.equal(newText)
})
it('retreiving a remote deleted item should succeed', async function () {
- const note = await Factory.createSyncedNote(this.application)
- const preDeleteSyncToken = await this.application.sync.getLastSyncToken()
- await this.application.mutator.deleteItem(note)
- await this.application.sync.sync()
- await this.application.sync.setLastSyncToken(preDeleteSyncToken)
- await this.application.sync.sync(syncOptions)
- expect(this.application.items.items.length).to.equal(this.expectedItemCount)
+ const note = await Factory.createSyncedNote(application)
+ const preDeleteSyncToken = await application.sync.getLastSyncToken()
+ await application.mutator.deleteItem(note)
+ await application.sync.sync()
+ await application.sync.setLastSyncToken(preDeleteSyncToken)
+ await application.sync.sync(syncOptions)
+ expect(application.items.items.length).to.equal(expectedItemCount)
})
it('errored items should not be synced', async function () {
- const note = await Factory.createSyncedNote(this.application)
- this.expectedItemCount++
+ const note = await Factory.createSyncedNote(application)
+ expectedItemCount++
const lastSyncBegan = note.lastSyncBegan
const lastSyncEnd = note.lastSyncEnd
- const encrypted = await this.application.encryption.encryptSplitSingle({
+ const encrypted = await application.encryption.encryptSplitSingle({
usesItemsKeyWithKeyLookup: {
items: [note.payload],
},
@@ -929,10 +930,10 @@ describe('online syncing', function () {
dirty: true,
})
- await this.application.payloads.emitPayload(errored)
- await this.application.sync.sync(syncOptions)
+ await application.payloads.emitPayload(errored)
+ await application.sync.sync(syncOptions)
- const updatedNote = this.application.items.findAnyItem(note.uuid)
+ const updatedNote = application.items.findAnyItem(note.uuid)
expect(updatedNote.lastSyncBegan.getTime()).to.equal(lastSyncBegan.getTime())
expect(updatedNote.lastSyncEnd.getTime()).to.equal(lastSyncEnd.getTime())
})
@@ -949,7 +950,7 @@ describe('online syncing', function () {
content: '004:...',
})
- this.expectedItemCount++
+ expectedItemCount++
const response = new ServerSyncResponse({
data: {
@@ -957,16 +958,16 @@ describe('online syncing', function () {
},
})
- await this.application.sync.handleSuccessServerResponse({ payloadsSavedOrSaving: [], options: {} }, response)
+ await application.sync.handleSuccessServerResponse({ payloadsSavedOrSaving: [], options: {} }, response)
- expect(this.application.payloads.findOne(invalidPayload.uuid)).to.not.be.ok
- expect(this.application.payloads.findOne(validPayload.uuid)).to.be.ok
+ expect(application.payloads.findOne(invalidPayload.uuid)).to.not.be.ok
+ expect(application.payloads.findOne(validPayload.uuid)).to.be.ok
})
it('retrieved items should have both updated_at and updated_at_timestamps', async function () {
- const note = await Factory.createSyncedNote(this.application)
+ const note = await Factory.createSyncedNote(application)
- this.expectedItemCount++
+ expectedItemCount++
expect(note.payload.created_at_timestamp).to.be.ok
expect(note.payload.created_at).to.be.ok
@@ -985,24 +986,24 @@ describe('online syncing', function () {
dirty: true,
content: {},
})
- this.expectedItemCount++
- await this.application.mutator.emitItemsFromPayloads([payload])
- await this.application.sync.sync(syncOptions)
+ expectedItemCount++
+ await application.mutator.emitItemsFromPayloads([payload])
+ await application.sync.sync(syncOptions)
/** Item should no longer be dirty, otherwise it would keep syncing */
- const item = this.application.items.findItem(payload.uuid)
+ const item = application.items.findItem(payload.uuid)
expect(item.dirty).to.not.be.ok
})
it('should call onPresyncSave before sync begins', async function () {
const events = []
- this.application.sync.addEventObserver((event) => {
+ application.sync.addEventObserver((event) => {
if (event === SyncEvent.SyncDidBeginProcessing) {
events.push('sync-will-begin')
}
})
- await this.application.sync.sync({
+ await application.sync.sync({
onPresyncSave: () => {
events.push('on-presync-save')
},
@@ -1015,21 +1016,21 @@ describe('online syncing', function () {
it('deleting an item permanently should include it in PayloadEmitSource.PreSyncSave item change observer', async function () {
let conditionMet = false
- this.application.items.streamItems([ContentType.TYPES.Note], async ({ removed, source }) => {
+ application.items.streamItems([ContentType.TYPES.Note], async ({ removed, source }) => {
if (source === PayloadEmitSource.PreSyncSave && removed.length === 1) {
conditionMet = true
}
})
- const note = await Factory.createSyncedNote(this.application)
- await this.application.mutator.deleteItem(note)
- await this.application.sync.sync()
+ const note = await Factory.createSyncedNote(application)
+ await application.mutator.deleteItem(note)
+ await application.sync.sync()
expect(conditionMet).to.equal(true)
})
it('deleting a note on one client should update notes count on the other', async function () {
- const contextA = this.context
+ const contextA = context
const contextB = await Factory.createAppContextWithFakeCrypto('AppB', contextA.email, contextA.password)
await contextB.launch()
@@ -1049,7 +1050,7 @@ describe('online syncing', function () {
})
it('should sync note when running raw sync request for external use', async function () {
- const contextA = this.context
+ const contextA = context
const contextB = await Factory.createAppContextWithFakeCrypto('AppB', contextA.email, contextA.password)
await contextB.launch()
@@ -1057,15 +1058,17 @@ describe('online syncing', function () {
const notePayload = Factory.createNote()
- const rawSyncRequest = await this.application.sync.getRawSyncRequestForExternalUse([notePayload])
+ const rawSyncRequest = await application.sync.getRawSyncRequestForExternalUse([notePayload])
expect(rawSyncRequest).to.be.ok
- const response = await this.application.http.runHttp(rawSyncRequest)
+ const response = await application.http.runHttp(rawSyncRequest)
expect(response.status).to.equal(200)
await contextB.sync()
const note = contextB.application.items.findItem(notePayload.uuid)
expect(note).to.be.ok
+
+ await contextB.deinit()
})
})
diff --git a/packages/snjs/mocha/upgrading.test.js b/packages/snjs/mocha/upgrading.test.js
index a0ce3adc2..7aa23be4c 100644
--- a/packages/snjs/mocha/upgrading.test.js
+++ b/packages/snjs/mocha/upgrading.test.js
@@ -1,41 +1,49 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
import * as Factory from './lib/factory.js'
+
chai.use(chaiAsPromised)
const expect = chai.expect
describe('upgrading', () => {
+ let application
+ let context
+ let email
+ let password
+ let passcode
+ let receiveChallenge
+ let receiveChallengeWithApp
+
beforeEach(async function () {
localStorage.clear()
- this.context = await Factory.createAppContext()
- await this.context.launch()
+ context = await Factory.createAppContext()
+ await context.launch()
- this.application = this.context.application
- this.email = UuidGenerator.GenerateUuid()
- this.password = UuidGenerator.GenerateUuid()
- this.passcode = '1234'
+ application = context.application
+ email = UuidGenerator.GenerateUuid()
+ password = UuidGenerator.GenerateUuid()
+ passcode = '1234'
const promptValueReply = (prompts) => {
const values = []
for (const prompt of prompts) {
if (prompt.validation === ChallengeValidation.LocalPasscode) {
- values.push(CreateChallengeValue(prompt, this.passcode))
+ values.push(CreateChallengeValue(prompt, passcode))
} else {
- values.push(CreateChallengeValue(prompt, this.password))
+ values.push(CreateChallengeValue(prompt, password))
}
}
return values
}
- this.receiveChallenge = (challenge) => {
- void this.receiveChallengeWithApp(this.application, challenge)
+
+ receiveChallenge = (challenge) => {
+ void receiveChallengeWithApp(application, challenge)
}
- this.receiveChallengeWithApp = (application, challenge) => {
+
+ receiveChallengeWithApp = (application, challenge) => {
application.addChallengeObserver(challenge, {
onInvalidValue: (value) => {
const values = promptValueReply([value.prompt])
application.submitValuesForChallenge(challenge, values)
- numPasscodeAttempts++
},
})
const initialValues = promptValueReply(challenge.prompts)
@@ -44,7 +52,7 @@ describe('upgrading', () => {
})
afterEach(async function () {
- await Factory.safeDeinit(this.application)
+ await Factory.safeDeinit(application)
localStorage.clear()
})
@@ -52,76 +60,72 @@ describe('upgrading', () => {
const oldVersion = ProtocolVersion.V003
/** Register with 003 version */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: oldVersion,
})
- expect(await this.application.protocolUpgradeAvailable()).to.equal(true)
+ expect(await application.protocolUpgradeAvailable()).to.equal(true)
})
it('upgrade should be available when passcode only', async function () {
const oldVersion = ProtocolVersion.V003
await Factory.setOldVersionPasscode({
- application: this.application,
- passcode: this.passcode,
+ application: application,
+ passcode: passcode,
version: oldVersion,
})
- expect(await this.application.protocolUpgradeAvailable()).to.equal(true)
+ expect(await application.protocolUpgradeAvailable()).to.equal(true)
})
it('upgrades application protocol from 003 to 004', async function () {
const oldVersion = ProtocolVersion.V003
const newVersion = ProtocolVersion.V004
- await Factory.createMappedNote(this.application)
+ await Factory.createMappedNote(application)
/** Register with 003 version */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: oldVersion,
})
await Factory.setOldVersionPasscode({
- application: this.application,
- passcode: this.passcode,
+ application: application,
+ passcode: passcode,
version: oldVersion,
})
- expect((await this.application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(
- oldVersion,
- )
- expect((await this.application.encryption.getRootKeyParams()).version).to.equal(oldVersion)
- expect((await this.application.encryption.getRootKey()).keyVersion).to.equal(oldVersion)
+ expect((await application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(oldVersion)
+ expect((await application.encryption.getRootKeyParams()).version).to.equal(oldVersion)
+ expect((await application.encryption.getRootKey()).keyVersion).to.equal(oldVersion)
- this.application.setLaunchCallback({
- receiveChallenge: this.receiveChallenge,
+ application.setLaunchCallback({
+ receiveChallenge: receiveChallenge,
})
- const result = await this.application.upgradeProtocolVersion()
+ const result = await application.upgradeProtocolVersion()
expect(result).to.deep.equal({ success: true })
- const wrappedRootKey = await this.application.encryption.rootKeyManager.getWrappedRootKey()
+ const wrappedRootKey = await application.encryption.rootKeyManager.getWrappedRootKey()
const payload = new EncryptedPayload(wrappedRootKey)
expect(payload.version).to.equal(newVersion)
- expect((await this.application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(
- newVersion,
- )
- expect((await this.application.encryption.getRootKeyParams()).version).to.equal(newVersion)
- expect((await this.application.encryption.getRootKey()).keyVersion).to.equal(newVersion)
+ expect((await application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(newVersion)
+ expect((await application.encryption.getRootKeyParams()).version).to.equal(newVersion)
+ expect((await application.encryption.getRootKey()).keyVersion).to.equal(newVersion)
/**
* Immediately logging out ensures we don't rely on subsequent
* sync events to complete the upgrade
*/
- this.application = await Factory.signOutApplicationAndReturnNew(this.application)
- await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
- expect(this.application.items.getDisplayableNotes().length).to.equal(1)
- expect(this.application.payloads.invalidPayloads).to.be.empty
+ application = await Factory.signOutApplicationAndReturnNew(application)
+ await application.signIn(email, password, undefined, undefined, undefined, true)
+ expect(application.items.getDisplayableNotes().length).to.equal(1)
+ expect(application.payloads.invalidPayloads).to.be.empty
}).timeout(15000)
it('upgrading from 003 to 004 with passcode only then reiniting app should create valid state', async function () {
@@ -133,23 +137,23 @@ describe('upgrading', () => {
const oldVersion = ProtocolVersion.V003
await Factory.setOldVersionPasscode({
- application: this.application,
- passcode: this.passcode,
+ application: application,
+ passcode: passcode,
version: oldVersion,
})
- await Factory.createSyncedNote(this.application)
+ await Factory.createSyncedNote(application)
- this.application.setLaunchCallback({
- receiveChallenge: this.receiveChallenge,
+ application.setLaunchCallback({
+ receiveChallenge: receiveChallenge,
})
- const identifier = this.application.identifier
+ const identifier = application.identifier
/** Recreate the app once */
const appFirst = Factory.createApplicationWithFakeCrypto(identifier)
await appFirst.prepareForLaunch({
receiveChallenge: (challenge) => {
- this.receiveChallengeWithApp(appFirst, challenge)
+ receiveChallengeWithApp(appFirst, challenge)
},
})
await appFirst.launch(true)
@@ -162,7 +166,7 @@ describe('upgrading', () => {
const appSecond = Factory.createApplicationWithFakeCrypto(identifier)
await appSecond.prepareForLaunch({
receiveChallenge: (challenge) => {
- this.receiveChallengeWithApp(appSecond, challenge)
+ receiveChallengeWithApp(appSecond, challenge)
},
})
await appSecond.launch(true)
@@ -172,46 +176,46 @@ describe('upgrading', () => {
it('protocol version should be upgraded on password change', async function () {
/** Delete default items key that is created on launch */
- const itemsKey = await this.application.encryption.getSureDefaultItemsKey()
- await this.application.mutator.setItemToBeDeleted(itemsKey)
- expect(Uuids(this.application.items.getDisplayableItemsKeys()).includes(itemsKey.uuid)).to.equal(false)
+ const itemsKey = await application.encryption.getSureDefaultItemsKey()
+ await application.mutator.setItemToBeDeleted(itemsKey)
+ expect(Uuids(application.items.getDisplayableItemsKeys()).includes(itemsKey.uuid)).to.equal(false)
- Factory.createMappedNote(this.application)
+ Factory.createMappedNote(application)
/** Register with 003 version */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: ProtocolVersion.V003,
})
- expect(this.application.items.getDisplayableItemsKeys().length).to.equal(1)
+ expect(application.items.getDisplayableItemsKeys().length).to.equal(1)
- expect((await this.application.encryption.getRootKeyParams()).version).to.equal(ProtocolVersion.V003)
- expect((await this.application.encryption.getRootKey()).keyVersion).to.equal(ProtocolVersion.V003)
+ expect((await application.encryption.getRootKeyParams()).version).to.equal(ProtocolVersion.V003)
+ expect((await application.encryption.getRootKey()).keyVersion).to.equal(ProtocolVersion.V003)
/** Ensure note is encrypted with 003 */
- const notePayloads = await Factory.getStoragePayloadsOfType(this.application, ContentType.TYPES.Note)
+ const notePayloads = await Factory.getStoragePayloadsOfType(application, ContentType.TYPES.Note)
expect(notePayloads.length).to.equal(1)
expect(notePayloads[0].version).to.equal(ProtocolVersion.V003)
- const { error } = await this.application.changePassword(this.password, 'foobarfoo')
+ const { error } = await application.changePassword(password, 'foobarfoo')
expect(error).to.not.exist
- const latestVersion = this.application.encryption.getLatestVersion()
- expect((await this.application.encryption.getRootKeyParams()).version).to.equal(latestVersion)
- expect((await this.application.encryption.getRootKey()).keyVersion).to.equal(latestVersion)
+ const latestVersion = application.encryption.getLatestVersion()
+ expect((await application.encryption.getRootKeyParams()).version).to.equal(latestVersion)
+ expect((await application.encryption.getRootKey()).keyVersion).to.equal(latestVersion)
- const defaultItemsKey = await this.application.encryption.getSureDefaultItemsKey()
+ const defaultItemsKey = await application.encryption.getSureDefaultItemsKey()
expect(defaultItemsKey.keyVersion).to.equal(latestVersion)
/** After change, note should now be encrypted with latest protocol version */
- const note = this.application.items.getDisplayableNotes()[0]
- await Factory.markDirtyAndSyncItem(this.application, note)
+ const note = application.items.getDisplayableNotes()[0]
+ await Factory.markDirtyAndSyncItem(application, note)
- const refreshedNotePayloads = await Factory.getStoragePayloadsOfType(this.application, ContentType.TYPES.Note)
+ const refreshedNotePayloads = await Factory.getStoragePayloadsOfType(application, ContentType.TYPES.Note)
const refreshedNotePayload = refreshedNotePayloads[0]
expect(refreshedNotePayload.version).to.equal(latestVersion)
}).timeout(5000)
@@ -221,19 +225,19 @@ describe('upgrading', () => {
const oldVersion = ProtocolVersion.V003
beforeEach(async function () {
- await Factory.createMappedNote(this.application)
+ await Factory.createMappedNote(application)
/** Register with 003 version */
await Factory.registerOldUser({
- application: this.application,
- email: this.email,
- password: this.password,
+ application: application,
+ email: email,
+ password: password,
version: oldVersion,
})
await Factory.setOldVersionPasscode({
- application: this.application,
- passcode: this.passcode,
+ application: application,
+ passcode: passcode,
version: oldVersion,
})
})
@@ -243,44 +247,36 @@ describe('upgrading', () => {
})
it('rolls back the local protocol upgrade if syncing fails', async function () {
- sinon.replace(this.application.sync, 'sync', sinon.fake())
- this.application.setLaunchCallback({
- receiveChallenge: this.receiveChallenge,
+ sinon.replace(application.sync, 'sync', sinon.fake())
+ application.setLaunchCallback({
+ receiveChallenge: receiveChallenge,
})
- expect((await this.application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(
- oldVersion,
- )
- const errors = await this.application.upgradeProtocolVersion()
+ expect((await application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(oldVersion)
+ const errors = await application.upgradeProtocolVersion()
expect(errors).to.not.be.empty
/** Ensure we're still on 003 */
- expect((await this.application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(
- oldVersion,
- )
- expect((await this.application.encryption.getRootKeyParams()).version).to.equal(oldVersion)
- expect((await this.application.encryption.getRootKey()).keyVersion).to.equal(oldVersion)
- expect((await this.application.encryption.getSureDefaultItemsKey()).keyVersion).to.equal(oldVersion)
+ expect((await application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(oldVersion)
+ expect((await application.encryption.getRootKeyParams()).version).to.equal(oldVersion)
+ expect((await application.encryption.getRootKey()).keyVersion).to.equal(oldVersion)
+ expect((await application.encryption.getSureDefaultItemsKey()).keyVersion).to.equal(oldVersion)
})
it('rolls back the local protocol upgrade if the server responds with an error', async function () {
- sinon.replace(this.application.sessions, 'changeCredentials', () => [Error()])
+ sinon.replace(application.sessions, 'changeCredentials', () => [Error()])
- this.application.setLaunchCallback({
- receiveChallenge: this.receiveChallenge,
+ application.setLaunchCallback({
+ receiveChallenge: receiveChallenge,
})
- expect((await this.application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(
- oldVersion,
- )
- const errors = await this.application.upgradeProtocolVersion()
+ expect((await application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(oldVersion)
+ const errors = await application.upgradeProtocolVersion()
expect(errors).to.not.be.empty
/** Ensure we're still on 003 */
- expect((await this.application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(
- oldVersion,
- )
- expect((await this.application.encryption.getRootKeyParams()).version).to.equal(oldVersion)
- expect((await this.application.encryption.getRootKey()).keyVersion).to.equal(oldVersion)
- expect((await this.application.encryption.getSureDefaultItemsKey()).keyVersion).to.equal(oldVersion)
+ expect((await application.encryption.rootKeyManager.getRootKeyWrapperKeyParams()).version).to.equal(oldVersion)
+ expect((await application.encryption.getRootKeyParams()).version).to.equal(oldVersion)
+ expect((await application.encryption.getRootKey()).keyVersion).to.equal(oldVersion)
+ expect((await application.encryption.getSureDefaultItemsKey()).keyVersion).to.equal(oldVersion)
})
})
})
diff --git a/packages/snjs/mocha/utils.test.js b/packages/snjs/mocha/utils.test.js
index a525a8fe6..1acb6e006 100644
--- a/packages/snjs/mocha/utils.test.js
+++ b/packages/snjs/mocha/utils.test.js
@@ -1,5 +1,4 @@
-/* eslint-disable no-unused-expressions */
-/* eslint-disable no-undef */
+
chai.use(chaiAsPromised)
const expect = chai.expect
diff --git a/packages/snjs/mocha/vaults/asymmetric-messages.test.js b/packages/snjs/mocha/vaults/asymmetric-messages.test.js
index 1d918773f..b2864c892 100644
--- a/packages/snjs/mocha/vaults/asymmetric-messages.test.js
+++ b/packages/snjs/mocha/vaults/asymmetric-messages.test.js
@@ -9,11 +9,6 @@ describe('asymmetric messages', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('asymmetric messages', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('should not trust message if the trusted payload data recipientUuid does not match the message user uuid', async () => {
const { sharedVault, contactContext, deinitContactContext } =
await Collaboration.createSharedVaultWithAcceptedInvite(context)
diff --git a/packages/snjs/mocha/vaults/conflicts.test.js b/packages/snjs/mocha/vaults/conflicts.test.js
index ff45780cf..39d8879ac 100644
--- a/packages/snjs/mocha/vaults/conflicts.test.js
+++ b/packages/snjs/mocha/vaults/conflicts.test.js
@@ -9,11 +9,6 @@ describe('shared vault conflicts', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('shared vault conflicts', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('after being removed from shared vault, attempting to sync previous vault item should result in SharedVaultNotMemberError. The item should be duplicated then removed.', async () => {
const { sharedVault, note, contactContext, deinitContactContext } =
await Collaboration.createSharedVaultWithAcceptedInviteAndNote(context)
@@ -81,7 +82,10 @@ describe('shared vault conflicts', function () {
it('attempting to modify note as read user should result in SharedVaultInsufficientPermissionsError', async () => {
const { note, contactContext, deinitContactContext } =
- await Collaboration.createSharedVaultWithAcceptedInviteAndNote(context, SharedVaultUserPermission.PERMISSIONS.Read)
+ await Collaboration.createSharedVaultWithAcceptedInviteAndNote(
+ context,
+ SharedVaultUserPermission.PERMISSIONS.Read,
+ )
const promise = contactContext.resolveWithConflicts()
await contactContext.changeNoteTitleAndSync(note, 'new title')
diff --git a/packages/snjs/mocha/vaults/contacts.test.js b/packages/snjs/mocha/vaults/contacts.test.js
index 4361aef4d..7ba28f2a3 100644
--- a/packages/snjs/mocha/vaults/contacts.test.js
+++ b/packages/snjs/mocha/vaults/contacts.test.js
@@ -9,11 +9,6 @@ describe('contacts', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('contacts', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('should create contact', async () => {
const contact = await context.contacts.createOrEditTrustedContact({
name: 'John Doe',
diff --git a/packages/snjs/mocha/vaults/crypto.test.js b/packages/snjs/mocha/vaults/crypto.test.js
index 0d98caa48..1275d8953 100644
--- a/packages/snjs/mocha/vaults/crypto.test.js
+++ b/packages/snjs/mocha/vaults/crypto.test.js
@@ -9,11 +9,6 @@ describe('shared vault crypto', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('shared vault crypto', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
describe('root key', () => {
it('root key loaded from disk should have keypairs', async () => {
const appIdentifier = context.identifier
diff --git a/packages/snjs/mocha/vaults/deletion.test.js b/packages/snjs/mocha/vaults/deletion.test.js
index 896f8abeb..1539dc979 100644
--- a/packages/snjs/mocha/vaults/deletion.test.js
+++ b/packages/snjs/mocha/vaults/deletion.test.js
@@ -10,11 +10,6 @@ describe('shared vault deletion', function () {
let context
let sharedVaults
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -26,6 +21,12 @@ describe('shared vault deletion', function () {
sharedVaults = context.sharedVaults
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('should remove item from all user devices when item is deleted permanently', async () => {
const { note, contactContext, deinitContactContext } =
await Collaboration.createSharedVaultWithAcceptedInviteAndNote(context)
@@ -102,7 +103,10 @@ describe('shared vault deletion', function () {
it('leaving a shared vault should remove its items locally', async () => {
const { sharedVault, note, contactContext, deinitContactContext } =
- await Collaboration.createSharedVaultWithAcceptedInviteAndNote(context, SharedVaultUserPermission.PERMISSIONS.Admin)
+ await Collaboration.createSharedVaultWithAcceptedInviteAndNote(
+ context,
+ SharedVaultUserPermission.PERMISSIONS.Admin,
+ )
const originalNote = contactContext.items.findItem(note.uuid)
expect(originalNote).to.not.be.undefined
diff --git a/packages/snjs/mocha/vaults/files.test.js b/packages/snjs/mocha/vaults/files.test.js
index ab5264859..d29658e90 100644
--- a/packages/snjs/mocha/vaults/files.test.js
+++ b/packages/snjs/mocha/vaults/files.test.js
@@ -11,11 +11,6 @@ describe('shared vault files', function () {
let context
let vaults
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -28,6 +23,12 @@ describe('shared vault files', function () {
await context.activatePaidSubscriptionForUser()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
describe('private vaults', () => {
it('should be able to upload and download file to private vault as owner', async () => {
const vault = await Collaboration.createPrivateVault(context)
diff --git a/packages/snjs/mocha/vaults/importing.test.js b/packages/snjs/mocha/vaults/importing.test.js
index 45a1c7d43..8b1a64d35 100644
--- a/packages/snjs/mocha/vaults/importing.test.js
+++ b/packages/snjs/mocha/vaults/importing.test.js
@@ -9,11 +9,6 @@ describe.skip('vault importing', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe.skip('vault importing', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('should import vaulted items with synced root key', async () => {
console.error('TODO: implement')
})
diff --git a/packages/snjs/mocha/vaults/invites.test.js b/packages/snjs/mocha/vaults/invites.test.js
index 777aae856..6ccd9e90c 100644
--- a/packages/snjs/mocha/vaults/invites.test.js
+++ b/packages/snjs/mocha/vaults/invites.test.js
@@ -9,11 +9,6 @@ describe('shared vault invites', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -22,6 +17,12 @@ describe('shared vault invites', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('should invite contact to vault', async () => {
const sharedVault = await Collaboration.createSharedVault(context)
const { contactContext, deinitContactContext } = await Collaboration.createContactContext()
diff --git a/packages/snjs/mocha/vaults/items.test.js b/packages/snjs/mocha/vaults/items.test.js
index c23e39bdf..f1d17cf34 100644
--- a/packages/snjs/mocha/vaults/items.test.js
+++ b/packages/snjs/mocha/vaults/items.test.js
@@ -9,11 +9,6 @@ describe('shared vault items', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('shared vault items', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('should add item to shared vault with no other members', async () => {
const note = await context.createSyncedNote('foo', 'bar')
diff --git a/packages/snjs/mocha/vaults/key-management.test.js b/packages/snjs/mocha/vaults/key-management.test.js
index 70f44f5f2..a304f0a53 100644
--- a/packages/snjs/mocha/vaults/key-management.test.js
+++ b/packages/snjs/mocha/vaults/key-management.test.js
@@ -8,11 +8,6 @@ describe('vault key management', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -21,6 +16,12 @@ describe('vault key management', function () {
await context.launch()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
describe('locking', () => {
it('should throw if attempting to add item to locked vault', async () => {
const vault = await context.vaults.createUserInputtedPasswordVault({
diff --git a/packages/snjs/mocha/vaults/key-rotation.test.js b/packages/snjs/mocha/vaults/key-rotation.test.js
index 6094ce192..d5bfb29fd 100644
--- a/packages/snjs/mocha/vaults/key-rotation.test.js
+++ b/packages/snjs/mocha/vaults/key-rotation.test.js
@@ -9,11 +9,6 @@ describe('vault key rotation', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('vault key rotation', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('should reencrypt all items keys belonging to key system', async () => {
const { sharedVault, contactContext, deinitContactContext } =
await Collaboration.createSharedVaultWithAcceptedInvite(context)
diff --git a/packages/snjs/mocha/vaults/key-sharing.test.js b/packages/snjs/mocha/vaults/key-sharing.test.js
index 34a1d96b9..a8be0bbb7 100644
--- a/packages/snjs/mocha/vaults/key-sharing.test.js
+++ b/packages/snjs/mocha/vaults/key-sharing.test.js
@@ -9,11 +9,6 @@ describe('vault key sharing', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('vault key sharing', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('sharing a vault with user inputted and ephemeral password should share the key as synced for the recipient', async () => {
const privateVault = await context.vaults.createUserInputtedPasswordVault({
name: 'My Private Vault',
diff --git a/packages/snjs/mocha/vaults/keypair-change.test.js b/packages/snjs/mocha/vaults/keypair-change.test.js
index 323e17160..16814446c 100644
--- a/packages/snjs/mocha/vaults/keypair-change.test.js
+++ b/packages/snjs/mocha/vaults/keypair-change.test.js
@@ -9,11 +9,6 @@ describe('keypair change', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('keypair change', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('contacts should be able to handle receiving multiple keypair changed messages and trust them in order', async () => {
const { note, contactContext, deinitContactContext } =
await Collaboration.createSharedVaultWithAcceptedInviteAndNote(context)
diff --git a/packages/snjs/mocha/vaults/permissions.test.js b/packages/snjs/mocha/vaults/permissions.test.js
index bfa031275..f229c01fa 100644
--- a/packages/snjs/mocha/vaults/permissions.test.js
+++ b/packages/snjs/mocha/vaults/permissions.test.js
@@ -9,11 +9,6 @@ describe('shared vault permissions', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,12 @@ describe('shared vault permissions', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ })
+
it('non-admin user should not be able to invite user', async () => {
context.anticipateConsoleError('Could not create invite')
@@ -42,6 +43,8 @@ describe('shared vault permissions', function () {
expect(result.isFailed()).to.be.true
+ await thirdParty.deinitContactContext()
+
await deinitContactContext()
})
diff --git a/packages/snjs/mocha/vaults/pkc.test.js b/packages/snjs/mocha/vaults/pkc.test.js
index 70eaf9934..703ac30ac 100644
--- a/packages/snjs/mocha/vaults/pkc.test.js
+++ b/packages/snjs/mocha/vaults/pkc.test.js
@@ -7,24 +7,23 @@ describe('public key cryptography', function () {
this.timeout(Factory.TwentySecondTimeout)
let context
- let sessions
- let encryption
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
- beforeEach(async function () {
+ beforeEach(async () => {
localStorage.clear()
context = await Factory.createVaultsContextWithRealCrypto()
await context.launch()
await context.register()
+ })
- sessions = context.application.sessions
- encryption = context.encryption
+ afterEach(async () => {
+ await context.deinit()
+ localStorage.clear()
+
+ sinon.restore()
+
+ context = undefined
})
it('should create keypair during registration', () => {
@@ -38,7 +37,7 @@ describe('public key cryptography', function () {
it('should populate keypair during sign in', async () => {
const email = context.email
const password = context.password
- await context.signout()
+ await context.deinit()
const recreatedContext = await Factory.createVaultsContextWithRealCrypto()
await recreatedContext.launch()
diff --git a/packages/snjs/mocha/vaults/shared_vaults.test.js b/packages/snjs/mocha/vaults/shared_vaults.test.js
index 8335eca8b..54984b82a 100644
--- a/packages/snjs/mocha/vaults/shared_vaults.test.js
+++ b/packages/snjs/mocha/vaults/shared_vaults.test.js
@@ -24,6 +24,8 @@ describe('shared vaults', function () {
afterEach(async function () {
await context.deinit()
localStorage.clear()
+ sinon.restore()
+ context = undefined
})
it('should update vault name and description', async () => {
diff --git a/packages/snjs/mocha/vaults/signatures.test.js b/packages/snjs/mocha/vaults/signatures.test.js
index 433578b3c..8c021e9a0 100644
--- a/packages/snjs/mocha/vaults/signatures.test.js
+++ b/packages/snjs/mocha/vaults/signatures.test.js
@@ -9,11 +9,6 @@ describe('signatures', function () {
let context
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
@@ -23,6 +18,13 @@ describe('signatures', function () {
await context.register()
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ context = undefined
+ })
+
describe('item decryption signature verification', () => {
it('should have failing signature if contact public key does not match', async () => {
const { note, contactContext, deinitContactContext } =
diff --git a/packages/snjs/mocha/vaults/vaults.test.js b/packages/snjs/mocha/vaults/vaults.test.js
index de7c80399..04b4206af 100644
--- a/packages/snjs/mocha/vaults/vaults.test.js
+++ b/packages/snjs/mocha/vaults/vaults.test.js
@@ -9,21 +9,24 @@ describe('vaults', function () {
let context
let vaults
- afterEach(async function () {
- await context.deinit()
- localStorage.clear()
- })
-
beforeEach(async function () {
localStorage.clear()
- context = await Factory.createVaultsContextWithRealCrypto()
+ context = await Factory.createVaultsContextWithFakeCrypto()
await context.launch()
vaults = context.vaults
})
+ afterEach(async function () {
+ await context.deinit()
+ localStorage.clear()
+ sinon.restore()
+ context = undefined
+ vaults = undefined
+ })
+
describe('offline', function () {
it('should be able to create an offline vault', async () => {
const vault = await vaults.createRandomizedVault({
@@ -77,7 +80,7 @@ describe('vaults', function () {
await vaults.moveItemToVault(vault, note)
await context.deinit()
- const recreatedContext = await Factory.createVaultsContextWithRealCrypto(appIdentifier)
+ const recreatedContext = await Factory.createVaultsContextWithFakeCrypto(appIdentifier)
await recreatedContext.launch()
const updatedNote = recreatedContext.items.findItem(note.uuid)
@@ -101,7 +104,7 @@ describe('vaults', function () {
await context.deinit()
- const recreatedContext = await Factory.createVaultsContextWithRealCrypto(appIdentifier)
+ const recreatedContext = await Factory.createVaultsContextWithFakeCrypto(appIdentifier)
await recreatedContext.launch()
const notes = recreatedContext.notes
@@ -128,7 +131,7 @@ describe('vaults', function () {
await context.deinit()
- const recreatedContext = await Factory.createVaultsContextWithRealCrypto(appIdentifier)
+ const recreatedContext = await Factory.createVaultsContextWithFakeCrypto(appIdentifier)
await recreatedContext.launch()
const updatedNote = recreatedContext.items.findItem(note.uuid)
@@ -181,7 +184,7 @@ describe('vaults', function () {
await vaults.moveItemToVault(vault, note)
await context.deinit()
- const recreatedContext = await Factory.createVaultsContextWithRealCrypto(appIdentifier)
+ const recreatedContext = await Factory.createVaultsContextWithFakeCrypto(appIdentifier)
await recreatedContext.launch()
const updatedNote = recreatedContext.items.findItem(note.uuid)