perf: 支持约课以及消息推送能力
This commit is contained in:
@@ -2,7 +2,13 @@ import { Test, TestingModule } from '@nestjs/testing'
|
||||
import { NotFoundException } from '@nestjs/common'
|
||||
import { UserService } from '../user.service'
|
||||
import { PrismaService } from '../../prisma/prisma.service'
|
||||
import { MembershipStatus, BookingStatus, UserRole } from '@mp-pilates/shared'
|
||||
import {
|
||||
MembershipStatus,
|
||||
BookingStatus,
|
||||
UserRole,
|
||||
SubscriptionMessageScene,
|
||||
} from '@mp-pilates/shared'
|
||||
import { ConfigService } from '@nestjs/config'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers
|
||||
@@ -48,11 +54,22 @@ const mockPrisma = {
|
||||
findUnique: jest.fn(),
|
||||
update: jest.fn(),
|
||||
},
|
||||
subscriptionMessageConsent: {
|
||||
upsert: jest.fn(),
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
booking: {
|
||||
findMany: jest.fn(),
|
||||
},
|
||||
}
|
||||
|
||||
const mockConfigService = {
|
||||
get: jest.fn((key: string, defaultValue = '') => {
|
||||
if (key === 'WX_SUBSCRIBE_TEMPLATE_BOOKING_CONFIRMED') return 'tmpl-booking-confirmed'
|
||||
return defaultValue
|
||||
}),
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tests
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -65,6 +82,7 @@ describe('UserService', () => {
|
||||
providers: [
|
||||
UserService,
|
||||
{ provide: PrismaService, useValue: mockPrisma },
|
||||
{ provide: ConfigService, useValue: mockConfigService },
|
||||
],
|
||||
}).compile()
|
||||
|
||||
@@ -101,6 +119,15 @@ describe('UserService', () => {
|
||||
avatarUrl: 'https://example.com/avatar.png',
|
||||
role: UserRole.MEMBER,
|
||||
activeMembershipCount: 3,
|
||||
subscriptionMessageTemplates: {
|
||||
templates: [
|
||||
{
|
||||
templateId: 'tmpl-booking-confirmed',
|
||||
scene: SubscriptionMessageScene.BOOKING_CREATED,
|
||||
description: '购卡或预约时请求一次订阅,用于后续预约确认通知推送',
|
||||
},
|
||||
],
|
||||
},
|
||||
createdAt: new Date('2024-01-01T00:00:00Z').toISOString(),
|
||||
})
|
||||
})
|
||||
@@ -112,6 +139,89 @@ describe('UserService', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('reportSubscriptionMessageRequests', () => {
|
||||
it('aggregates and returns subscription consent stats', async () => {
|
||||
mockPrisma.subscriptionMessageConsent.upsert.mockResolvedValue(undefined)
|
||||
mockPrisma.subscriptionMessageConsent.findMany.mockResolvedValue([
|
||||
{
|
||||
userId: 'user-1',
|
||||
templateId: 'tmpl-booking-confirmed',
|
||||
scene: SubscriptionMessageScene.BOOKING_CREATED,
|
||||
totalRequestCount: 2,
|
||||
acceptCount: 1,
|
||||
rejectCount: 1,
|
||||
banCount: 0,
|
||||
filterCount: 0,
|
||||
sentCount: 0,
|
||||
lastResult: 'reject',
|
||||
lastRequestedAt: new Date('2024-01-03T00:00:00Z'),
|
||||
lastSentAt: null,
|
||||
createdAt: new Date('2024-01-01T00:00:00Z'),
|
||||
updatedAt: new Date('2024-01-03T00:00:00Z'),
|
||||
},
|
||||
])
|
||||
|
||||
const result = await service.reportSubscriptionMessageRequests('user-1', [
|
||||
{
|
||||
templateId: 'tmpl-booking-confirmed',
|
||||
scene: SubscriptionMessageScene.BOOKING_CREATED,
|
||||
result: 'reject',
|
||||
},
|
||||
])
|
||||
|
||||
expect(mockPrisma.subscriptionMessageConsent.upsert).toHaveBeenCalledWith({
|
||||
where: {
|
||||
userId_templateId_scene: {
|
||||
userId: 'user-1',
|
||||
templateId: 'tmpl-booking-confirmed',
|
||||
scene: SubscriptionMessageScene.BOOKING_CREATED,
|
||||
},
|
||||
},
|
||||
create: {
|
||||
userId: 'user-1',
|
||||
templateId: 'tmpl-booking-confirmed',
|
||||
scene: SubscriptionMessageScene.BOOKING_CREATED,
|
||||
totalRequestCount: 1,
|
||||
acceptCount: 0,
|
||||
rejectCount: 1,
|
||||
banCount: 0,
|
||||
filterCount: 0,
|
||||
sentCount: 0,
|
||||
lastResult: 'reject',
|
||||
lastRequestedAt: expect.any(Date),
|
||||
},
|
||||
update: {
|
||||
totalRequestCount: { increment: 1 },
|
||||
acceptCount: { increment: 0 },
|
||||
rejectCount: { increment: 1 },
|
||||
banCount: { increment: 0 },
|
||||
filterCount: { increment: 0 },
|
||||
lastResult: 'reject',
|
||||
lastRequestedAt: expect.any(Date),
|
||||
},
|
||||
})
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
userId: 'user-1',
|
||||
templateId: 'tmpl-booking-confirmed',
|
||||
scene: SubscriptionMessageScene.BOOKING_CREATED,
|
||||
totalRequestCount: 2,
|
||||
acceptCount: 1,
|
||||
rejectCount: 1,
|
||||
banCount: 0,
|
||||
filterCount: 0,
|
||||
sentCount: 0,
|
||||
lastResult: 'reject',
|
||||
lastRequestedAt: '2024-01-03T00:00:00.000Z',
|
||||
lastSentAt: null,
|
||||
createdAt: '2024-01-01T00:00:00.000Z',
|
||||
updatedAt: '2024-01-03T00:00:00.000Z',
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// updateProfile
|
||||
// -------------------------------------------------------------------------
|
||||
@@ -145,6 +255,7 @@ describe('UserService', () => {
|
||||
expect(result.nickname).toBe('Bob')
|
||||
expect(result.avatarUrl).toBe('https://example.com/new.png')
|
||||
expect(result.activeMembershipCount).toBe(1)
|
||||
expect(result.subscriptionMessageTemplates.templates).toHaveLength(1)
|
||||
})
|
||||
|
||||
it('only includes provided fields in the update payload', async () => {
|
||||
|
||||
Reference in New Issue
Block a user