feat: 下线支付功能; 月卡生效时间从第一次约课开始
This commit is contained in:
@@ -277,6 +277,43 @@ describe('BookingService', () => {
|
||||
expect(tx.booking.create).toHaveBeenCalledWith(expect.objectContaining({data:expect.objectContaining({membershipId:planned.id})}))
|
||||
expect(tx.membership.update).not.toHaveBeenCalled()
|
||||
})
|
||||
it('keeps a new monthly card undated through reservation and confirmation', async () => {
|
||||
jest.useFakeTimers().setSystemTime(new Date('2099-12-30T00:00:00Z'))
|
||||
try {
|
||||
const pending = { ...mockLimitedDurationMembership, startDate: null, expireDate: null, activationDurationDays: 30, status: MembershipStatus.SCHEDULED }
|
||||
const tx = buildTxMock()
|
||||
tx.timeSlot.findUnique.mockResolvedValue(mockOpenSlot)
|
||||
tx.booking.findUnique.mockResolvedValue(null)
|
||||
tx.membership.findUnique.mockResolvedValue(pending)
|
||||
tx.booking.create.mockResolvedValue({ ...mockConfirmedBooking, status: BookingStatus.PENDING_CONFIRMATION })
|
||||
;(prisma.$transaction as jest.Mock).mockImplementation(fn => fn(tx))
|
||||
;(prisma.booking.findUnique as jest.Mock).mockResolvedValue({ ...mockConfirmedBooking, timeSlot: mockOpenSlot, membership: pending })
|
||||
;(prisma.user.findMany as jest.Mock).mockResolvedValue([])
|
||||
await service.createBooking(MOCK_USER_ID, { timeSlotId: MOCK_SLOT_ID, membershipId: pending.id })
|
||||
expect(tx.membership.update).not.toHaveBeenCalled()
|
||||
tx.booking.findUnique.mockResolvedValue({ ...mockConfirmedBooking, status: BookingStatus.PENDING_CONFIRMATION, membershipId: pending.id, timeSlot: mockOpenSlot, membership: pending })
|
||||
tx.booking.update.mockResolvedValue(mockConfirmedBooking)
|
||||
;(prisma.user.findUnique as jest.Mock).mockResolvedValue(null)
|
||||
studioService.getInfo.mockResolvedValue(mockStudioConfig as never)
|
||||
await service.confirmBooking(MOCK_BOOKING_ID, MOCK_ADMIN_ID)
|
||||
expect(tx.membership.update).toHaveBeenCalledWith({ where: { id: pending.id }, data: { remainingTimes: 4, status: MembershipStatus.SCHEDULED } })
|
||||
expect(pending.startDate).toBeNull()
|
||||
expect(pending.expireDate).toBeNull()
|
||||
} finally { jest.useRealTimers() }
|
||||
})
|
||||
it('refunds cancellation to the pending card without setting activation dates', async () => {
|
||||
const pending = { ...mockLimitedDurationMembership, startDate: null, expireDate: null, activationDurationDays: 30, status: MembershipStatus.SCHEDULED }
|
||||
const tx = buildTxMock()
|
||||
const booking = { ...mockConfirmedBooking, membershipId: pending.id, membership: pending, timeSlot: { ...mockOpenSlot, bookedCount: 1 } }
|
||||
;(prisma.booking.findUnique as jest.Mock).mockResolvedValue(booking)
|
||||
;(prisma.user.findUnique as jest.Mock).mockResolvedValue(null)
|
||||
;(prisma.$transaction as jest.Mock).mockImplementation(fn => fn(tx))
|
||||
studioService.getInfo.mockResolvedValue(mockStudioConfig as never)
|
||||
tx.booking.update.mockResolvedValue({ ...booking, status: BookingStatus.CANCELLED })
|
||||
const result = await service.cancelBooking(MEMBER_ACTOR, MOCK_BOOKING_ID)
|
||||
expect(result.refunded).toBe(true)
|
||||
expect(tx.membership.update).toHaveBeenCalledWith({ where: { id: pending.id }, data: { remainingTimes: 6, status: MembershipStatus.SCHEDULED } })
|
||||
})
|
||||
it.each(['before','after'])('rejects a course %s the monthly period before writing a booking',async boundary=>{
|
||||
const tx=buildTxMock()
|
||||
const membership=boundary==='before'?{...planned,startDate:new Date('2100-01-01T00:00:00Z')}:{...planned,expireDate:new Date('2099-12-31T00:00:00Z')}
|
||||
|
||||
Reference in New Issue
Block a user