diff --git a/packages/api/src/resolvers/article/index.ts b/packages/api/src/resolvers/article/index.ts index 34c7abdd6..363f97f13 100644 --- a/packages/api/src/resolvers/article/index.ts +++ b/packages/api/src/resolvers/article/index.ts @@ -76,6 +76,7 @@ import { createOrUpdateLibraryItem, findLibraryItemsByPrefix, searchLibraryItems, + softDeleteLibraryItem, sortParamsToSort, updateLibraryItem, updateLibraryItemReadingProgress, @@ -532,15 +533,7 @@ export const setBookmarkArticleResolver = authorized< } // delete the item and its metadata - const deletedLibraryItem = await updateLibraryItem( - articleID, - { - state: LibraryItemState.Deleted, - deletedAt: new Date(), - }, - uid, - pubsub - ) + const deletedLibraryItem = await softDeleteLibraryItem(articleID, uid, pubsub) analytics.track({ userId: uid, diff --git a/packages/api/src/services/library_item.ts b/packages/api/src/services/library_item.ts index 20b47afb7..e56f3c9ef 100644 --- a/packages/api/src/services/library_item.ts +++ b/packages/api/src/services/library_item.ts @@ -708,6 +708,38 @@ export const restoreLibraryItem = async ( ) } +export const softDeleteLibraryItem = async ( + id: string, + userId: string, + pubsub = createPubSubClient() +): Promise => { + const deletedLibraryItem = await authTrx( + async (tx) => { + const itemRepo = tx.withRepository(libraryItemRepository) + + // mark item as deleted + await itemRepo.update(id, { + state: LibraryItemState.Deleted, + deletedAt: new Date(), + }) + + // delete all labels for this item + await tx.getRepository(EntityLabel).delete({ libraryItemId: id }) + + // delete all highlights for this item + await tx.getRepository(Highlight).delete({ libraryItem: { id } }) + + return itemRepo.findOneByOrFail({ id }) + }, + undefined, + userId + ) + + await pubsub.entityDeleted(EntityType.PAGE, id, userId) + + return deletedLibraryItem +} + export const updateLibraryItem = async ( id: string, libraryItem: QueryDeepPartialEntity, diff --git a/packages/api/test/resolvers/article.test.ts b/packages/api/test/resolvers/article.test.ts index c93a388b3..5d38e024d 100644 --- a/packages/api/test/resolvers/article.test.ts +++ b/packages/api/test/resolvers/article.test.ts @@ -21,7 +21,6 @@ import { } from '../../src/generated/graphql' import { getRepository } from '../../src/repository' import { createGroup, deleteGroup } from '../../src/services/groups' -import { createLabel, deleteLabels } from '../../src/services/labels' import { createOrUpdateLibraryItem, createLibraryItems, @@ -31,8 +30,9 @@ import { deleteLibraryItemsByUserId, findLibraryItemById, findLibraryItemByUrl, + softDeleteLibraryItem, updateLibraryItem, - CreateOrUpdateLibraryItemArgs, + CreateOrUpdateLibraryItemArgs,, } from '../../src/services/library_item' import { deleteUser } from '../../src/services/user' import * as createTask from '../../src/utils/createTask' @@ -43,7 +43,12 @@ import { createTestUser, saveLabelsInLibraryItem, } from '../db' -import { generateFakeUuid, graphqlRequest, request } from '../util' +import { + generateFakeShortId, + generateFakeUuid, + graphqlRequest, + request, +} from '../util' chai.use(chaiString) @@ -706,18 +711,39 @@ describe('Article API', () => { } const item = await createOrUpdateLibraryItem(itemToSave, user.id) itemId = item.id + + await createAndSaveLabelsInLibraryItem(itemId, user.id, [ + { + name: 'test label 2', + }, + ]) + await createHighlight( + { + shortId: generateFakeShortId(), + user: { id: user.id }, + quote: 'test quote 2', + }, + itemId, + user.id + ) }) after(async () => { await deleteLibraryItemById(itemId, user.id) }) - it('marks an article as deleted', async () => { + it('marks an item as deleted and deletes all the labels and highlights attached to the item', async () => { await graphqlRequest(setBookmarkQuery(itemId, false), authToken).expect( 200 ) const item = await findLibraryItemById(itemId, user.id) expect(item?.state).to.eql(LibraryItemState.Deleted) + + const labels = await findLabelsByLibraryItemId(itemId, user.id) + expect(labels).to.be.empty + + const highlights = await findHighlightsByLibraryItemId(itemId, user.id) + expect(highlights).to.be.empty }) }) @@ -2062,11 +2088,8 @@ describe('Article API', () => { // Delete some items for (let i = 0; i < 3; i++) { - await updateLibraryItem( - items[i].id, - { state: LibraryItemState.Deleted, deletedAt: new Date() }, - user.id - ) + await softDeleteLibraryItem(items[i].id, user.id) + deletedItems.push(items[i]) } })