feat(analytics): add saving revenue modifications upon subscription canceled
This commit is contained in:
parent
7480fb089b
commit
52a257abb1
4 changed files with 38 additions and 2 deletions
|
@ -9,14 +9,19 @@ import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||||
import { Period } from '../Time/Period'
|
import { Period } from '../Time/Period'
|
||||||
|
import { Result } from '../Core/Result'
|
||||||
|
import { RevenueModification } from '../Revenue/RevenueModification'
|
||||||
|
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||||
|
|
||||||
describe('SubscriptionCancelledEventHandler', () => {
|
describe('SubscriptionCancelledEventHandler', () => {
|
||||||
let event: SubscriptionCancelledEvent
|
let event: SubscriptionCancelledEvent
|
||||||
let getUserAnalyticsId: GetUserAnalyticsId
|
let getUserAnalyticsId: GetUserAnalyticsId
|
||||||
let analyticsStore: AnalyticsStoreInterface
|
let analyticsStore: AnalyticsStoreInterface
|
||||||
let statisticsStore: StatisticsStoreInterface
|
let statisticsStore: StatisticsStoreInterface
|
||||||
|
let saveRevenueModification: SaveRevenueModification
|
||||||
|
|
||||||
const createHandler = () => new SubscriptionCancelledEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore)
|
const createHandler = () =>
|
||||||
|
new SubscriptionCancelledEventHandler(getUserAnalyticsId, analyticsStore, statisticsStore, saveRevenueModification)
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
getUserAnalyticsId = {} as jest.Mocked<GetUserAnalyticsId>
|
||||||
|
@ -30,6 +35,7 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||||
|
|
||||||
event = {} as jest.Mocked<SubscriptionCancelledEvent>
|
event = {} as jest.Mocked<SubscriptionCancelledEvent>
|
||||||
event.createdAt = new Date(1)
|
event.createdAt = new Date(1)
|
||||||
|
event.type = 'SUBSCRIPTION_CANCELLED'
|
||||||
event.payload = {
|
event.payload = {
|
||||||
subscriptionId: 1,
|
subscriptionId: 1,
|
||||||
userEmail: 'test@test.com',
|
userEmail: 'test@test.com',
|
||||||
|
@ -41,7 +47,13 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||||
timestamp: 1,
|
timestamp: 1,
|
||||||
offline: false,
|
offline: false,
|
||||||
replaced: false,
|
replaced: false,
|
||||||
|
userExistingSubscriptionsCount: 1,
|
||||||
|
billingFrequency: 1,
|
||||||
|
payAmount: 12.99,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saveRevenueModification = {} as jest.Mocked<SaveRevenueModification>
|
||||||
|
saveRevenueModification.execute = jest.fn().mockReturnValue(Result.ok<RevenueModification>())
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should track subscription cancelled statistics', async () => {
|
it('should track subscription cancelled statistics', async () => {
|
||||||
|
@ -55,6 +67,7 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||||
Period.ThisWeek,
|
Period.ThisWeek,
|
||||||
Period.ThisMonth,
|
Period.ThisMonth,
|
||||||
])
|
])
|
||||||
|
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should not track statistics for subscriptions that are in a legacy 5 year plan', async () => {
|
it('should not track statistics for subscriptions that are in a legacy 5 year plan', async () => {
|
||||||
|
@ -65,5 +78,6 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||||
await createHandler().handle(event)
|
await createHandler().handle(event)
|
||||||
|
|
||||||
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
|
expect(statisticsStore.incrementMeasure).not.toHaveBeenCalled()
|
||||||
|
expect(saveRevenueModification.execute).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,10 +4,14 @@ import { inject, injectable } from 'inversify'
|
||||||
import TYPES from '../../Bootstrap/Types'
|
import TYPES from '../../Bootstrap/Types'
|
||||||
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
import { AnalyticsActivity } from '../Analytics/AnalyticsActivity'
|
||||||
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
import { AnalyticsStoreInterface } from '../Analytics/AnalyticsStoreInterface'
|
||||||
|
import { Email } from '../Common/Email'
|
||||||
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
import { StatisticsMeasure } from '../Statistics/StatisticsMeasure'
|
||||||
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
import { StatisticsStoreInterface } from '../Statistics/StatisticsStoreInterface'
|
||||||
|
import { SubscriptionEventType } from '../Subscription/SubscriptionEventType'
|
||||||
|
import { SubscriptionPlanName } from '../Subscription/SubscriptionPlanName'
|
||||||
import { Period } from '../Time/Period'
|
import { Period } from '../Time/Period'
|
||||||
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
import { GetUserAnalyticsId } from '../UseCase/GetUserAnalyticsId/GetUserAnalyticsId'
|
||||||
|
import { SaveRevenueModification } from '../UseCase/SaveRevenueModification/SaveRevenueModification'
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface {
|
export class SubscriptionCancelledEventHandler implements DomainEventHandlerInterface {
|
||||||
|
@ -15,10 +19,11 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||||
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
@inject(TYPES.GetUserAnalyticsId) private getUserAnalyticsId: GetUserAnalyticsId,
|
||||||
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
@inject(TYPES.AnalyticsStore) private analyticsStore: AnalyticsStoreInterface,
|
||||||
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
@inject(TYPES.StatisticsStore) private statisticsStore: StatisticsStoreInterface,
|
||||||
|
@inject(TYPES.SaveRevenueModification) private saveRevenueModification: SaveRevenueModification,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async handle(event: SubscriptionCancelledEvent): Promise<void> {
|
async handle(event: SubscriptionCancelledEvent): Promise<void> {
|
||||||
const { analyticsId } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
const { analyticsId, userUuid } = await this.getUserAnalyticsId.execute({ userEmail: event.payload.userEmail })
|
||||||
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionCancelled], analyticsId, [
|
await this.analyticsStore.markActivity([AnalyticsActivity.SubscriptionCancelled], analyticsId, [
|
||||||
Period.Today,
|
Period.Today,
|
||||||
Period.ThisWeek,
|
Period.ThisWeek,
|
||||||
|
@ -26,6 +31,17 @@ export class SubscriptionCancelledEventHandler implements DomainEventHandlerInte
|
||||||
])
|
])
|
||||||
|
|
||||||
await this.trackSubscriptionStatistics(event)
|
await this.trackSubscriptionStatistics(event)
|
||||||
|
|
||||||
|
await this.saveRevenueModification.execute({
|
||||||
|
billingFrequency: event.payload.billingFrequency,
|
||||||
|
eventType: SubscriptionEventType.create(event.type).getValue(),
|
||||||
|
newSubscriber: event.payload.userExistingSubscriptionsCount === 1,
|
||||||
|
payedAmount: event.payload.payAmount,
|
||||||
|
planName: SubscriptionPlanName.create(event.payload.subscriptionName).getValue(),
|
||||||
|
subscriptionId: event.payload.subscriptionId,
|
||||||
|
userEmail: Email.create(event.payload.userEmail).getValue(),
|
||||||
|
userUuid,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private async trackSubscriptionStatistics(event: SubscriptionCancelledEvent) {
|
private async trackSubscriptionStatistics(event: SubscriptionCancelledEvent) {
|
||||||
|
|
|
@ -40,6 +40,9 @@ describe('SubscriptionCancelledEventHandler', () => {
|
||||||
subscriptionEndsAt: 2,
|
subscriptionEndsAt: 2,
|
||||||
subscriptionUpdatedAt: 2,
|
subscriptionUpdatedAt: 2,
|
||||||
lastPayedAt: 1,
|
lastPayedAt: 1,
|
||||||
|
userExistingSubscriptionsCount: 1,
|
||||||
|
billingFrequency: 1,
|
||||||
|
payAmount: 12.99,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -11,4 +11,7 @@ export interface SubscriptionCancelledEventPayload {
|
||||||
timestamp: number
|
timestamp: number
|
||||||
offline: boolean
|
offline: boolean
|
||||||
replaced: boolean
|
replaced: boolean
|
||||||
|
userExistingSubscriptionsCount: number
|
||||||
|
billingFrequency: number
|
||||||
|
payAmount: number
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue