From 15defa991fcd30b9fa60bab17d2230b5929bf2a2 Mon Sep 17 00:00:00 2001
From: liujie <1793218484@qq.com>
Date: 星期一, 14 九月 2026 17:20:20 +0800
Subject: [PATCH] update
---
backend/src/test/java/com/tourguide/modules/order/service/OrderRefundServiceTest.java | 81 ++++++++++++++++++++++++++++++++++++++--
1 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/backend/src/test/java/com/tourguide/modules/order/service/OrderRefundServiceTest.java b/backend/src/test/java/com/tourguide/modules/order/service/OrderRefundServiceTest.java
index c5d3ddf..8091f9d 100644
--- a/backend/src/test/java/com/tourguide/modules/order/service/OrderRefundServiceTest.java
+++ b/backend/src/test/java/com/tourguide/modules/order/service/OrderRefundServiceTest.java
@@ -1,17 +1,23 @@
package com.tourguide.modules.order.service;
+import com.tourguide.modules.order.domain.OrderStatus;
import com.tourguide.modules.order.domain.RefundStatus;
import com.tourguide.modules.order.domain.PaymentMethod;
import com.tourguide.modules.order.entity.TourOrder;
+import com.tourguide.modules.order.entity.TourOrderRefund;
import com.tourguide.modules.order.mapper.TourOrderMapper;
+import com.tourguide.modules.order.mapper.TourOrderRefundMapper;
import com.tourguide.modules.order.payment.PaymentRefundGateway;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.mockito.ArgumentCaptor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -37,15 +43,18 @@
org.mockito.ArgumentMatchers.eq(new BigDecimal("36.00"))))
.thenAnswer(invocation -> order.getRefundOrderNo());
- refundService.requestRefund(order);
- refundService.requestRefund(order);
+ boolean accepted = refundService.requestRefund(order);
+ boolean duplicateAccepted = refundService.requestRefund(order);
+ assertThat(accepted).isTrue();
+ assertThat(duplicateAccepted).isTrue();
assertThat(order.getRefundStatus()).isEqualTo(RefundStatus.REFUNDING.getCode());
+ assertThat(order.getStatus()).isEqualTo(OrderStatus.CANCELLED.getCode());
assertThat(order.getRefundOrderNo()).startsWith("RF").hasSize(32);
assertThat(order.getRefundAmount()).isEqualByComparingTo("36.00");
assertThat(order.getRefundMethod()).isEqualTo("WECHAT");
verify(refundGateway, times(1)).refund(order, new BigDecimal("36.00"));
- verify(orderMapper, times(1)).updateById(order);
+ verify(orderMapper, times(2)).updateById(order);
}
@Test
@@ -55,8 +64,9 @@
org.mockito.ArgumentMatchers.any(BigDecimal.class)))
.thenThrow(new IllegalStateException("gateway unavailable"));
- refundService.requestRefund(order);
+ boolean accepted = refundService.requestRefund(order);
+ assertThat(accepted).isFalse();
assertThat(order.getRefundStatus()).isEqualTo(RefundStatus.REFUND_FAILED.getCode());
verify(orderMapper, times(2)).updateById(order);
}
@@ -81,11 +91,73 @@
refundService.requestRefund(order);
assertThat(order.getRefundStatus()).isEqualTo(RefundStatus.REFUNDED.getCode());
+ assertThat(order.getStatus()).isEqualTo(OrderStatus.REFUNDED.getCode());
assertThat(order.getRefundTime()).isNotNull();
assertThat(order.getRefundMethod()).isEqualTo(PaymentMethod.TEMPORARY_BYPASS.getCode());
verify(refundGateway, never()).refund(org.mockito.ArgumentMatchers.any(),
org.mockito.ArgumentMatchers.any());
verify(orderMapper).updateById(order);
+ }
+
+ @Test
+ void adminRefundShouldSubmitRequestedAmount() {
+ TourOrder order = paidOrder();
+ when(refundGateway.refund(eq(order), eq(new BigDecimal("20.00"))))
+ .thenAnswer(invocation -> order.getRefundOrderNo());
+
+ boolean accepted = refundService.requestRefund(order, new BigDecimal("20.00"));
+
+ assertThat(accepted).isTrue();
+ assertThat(order.getRefundAmount()).isEqualByComparingTo("20.00");
+ verify(refundGateway).refund(order, new BigDecimal("20.00"));
+ }
+
+ @Test
+ void followUpRefundShouldOnlyUseRemainingAmount() {
+ TourOrder order = paidOrder();
+ order.setStatus(OrderStatus.CANCELLED.getCode());
+ order.setRefundStatus(RefundStatus.PARTIAL.getCode());
+ order.setRefundedAmount(new BigDecimal("20.00"));
+ when(refundGateway.refund(eq(order), eq(new BigDecimal("16.00"))))
+ .thenAnswer(invocation -> order.getRefundOrderNo());
+
+ boolean accepted = refundService.requestRefund(order, new BigDecimal("16.00"));
+
+ assertThat(accepted).isTrue();
+ assertThat(order.getRefundAmount()).isEqualByComparingTo("16.00");
+ assertThat(order.getRefundStatus()).isEqualTo(RefundStatus.REFUNDING.getCode());
+ verify(refundGateway).refund(order, new BigDecimal("16.00"));
+ }
+
+ @Test
+ void eachSuccessfulLocalRefundShouldCreateAnIndependentCompletedRecord() {
+ TourOrderRefundMapper refundMapper = mock(TourOrderRefundMapper.class);
+ refundService = new OrderRefundService(orderMapper, refundGateway, refundMapper);
+ TourOrder order = paidOrder();
+ order.setPaymentMethod(PaymentMethod.TEMPORARY_BYPASS.getCode());
+
+ assertThat(refundService.requestRefund(order, new BigDecimal("20.00"))).isTrue();
+ assertThat(refundService.requestRefund(order, new BigDecimal("16.00"))).isTrue();
+
+ ArgumentCaptor<TourOrderRefund> insertCaptor = ArgumentCaptor.forClass(TourOrderRefund.class);
+ verify(refundMapper, times(2)).insert(insertCaptor.capture());
+ assertThat(insertCaptor.getAllValues()).extracting(TourOrderRefund::getRefundAmount)
+ .containsExactly(new BigDecimal("20.00"), new BigDecimal("16.00"));
+ verify(refundMapper, times(2)).updateById(any(TourOrderRefund.class));
+ assertThat(insertCaptor.getAllValues()).extracting(TourOrderRefund::getRefundStatus)
+ .containsOnly(RefundStatus.REFUNDED.getCode());
+ }
+
+ @Test
+ void refundShouldRejectAmountAboveRemainingBalance() {
+ TourOrder order = paidOrder();
+ order.setRefundedAmount(new BigDecimal("20.00"));
+
+ boolean accepted = refundService.requestRefund(order, new BigDecimal("17.00"));
+
+ assertThat(accepted).isFalse();
+ verify(refundGateway, never()).refund(org.mockito.ArgumentMatchers.any(),
+ org.mockito.ArgumentMatchers.any());
}
private TourOrder paidOrder() {
@@ -97,6 +169,7 @@
order.setAmount(new BigDecimal("40.00"));
order.setPaymentAmount(new BigDecimal("36.00"));
order.setPaymentTime(LocalDateTime.now());
+ order.setStatus(OrderStatus.COMPLETED.getCode());
order.setRefundStatus(RefundStatus.NONE.getCode());
return order;
}
--
Gitblit v1.7.1