tests: vaults (#2365)
* tests: signature tests * tests: asymmetric * feat: delete contact use case * chore: lint * chore: lint
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { DeleteContact } from './UseCase/DeleteContact'
|
||||
import { MutatorClientInterface } from './../Mutator/MutatorClientInterface'
|
||||
import { UserKeyPairChangedEventData } from './../Session/UserKeyPairChangedEventData'
|
||||
import { SessionEvent } from './../Session/SessionEvent'
|
||||
@@ -21,6 +22,7 @@ import { CreateOrEditContact } from './UseCase/CreateOrEditContact'
|
||||
import { EditContact } from './UseCase/EditContact'
|
||||
import { GetAllContacts } from './UseCase/GetAllContacts'
|
||||
import { EncryptionProviderInterface } from '../Encryption/EncryptionProviderInterface'
|
||||
import { Result } from '@standardnotes/domain-core'
|
||||
|
||||
export class ContactService
|
||||
extends AbstractService<ContactServiceEvent>
|
||||
@@ -34,6 +36,7 @@ export class ContactService
|
||||
private user: UserClientInterface,
|
||||
private selfContactManager: SelfContactManager,
|
||||
private encryption: EncryptionProviderInterface,
|
||||
private _deleteContact: DeleteContact,
|
||||
private _findContact: FindContact,
|
||||
private _getAllContacts: GetAllContacts,
|
||||
private _createOrEditContact: CreateOrEditContact,
|
||||
@@ -167,20 +170,15 @@ export class ContactService
|
||||
return contact
|
||||
}
|
||||
|
||||
async deleteContact(contact: TrustedContactInterface): Promise<void> {
|
||||
if (contact.isMe) {
|
||||
throw new Error('Cannot delete self')
|
||||
}
|
||||
|
||||
await this.mutator.setItemToBeDeleted(contact)
|
||||
await this.sync.sync()
|
||||
async deleteContact(contact: TrustedContactInterface): Promise<Result<void>> {
|
||||
return this._deleteContact.execute({ contact, ownUserUuid: this.session.userUuid })
|
||||
}
|
||||
|
||||
getAllContacts(): TrustedContactInterface[] {
|
||||
return this._getAllContacts.execute().getValue()
|
||||
}
|
||||
|
||||
findTrustedContact(userUuid: string): TrustedContactInterface | undefined {
|
||||
findContact(userUuid: string): TrustedContactInterface | undefined {
|
||||
const result = this._findContact.execute({ userUuid })
|
||||
if (result.isFailed()) {
|
||||
return undefined
|
||||
@@ -188,12 +186,12 @@ export class ContactService
|
||||
return result.getValue()
|
||||
}
|
||||
|
||||
findTrustedContactForServerUser(user: SharedVaultUserServerHash): TrustedContactInterface | undefined {
|
||||
return this.findTrustedContact(user.user_uuid)
|
||||
findContactForServerUser(user: SharedVaultUserServerHash): TrustedContactInterface | undefined {
|
||||
return this.findContact(user.user_uuid)
|
||||
}
|
||||
|
||||
findTrustedContactForInvite(invite: SharedVaultInviteServerHash): TrustedContactInterface | undefined {
|
||||
return this.findTrustedContact(invite.sender_uuid)
|
||||
findContactForInvite(invite: SharedVaultInviteServerHash): TrustedContactInterface | undefined {
|
||||
return this.findContact(invite.sender_uuid)
|
||||
}
|
||||
|
||||
getCollaborationIDForTrustedContact(contact: TrustedContactInterface): string {
|
||||
@@ -205,7 +203,7 @@ export class ContactService
|
||||
})
|
||||
}
|
||||
|
||||
isItemAuthenticallySigned(item: DecryptedItemInterface): ItemSignatureValidationResult {
|
||||
getItemSignatureStatus(item: DecryptedItemInterface): ItemSignatureValidationResult {
|
||||
return this._validateItemSigner.execute(item)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import { DecryptedItemInterface, TrustedContactInterface } from '@standardnotes/
|
||||
import { AbstractService } from '../Service/AbstractService'
|
||||
import { SharedVaultInviteServerHash, SharedVaultUserServerHash } from '@standardnotes/responses'
|
||||
import { ItemSignatureValidationResult } from './UseCase/Types/ItemSignatureValidationResult'
|
||||
import { Result } from '@standardnotes/domain-core'
|
||||
|
||||
export enum ContactServiceEvent {}
|
||||
|
||||
@@ -26,13 +27,13 @@ export interface ContactServiceInterface extends AbstractService<ContactServiceE
|
||||
contact: TrustedContactInterface,
|
||||
params: { name: string; collaborationID: string },
|
||||
): Promise<TrustedContactInterface>
|
||||
deleteContact(contact: TrustedContactInterface): Promise<void>
|
||||
deleteContact(contact: TrustedContactInterface): Promise<Result<void>>
|
||||
|
||||
getAllContacts(): TrustedContactInterface[]
|
||||
getSelfContact(): TrustedContactInterface | undefined
|
||||
findTrustedContact(userUuid: string): TrustedContactInterface | undefined
|
||||
findTrustedContactForServerUser(user: SharedVaultUserServerHash): TrustedContactInterface | undefined
|
||||
findTrustedContactForInvite(invite: SharedVaultInviteServerHash): TrustedContactInterface | undefined
|
||||
findContact(userUuid: string): TrustedContactInterface | undefined
|
||||
findContactForServerUser(user: SharedVaultUserServerHash): TrustedContactInterface | undefined
|
||||
findContactForInvite(invite: SharedVaultInviteServerHash): TrustedContactInterface | undefined
|
||||
|
||||
isItemAuthenticallySigned(item: DecryptedItemInterface): ItemSignatureValidationResult
|
||||
getItemSignatureStatus(item: DecryptedItemInterface): ItemSignatureValidationResult
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
import { ContactBelongsToVault } from './../../SharedVaults/UseCase/ContactBelongsToVault'
|
||||
import { GetOwnedSharedVaults } from './../../SharedVaults/UseCase/GetOwnedSharedVaults'
|
||||
import { SyncServiceInterface } from './../../Sync/SyncServiceInterface'
|
||||
import { MutatorClientInterface } from './../../Mutator/MutatorClientInterface'
|
||||
import { Result } from '@standardnotes/domain-core'
|
||||
import { TrustedContactInterface } from '@standardnotes/models'
|
||||
import { DeleteContact } from './DeleteContact'
|
||||
|
||||
describe('DeleteContact', () => {
|
||||
let mutator: jest.Mocked<MutatorClientInterface>
|
||||
let sync: jest.Mocked<SyncServiceInterface>
|
||||
let getOwnedVaults: jest.Mocked<GetOwnedSharedVaults>
|
||||
let contactBelongsToVault: jest.Mocked<ContactBelongsToVault>
|
||||
let deleteContact: DeleteContact
|
||||
let mockDto: {
|
||||
contact: TrustedContactInterface
|
||||
ownUserUuid: string
|
||||
}
|
||||
let mockVaults: { id: string }[]
|
||||
|
||||
beforeEach(() => {
|
||||
mutator = {} as jest.Mocked<MutatorClientInterface>
|
||||
sync = {} as jest.Mocked<SyncServiceInterface>
|
||||
|
||||
getOwnedVaults = {} as jest.Mocked<GetOwnedSharedVaults>
|
||||
getOwnedVaults.execute = jest.fn()
|
||||
|
||||
contactBelongsToVault = {} as jest.Mocked<ContactBelongsToVault>
|
||||
contactBelongsToVault.execute = jest.fn()
|
||||
|
||||
deleteContact = new DeleteContact(mutator, sync, getOwnedVaults, contactBelongsToVault)
|
||||
|
||||
mockDto = {
|
||||
contact: { isMe: false } as TrustedContactInterface,
|
||||
ownUserUuid: 'test-user-uuid',
|
||||
}
|
||||
|
||||
mockVaults = [{ id: 'vault1' }, { id: 'vault2' }]
|
||||
})
|
||||
|
||||
describe('execute', () => {
|
||||
it('should throw error when deleting self', async () => {
|
||||
mockDto.contact.isMe = true
|
||||
await expect(deleteContact.execute(mockDto)).rejects.toThrow('Cannot delete self')
|
||||
})
|
||||
|
||||
it('should return failure when getting owned vaults fails', async () => {
|
||||
getOwnedVaults.execute = jest.fn().mockReturnValue(Result.fail('Failed to get owned vaults'))
|
||||
|
||||
const result = await deleteContact.execute(mockDto)
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Failed to get owned vaults')
|
||||
})
|
||||
|
||||
it('should return failure when checking contact membership fails', async () => {
|
||||
getOwnedVaults.execute = jest.fn().mockReturnValue(Result.ok(mockVaults))
|
||||
contactBelongsToVault.execute = jest.fn().mockResolvedValue(Result.fail('Failed to check contact membership'))
|
||||
|
||||
const result = await deleteContact.execute(mockDto)
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Failed to check contact membership')
|
||||
})
|
||||
|
||||
it('should return failure when contact belongs to an owned vault', async () => {
|
||||
getOwnedVaults.execute = jest.fn().mockReturnValue(Result.ok(mockVaults))
|
||||
contactBelongsToVault.execute = jest.fn().mockResolvedValue(Result.ok(true))
|
||||
|
||||
const result = await deleteContact.execute(mockDto)
|
||||
|
||||
expect(result.isFailed()).toBe(true)
|
||||
expect(result.getError()).toBe('Cannot delete contact that belongs to an owned vault')
|
||||
})
|
||||
|
||||
it('should return success when contact is successfully deleted', async () => {
|
||||
getOwnedVaults.execute = jest.fn().mockReturnValue(Result.ok(mockVaults))
|
||||
contactBelongsToVault.execute = jest.fn().mockResolvedValue(Result.ok(false))
|
||||
mutator.setItemToBeDeleted = jest.fn().mockResolvedValue(undefined)
|
||||
sync.sync = jest.fn().mockResolvedValue(undefined)
|
||||
|
||||
const result = await deleteContact.execute(mockDto)
|
||||
|
||||
expect(result.isFailed()).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,45 @@
|
||||
import { ContactBelongsToVault } from './../../SharedVaults/UseCase/ContactBelongsToVault'
|
||||
import { GetOwnedSharedVaults } from './../../SharedVaults/UseCase/GetOwnedSharedVaults'
|
||||
import { SyncServiceInterface } from './../../Sync/SyncServiceInterface'
|
||||
import { MutatorClientInterface } from './../../Mutator/MutatorClientInterface'
|
||||
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
|
||||
import { TrustedContactInterface } from '@standardnotes/models'
|
||||
|
||||
export class DeleteContact implements UseCaseInterface<void> {
|
||||
constructor(
|
||||
private mutator: MutatorClientInterface,
|
||||
private sync: SyncServiceInterface,
|
||||
private getOwnedVaults: GetOwnedSharedVaults,
|
||||
private contactBelongsToVault: ContactBelongsToVault,
|
||||
) {}
|
||||
|
||||
async execute(dto: { contact: TrustedContactInterface; ownUserUuid: string }): Promise<Result<void>> {
|
||||
if (dto.contact.isMe) {
|
||||
throw new Error('Cannot delete self')
|
||||
}
|
||||
|
||||
const vaults = this.getOwnedVaults.execute({ userUuid: dto.ownUserUuid })
|
||||
if (vaults.isFailed()) {
|
||||
return Result.fail('Failed to get owned vaults')
|
||||
}
|
||||
|
||||
for (const vault of vaults.getValue()) {
|
||||
const contactBelongsToVault = await this.contactBelongsToVault.execute({
|
||||
contact: dto.contact,
|
||||
vault: vault,
|
||||
})
|
||||
if (contactBelongsToVault.isFailed()) {
|
||||
return Result.fail('Failed to check contact membership')
|
||||
}
|
||||
|
||||
if (contactBelongsToVault.getValue()) {
|
||||
return Result.fail('Cannot delete contact that belongs to an owned vault')
|
||||
}
|
||||
}
|
||||
|
||||
await this.mutator.setItemToBeDeleted(dto.contact)
|
||||
await this.sync.sync()
|
||||
|
||||
return Result.ok()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user