chore: fix deleting account specs (#2378)

* chore: fix deleting account specs

* fix: specs
This commit is contained in:
Karol Sójko
2023-07-31 17:23:20 +02:00
committed by GitHub
parent 661fddf433
commit f18c86da54
2 changed files with 183 additions and 169 deletions

View File

@@ -244,7 +244,9 @@ export class UserService
await this.signOut(true) await this.signOut(true)
void this.alerts.alert(InfoStrings.AccountDeleted) if (this.alerts) {
void this.alerts.alert(InfoStrings.AccountDeleted)
}
return { return {
error: false, error: false,

View File

@@ -13,25 +13,27 @@ describe('basic auth', function () {
awaitAll: true, awaitAll: true,
} }
beforeEach(async function () { let context
localStorage.clear()
this.expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
this.context = await Factory.createAppContext()
await this.context.launch()
this.application = this.context.application
this.email = UuidGenerator.GenerateUuid()
this.password = UuidGenerator.GenerateUuid()
})
afterEach(async function () { afterEach(async function () {
await Factory.safeDeinit(this.application) await context.deinit()
localStorage.clear() localStorage.clear()
}) })
beforeEach(async function () {
localStorage.clear()
context = await Factory.createAppContextWithRealCrypto()
await context.launch()
this.expectedItemCount = BaseItemCounts.DefaultItemsWithAccount
})
it('successfully register new account', async function () { it('successfully register new account', async function () {
const response = await this.application.register(this.email, this.password) const response = await context.register()
expect(response).to.be.ok expect(response).to.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
}) })
it('fails register new account with short password', async function () { it('fails register new account with short password', async function () {
@@ -39,7 +41,7 @@ describe('basic auth', function () {
let error = null let error = null
try { try {
await this.application.register(this.email, password) await context.application.register(context.email, password)
} catch (caughtError) { } catch (caughtError) {
error = caughtError error = caughtError
} }
@@ -49,41 +51,44 @@ describe('basic auth', function () {
'For your security, please choose a longer password or, ideally, a passphrase, and try again.', 'For your security, please choose a longer password or, ideally, a passphrase, and try again.',
) )
expect(await this.application.encryption.getRootKey()).to.not.be.ok expect(await context.application.encryption.getRootKey()).to.not.be.ok
}) })
it('successfully signs out of account', async function () { it('successfully signs out of account', async function () {
await this.application.register(this.email, this.password) await context.register()
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
this.application = await Factory.signOutApplicationAndReturnNew(this.application) context.application = await Factory.signOutApplicationAndReturnNew(context.application)
expect(await this.application.encryption.getRootKey()).to.not.be.ok expect(await context.application.encryption.getRootKey()).to.not.be.ok
expect(this.application.encryption.rootKeyManager.getKeyMode()).to.equal(KeyMode.RootKeyNone) expect(context.application.encryption.rootKeyManager.getKeyMode()).to.equal(KeyMode.RootKeyNone)
}) })
it('successfully signs in to registered account', async function () { it('successfully signs in to registered account', async function () {
await this.application.register(this.email, this.password) await context.register()
this.application = await Factory.signOutApplicationAndReturnNew(this.application)
const response = await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true) await context.signout()
const response = await context.application.signIn(context.email, context.password, undefined, undefined, undefined, true)
expect(response).to.be.ok expect(response).to.be.ok
expect(response.data.error).to.not.be.ok expect(response.data.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
}).timeout(20000) }).timeout(20000)
it('cannot sign while already signed in', async function () { it('cannot sign while already signed in', async function () {
await this.application.register(this.email, this.password) await context.register()
await Factory.createSyncedNote(this.application) await Factory.createSyncedNote(context.application)
this.application = await Factory.signOutApplicationAndReturnNew(this.application) await context.signout()
const response = await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true)
const response = await context.application.signIn(context.email, context.password, undefined, undefined, undefined, true)
expect(response).to.be.ok expect(response).to.be.ok
expect(response.data.error).to.not.be.ok expect(response.data.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
let error let error
try { try {
await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true) await context.application.signIn(context.email, context.password, undefined, undefined, undefined, true)
} catch (e) { } catch (e) {
error = e error = e
} }
@@ -91,27 +96,27 @@ describe('basic auth', function () {
}).timeout(20000) }).timeout(20000)
it('cannot register while already signed in', async function () { it('cannot register while already signed in', async function () {
await this.application.register(this.email, this.password) await context.register()
let error let error
try { try {
await this.application.register(this.email, this.password) await context.register()
} catch (e) { } catch (e) {
error = e error = e
} }
expect(error).to.be.ok expect(error).to.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
}).timeout(20000) }).timeout(20000)
it('cannot perform two sign-ins at the same time', async function () { it('cannot perform two sign-ins at the same time', async function () {
await this.application.register(this.email, this.password) await context.register()
this.application = await Factory.signOutApplicationAndReturnNew(this.application) await context.signout()
await Promise.all([ await Promise.all([
(async () => { (async () => {
const response = await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true) const response = await context.application.signIn(context.email, context.password, undefined, undefined, undefined, true)
expect(response).to.be.ok expect(response).to.be.ok
expect(response.data.error).to.not.be.ok expect(response.data.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
})(), })(),
(async () => { (async () => {
/** Make sure the first function runs first */ /** Make sure the first function runs first */
@@ -119,7 +124,7 @@ describe('basic auth', function () {
/** Try to sign in while the first request is going */ /** Try to sign in while the first request is going */
let error let error
try { try {
await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true) await context.application.signIn(context.email, context.password, undefined, undefined, undefined, true)
} catch (e) { } catch (e) {
error = e error = e
} }
@@ -131,10 +136,10 @@ describe('basic auth', function () {
it('cannot perform two register operations at the same time', async function () { it('cannot perform two register operations at the same time', async function () {
await Promise.all([ await Promise.all([
(async () => { (async () => {
const response = await this.application.register(this.email, this.password) const response = await context.register()
expect(response).to.be.ok expect(response).to.be.ok
expect(response.error).to.not.be.ok expect(response.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
})(), })(),
(async () => { (async () => {
/** Make sure the first function runs first */ /** Make sure the first function runs first */
@@ -142,7 +147,7 @@ describe('basic auth', function () {
/** Try to register in while the first request is going */ /** Try to register in while the first request is going */
let error let error
try { try {
await this.application.register(this.email, this.password) await context.register()
} catch (e) { } catch (e) {
error = e error = e
} }
@@ -152,14 +157,14 @@ describe('basic auth', function () {
}).timeout(20000) }).timeout(20000)
it('successfuly signs in after failing once', async function () { it('successfuly signs in after failing once', async function () {
await this.application.register(this.email, this.password) await context.register()
this.application = await Factory.signOutApplicationAndReturnNew(this.application) await context.signout()
let response = await this.application.signIn(this.email, 'wrong password', undefined, undefined, undefined, true) let response = await context.application.signIn(context.email, 'wrong password', undefined, undefined, undefined, true)
expect(response).to.have.property('status', 401) expect(response).to.have.property('status', 401)
expect(response.data.error).to.be.ok expect(response.data.error).to.be.ok
response = await this.application.signIn(this.email, this.password, undefined, undefined, undefined, true) response = await context.application.signIn(context.email, context.password, undefined, undefined, undefined, true)
expect(response.status).to.equal(200) expect(response.status).to.equal(200)
expect(response.data).to.not.haveOwnProperty('error') expect(response.data).to.not.haveOwnProperty('error')
@@ -183,9 +188,9 @@ describe('basic auth', function () {
* Registering with an uppercase email should still allow us to sign in * Registering with an uppercase email should still allow us to sign in
* with lowercase email * with lowercase email
*/ */
await this.application.register(uppercase, this.password) await context.application.register(uppercase, context.password)
const response = await this.application.sessions.retrieveKeyParams(lowercase) const response = await context.application.sessions.retrieveKeyParams(lowercase)
const keyParams = response.keyParams const keyParams = response.keyParams
expect(keyParams.identifier).to.equal(lowercase) expect(keyParams.identifier).to.equal(lowercase)
expect(keyParams.identifier).to.not.equal(uppercase) expect(keyParams.identifier).to.not.equal(uppercase)
@@ -195,16 +200,23 @@ describe('basic auth', function () {
const rand = `${Math.random()}` const rand = `${Math.random()}`
const uppercase = `FOO@BAR.COM${rand}` const uppercase = `FOO@BAR.COM${rand}`
const lowercase = `foo@bar.com${rand}` const lowercase = `foo@bar.com${rand}`
/**
* Registering with a lowercase email should allow us to sign in const password = UuidGenerator.GenerateUuid()
* with an uppercase email let specContext = await Factory.createAppContextWithFakeCrypto(Math.random(), lowercase, password)
*/
await this.application.register(lowercase, this.password) await specContext.launch()
this.application = await Factory.signOutApplicationAndReturnNew(this.application) await specContext.register()
const response = await this.application.signIn(uppercase, this.password, undefined, undefined, undefined, true) await specContext.signout()
await specContext.deinit()
specContext = await Factory.createAppContextWithFakeCrypto(Math.random(), uppercase, password)
await specContext.launch()
const response = await specContext.signIn()
expect(response).to.be.ok expect(response).to.be.ok
expect(response.data.error).to.not.be.ok expect(response.data.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await specContext.application.encryption.getRootKey()).to.be.ok
}).timeout(20000) }).timeout(20000)
it('can sign into account regardless of whitespace', async function () { it('can sign into account regardless of whitespace', async function () {
@@ -215,47 +227,55 @@ describe('basic auth', function () {
* Registering with a lowercase email should allow us to sign in * Registering with a lowercase email should allow us to sign in
* with an uppercase email * with an uppercase email
*/ */
await this.application.register(nospace, this.password) const password = UuidGenerator.GenerateUuid()
this.application = await Factory.signOutApplicationAndReturnNew(this.application) let specContext = await Factory.createAppContextWithFakeCrypto(Math.random(), nospace, password)
const response = await this.application.signIn(withspace, this.password, undefined, undefined, undefined, true) await specContext.launch()
await specContext.register()
await specContext.signout()
await specContext.deinit()
specContext = await Factory.createAppContextWithFakeCrypto(Math.random(), withspace, password)
await specContext.launch()
const response = await specContext.signIn()
expect(response).to.be.ok expect(response).to.be.ok
expect(response.data.error).to.not.be.ok expect(response.data.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await specContext.application.encryption.getRootKey()).to.be.ok
}).timeout(20000) }).timeout(20000)
it('fails login with wrong password', async function () { it('fails login with wrong password', async function () {
await this.application.register(this.email, this.password) await context.register()
this.application = await Factory.signOutApplicationAndReturnNew(this.application) context.application = await Factory.signOutApplicationAndReturnNew(context.application)
const response = await this.application.signIn(this.email, 'wrongpassword', undefined, undefined, undefined, true) const response = await context.application.signIn(context.email, 'wrongpassword', undefined, undefined, undefined, true)
expect(response).to.be.ok expect(response).to.be.ok
expect(response.data.error).to.be.ok expect(response.data.error).to.be.ok
expect(await this.application.encryption.getRootKey()).to.not.be.ok expect(await context.application.encryption.getRootKey()).to.not.be.ok
}).timeout(20000) }).timeout(20000)
it('fails to change to short password', async function () { it('fails to change to short password', async function () {
await this.application.register(this.email, this.password) await context.register()
const newPassword = '123456' const newPassword = '123456'
const response = await this.application.changePassword(this.password, newPassword) const response = await context.application.changePassword(context.password, newPassword)
expect(response.error).to.be.ok expect(response.error).to.be.ok
}).timeout(20000) }).timeout(20000)
it('fails to change password when current password is incorrect', async function () { it('fails to change password when current password is incorrect', async function () {
await this.application.register(this.email, this.password) await context.register()
const response = await this.application.changePassword('Invalid password', 'New password') const response = await context.application.changePassword('Invalid password', 'New password')
expect(response.error).to.be.ok expect(response.error).to.be.ok
/** Ensure we can still log in */ /** Ensure we can still log in */
this.application = await Factory.signOutAndBackIn(this.application, this.email, this.password) context.application = await Factory.signOutAndBackIn(context.application, context.email, context.password)
}).timeout(20000) }).timeout(20000)
it('registering for new account and completing first after download sync should not put us out of sync', async function () { it('registering for new account and completing first after download sync should not put us out of sync', async function () {
this.email = UuidGenerator.GenerateUuid() context.email = UuidGenerator.GenerateUuid()
this.password = UuidGenerator.GenerateUuid() context.password = UuidGenerator.GenerateUuid()
let outOfSync = true let outOfSync = true
let didCompletePostDownloadFirstSync = false let didCompletePostDownloadFirstSync = false
let didCompleteDownloadFirstSync = false let didCompleteDownloadFirstSync = false
this.application.sync.addEventObserver((eventName) => { context.application.sync.addEventObserver((eventName) => {
if (eventName === SyncEvent.DownloadFirstSyncCompleted) { if (eventName === SyncEvent.DownloadFirstSyncCompleted) {
didCompleteDownloadFirstSync = true didCompleteDownloadFirstSync = true
} }
@@ -265,14 +285,14 @@ describe('basic auth', function () {
if (!didCompletePostDownloadFirstSync && eventName === SyncEvent.PaginatedSyncRequestCompleted) { if (!didCompletePostDownloadFirstSync && eventName === SyncEvent.PaginatedSyncRequestCompleted) {
didCompletePostDownloadFirstSync = true didCompletePostDownloadFirstSync = true
/** Should be in sync */ /** Should be in sync */
outOfSync = this.application.sync.isOutOfSync() outOfSync = context.application.sync.isOutOfSync()
} }
}) })
await Factory.registerUserToApplication({ await Factory.registerUserToApplication({
application: this.application, application: context.application,
email: this.email, email: context.email,
password: this.password, password: context.password,
}) })
expect(didCompleteDownloadFirstSync).to.equal(true) expect(didCompleteDownloadFirstSync).to.equal(true)
@@ -281,47 +301,47 @@ describe('basic auth', function () {
}) })
async function changePassword() { async function changePassword() {
await this.application.register(this.email, this.password) await context.register()
const noteCount = 10 const noteCount = 10
await Factory.createManyMappedNotes(this.application, noteCount) await Factory.createManyMappedNotes(context.application, noteCount)
this.expectedItemCount += noteCount this.expectedItemCount += noteCount
await this.application.sync.sync(syncOptions) await context.application.sync.sync(syncOptions)
expect(this.application.items.items.length).to.equal(this.expectedItemCount) expect(context.application.items.items.length).to.equal(this.expectedItemCount)
const newPassword = 'newpassword' const newPassword = 'newpassword'
const response = await this.application.changePassword(this.password, newPassword) const response = await context.application.changePassword(context.password, newPassword)
/** New items key */ /** New items key */
this.expectedItemCount++ this.expectedItemCount++
expect(this.application.items.items.length).to.equal(this.expectedItemCount) expect(context.application.items.items.length).to.equal(this.expectedItemCount)
expect(response.error).to.not.be.ok expect(response.error).to.not.be.ok
expect(this.application.items.items.length).to.equal(this.expectedItemCount) expect(context.application.items.items.length).to.equal(this.expectedItemCount)
expect(this.application.payloads.invalidPayloads.length).to.equal(0) expect(context.application.payloads.invalidPayloads.length).to.equal(0)
await this.application.sync.markAllItemsAsNeedingSyncAndPersist() await context.application.sync.markAllItemsAsNeedingSyncAndPersist()
await this.application.sync.sync(syncOptions) await context.application.sync.sync(syncOptions)
expect(this.application.items.items.length).to.equal(this.expectedItemCount) expect(context.application.items.items.length).to.equal(this.expectedItemCount)
const note = this.application.items.getDisplayableNotes()[0] const note = context.application.items.getDisplayableNotes()[0]
/** /**
* Create conflict for a note. First modify the item without saving so that * Create conflict for a note. First modify the item without saving so that
* our local contents digress from the server's * our local contents digress from the server's
*/ */
await this.application.mutator.changeItem(note, (mutator) => { await context.application.mutator.changeItem(note, (mutator) => {
mutator.title = `${Math.random()}` mutator.title = `${Math.random()}`
}) })
await Factory.changePayloadTimeStampAndSync( await Factory.changePayloadTimeStampAndSync(
this.application, context.application,
note.payload, note.payload,
Factory.dateToMicroseconds(Factory.yesterday()), Factory.dateToMicroseconds(Factory.yesterday()),
{ {
@@ -331,18 +351,18 @@ describe('basic auth', function () {
) )
this.expectedItemCount++ this.expectedItemCount++
this.application = await Factory.signOutApplicationAndReturnNew(this.application) await context.signout()
/** Should login with new password */ /** Should login with new password */
const signinResponse = await this.application.signIn(this.email, newPassword, undefined, undefined, undefined, true) const signinResponse = await context.application.signIn(context.email, newPassword, undefined, undefined, undefined, true)
expect(signinResponse).to.be.ok expect(signinResponse).to.be.ok
expect(signinResponse.data.error).to.not.be.ok expect(signinResponse.data.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
expect(this.application.items.items.length).to.equal(this.expectedItemCount) expect(context.application.items.items.length).to.equal(this.expectedItemCount)
expect(this.application.payloads.invalidPayloads.length).to.equal(0) expect(context.application.payloads.invalidPayloads.length).to.equal(0)
} }
it('successfully changes password', changePassword).timeout(40000) it('successfully changes password', changePassword).timeout(40000)
@@ -355,42 +375,42 @@ describe('basic auth', function () {
if (prompt.validation === ChallengeValidation.LocalPasscode) { if (prompt.validation === ChallengeValidation.LocalPasscode) {
values.push(CreateChallengeValue(prompt, passcode)) values.push(CreateChallengeValue(prompt, passcode))
} else { } else {
values.push(CreateChallengeValue(prompt, this.password)) values.push(CreateChallengeValue(prompt, context.password))
} }
} }
return values return values
} }
this.application.setLaunchCallback({ context.application.setLaunchCallback({
receiveChallenge: (challenge) => { receiveChallenge: (challenge) => {
this.application.addChallengeObserver(challenge, { context.application.addChallengeObserver(challenge, {
onInvalidValue: (value) => { onInvalidValue: (value) => {
const values = promptValueReply([value.prompt]) const values = promptValueReply([value.prompt])
this.application.submitValuesForChallenge(challenge, values) context.application.submitValuesForChallenge(challenge, values)
numPasscodeAttempts++ numPasscodeAttempts++
}, },
}) })
const initialValues = promptValueReply(challenge.prompts) const initialValues = promptValueReply(challenge.prompts)
this.application.submitValuesForChallenge(challenge, initialValues) context.application.submitValuesForChallenge(challenge, initialValues)
}, },
}) })
await this.application.setPasscode(passcode) await context.application.setPasscode(passcode)
await changePassword.bind(this)() await changePassword.bind(this)()
}).timeout(20000) }).timeout(20000)
it('changes password many times', async function () { it('changes password many times', async function () {
await this.application.register(this.email, this.password) await context.register()
const noteCount = 10 const noteCount = 10
await Factory.createManyMappedNotes(this.application, noteCount) await Factory.createManyMappedNotes(context.application, noteCount)
this.expectedItemCount += noteCount this.expectedItemCount += noteCount
await this.application.sync.sync(syncOptions) await context.application.sync.sync(syncOptions)
const numTimesToChangePw = 3 const numTimesToChangePw = 3
let newPassword = Factory.randomString() let newPassword = Factory.randomString()
let currentPassword = this.password let currentPassword = context.password
for (let i = 0; i < numTimesToChangePw; i++) { for (let i = 0; i < numTimesToChangePw; i++) {
await this.application.changePassword(currentPassword, newPassword) await context.application.changePassword(currentPassword, newPassword)
/** New items key */ /** New items key */
this.expectedItemCount++ this.expectedItemCount++
@@ -398,20 +418,20 @@ describe('basic auth', function () {
currentPassword = newPassword currentPassword = newPassword
newPassword = Factory.randomString() newPassword = Factory.randomString()
expect(this.application.items.items.length).to.equal(this.expectedItemCount) expect(context.application.items.items.length).to.equal(this.expectedItemCount)
expect(this.application.payloads.invalidPayloads.length).to.equal(0) expect(context.application.payloads.invalidPayloads.length).to.equal(0)
await this.application.sync.markAllItemsAsNeedingSyncAndPersist() await context.application.sync.markAllItemsAsNeedingSyncAndPersist()
await this.application.sync.sync(syncOptions) await context.application.sync.sync(syncOptions)
this.application = await this.context.signout() await context.signout()
expect(this.application.items.items.length).to.equal(BaseItemCounts.DefaultItems) expect(context.application.items.items.length).to.equal(BaseItemCounts.DefaultItems)
expect(this.application.payloads.invalidPayloads.length).to.equal(0) expect(context.application.payloads.invalidPayloads.length).to.equal(0)
/** Should login with new password */ /** Should login with new password */
const signinResponse = await this.application.signIn( const signinResponse = await context.application.signIn(
this.email, context.email,
currentPassword, currentPassword,
undefined, undefined,
undefined, undefined,
@@ -421,40 +441,40 @@ describe('basic auth', function () {
expect(signinResponse).to.be.ok expect(signinResponse).to.be.ok
expect(signinResponse.data.error).to.not.be.ok expect(signinResponse.data.error).to.not.be.ok
expect(await this.application.encryption.getRootKey()).to.be.ok expect(await context.application.encryption.getRootKey()).to.be.ok
} }
}).timeout(80000) }).timeout(80000)
it('signing in with a clean email string should only try once', async function () { it('signing in with a clean email string should only try once', async function () {
await Factory.registerUserToApplication({ await Factory.registerUserToApplication({
application: this.application, application: context.application,
email: this.email, email: context.email,
password: this.password, password: context.password,
}) })
this.application = await Factory.signOutApplicationAndReturnNew(this.application) context.application = await Factory.signOutApplicationAndReturnNew(context.application)
const performSignIn = sinon.spy(this.application.sessions, 'performSignIn') const performSignIn = sinon.spy(context.application.sessions, 'performSignIn')
await this.application.signIn(this.email, 'wrong password', undefined, undefined, undefined, true) await context.application.signIn(context.email, 'wrong password', undefined, undefined, undefined, true)
expect(performSignIn.callCount).to.equal(1) expect(performSignIn.callCount).to.equal(1)
}) })
it('should rollback password change if fails to sync new items key', async function () { it('should rollback password change if fails to sync new items key', async function () {
/** Should delete the new items key locally without marking it as deleted so that it doesn't sync */ /** Should delete the new items key locally without marking it as deleted so that it doesn't sync */
await this.context.register() await context.register()
const originalImpl = this.application.encryption.getSureDefaultItemsKey const originalImpl = context.application.encryption.getSureDefaultItemsKey
this.application.encryption.getSureDefaultItemsKey = () => { context.application.encryption.getSureDefaultItemsKey = () => {
return { return {
neverSynced: true, neverSynced: true,
} }
} }
const mutatorSpy = sinon.spy(this.application.mutator, 'setItemToBeDeleted') const mutatorSpy = sinon.spy(context.application.mutator, 'setItemToBeDeleted')
const removeItemsSpy = sinon.spy(this.application.items, 'removeItemsFromMemory') const removeItemsSpy = sinon.spy(context.application.items, 'removeItemsFromMemory')
const deletePayloadsSpy = sinon.spy(this.application.storage, 'deletePayloadsWithUuids') const deletePayloadsSpy = sinon.spy(context.application.storage, 'deletePayloadsWithUuids')
await this.context.changePassword('new-password') await context.changePassword('new-password')
this.application.encryption.getSureDefaultItemsKey = originalImpl context.application.encryption.getSureDefaultItemsKey = originalImpl
expect(mutatorSpy.callCount).to.equal(0) expect(mutatorSpy.callCount).to.equal(0)
expect(removeItemsSpy.callCount).to.equal(1) expect(removeItemsSpy.callCount).to.equal(1)
@@ -464,13 +484,13 @@ describe('basic auth', function () {
describe('add passcode', function () { describe('add passcode', function () {
it('should set passcode successfully', async function () { it('should set passcode successfully', async function () {
const passcode = 'passcode' const passcode = 'passcode'
const result = await this.application.addPasscode(passcode) const result = await context.application.addPasscode(passcode)
expect(result).to.be.true expect(result).to.be.true
}) })
it('should fail when attempting to set 0 character passcode', async function () { it('should fail when attempting to set 0 character passcode', async function () {
const passcode = '' const passcode = ''
const result = await this.application.addPasscode(passcode) const result = await context.application.addPasscode(passcode)
expect(result).to.be.false expect(result).to.be.false
}) })
}) })
@@ -479,65 +499,57 @@ describe('basic auth', function () {
it('should change passcode successfully', async function () { it('should change passcode successfully', async function () {
const passcode = 'passcode' const passcode = 'passcode'
const newPasscode = 'newPasscode' const newPasscode = 'newPasscode'
await this.application.addPasscode(passcode) await context.application.addPasscode(passcode)
Factory.handlePasswordChallenges(this.application, passcode) Factory.handlePasswordChallenges(context.application, passcode)
const result = await this.application.changePasscode(newPasscode) const result = await context.application.changePasscode(newPasscode)
expect(result).to.be.true expect(result).to.be.true
}).timeout(Factory.TenSecondTimeout) }).timeout(Factory.TenSecondTimeout)
it('should fail when attempting to change to a 0 character passcode', async function () { it('should fail when attempting to change to a 0 character passcode', async function () {
const passcode = 'passcode' const passcode = 'passcode'
const newPasscode = '' const newPasscode = ''
await this.application.addPasscode(passcode) await context.application.addPasscode(passcode)
Factory.handlePasswordChallenges(this.application, passcode) Factory.handlePasswordChallenges(context.application, passcode)
const result = await this.application.changePasscode(newPasscode) const result = await context.application.changePasscode(newPasscode)
expect(result).to.be.false expect(result).to.be.false
}).timeout(Factory.TenSecondTimeout) }).timeout(Factory.TenSecondTimeout)
}) })
describe.skip('account deletion', function () { describe('account deletion', function () {
it('should delete account', async function () { beforeEach(async () => {
await Factory.registerUserToApplication({ await context.register()
application: this.application, })
email: this.email,
password: this.password,
})
Factory.handlePasswordChallenges(this.application, this.password)
const _response = await this.application.user.deleteAccount()
}).timeout(Factory.TenSecondTimeout)
it('should prompt for account password when deleting account', async function () { it('should prompt for account password when deleting account', async function () {
await Factory.registerUserToApplication({ Factory.handlePasswordChallenges(context.application, context.password)
application: this.application,
email: this.email,
password: this.password,
})
Factory.handlePasswordChallenges(this.application, this.password) const sendChallengeSpy = sinon.spy(context.application.challenges, 'sendChallenge')
const _response = await this.application.deleteAccount() await context.application.user.deleteAccount()
sinon.spy(snApp.challenges, 'sendChallenge') expect(sendChallengeSpy.callCount).to.equal(1)
const spyCall = snApp.challenges.sendChallenge.getCall(0)
const challenge = spyCall.firstArg
expect(challenge.prompts).to.have.lengthOf(2)
expect(challenge.prompts[0].validation).to.equal(ChallengeValidation.AccountPassword)
// ...
}).timeout(Factory.TenSecondTimeout) }).timeout(Factory.TenSecondTimeout)
it('deleting account should sign out current user', async function () { it('deleting account should sign out current user', async function () {
await Factory.registerUserToApplication({ Factory.handlePasswordChallenges(context.application, context.password)
application: this.application,
email: this.email,
password: this.password,
})
Factory.handlePasswordChallenges(this.application, this.password) const signOutSpy = sinon.spy(context.application.user.sessions, 'signOut')
const _response = await this.application.deleteAccount() await context.application.user.deleteAccount()
expect(application.hasAccount()).to.be.false expect(context.application.dealloced).to.be.true
expect(signOutSpy.callCount).to.equal(1)
}).timeout(Factory.TenSecondTimeout) }).timeout(Factory.TenSecondTimeout)
it('should not allow to delete someone else\'s account', async function () {
const secondContext = await Factory.createAppContextWithRealCrypto()
await secondContext.launch()
const registerResponse = await secondContext.register()
const response = await context.application.dependencies.get(TYPES.UserApiService).deleteAccount(registerResponse.user.uuid)
expect(response.status).to.equal(401)
expect(response.data.error.message).to.equal('Operation not allowed.')
})
}) })
}) })