Skip to content

Commit

Permalink
feat: Add a destroy method in ContactsCollection
Browse files Browse the repository at this point in the history
Depending if a contact has been imported by a konnector or not, there
is logic to delete a contact.

We need to delete a contact at least in :
- cozy-contacts
- cozy-keys-browser

So let's centralize this logic.
  • Loading branch information
zatteo committed Apr 3, 2024
1 parent 6ec9814 commit 4dd9c59
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
22 changes: 22 additions & 0 deletions packages/cozy-stack-client/src/ContactsCollection.js
Expand Up @@ -31,6 +31,28 @@ class ContactsCollection extends DocumentCollection {
}
return col
}

/**
* Destroys a contact
*
* If the contact is linked to accounts, it will be trashed instead of being
* destroyed.
*
* @param {object} contact - Contact to destroy. IT MUST BE THE FULL CONTACT OBJECT
* @returns {Promise} - Resolves when contact has been destroyed
*/
async destroy(contact) {
const syncData = contact?.cozyMetadata?.sync || {}
const isLinkedToAccounts = Object.keys(syncData).length > 0
if (isLinkedToAccounts) {
return super.update({
...contact,
trashed: true
})
} else {
return super.destroy(contact)
}
}
}

export const CONTACTS_DOCTYPE = 'io.cozy.contacts'
Expand Down
70 changes: 70 additions & 0 deletions packages/cozy-stack-client/src/ContactsCollection.spec.js
@@ -1,5 +1,6 @@
import CozyStackClient from './CozyStackClient'
import ContactsCollection from './ContactsCollection'
import DocumentCollection from './DocumentCollection'

const stackMyselfResponse = {
data: {
Expand Down Expand Up @@ -78,4 +79,73 @@ describe('ContactsCollection', () => {
)
})
})

describe('destroy', () => {
const setup = () => {
const stackClient = new CozyStackClient({})
const col = new ContactsCollection('io.cozy.contacts', stackClient)
return { col }
}

beforeEach(() => {
jest.clearAllMocks()
})

it('should delete a contact with no sources', async () => {
const { col } = setup()

const documentCollectionDestroySpy = jest
.spyOn(DocumentCollection.prototype, 'destroy')
.mockImplementation()

const contact = {
_id: '123',
_rev: '1',
cozyMetadata: {
sync: {}
}
}

await col.destroy(contact)
expect(documentCollectionDestroySpy).toHaveBeenCalledWith(contact)

const contactWithoutMetadata = {
_id: '456',
_rev: '1'
}
await col.destroy(contactWithoutMetadata)
expect(documentCollectionDestroySpy).toHaveBeenCalledWith(
contactWithoutMetadata
)
})

it('should flag a contact with sources as trashed', async () => {
const { col } = setup()

const documentCollectionDestroySpy = jest
.spyOn(DocumentCollection.prototype, 'destroy')
.mockImplementation()
const documentCollectionUpdateSpy = jest
.spyOn(DocumentCollection.prototype, 'update')
.mockImplementation()

const contact = {
_id: '123',
cozyMetadata: {
sync: {
456: {
id: 'people/657623'
}
}
}
}

await col.destroy(contact)
expect(documentCollectionDestroySpy).not.toHaveBeenCalled()
expect(documentCollectionUpdateSpy).toHaveBeenCalledWith({
...contact,
trashed: true
})
})
})
})

0 comments on commit 4dd9c59

Please sign in to comment.