refactor(web): dependency management (#2386)

This commit is contained in:
Mo
2023-08-05 12:48:39 -05:00
committed by GitHub
parent b07da5b663
commit d8d4052a52
274 changed files with 4065 additions and 3873 deletions

View File

@@ -79,8 +79,8 @@ describe('application instances', () => {
})
await recreatedContext.launch()
expect(recreatedContext.application.getHost()).to.not.equal('http://nonsense.host')
expect(recreatedContext.application.getHost()).to.equal(Factory.getDefaultHost())
expect(recreatedContext.application.getHost.execute().getValue()).to.not.equal('http://nonsense.host')
expect(recreatedContext.application.getHost.execute().getValue()).to.equal(Factory.getDefaultHost())
await recreatedContext.deinit()
})

View File

@@ -85,7 +85,7 @@ describe('auth fringe cases', () => {
const serverText = 'server text'
await context.application.changeAndSaveItem(firstVersionOfNote, (mutator) => {
await context.application.changeAndSaveItem.execute(firstVersionOfNote, (mutator) => {
mutator.text = serverText
})

View File

@@ -141,7 +141,7 @@ describe('features', () => {
expect(await application.settings.getDoesSensitiveSettingExist(setting)).to.equal(false)
const extensionKey = UuidGenerator.GenerateUuid().split('-').join('')
const promise = new Promise((resolve) => {
application.streamItems(ContentType.TYPES.ExtensionRepo, ({ changed }) => {
application.items.streamItems(ContentType.TYPES.ExtensionRepo, ({ changed }) => {
for (const item of changed) {
if (item.content.migratedToUserSetting) {
resolve()

View File

@@ -34,8 +34,8 @@ describe('history manager', () => {
await Factory.safeDeinit(this.application)
})
function setTextAndSync(application, item, text) {
return application.changeAndSaveItem(
async function setTextAndSync(application, item, text) {
const result = await application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.text = text
@@ -44,6 +44,8 @@ describe('history manager', () => {
undefined,
syncOptions,
)
return result.getValue()
}
function deleteCharsFromString(string, amount) {
@@ -59,7 +61,7 @@ describe('history manager', () => {
expect(this.history.sessionHistoryForItem(item).length).to.equal(0)
/** Sync with different contents, should create new entry */
await this.application.changeAndSaveItem(
await this.application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -79,7 +81,7 @@ describe('history manager', () => {
const context = await Factory.createAppContext({ identifier })
await context.launch()
expect(context.history.sessionHistoryForItem(item).length).to.equal(0)
await context.application.changeAndSaveItem(
await context.application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -103,7 +105,7 @@ describe('history manager', () => {
await context.application.mutator.insertItem(item)
expect(context.history.sessionHistoryForItem(item).length).to.equal(0)
await context.application.changeAndSaveItem(
await context.application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -243,7 +245,7 @@ describe('history manager', () => {
const payload = Factory.createNotePayload()
await this.application.mutator.emitItemFromPayload(payload, PayloadEmitSource.LocalChanged)
const item = this.application.items.findItem(payload.uuid)
await this.application.changeAndSaveItem(
await this.application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -306,7 +308,7 @@ describe('history manager', () => {
expect(itemHistory.length).to.equal(1)
/** Sync with different contents, should not create a new entry */
await this.application.changeAndSaveItem(
await this.application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = Math.random()
@@ -327,7 +329,7 @@ describe('history manager', () => {
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(
await this.application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.title = newTitleAfterFirstChange
@@ -411,7 +413,7 @@ describe('history manager', () => {
await Factory.sleep(Factory.ServerRevisionFrequency)
const changedText = `${Math.random()}`
await this.application.changeAndSaveItem(note, (mutator) => {
await this.application.changeAndSaveItem.execute(note, (mutator) => {
mutator.title = changedText
})
await Factory.markDirtyAndSyncItem(this.application, note)

View File

@@ -813,7 +813,7 @@ describe('importing', function () {
},
})
await application.launch(false)
await application.setHost(Factory.getDefaultHost())
await application.setHost.execute(Factory.getDefaultHost())
const backupFile = {
items: [

View File

@@ -50,17 +50,19 @@ describe('items', () => {
const item = this.application.items.items[0]
expect(item.pinned).to.not.be.ok
const refreshedItem = await this.application.changeAndSaveItem(
item,
(mutator) => {
mutator.pinned = true
mutator.archived = true
mutator.locked = true
},
undefined,
undefined,
syncOptions,
)
const refreshedItem = (
await this.application.changeAndSaveItem.execute(
item,
(mutator) => {
mutator.pinned = true
mutator.archived = true
mutator.locked = true
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(refreshedItem.pinned).to.equal(true)
expect(refreshedItem.archived).to.equal(true)
expect(refreshedItem.locked).to.equal(true)
@@ -77,94 +79,110 @@ describe('items', () => {
expect(item1.isItemContentEqualWith(item2)).to.equal(true)
// items should ignore this field when checking for equality
item1 = await this.application.changeAndSaveItem(
item1,
(mutator) => {
mutator.userModifiedDate = new Date()
},
undefined,
undefined,
syncOptions,
)
item2 = await this.application.changeAndSaveItem(
item2,
(mutator) => {
mutator.userModifiedDate = undefined
},
undefined,
undefined,
syncOptions,
)
item1 = (
await this.application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.userModifiedDate = new Date()
},
undefined,
undefined,
syncOptions,
)
).getValue()
item2 = (
await this.application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.userModifiedDate = undefined
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(item1.isItemContentEqualWith(item2)).to.equal(true)
item1 = await this.application.changeAndSaveItem(
item1,
(mutator) => {
mutator.mutableContent.foo = 'bar'
},
undefined,
undefined,
syncOptions,
)
item1 = (
await this.application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.mutableContent.foo = 'bar'
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(item1.isItemContentEqualWith(item2)).to.equal(false)
item2 = await this.application.changeAndSaveItem(
item2,
(mutator) => {
mutator.mutableContent.foo = 'bar'
},
undefined,
undefined,
syncOptions,
)
item2 = (
await this.application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.mutableContent.foo = 'bar'
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(item1.isItemContentEqualWith(item2)).to.equal(true)
expect(item2.isItemContentEqualWith(item1)).to.equal(true)
item1 = await this.application.changeAndSaveItem(
item1,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
},
undefined,
undefined,
syncOptions,
)
item2 = await this.application.changeAndSaveItem(
item2,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item1)
},
undefined,
undefined,
syncOptions,
)
item1 = (
await this.application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item2)
},
undefined,
undefined,
syncOptions,
)
).getValue()
item2 = (
await this.application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(item1)
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(item1.content.references.length).to.equal(1)
expect(item2.content.references.length).to.equal(1)
expect(item1.isItemContentEqualWith(item2)).to.equal(false)
item1 = await this.application.changeAndSaveItem(
item1,
(mutator) => {
mutator.removeItemAsRelationship(item2)
},
undefined,
undefined,
syncOptions,
)
item2 = await this.application.changeAndSaveItem(
item2,
(mutator) => {
mutator.removeItemAsRelationship(item1)
},
undefined,
undefined,
syncOptions,
)
item1 = (
await this.application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.removeItemAsRelationship(item2)
},
undefined,
undefined,
syncOptions,
)
).getValue()
item2 = (
await this.application.changeAndSaveItem.execute(
item2,
(mutator) => {
mutator.removeItemAsRelationship(item1)
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(item1.isItemContentEqualWith(item2)).to.equal(true)
expect(item1.content.references.length).to.equal(0)
@@ -179,15 +197,17 @@ describe('items', () => {
let item1 = this.application.items.getDisplayableNotes()[0]
const item2 = this.application.items.getDisplayableNotes()[1]
item1 = await this.application.changeAndSaveItem(
item1,
(mutator) => {
mutator.mutableContent.foo = 'bar'
},
undefined,
undefined,
syncOptions,
)
item1 = (
await this.application.changeAndSaveItem.execute(
item1,
(mutator) => {
mutator.mutableContent.foo = 'bar'
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(item1.content.foo).to.equal('bar')

View File

@@ -184,15 +184,17 @@ describe('notes and tags', () => {
expect(note.content.references.length).to.equal(0)
expect(tag.content.references.length).to.equal(1)
tag = await this.application.changeAndSaveItem(
tag,
(mutator) => {
mutator.removeItemAsRelationship(note)
},
undefined,
undefined,
syncOptions,
)
tag = (
await this.application.changeAndSaveItem.execute(
tag,
(mutator) => {
mutator.removeItemAsRelationship(note)
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(this.application.items.itemsReferencingItem(note).length).to.equal(0)
expect(tag.noteCount).to.equal(0)
@@ -265,15 +267,17 @@ describe('notes and tags', () => {
const notePayload = Factory.createNotePayload()
await this.application.mutator.emitItemsFromPayloads([notePayload], PayloadEmitSource.LocalChanged)
let note = this.application.items.getItems([ContentType.TYPES.Note])[0]
note = await this.application.changeAndSaveItem(
note,
(mutator) => {
mutator.mutableContent.title = Math.random()
},
undefined,
undefined,
syncOptions,
)
note = (
await this.application.changeAndSaveItem.execute(
note,
(mutator) => {
mutator.mutableContent.title = Math.random()
},
undefined,
undefined,
syncOptions,
)
).getValue()
expect(note.content.title).to.not.equal(notePayload.content.title)
})

View File

@@ -382,19 +382,19 @@ describe('protections', function () {
this.foo = 'tar'
application = await Factory.createInitAppWithFakeCrypto()
await application.addPasscode('passcode')
expect(application.hasUnprotectedAccessSession()).to.be.false
expect(application.protections.hasUnprotectedAccessSession()).to.be.false
})
it('should return true when session length has been set', async function () {
application = await Factory.createInitAppWithFakeCrypto()
await application.addPasscode('passcode')
await application.protections.setSessionLength(UnprotectedAccessSecondsDuration.OneMinute)
expect(application.hasUnprotectedAccessSession()).to.be.true
expect(application.protections.hasUnprotectedAccessSession()).to.be.true
})
it('should return true when there are no protection sources', async function () {
application = await Factory.createInitAppWithFakeCrypto()
expect(application.hasUnprotectedAccessSession()).to.be.true
expect(application.protections.hasUnprotectedAccessSession()).to.be.true
})
})

View File

@@ -298,7 +298,7 @@ describe('online conflict handling', function () {
await this.application.mutator.setItemDirty(note)
this.expectedItemCount++
await this.application.changeAndSaveItem(
await this.application.changeAndSaveItem.execute(
note,
(mutator) => {
// client A
@@ -332,7 +332,7 @@ describe('online conflict handling', function () {
await this.application.mutator.setItemDirty(note)
this.expectedItemCount++
await this.application.changeAndSaveItem(
await this.application.changeAndSaveItem.execute(
note,
(mutator) => {
// client A
@@ -602,15 +602,17 @@ describe('online conflict handling', function () {
*/
let tag = await Factory.createMappedTag(this.application)
let note = await Factory.createMappedNote(this.application)
tag = await this.application.changeAndSaveItem(
tag,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(note)
},
undefined,
undefined,
syncOptions,
)
tag = (
await this.application.changeAndSaveItem.execute(
tag,
(mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(note)
},
undefined,
undefined,
syncOptions,
)
).getValue()
await this.application.mutator.setItemDirty(note)
this.expectedItemCount += 2
@@ -732,39 +734,42 @@ describe('online conflict handling', function () {
})
/** 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 () {
/**
* 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.
* The second page of sync waiting to be sent up is still encrypted with the old items key UUID.
* This causes a problem because when that second page is returned as conflicts, we will be looking
* for an items_key_id that no longer exists (has been rotated). Rather than modifying the entire
* sync paradigm to allow multi-page requests to consider side-effects of each page, we will instead
* take the approach of making sure the decryption function is liberal with regards to searching
* for the right items key. It will now consider (as a result of this test) an items key as being
* the correct key to decrypt an item if the itemskey.uuid == item.items_key_id OR if the itemsKey.duplicateOf
* value is equal to item.items_key_id.
*/
it.skip(
'registering for account with bulk offline data belonging to another account should be error-free',
async function () {
/**
* 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.
* The second page of sync waiting to be sent up is still encrypted with the old items key UUID.
* This causes a problem because when that second page is returned as conflicts, we will be looking
* for an items_key_id that no longer exists (has been rotated). Rather than modifying the entire
* sync paradigm to allow multi-page requests to consider side-effects of each page, we will instead
* take the approach of making sure the decryption function is liberal with regards to searching
* for the right items key. It will now consider (as a result of this test) an items key as being
* the correct key to decrypt an item if the itemskey.uuid == item.items_key_id OR if the itemsKey.duplicateOf
* value is equal to item.items_key_id.
*/
/** 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
/** 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
/** Register new account and import this same data */
const newApp = await Factory.signOutApplicationAndReturnNew(this.application)
await Factory.registerUserToApplication({
application: newApp,
email: Utils.generateUuid(),
password: Utils.generateUuid(),
})
await newApp.mutator.emitItemsFromPayloads(priorData.map((i) => i.payload))
await newApp.sync.markAllItemsAsNeedingSyncAndPersist()
await newApp.sync.sync(syncOptions)
expect(newApp.payloads.invalidPayloads.length).to.equal(0)
await Factory.safeDeinit(newApp)
}).timeout(80000)
/** Register new account and import this same data */
const newApp = await Factory.signOutApplicationAndReturnNew(this.application)
await Factory.registerUserToApplication({
application: newApp,
email: Utils.generateUuid(),
password: Utils.generateUuid(),
})
await newApp.mutator.emitItemsFromPayloads(priorData.map((i) => i.payload))
await newApp.sync.markAllItemsAsNeedingSyncAndPersist()
await newApp.sync.sync(syncOptions)
expect(newApp.payloads.invalidPayloads.length).to.equal(0)
await Factory.safeDeinit(newApp)
},
).timeout(80000)
it('importing data belonging to another account should not result in duplication', async function () {
/** Create primary account and export data */
@@ -801,7 +806,7 @@ describe('online conflict handling', function () {
await createSyncedNoteWithTag(this.application)
const tag = this.application.items.getDisplayableTags()[0]
const note2 = await Factory.createMappedNote(this.application)
await this.application.changeAndSaveItem(tag, (mutator) => {
await this.application.changeAndSaveItem.execute(tag, (mutator) => {
mutator.e2ePendingRefactor_addItemAsRelationship(note2)
})
let backupFile = await this.application.createEncryptedBackupFileForAutomatedDesktopBackups()

View File

@@ -98,7 +98,7 @@ describe('offline syncing', () => {
this.expectedItemCount++
await this.application.sync.sync(syncOptions)
this.application = await Factory.signOutApplicationAndReturnNew(this.application)
expect(this.application.noAccount()).to.equal(true)
expect(this.application.getUser()).to.not.be.ok
expect(this.application.sessions.isSignedIn()).to.equal(false)
expect(this.application.sessions.getUser()).to.not.be.ok
})
})

View File

@@ -600,7 +600,7 @@ describe('online syncing', function () {
it('saving an item after sync should persist it with content property', async function () {
const note = await Factory.createMappedNote(this.application)
const text = Factory.randomString(10000)
await this.application.changeAndSaveItem(
await this.application.changeAndSaveItem.execute(
note,
(mutator) => {
mutator.text = text
@@ -1015,7 +1015,7 @@ 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.streamItems([ContentType.TYPES.Note], async ({ removed, source }) => {
this.application.items.streamItems([ContentType.TYPES.Note], async ({ removed, source }) => {
if (source === PayloadEmitSource.PreSyncSave && removed.length === 1) {
conditionMet = true
}