can cancel a rental request before owner approval
This commit is contained in:
@@ -277,8 +277,9 @@ describe('RefundService', () => {
|
||||
});
|
||||
|
||||
describe('Payment status validation', () => {
|
||||
it('should reject cancellation for unpaid rental', () => {
|
||||
const rental = { ...baseRental, paymentStatus: 'pending' };
|
||||
it('should reject cancellation for confirmed rental with unpaid status', () => {
|
||||
// Confirmed rentals require payment to be settled
|
||||
const rental = { ...baseRental, status: 'confirmed', paymentStatus: 'pending' };
|
||||
const result = RefundService.validateCancellationEligibility(rental, 100);
|
||||
|
||||
expect(result).toEqual({
|
||||
@@ -288,8 +289,8 @@ describe('RefundService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should reject cancellation for failed payment', () => {
|
||||
const rental = { ...baseRental, paymentStatus: 'failed' };
|
||||
it('should reject cancellation for confirmed rental with failed payment', () => {
|
||||
const rental = { ...baseRental, status: 'confirmed', paymentStatus: 'failed' };
|
||||
const result = RefundService.validateCancellationEligibility(rental, 100);
|
||||
|
||||
expect(result).toEqual({
|
||||
@@ -311,6 +312,31 @@ describe('RefundService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Pending rental cancellation (before owner approval)', () => {
|
||||
it('should allow renter to cancel pending rental even with pending payment', () => {
|
||||
// Pending rentals can be cancelled before owner approval, no payment processed yet
|
||||
const rental = { ...baseRental, status: 'pending', paymentStatus: 'pending' };
|
||||
const result = RefundService.validateCancellationEligibility(rental, 100);
|
||||
|
||||
expect(result).toEqual({
|
||||
canCancel: true,
|
||||
reason: 'Cancellation allowed',
|
||||
cancelledBy: 'renter'
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow owner to cancel pending rental', () => {
|
||||
const rental = { ...baseRental, status: 'pending', paymentStatus: 'pending' };
|
||||
const result = RefundService.validateCancellationEligibility(rental, 200);
|
||||
|
||||
expect(result).toEqual({
|
||||
canCancel: true,
|
||||
reason: 'Cancellation allowed',
|
||||
cancelledBy: 'owner'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edge cases', () => {
|
||||
it('should handle string user IDs that don\'t match', () => {
|
||||
const result = RefundService.validateCancellationEligibility(baseRental, '100');
|
||||
@@ -528,6 +554,40 @@ describe('RefundService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Pending rental cancellation (before owner approval)', () => {
|
||||
it('should process cancellation for pending rental without Stripe refund', async () => {
|
||||
// Pending rental with no payment processed yet
|
||||
mockRental.status = 'pending';
|
||||
mockRental.paymentStatus = 'pending';
|
||||
mockRental.stripePaymentIntentId = null;
|
||||
|
||||
jest.useFakeTimers();
|
||||
jest.setSystemTime(new Date('2023-11-28T10:00:00Z'));
|
||||
|
||||
const result = await RefundService.processCancellation(1, 100, 'Changed my mind');
|
||||
|
||||
// No Stripe refund should be attempted
|
||||
expect(mockCreateRefund).not.toHaveBeenCalled();
|
||||
|
||||
// Rental should be updated
|
||||
expect(mockRentalUpdate).toHaveBeenCalledWith({
|
||||
status: 'cancelled',
|
||||
cancelledBy: 'renter',
|
||||
cancelledAt: expect.any(Date),
|
||||
refundAmount: 100.00,
|
||||
refundProcessedAt: null,
|
||||
refundReason: 'Changed my mind',
|
||||
stripeRefundId: null,
|
||||
payoutStatus: 'pending'
|
||||
});
|
||||
|
||||
expect(result.refund.processed).toBe(false);
|
||||
expect(result.refund.stripeRefundId).toBeNull();
|
||||
|
||||
jest.useRealTimers();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Error handling', () => {
|
||||
beforeEach(() => {
|
||||
jest.useFakeTimers();
|
||||
|
||||
Reference in New Issue
Block a user