Selaa lähdekoodia

fix: account deletion event (#904)

* fix: account deletion event

* fix: feature service binding
Karol Sójko 1 vuosi sitten
vanhempi
commit
d66ae62cf4
30 muutettua tiedostoa jossa 260 lisäystä ja 156 poistoa
  1. 11 1
      packages/auth/src/Bootstrap/Container.ts
  2. 9 2
      packages/auth/src/Domain/Event/DomainEventFactory.ts
  3. 9 2
      packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts
  4. 34 18
      packages/auth/src/Domain/Feature/FeatureService.spec.ts
  5. 7 9
      packages/auth/src/Domain/Feature/FeatureService.ts
  6. 17 2
      packages/auth/src/Domain/Handler/SubscriptionExpiredEventHandler.ts
  7. 1 1
      packages/auth/src/Domain/Handler/SubscriptionPurchasedEventHandler.ts
  8. 1 1
      packages/auth/src/Domain/Handler/SubscriptionReassignedEventHandler.ts
  9. 17 2
      packages/auth/src/Domain/Handler/SubscriptionRefundedEventHandler.ts
  10. 15 2
      packages/auth/src/Domain/Handler/SubscriptionRenewedEventHandler.ts
  11. 1 1
      packages/auth/src/Domain/Handler/SubscriptionSyncRequestedEventHandler.ts
  12. 6 12
      packages/auth/src/Domain/Subscription/UserSubscription.ts
  13. 2 2
      packages/auth/src/Domain/UseCase/AcceptSharedSubscriptionInvitation/AcceptSharedSubscriptionInvitation.spec.ts
  14. 1 1
      packages/auth/src/Domain/UseCase/AcceptSharedSubscriptionInvitation/AcceptSharedSubscriptionInvitation.ts
  15. 1 1
      packages/auth/src/Domain/UseCase/ActivatePremiumFeatures/ActivatePremiumFeatures.ts
  16. 2 2
      packages/auth/src/Domain/UseCase/CancelSharedSubscriptionInvitation/CancelSharedSubscriptionInvitation.spec.ts
  17. 2 8
      packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.spec.ts
  18. 84 12
      packages/auth/src/Domain/UseCase/DeleteAccount/DeleteAccount.spec.ts
  19. 27 8
      packages/auth/src/Domain/UseCase/DeleteAccount/DeleteAccount.ts
  20. 2 2
      packages/auth/src/Domain/UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser.spec.ts
  21. 1 2
      packages/auth/src/Domain/UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser.ts
  22. 0 11
      packages/auth/src/Domain/User/User.ts
  23. 9 1
      packages/domain-events/src/Domain/Event/AccountDeletionRequestedEventPayload.ts
  24. 0 1
      packages/domain-events/src/Domain/Event/FileRemovedEventPayload.ts
  25. 0 1
      packages/files/src/Domain/Event/DomainEventFactory.ts
  26. 0 1
      packages/files/src/Domain/Event/DomainEventFactoryInterface.ts
  27. 1 2
      packages/files/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts
  28. 0 1
      packages/files/src/Domain/Handler/SharedSubscriptionInvitationCanceledEventHandler.ts
  29. 0 1
      packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.ts
  30. 0 46
      packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.spec.ts

+ 11 - 1
packages/auth/src/Bootstrap/Container.ts

@@ -791,7 +791,16 @@ export class ContainerConfigLoader {
     container
       .bind<SubscriptionSettingsAssociationServiceInterface>(TYPES.Auth_SubscriptionSettingsAssociationService)
       .to(SubscriptionSettingsAssociationService)
-    container.bind<FeatureServiceInterface>(TYPES.Auth_FeatureService).to(FeatureService)
+    container
+      .bind<FeatureServiceInterface>(TYPES.Auth_FeatureService)
+      .toConstantValue(
+        new FeatureService(
+          container.get<RoleToSubscriptionMapInterface>(TYPES.Auth_RoleToSubscriptionMap),
+          container.get<OfflineUserSubscriptionRepositoryInterface>(TYPES.Auth_OfflineUserSubscriptionRepository),
+          container.get<TimerInterface>(TYPES.Auth_Timer),
+          container.get<UserSubscriptionRepositoryInterface>(TYPES.Auth_UserSubscriptionRepository),
+        ),
+      )
     container
       .bind<SelectorInterface<boolean>>(TYPES.Auth_BooleanSelector)
       .toConstantValue(new DeterministicSelector<boolean>())
@@ -1104,6 +1113,7 @@ export class ContainerConfigLoader {
         new DeleteAccount(
           container.get<UserRepositoryInterface>(TYPES.Auth_UserRepository),
           container.get<GetRegularSubscriptionForUser>(TYPES.Auth_GetRegularSubscriptionForUser),
+          container.get<GetSharedSubscriptionForUser>(TYPES.Auth_GetSharedSubscriptionForUser),
           container.get<DomainEventPublisherInterface>(TYPES.Auth_DomainEventPublisher),
           container.get<DomainEventFactoryInterface>(TYPES.Auth_DomainEventFactory),
           container.get<TimerInterface>(TYPES.Auth_Timer),

+ 9 - 2
packages/auth/src/Domain/Event/DomainEventFactory.ts

@@ -281,9 +281,16 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
 
   createAccountDeletionRequestedEvent(dto: {
     userUuid: string
+    email: string
     userCreatedAtTimestamp: number
-    regularSubscriptionUuid: string | undefined
-    roleNames: string[]
+    regularSubscription?: {
+      uuid: string
+      ownerUuid: string
+    }
+    sharedSubscription?: {
+      uuid: string
+      ownerUuid: string
+    }
   }): AccountDeletionRequestedEvent {
     return {
       type: 'ACCOUNT_DELETION_REQUESTED',

+ 9 - 2
packages/auth/src/Domain/Event/DomainEventFactoryInterface.ts

@@ -45,9 +45,16 @@ export interface DomainEventFactoryInterface {
   ): EmailBackupRequestedEvent
   createAccountDeletionRequestedEvent(dto: {
     userUuid: string
+    email: string
     userCreatedAtTimestamp: number
-    regularSubscriptionUuid: string | undefined
-    roleNames: string[]
+    regularSubscription?: {
+      uuid: string
+      ownerUuid: string
+    }
+    sharedSubscription?: {
+      uuid: string
+      ownerUuid: string
+    }
   }): AccountDeletionRequestedEvent
   createUserRolesChangedEvent(userUuid: string, email: string, currentRoles: string[]): UserRolesChangedEvent
   createUserEmailChangedEvent(userUuid: string, fromEmail: string, toEmail: string): UserEmailChangedEvent

+ 34 - 18
packages/auth/src/Domain/Feature/FeatureService.spec.ts

@@ -35,6 +35,7 @@ import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/Offl
 import { TimerInterface } from '@standardnotes/time'
 import { OfflineUserSubscription } from '../Subscription/OfflineUserSubscription'
 import { UserSubscriptionType } from '../Subscription/UserSubscriptionType'
+import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface'
 
 describe('FeatureService', () => {
   let roleToSubscriptionMap: RoleToSubscriptionMapInterface
@@ -52,8 +53,10 @@ describe('FeatureService', () => {
   let offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface
   let timer: TimerInterface
   let offlineUserSubscription: OfflineUserSubscription
+  let userSubscriptionRepository: UserSubscriptionRepositoryInterface
 
-  const createService = () => new FeatureService(roleToSubscriptionMap, offlineUserSubscriptionRepository, timer)
+  const createService = () =>
+    new FeatureService(roleToSubscriptionMap, offlineUserSubscriptionRepository, timer, userSubscriptionRepository)
 
   beforeEach(() => {
     roleToSubscriptionMap = {} as jest.Mocked<RoleToSubscriptionMapInterface>
@@ -107,7 +110,7 @@ describe('FeatureService', () => {
       renewedAt: null,
       planName: SubscriptionName.PlusPlan,
       endsAt: 555,
-      user: Promise.resolve(user),
+      userUuid: 'user-1-1-1',
       cancelled: false,
       subscriptionId: 1,
       subscriptionType: UserSubscriptionType.Regular,
@@ -120,7 +123,7 @@ describe('FeatureService', () => {
       renewedAt: null,
       planName: SubscriptionName.ProPlan,
       endsAt: 777,
-      user: Promise.resolve(user),
+      userUuid: 'user-1-1-1',
       cancelled: false,
       subscriptionId: 2,
       subscriptionType: UserSubscriptionType.Regular,
@@ -133,7 +136,7 @@ describe('FeatureService', () => {
       renewedAt: null,
       planName: SubscriptionName.PlusPlan,
       endsAt: 333,
-      user: Promise.resolve(user),
+      userUuid: 'user-1-1-1',
       cancelled: true,
       subscriptionId: 3,
       subscriptionType: UserSubscriptionType.Regular,
@@ -146,7 +149,7 @@ describe('FeatureService', () => {
       renewedAt: null,
       planName: SubscriptionName.PlusPlan,
       endsAt: 333,
-      user: Promise.resolve(user),
+      userUuid: 'user-1-1-1',
       cancelled: true,
       subscriptionId: 4,
       subscriptionType: UserSubscriptionType.Regular,
@@ -155,9 +158,11 @@ describe('FeatureService', () => {
     user = {
       uuid: 'user-1-1-1',
       roles: Promise.resolve([role1]),
-      subscriptions: Promise.resolve([subscription1]),
     } as jest.Mocked<User>
 
+    userSubscriptionRepository = {} as jest.Mocked<UserSubscriptionRepositoryInterface>
+    userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([subscription1])
+
     offlineUserSubscription = {
       roles: Promise.resolve([role1]),
       uuid: 'subscription-1-1-1',
@@ -247,9 +252,10 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1, role2, nonSubscriptionRole]),
-        subscriptions: Promise.resolve([subscription1, subscription2]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([subscription1, subscription2])
+
       expect(await createService().userIsEntitledToFeature(user, 'files-beta')).toBe(true)
     })
 
@@ -269,9 +275,12 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1]),
-        subscriptions: Promise.resolve([subscription3, subscription1, subscription4]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest
+        .fn()
+        .mockReturnValue([subscription3, subscription1, subscription4])
+
       const features = await createService().getFeaturesForUser(user)
       expect(features).toEqual(
         expect.arrayContaining([
@@ -284,14 +293,13 @@ describe('FeatureService', () => {
     })
 
     it('should not return user features if a subscription could not be found', async () => {
-      const subscriptions: Array<UserSubscription> = []
-
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1]),
-        subscriptions: Promise.resolve(subscriptions),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([])
+
       expect(await createService().getFeaturesForUser(user)).toEqual([])
     })
 
@@ -307,9 +315,12 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1]),
-        subscriptions: Promise.resolve([subscription3, subscription1, subscription4]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest
+        .fn()
+        .mockReturnValue([subscription3, subscription1, subscription4])
+
       expect(await createService().getFeaturesForUser(user)).toEqual([])
     })
 
@@ -321,7 +332,7 @@ describe('FeatureService', () => {
         renewedAt: null,
         planName: 'non existing plan name' as SubscriptionName,
         endsAt: 555,
-        user: Promise.resolve(user),
+        userUuid: 'user-1-1-1',
         cancelled: false,
         subscriptionId: 1,
         subscriptionType: UserSubscriptionType.Regular,
@@ -330,9 +341,10 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1]),
-        subscriptions: Promise.resolve([subscription1]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([subscription1])
+
       expect(await createService().getFeaturesForUser(user)).toEqual([])
     })
 
@@ -351,9 +363,10 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1, role2]),
-        subscriptions: Promise.resolve([subscription1, subscription2]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([subscription1, subscription2])
+
       const features = await createService().getFeaturesForUser(user)
       expect(features).toEqual(
         expect.arrayContaining([
@@ -409,9 +422,10 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1, role2, nonSubscriptionRole]),
-        subscriptions: Promise.resolve([subscription1, subscription2]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([subscription1, subscription2])
+
       const features = await createService().getFeaturesForUser(user)
       expect(features).toEqual(
         expect.arrayContaining([
@@ -445,9 +459,10 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1, role2]),
-        subscriptions: Promise.resolve([subscription1, subscription2]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([subscription1, subscription2])
+
       const longestExpireAt = 777
 
       const features = await createService().getFeaturesForUser(user)
@@ -482,9 +497,10 @@ describe('FeatureService', () => {
       user = {
         uuid: 'user-1-1-1',
         roles: Promise.resolve([role1, role2]),
-        subscriptions: Promise.resolve([subscription1, subscription2]),
       } as jest.Mocked<User>
 
+      userSubscriptionRepository.findByUserUuid = jest.fn().mockReturnValue([subscription1, subscription2])
+
       const features = await createService().getFeaturesForUser(user)
       expect(features).toEqual(
         expect.arrayContaining([

+ 7 - 9
packages/auth/src/Domain/Feature/FeatureService.ts

@@ -1,24 +1,22 @@
 import { SubscriptionName } from '@standardnotes/common'
 import { FeatureDescription, GetFeatures } from '@standardnotes/features'
-import { inject, injectable } from 'inversify'
-import TYPES from '../../Bootstrap/Types'
-import { RoleToSubscriptionMapInterface } from '../Role/RoleToSubscriptionMapInterface'
+import { TimerInterface } from '@standardnotes/time'
 
+import { RoleToSubscriptionMapInterface } from '../Role/RoleToSubscriptionMapInterface'
 import { User } from '../User/User'
 import { UserSubscription } from '../Subscription/UserSubscription'
 import { FeatureServiceInterface } from './FeatureServiceInterface'
 import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/OfflineUserSubscriptionRepositoryInterface'
 import { Role } from '../Role/Role'
 import { OfflineUserSubscription } from '../Subscription/OfflineUserSubscription'
-import { TimerInterface } from '@standardnotes/time'
+import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface'
 
-@injectable()
 export class FeatureService implements FeatureServiceInterface {
   constructor(
-    @inject(TYPES.Auth_RoleToSubscriptionMap) private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
-    @inject(TYPES.Auth_OfflineUserSubscriptionRepository)
+    private roleToSubscriptionMap: RoleToSubscriptionMapInterface,
     private offlineUserSubscriptionRepository: OfflineUserSubscriptionRepositoryInterface,
-    @inject(TYPES.Auth_Timer) private timer: TimerInterface,
+    private timer: TimerInterface,
+    private userSubscriptionRepository: UserSubscriptionRepositoryInterface,
   ) {}
 
   async userIsEntitledToFeature(user: User, featureIdentifier: string): Promise<boolean> {
@@ -61,7 +59,7 @@ export class FeatureService implements FeatureServiceInterface {
   }
 
   async getFeaturesForUser(user: User): Promise<Array<FeatureDescription>> {
-    const userSubscriptions = await user.subscriptions
+    const userSubscriptions = await this.userSubscriptionRepository.findByUserUuid(user.uuid)
 
     return this.getFeaturesForSubscriptions(userSubscriptions, await user.roles)
   }

+ 17 - 2
packages/auth/src/Domain/Handler/SubscriptionExpiredEventHandler.ts

@@ -7,7 +7,7 @@ import { RoleServiceInterface } from '../Role/RoleServiceInterface'
 import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
 import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface'
 import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/OfflineUserSubscriptionRepositoryInterface'
-import { Username } from '@standardnotes/domain-core'
+import { Username, Uuid } from '@standardnotes/domain-core'
 
 @injectable()
 export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterface {
@@ -48,7 +48,22 @@ export class SubscriptionExpiredEventHandler implements DomainEventHandlerInterf
   private async removeRoleFromSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
     const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
     for (const userSubscription of userSubscriptions) {
-      await this.roleService.removeUserRoleBasedOnSubscription(await userSubscription.user, subscriptionName)
+      const userUuidOrError = Uuid.create(userSubscription.userUuid)
+      if (userUuidOrError.isFailed()) {
+        this.logger.warn(`Could not remove role from user with uuid: ${userUuidOrError.getError()}`)
+
+        continue
+      }
+      const userUuid = userUuidOrError.getValue()
+
+      const user = await this.userRepository.findOneByUuid(userUuid)
+      if (user === null) {
+        this.logger.warn(`Could not find user with uuid: ${userUuid.value}`)
+
+        continue
+      }
+
+      await this.roleService.removeUserRoleBasedOnSubscription(user, subscriptionName)
     }
   }
 

+ 1 - 1
packages/auth/src/Domain/Handler/SubscriptionPurchasedEventHandler.ts

@@ -84,7 +84,7 @@ export class SubscriptionPurchasedEventHandler implements DomainEventHandlerInte
   ): Promise<UserSubscription> {
     const subscription = new UserSubscription()
     subscription.planName = subscriptionName
-    subscription.user = Promise.resolve(user)
+    subscription.userUuid = user.uuid
     subscription.createdAt = timestamp
     subscription.updatedAt = timestamp
     subscription.endsAt = subscriptionExpiresAt

+ 1 - 1
packages/auth/src/Domain/Handler/SubscriptionReassignedEventHandler.ts

@@ -80,7 +80,7 @@ export class SubscriptionReassignedEventHandler implements DomainEventHandlerInt
   ): Promise<UserSubscription> {
     const subscription = new UserSubscription()
     subscription.planName = subscriptionName
-    subscription.user = Promise.resolve(user)
+    subscription.userUuid = user.uuid
     subscription.createdAt = timestamp
     subscription.updatedAt = timestamp
     subscription.endsAt = subscriptionExpiresAt

+ 17 - 2
packages/auth/src/Domain/Handler/SubscriptionRefundedEventHandler.ts

@@ -7,7 +7,7 @@ import { RoleServiceInterface } from '../Role/RoleServiceInterface'
 import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
 import { UserSubscriptionRepositoryInterface } from '../Subscription/UserSubscriptionRepositoryInterface'
 import { OfflineUserSubscriptionRepositoryInterface } from '../Subscription/OfflineUserSubscriptionRepositoryInterface'
-import { Username } from '@standardnotes/domain-core'
+import { Username, Uuid } from '@standardnotes/domain-core'
 
 @injectable()
 export class SubscriptionRefundedEventHandler implements DomainEventHandlerInterface {
@@ -48,7 +48,22 @@ export class SubscriptionRefundedEventHandler implements DomainEventHandlerInter
   private async removeRoleFromSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
     const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
     for (const userSubscription of userSubscriptions) {
-      await this.roleService.removeUserRoleBasedOnSubscription(await userSubscription.user, subscriptionName)
+      const userUuidOrError = Uuid.create(userSubscription.userUuid)
+      if (userUuidOrError.isFailed()) {
+        this.logger.warn(`Could not remove role from user with uuid: ${userUuidOrError.getError()}`)
+
+        continue
+      }
+      const userUuid = userUuidOrError.getValue()
+
+      const user = await this.userRepository.findOneByUuid(userUuid)
+      if (user === null) {
+        this.logger.warn(`Could not find user with uuid: ${userUuid.value}`)
+
+        continue
+      }
+
+      await this.roleService.removeUserRoleBasedOnSubscription(user, subscriptionName)
     }
   }
 

+ 15 - 2
packages/auth/src/Domain/Handler/SubscriptionRenewedEventHandler.ts

@@ -8,7 +8,7 @@ import { RoleServiceInterface } from '../Role/RoleServiceInterface'
 import { UserRepositoryInterface } from '../User/UserRepositoryInterface'
 import { Logger } from 'winston'
 import { OfflineUserSubscription } from '../Subscription/OfflineUserSubscription'
-import { Username } from '@standardnotes/domain-core'
+import { Username, Uuid } from '@standardnotes/domain-core'
 
 @injectable()
 export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterface {
@@ -71,7 +71,20 @@ export class SubscriptionRenewedEventHandler implements DomainEventHandlerInterf
   private async addRoleToSubscriptionUsers(subscriptionId: number, subscriptionName: string): Promise<void> {
     const userSubscriptions = await this.userSubscriptionRepository.findBySubscriptionId(subscriptionId)
     for (const userSubscription of userSubscriptions) {
-      const user = await userSubscription.user
+      const userUuidOrError = Uuid.create(userSubscription.userUuid)
+      if (userUuidOrError.isFailed()) {
+        this.logger.warn(`Could not add role to user with uuid: ${userUuidOrError.getError()}`)
+
+        continue
+      }
+      const userUuid = userUuidOrError.getValue()
+
+      const user = await this.userRepository.findOneByUuid(userUuid)
+      if (user === null) {
+        this.logger.warn(`Could not find user with uuid: ${userUuid.value}`)
+
+        continue
+      }
 
       await this.roleService.addUserRoleBasedOnSubscription(user, subscriptionName)
     }

+ 1 - 1
packages/auth/src/Domain/Handler/SubscriptionSyncRequestedEventHandler.ts

@@ -128,7 +128,7 @@ export class SubscriptionSyncRequestedEventHandler implements DomainEventHandler
     }
 
     subscription.planName = subscriptionName
-    subscription.user = Promise.resolve(user)
+    subscription.userUuid = user.uuid
     subscription.createdAt = timestamp
     subscription.updatedAt = timestamp
     subscription.endsAt = subscriptionExpiresAt

+ 6 - 12
packages/auth/src/Domain/Subscription/UserSubscription.ts

@@ -1,5 +1,4 @@
-import { Column, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn } from 'typeorm'
-import { User } from '../User/User'
+import { Column, Entity, Index, PrimaryGeneratedColumn } from 'typeorm'
 import { UserSubscriptionType } from './UserSubscriptionType'
 
 @Entity({ name: 'user_subscriptions' })
@@ -63,14 +62,9 @@ export class UserSubscription {
   })
   declare subscriptionType: UserSubscriptionType
 
-  @ManyToOne(
-    /* istanbul ignore next */
-    () => User,
-    /* istanbul ignore next */
-    (user) => user.subscriptions,
-    /* istanbul ignore next */
-    { onDelete: 'CASCADE', nullable: false, lazy: true, eager: false },
-  )
-  @JoinColumn({ name: 'user_uuid', referencedColumnName: 'uuid' })
-  declare user: Promise<User>
+  @Column({
+    name: 'user_uuid',
+    length: 36,
+  })
+  declare userUuid: string
 }

+ 2 - 2
packages/auth/src/Domain/UseCase/AcceptSharedSubscriptionInvitation/AcceptSharedSubscriptionInvitation.spec.ts

@@ -107,7 +107,7 @@ describe('AcceptSharedSubscriptionInvitation', () => {
       subscriptionId: 3,
       subscriptionType: 'shared',
       updatedAt: 1,
-      user: Promise.resolve(invitee),
+      userUuid: '123',
     })
     expect(roleService.addUserRoleBasedOnSubscription).toHaveBeenCalledWith(invitee, 'PLUS_PLAN')
     expect(applyDefaultSubscriptionSettings.execute).toHaveBeenCalled()
@@ -145,7 +145,7 @@ describe('AcceptSharedSubscriptionInvitation', () => {
       subscriptionId: 3,
       subscriptionType: 'shared',
       updatedAt: 3,
-      user: Promise.resolve(invitee),
+      userUuid: '123',
     })
     expect(roleService.addUserRoleBasedOnSubscription).toHaveBeenCalledWith(invitee, 'PLUS_PLAN')
     expect(applyDefaultSubscriptionSettings.execute).toHaveBeenCalled()

+ 1 - 1
packages/auth/src/Domain/UseCase/AcceptSharedSubscriptionInvitation/AcceptSharedSubscriptionInvitation.ts

@@ -115,7 +115,7 @@ export class AcceptSharedSubscriptionInvitation implements UseCaseInterface {
   ): Promise<UserSubscription> {
     const subscription = new UserSubscription()
     subscription.planName = subscriptionName
-    subscription.user = Promise.resolve(user)
+    subscription.userUuid = user.uuid
     const timestamp = this.timer.getTimestampInMicroseconds()
     subscription.createdAt = timestamp
     subscription.updatedAt = timestamp

+ 1 - 1
packages/auth/src/Domain/UseCase/ActivatePremiumFeatures/ActivatePremiumFeatures.ts

@@ -53,7 +53,7 @@ export class ActivatePremiumFeatures implements UseCaseInterface<string> {
 
     const subscription = new UserSubscription()
     subscription.planName = subscriptionPlanName.value
-    subscription.user = Promise.resolve(user)
+    subscription.userUuid = user.uuid
     subscription.createdAt = timestamp
     subscription.updatedAt = timestamp
     subscription.endsAt = this.timer.convertDateToMicroseconds(endsAt)

+ 2 - 2
packages/auth/src/Domain/UseCase/CancelSharedSubscriptionInvitation/CancelSharedSubscriptionInvitation.spec.ts

@@ -80,7 +80,7 @@ describe('CancelSharedSubscriptionInvitation', () => {
     userSubscriptionRepository.findBySubscriptionIdAndType = jest.fn().mockReturnValue([inviterSubscription])
     userSubscriptionRepository.findOneByUserUuidAndSubscriptionId = jest
       .fn()
-      .mockReturnValue({ user: Promise.resolve(invitee) } as jest.Mocked<UserSubscription>)
+      .mockReturnValue({ userUuid: '123' } as jest.Mocked<UserSubscription>)
     userSubscriptionRepository.save = jest.fn()
 
     roleService = {} as jest.Mocked<RoleServiceInterface>
@@ -120,7 +120,7 @@ describe('CancelSharedSubscriptionInvitation', () => {
     })
     expect(userSubscriptionRepository.save).toHaveBeenCalledWith({
       endsAt: 1,
-      user: Promise.resolve(invitee),
+      userUuid: '123',
     })
     expect(roleService.removeUserRoleBasedOnSubscription).toHaveBeenCalledWith(invitee, 'PLUS_PLAN')
     expect(domainEventPublisher.publish).toHaveBeenCalled()

+ 2 - 8
packages/auth/src/Domain/UseCase/CreateValetToken/CreateValetToken.spec.ts

@@ -5,7 +5,6 @@ import { TokenEncoderInterface, ValetTokenData, ValetTokenOperation } from '@sta
 
 import { CreateValetToken } from './CreateValetToken'
 import { UserSubscription } from '../../Subscription/UserSubscription'
-import { User } from '../../User/User'
 import { UserSubscriptionType } from '../../Subscription/UserSubscriptionType'
 import { SubscriptionSettingsAssociationServiceInterface } from '../../Setting/SubscriptionSettingsAssociationServiceInterface'
 import { GetRegularSubscriptionForUser } from '../GetRegularSubscriptionForUser/GetRegularSubscriptionForUser'
@@ -25,7 +24,6 @@ describe('CreateValetToken', () => {
   const valetTokenTTL = 123
   let regularSubscription: UserSubscription
   let sharedSubscription: UserSubscription
-  let user: User
 
   const createUseCase = () =>
     new CreateValetToken(
@@ -59,20 +57,16 @@ describe('CreateValetToken', () => {
     subscriptionSettingsAssociationService = {} as jest.Mocked<SubscriptionSettingsAssociationServiceInterface>
     subscriptionSettingsAssociationService.getFileUploadLimit = jest.fn().mockReturnValue(5_368_709_120)
 
-    user = {
-      uuid: '123',
-    } as jest.Mocked<User>
-
     regularSubscription = {
       uuid: '1-2-3',
       subscriptionType: UserSubscriptionType.Regular,
-      user: Promise.resolve(user),
+      userUuid: '123',
     } as jest.Mocked<UserSubscription>
 
     sharedSubscription = {
       uuid: '2-3-4',
       subscriptionType: UserSubscriptionType.Shared,
-      user: Promise.resolve(user),
+      userUuid: '123',
     } as jest.Mocked<UserSubscription>
 
     getRegularSubscription = {} as jest.Mocked<GetRegularSubscriptionForUser>

+ 84 - 12
packages/auth/src/Domain/UseCase/DeleteAccount/DeleteAccount.spec.ts

@@ -11,29 +11,46 @@ import { TimerInterface } from '@standardnotes/time'
 import { Result, RoleName } from '@standardnotes/domain-core'
 import { Role } from '../../Role/Role'
 import { GetRegularSubscriptionForUser } from '../GetRegularSubscriptionForUser/GetRegularSubscriptionForUser'
+import { GetSharedSubscriptionForUser } from '../GetSharedSubscriptionForUser/GetSharedSubscriptionForUser'
 
 describe('DeleteAccount', () => {
   let userRepository: UserRepositoryInterface
   let domainEventPublisher: DomainEventPublisherInterface
   let domainEventFactory: DomainEventFactoryInterface
   let getRegularSubscription: GetRegularSubscriptionForUser
+  let getSharedSubscription: GetSharedSubscriptionForUser
   let user: User
   let regularSubscription: UserSubscription
+  let sharedSubscription: UserSubscription
   let timer: TimerInterface
 
   const createUseCase = () =>
-    new DeleteAccount(userRepository, getRegularSubscription, domainEventPublisher, domainEventFactory, timer)
+    new DeleteAccount(
+      userRepository,
+      getRegularSubscription,
+      getSharedSubscription,
+      domainEventPublisher,
+      domainEventFactory,
+      timer,
+    )
 
   beforeEach(() => {
     user = {
       uuid: '1-2-3',
+      email: 'test@test.te',
     } as jest.Mocked<User>
     user.roles = Promise.resolve([{ name: RoleName.NAMES.CoreUser } as jest.Mocked<Role>])
 
     regularSubscription = {
       uuid: '1-2-3',
       subscriptionType: UserSubscriptionType.Regular,
-      user: Promise.resolve(user),
+      userUuid: 'u-1-2-3',
+    } as jest.Mocked<UserSubscription>
+
+    sharedSubscription = {
+      uuid: '1-2-3',
+      subscriptionType: UserSubscriptionType.Shared,
+      userUuid: 'u-1-2-3',
     } as jest.Mocked<UserSubscription>
 
     userRepository = {} as jest.Mocked<UserRepositoryInterface>
@@ -43,6 +60,9 @@ describe('DeleteAccount', () => {
     getRegularSubscription = {} as jest.Mocked<GetRegularSubscriptionForUser>
     getRegularSubscription.execute = jest.fn().mockReturnValue(Result.ok(regularSubscription))
 
+    getSharedSubscription = {} as jest.Mocked<GetSharedSubscriptionForUser>
+    getSharedSubscription.execute = jest.fn().mockReturnValue(Result.ok(sharedSubscription))
+
     domainEventPublisher = {} as jest.Mocked<DomainEventPublisherInterface>
     domainEventPublisher.publish = jest.fn()
 
@@ -58,20 +78,43 @@ describe('DeleteAccount', () => {
   describe('when user uuid is provided', () => {
     it('should trigger account deletion - no subscription', async () => {
       getRegularSubscription.execute = jest.fn().mockReturnValue(Result.fail('not found'))
+      getSharedSubscription.execute = jest.fn().mockReturnValue(Result.fail('not found'))
+
+      const result = await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })
+
+      expect(result.isFailed()).toBeFalsy()
+      expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
+      expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
+        userUuid: '1-2-3',
+        userCreatedAtTimestamp: 1,
+        email: 'test@test.te',
+      })
+    })
 
+    it('should trigger account deletion - shared subscription present', async () => {
       const result = await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })
 
       expect(result.isFailed()).toBeFalsy()
+
       expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
       expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
         userUuid: '1-2-3',
+        email: 'test@test.te',
         userCreatedAtTimestamp: 1,
-        regularSubscriptionUuid: undefined,
-        roleNames: ['CORE_USER'],
+        regularSubscription: {
+          ownerUuid: 'u-1-2-3',
+          uuid: '1-2-3',
+        },
+        sharedSubscription: {
+          ownerUuid: 'u-1-2-3',
+          uuid: '1-2-3',
+        },
       })
     })
 
-    it('should trigger account deletion - subscription present', async () => {
+    it('should trigger account deletion - regular subscription present', async () => {
+      getSharedSubscription.execute = jest.fn().mockReturnValue(Result.fail('not found'))
+
       const result = await createUseCase().execute({ userUuid: '00000000-0000-0000-0000-000000000000' })
 
       expect(result.isFailed()).toBeFalsy()
@@ -79,9 +122,12 @@ describe('DeleteAccount', () => {
       expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
       expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
         userUuid: '1-2-3',
+        email: 'test@test.te',
         userCreatedAtTimestamp: 1,
-        regularSubscriptionUuid: '1-2-3',
-        roleNames: ['CORE_USER'],
+        regularSubscription: {
+          ownerUuid: 'u-1-2-3',
+          uuid: '1-2-3',
+        },
       })
     })
 
@@ -109,20 +155,43 @@ describe('DeleteAccount', () => {
   describe('when username is provided', () => {
     it('should trigger account deletion - no subscription', async () => {
       getRegularSubscription.execute = jest.fn().mockReturnValue(Result.fail('not found'))
+      getSharedSubscription.execute = jest.fn().mockReturnValue(Result.fail('not found'))
+
+      const result = await createUseCase().execute({ username: 'test@test.te' })
+
+      expect(result.isFailed()).toBeFalsy()
+      expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
+      expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
+        userUuid: '1-2-3',
+        email: 'test@test.te',
+        userCreatedAtTimestamp: 1,
+      })
+    })
 
+    it('should trigger account deletion - shared subscription present', async () => {
       const result = await createUseCase().execute({ username: 'test@test.te' })
 
       expect(result.isFailed()).toBeFalsy()
+
       expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
       expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
         userUuid: '1-2-3',
+        email: 'test@test.te',
         userCreatedAtTimestamp: 1,
-        regularSubscriptionUuid: undefined,
-        roleNames: ['CORE_USER'],
+        regularSubscription: {
+          ownerUuid: 'u-1-2-3',
+          uuid: '1-2-3',
+        },
+        sharedSubscription: {
+          ownerUuid: 'u-1-2-3',
+          uuid: '1-2-3',
+        },
       })
     })
 
-    it('should trigger account deletion - subscription present', async () => {
+    it('should trigger account deletion - regular subscription present', async () => {
+      getSharedSubscription.execute = jest.fn().mockReturnValue(Result.fail('not found'))
+
       const result = await createUseCase().execute({ username: 'test@test.te' })
 
       expect(result.isFailed()).toBeFalsy()
@@ -130,9 +199,12 @@ describe('DeleteAccount', () => {
       expect(domainEventPublisher.publish).toHaveBeenCalledTimes(1)
       expect(domainEventFactory.createAccountDeletionRequestedEvent).toHaveBeenLastCalledWith({
         userUuid: '1-2-3',
+        email: 'test@test.te',
         userCreatedAtTimestamp: 1,
-        regularSubscriptionUuid: '1-2-3',
-        roleNames: ['CORE_USER'],
+        regularSubscription: {
+          ownerUuid: 'u-1-2-3',
+          uuid: '1-2-3',
+        },
       })
     })
 

+ 27 - 8
packages/auth/src/Domain/UseCase/DeleteAccount/DeleteAccount.ts

@@ -8,11 +8,14 @@ import { UserRepositoryInterface } from '../../User/UserRepositoryInterface'
 import { DeleteAccountDTO } from './DeleteAccountDTO'
 import { User } from '../../User/User'
 import { GetRegularSubscriptionForUser } from '../GetRegularSubscriptionForUser/GetRegularSubscriptionForUser'
+import { UserSubscription } from '../../Subscription/UserSubscription'
+import { GetSharedSubscriptionForUser } from '../GetSharedSubscriptionForUser/GetSharedSubscriptionForUser'
 
 export class DeleteAccount implements UseCaseInterface<string> {
   constructor(
     private userRepository: UserRepositoryInterface,
     private getRegularSubscription: GetRegularSubscriptionForUser,
+    private getSharedSubscription: GetSharedSubscriptionForUser,
     private domainEventPublisher: DomainEventPublisherInterface,
     private domainEventFactory: DomainEventFactoryInterface,
     private timer: TimerInterface,
@@ -44,23 +47,39 @@ export class DeleteAccount implements UseCaseInterface<string> {
       return Result.ok('User already deleted.')
     }
 
-    const roles = await user.roles
+    let sharedSubscription: UserSubscription | undefined
+    const sharedSubscriptionOrError = await this.getSharedSubscription.execute({
+      userUuid: user.uuid,
+    })
+    if (!sharedSubscriptionOrError.isFailed()) {
+      sharedSubscription = sharedSubscriptionOrError.getValue()
+    }
 
-    let regularSubscriptionUuid: string | undefined
-    const result = await this.getRegularSubscription.execute({
+    let regularSubscription: UserSubscription | undefined
+    const regularSubscriptionOrError = await this.getRegularSubscription.execute({
       userUuid: user.uuid,
     })
-    if (!result.isFailed()) {
-      const regularSubscription = result.getValue()
-      regularSubscriptionUuid = regularSubscription.uuid
+    if (!regularSubscriptionOrError.isFailed()) {
+      regularSubscription = regularSubscriptionOrError.getValue()
     }
 
     await this.domainEventPublisher.publish(
       this.domainEventFactory.createAccountDeletionRequestedEvent({
         userUuid: user.uuid,
+        email: user.email,
         userCreatedAtTimestamp: this.timer.convertDateToMicroseconds(user.createdAt),
-        regularSubscriptionUuid,
-        roleNames: roles.map((role) => role.name),
+        regularSubscription: regularSubscription
+          ? {
+              ownerUuid: regularSubscription.userUuid,
+              uuid: regularSubscription.uuid,
+            }
+          : undefined,
+        sharedSubscription: sharedSubscription
+          ? {
+              ownerUuid: sharedSubscription.userUuid,
+              uuid: sharedSubscription.uuid,
+            }
+          : undefined,
       }),
     )
 

+ 2 - 2
packages/auth/src/Domain/UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser.spec.ts

@@ -45,13 +45,13 @@ describe('UpdateStorageQuotaUsedForUser', () => {
     regularSubscription = {
       uuid: '00000000-0000-0000-0000-000000000000',
       subscriptionType: UserSubscriptionType.Regular,
-      user: Promise.resolve(user),
+      userUuid: '123',
     } as jest.Mocked<UserSubscription>
 
     sharedSubscription = {
       uuid: '2-3-4',
       subscriptionType: UserSubscriptionType.Shared,
-      user: Promise.resolve(user),
+      userUuid: '123',
     } as jest.Mocked<UserSubscription>
 
     getSharedSubscription = {} as jest.Mocked<GetSharedSubscriptionForUser>

+ 1 - 2
packages/auth/src/Domain/UseCase/UpdateStorageQuotaUsedForUser/UpdateStorageQuotaUsedForUser.ts

@@ -56,7 +56,6 @@ export class UpdateStorageQuotaUsedForUser implements UseCaseInterface<void> {
 
   private async updateUploadBytesUsedSetting(subscription: UserSubscription, bytesUsed: number): Promise<void> {
     let bytesAlreadyUsed = '0'
-    const subscriptionUser = await subscription.user
 
     const bytesUsedSettingExists = await this.getSubscriptionSetting.execute({
       userSubscriptionUuid: subscription.uuid,
@@ -77,7 +76,7 @@ export class UpdateStorageQuotaUsedForUser implements UseCaseInterface<void> {
 
     /* istanbul ignore next */
     if (result.isFailed()) {
-      this.logger.error(`Could not set file upload bytes used for user ${subscriptionUser.uuid}`)
+      this.logger.error(`Could not set file upload bytes used for subscription ${subscription.uuid}`)
     }
   }
 }

+ 0 - 11
packages/auth/src/Domain/User/User.ts

@@ -1,7 +1,6 @@
 import { Column, Entity, Index, JoinTable, ManyToMany, OneToMany, PrimaryGeneratedColumn } from 'typeorm'
 import { RevokedSession } from '../Session/RevokedSession'
 import { Role } from '../Role/Role'
-import { UserSubscription } from '../Subscription/UserSubscription'
 import { ProtocolVersion } from '@standardnotes/common'
 import { TypeORMEmergencyAccessInvitation } from '../../Infra/TypeORM/TypeORMEmergencyAccessInvitation'
 
@@ -161,16 +160,6 @@ export class User {
   })
   declare roles: Promise<Array<Role>>
 
-  @OneToMany(
-    /* istanbul ignore next */
-    () => UserSubscription,
-    /* istanbul ignore next */
-    (subscription) => subscription.user,
-    /* istanbul ignore next */
-    { lazy: true, eager: false },
-  )
-  declare subscriptions: Promise<UserSubscription[]>
-
   @OneToMany(
     /* istanbul ignore next */
     () => TypeORMEmergencyAccessInvitation,

+ 9 - 1
packages/domain-events/src/Domain/Event/AccountDeletionRequestedEventPayload.ts

@@ -1,5 +1,13 @@
 export interface AccountDeletionRequestedEventPayload {
   userUuid: string
+  email: string
   userCreatedAtTimestamp: number
-  regularSubscriptionUuid: string | undefined
+  regularSubscription?: {
+    uuid: string
+    ownerUuid: string
+  }
+  sharedSubscription?: {
+    uuid: string
+    ownerUuid: string
+  }
 }

+ 0 - 1
packages/domain-events/src/Domain/Event/FileRemovedEventPayload.ts

@@ -1,6 +1,5 @@
 export interface FileRemovedEventPayload {
   userUuid: string
-  regularSubscriptionUuid: string
   fileByteSize: number
   filePath: string
   fileName: string

+ 0 - 1
packages/files/src/Domain/Event/DomainEventFactory.ts

@@ -18,7 +18,6 @@ export class DomainEventFactory implements DomainEventFactoryInterface {
     filePath: string
     fileName: string
     fileByteSize: number
-    regularSubscriptionUuid: string
   }): FileRemovedEvent {
     return {
       type: 'FILE_REMOVED',

+ 0 - 1
packages/files/src/Domain/Event/DomainEventFactoryInterface.ts

@@ -18,7 +18,6 @@ export interface DomainEventFactoryInterface {
     filePath: string
     fileName: string
     fileByteSize: number
-    regularSubscriptionUuid: string
   }): FileRemovedEvent
   createSharedVaultFileMovedEvent(payload: {
     fileByteSize: number

+ 1 - 2
packages/files/src/Domain/Handler/AccountDeletionRequestedEventHandler.ts

@@ -17,7 +17,7 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
   ) {}
 
   async handle(event: AccountDeletionRequestedEvent): Promise<void> {
-    if (event.payload.regularSubscriptionUuid === undefined) {
+    if (event.payload.regularSubscription === undefined) {
       return
     }
 
@@ -38,7 +38,6 @@ export class AccountDeletionRequestedEventHandler implements DomainEventHandlerI
     for (const fileRemoved of filesRemoved) {
       await this.domainEventPublisher.publish(
         this.domainEventFactory.createFileRemovedEvent({
-          regularSubscriptionUuid: event.payload.regularSubscriptionUuid,
           userUuid: fileRemoved.userOrSharedVaultUuid,
           filePath: fileRemoved.filePath,
           fileName: fileRemoved.fileName,

+ 0 - 1
packages/files/src/Domain/Handler/SharedSubscriptionInvitationCanceledEventHandler.ts

@@ -40,7 +40,6 @@ export class SharedSubscriptionInvitationCanceledEventHandler implements DomainE
     for (const fileRemoved of filesRemoved) {
       await this.domainEventPublisher.publish(
         this.domainEventFactory.createFileRemovedEvent({
-          regularSubscriptionUuid: event.payload.inviterSubscriptionUuid,
           userUuid: fileRemoved.userOrSharedVaultUuid,
           filePath: fileRemoved.filePath,
           fileName: fileRemoved.fileName,

+ 0 - 1
packages/files/src/Domain/UseCase/RemoveFile/RemoveFile.ts

@@ -36,7 +36,6 @@ export class RemoveFile implements UseCaseInterface<boolean> {
             filePath: `${dto.userInput.userUuid}/${dto.userInput.resourceRemoteIdentifier}`,
             fileName: dto.userInput.resourceRemoteIdentifier,
             fileByteSize: removedFileSize,
-            regularSubscriptionUuid: dto.userInput.regularSubscriptionUuid,
           }),
         )
       } else if (dto.vaultInput !== undefined) {

+ 0 - 46
packages/revisions/src/Domain/Handler/AccountDeletionRequestedEventHandler.spec.ts

@@ -1,46 +0,0 @@
-import 'reflect-metadata'
-
-import { AccountDeletionRequestedEvent } from '@standardnotes/domain-events'
-import { Logger } from 'winston'
-import { AccountDeletionRequestedEventHandler } from './AccountDeletionRequestedEventHandler'
-import { RevisionRepositoryInterface } from '../Revision/RevisionRepositoryInterface'
-
-describe('AccountDeletionRequestedEventHandler', () => {
-  let revisionRepository: RevisionRepositoryInterface
-  let logger: Logger
-  let event: AccountDeletionRequestedEvent
-
-  const createHandler = () => new AccountDeletionRequestedEventHandler(revisionRepository, logger)
-
-  beforeEach(() => {
-    revisionRepository = {} as jest.Mocked<RevisionRepositoryInterface>
-    revisionRepository.removeByUserUuid = jest.fn()
-
-    logger = {} as jest.Mocked<Logger>
-    logger.info = jest.fn()
-    logger.warn = jest.fn()
-    logger.error = jest.fn()
-
-    event = {} as jest.Mocked<AccountDeletionRequestedEvent>
-    event.createdAt = new Date(1)
-    event.payload = {
-      userUuid: '2-3-4',
-      userCreatedAtTimestamp: 1,
-      regularSubscriptionUuid: '1-2-3',
-    }
-  })
-
-  it('should remove all revisions for a user', async () => {
-    event.payload.userUuid = '84c0f8e8-544a-4c7e-9adf-26209303bc1d'
-
-    await createHandler().handle(event)
-
-    expect(revisionRepository.removeByUserUuid).toHaveBeenCalled()
-  })
-
-  it('should not remove all revisions for an invalid user uuid', async () => {
-    await createHandler().handle(event)
-
-    expect(revisionRepository.removeByUserUuid).not.toHaveBeenCalled()
-  })
-})