|
|
@@ -0,0 +1,482 @@
|
|
|
+package com.etotem.cfc.controller;
|
|
|
+
|
|
|
+import com.etotem.cfc.common.Result;
|
|
|
+import com.etotem.cfc.controller.assessment.AssessmentOrderController;
|
|
|
+import com.etotem.cfc.entity.AssessmentAppointment;
|
|
|
+import com.etotem.cfc.entity.AssessmentOrder;
|
|
|
+import com.etotem.cfc.entity.Family;
|
|
|
+import com.etotem.cfc.mapper.FamilyMapper;
|
|
|
+import com.etotem.cfc.service.AssessmentAppointmentService;
|
|
|
+import com.etotem.cfc.service.AssessmentOrderService;
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
+import org.springframework.boot.test.context.SpringBootTest;
|
|
|
+import org.springframework.boot.test.mock.mockito.MockBean;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+import static org.junit.jupiter.api.Assertions.*;
|
|
|
+import static org.mockito.ArgumentMatchers.*;
|
|
|
+import static org.mockito.Mockito.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * P0-测评测试:评估订单创建 → 支付 → 取消 → 退款
|
|
|
+ * 覆盖 AssessmentOrderController 全链路
|
|
|
+ */
|
|
|
+@SpringBootTest
|
|
|
+public class AssessmentOrderControllerTest {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private AssessmentOrderController controller;
|
|
|
+
|
|
|
+ @MockBean
|
|
|
+ private AssessmentOrderService orderService;
|
|
|
+
|
|
|
+ @MockBean
|
|
|
+ private AssessmentAppointmentService appointmentService;
|
|
|
+
|
|
|
+ @MockBean
|
|
|
+ private FamilyMapper familyMapper;
|
|
|
+
|
|
|
+ // ===== 创建订单 =====
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void createOrder_Success() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("familyId", 100L);
|
|
|
+ body.put("childId", 10L);
|
|
|
+ body.put("guideId", 50L);
|
|
|
+ body.put("packageId", 5L);
|
|
|
+ body.put("guideName", "张规划师");
|
|
|
+ body.put("packageName", "DAN测评年度版");
|
|
|
+ body.put("totalPrice", 198000L);
|
|
|
+ body.put("discountAmount", 0L);
|
|
|
+
|
|
|
+ AssessmentOrder mockOrder = new AssessmentOrder();
|
|
|
+ mockOrder.setId(1L);
|
|
|
+ mockOrder.setOrderNo("ASR20260622001");
|
|
|
+ mockOrder.setFamilyId(100L);
|
|
|
+ mockOrder.setChildId(10L);
|
|
|
+ mockOrder.setGuideId(50L);
|
|
|
+ mockOrder.setPackageId(5L);
|
|
|
+ mockOrder.setActualPrice(198000L);
|
|
|
+ mockOrder.setStatus("pending");
|
|
|
+
|
|
|
+ when(orderService.createOrder(
|
|
|
+ eq(100L), eq(1L), eq(10L), eq(50L), eq(5L),
|
|
|
+ eq("张规划师"), eq("DAN测评年度版"), eq(198000L), eq(0L)
|
|
|
+ )).thenReturn(mockOrder);
|
|
|
+
|
|
|
+ Result<Map<String, Object>> result = controller.createOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ assertNotNull(result.getData());
|
|
|
+ assertEquals("ASR20260622001", result.getData().get("orderNo"));
|
|
|
+ assertEquals("pending", result.getData().get("status"));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void createOrder_WithAutoGuideAssignment() {
|
|
|
+ // guideId is null but family has teacherId → should auto-assign
|
|
|
+ Family family = new Family();
|
|
|
+ family.setId(100L);
|
|
|
+ family.setTeacherId(50L);
|
|
|
+
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("familyId", 100L);
|
|
|
+ body.put("childId", 10L);
|
|
|
+ // guideId not provided
|
|
|
+ body.put("packageId", 5L);
|
|
|
+ body.put("guideName", "自动分配");
|
|
|
+ body.put("packageName", "DAN测评");
|
|
|
+ body.put("totalPrice", 98000L);
|
|
|
+ body.put("discountAmount", 0L);
|
|
|
+
|
|
|
+ AssessmentOrder mockOrder = new AssessmentOrder();
|
|
|
+ mockOrder.setOrderNo("ASR20260622002");
|
|
|
+ mockOrder.setStatus("pending");
|
|
|
+ mockOrder.setActualPrice(98000L);
|
|
|
+
|
|
|
+ when(familyMapper.selectById(100L)).thenReturn(family);
|
|
|
+ when(orderService.createOrder(
|
|
|
+ eq(100L), eq(1L), eq(10L), eq(50L), eq(5L),
|
|
|
+ anyString(), anyString(), eq(98000L), eq(0L)
|
|
|
+ )).thenReturn(mockOrder);
|
|
|
+
|
|
|
+ Result<Map<String, Object>> result = controller.createOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void createOrder_WithoutChildId() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("familyId", 100L);
|
|
|
+ // childId not provided
|
|
|
+ body.put("guideId", 50L);
|
|
|
+ body.put("packageId", 5L);
|
|
|
+ body.put("guideName", "张规划师");
|
|
|
+ body.put("packageName", "DAN测评");
|
|
|
+ body.put("totalPrice", 98000L);
|
|
|
+
|
|
|
+ AssessmentOrder mockOrder = new AssessmentOrder();
|
|
|
+ mockOrder.setOrderNo("ASR20260622003");
|
|
|
+ mockOrder.setStatus("pending");
|
|
|
+
|
|
|
+ when(orderService.createOrder(
|
|
|
+ eq(100L), eq(1L), isNull(), eq(50L), eq(5L),
|
|
|
+ anyString(), anyString(), eq(98000L), isNull()
|
|
|
+ )).thenReturn(mockOrder);
|
|
|
+
|
|
|
+ Result<Map<String, Object>> result = controller.createOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ===== 订单详情 =====
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void getOrderDetail_Success() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setId(1L);
|
|
|
+ order.setOrderNo("ASR20260622001");
|
|
|
+ order.setUserId(1L);
|
|
|
+ order.setStatus("pending");
|
|
|
+ order.setActualPrice(198000L);
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+
|
|
|
+ Result<AssessmentOrder> result = controller.getOrderDetail(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ assertNotNull(result.getData());
|
|
|
+ assertEquals("ASR20260622001", result.getData().getOrderNo());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void getOrderDetail_OrderNotFound() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "NOTEXIST");
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("NOTEXIST")).thenReturn(null);
|
|
|
+
|
|
|
+ Result<AssessmentOrder> result = controller.getOrderDetail(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("订单不存在", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void getOrderDetail_NoPermission() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setUserId(999L); // different user
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+
|
|
|
+ Result<AssessmentOrder> result = controller.getOrderDetail(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("无权查看", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void getOrderDetail_NullOrderNo() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ // orderNo not provided
|
|
|
+
|
|
|
+ Result<AssessmentOrder> result = controller.getOrderDetail(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("订单号不能为空", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ===== 我的订单列表 =====
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void getMyOrders_Success() {
|
|
|
+ List<AssessmentOrder> orders = Arrays.asList(
|
|
|
+ createOrder(1L, "ASR001", 1L, "pending"),
|
|
|
+ createOrder(2L, "ASR002", 1L, "paid")
|
|
|
+ );
|
|
|
+ when(orderService.getByUserId(1L)).thenReturn(orders);
|
|
|
+
|
|
|
+ Result<List<AssessmentOrder>> result = controller.getMyOrders(1L);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ assertEquals(2, result.getData().size());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void getMyOrders_EmptyList() {
|
|
|
+ when(orderService.getByUserId(1L)).thenReturn(Collections.emptyList());
|
|
|
+
|
|
|
+ Result<List<AssessmentOrder>> result = controller.getMyOrders(1L);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ assertTrue(result.getData().isEmpty());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ===== 支付订单 =====
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void payOrder_Success() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+ body.put("payType", "wechat");
|
|
|
+
|
|
|
+ AssessmentOrder paidOrder = new AssessmentOrder();
|
|
|
+ paidOrder.setOrderNo("ASR20260622001");
|
|
|
+ paidOrder.setStatus("paid");
|
|
|
+ paidOrder.setChildId(10L);
|
|
|
+
|
|
|
+ when(orderService.payOrder("ASR20260622001", "wechat")).thenReturn(true);
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(paidOrder);
|
|
|
+
|
|
|
+ Result<Map<String, Object>> result = controller.payOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ assertEquals("ASR20260622001", result.getData().get("orderNo"));
|
|
|
+ assertEquals("paid", result.getData().get("status"));
|
|
|
+ verify(appointmentService).confirmAppointmentByOrder(paidOrder);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void payOrder_AlipayType() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622002");
|
|
|
+ body.put("payType", "alipay");
|
|
|
+
|
|
|
+ AssessmentOrder paidOrder = new AssessmentOrder();
|
|
|
+ paidOrder.setOrderNo("ASR20260622002");
|
|
|
+ paidOrder.setStatus("paid");
|
|
|
+ paidOrder.setChildId(10L);
|
|
|
+
|
|
|
+ when(orderService.payOrder("ASR20260622002", "alipay")).thenReturn(true);
|
|
|
+ when(orderService.getByOrderNo("ASR20260622002")).thenReturn(paidOrder);
|
|
|
+
|
|
|
+ Result<Map<String, Object>> result = controller.payOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ verify(appointmentService).confirmAppointmentByOrder(paidOrder);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void payOrder_Fails() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622003");
|
|
|
+ body.put("payType", "wechat");
|
|
|
+
|
|
|
+ when(orderService.payOrder("ASR20260622003", "wechat")).thenReturn(false);
|
|
|
+
|
|
|
+ Result<Map<String, Object>> result = controller.payOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("支付失败", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void payOrder_NullOrderNo() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ // orderNo not provided
|
|
|
+
|
|
|
+ Result<Map<String, Object>> result = controller.payOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("订单号不能为空", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void payOrder_NoChildId_DoesNotTriggerConfirm() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622004");
|
|
|
+ body.put("payType", "wechat");
|
|
|
+
|
|
|
+ AssessmentOrder paidOrder = new AssessmentOrder();
|
|
|
+ paidOrder.setOrderNo("ASR20260622004");
|
|
|
+ paidOrder.setStatus("paid");
|
|
|
+ paidOrder.setChildId(null); // no child id
|
|
|
+
|
|
|
+ when(orderService.payOrder("ASR20260622004", "wechat")).thenReturn(true);
|
|
|
+ when(orderService.getByOrderNo("ASR20260622004")).thenReturn(paidOrder);
|
|
|
+
|
|
|
+ controller.payOrder(1L, body);
|
|
|
+
|
|
|
+ verify(appointmentService, never()).confirmAppointmentByOrder(any());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ===== 取消订单 =====
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void cancelOrder_Success() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setUserId(1L);
|
|
|
+ order.setOrderNo("ASR20260622001");
|
|
|
+ order.setStatus("pending");
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+ when(orderService.cancelOrder("ASR20260622001")).thenReturn(true);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.cancelOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ assertTrue(result.getData());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void cancelOrder_OrderNotFound() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "NOTEXIST");
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("NOTEXIST")).thenReturn(null);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.cancelOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("订单不存在", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void cancelOrder_NoPermission() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setUserId(999L); // different user
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.cancelOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("无权操作", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void cancelOrder_AlreadyCancelled() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setUserId(1L);
|
|
|
+ order.setOrderNo("ASR20260622001");
|
|
|
+ order.setStatus("cancelled");
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+ when(orderService.cancelOrder("ASR20260622001")).thenReturn(false);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.cancelOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("取消失败,仅待支付订单可取消", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void cancelOrder_NullOrderNo() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.cancelOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("订单号不能为空", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ===== 退款订单 =====
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void refundOrder_Success() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setUserId(1L);
|
|
|
+ order.setOrderNo("ASR20260622001");
|
|
|
+ order.setStatus("paid");
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+ when(orderService.refundOrder("ASR20260622001")).thenReturn(true);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.refundOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(200, result.getCode());
|
|
|
+ assertTrue(result.getData());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void refundOrder_OrderNotFound() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "NOTEXIST");
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("NOTEXIST")).thenReturn(null);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.refundOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("订单不存在", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void refundOrder_NoPermission() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setUserId(999L);
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.refundOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("无权操作", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void refundOrder_NotYetPaid() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+ body.put("orderNo", "ASR20260622001");
|
|
|
+
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setUserId(1L);
|
|
|
+ order.setOrderNo("ASR20260622001");
|
|
|
+ order.setStatus("pending");
|
|
|
+
|
|
|
+ when(orderService.getByOrderNo("ASR20260622001")).thenReturn(order);
|
|
|
+ when(orderService.refundOrder("ASR20260622001")).thenReturn(false);
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.refundOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("退款失败,仅已支付订单可退款", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Test
|
|
|
+ public void refundOrder_NullOrderNo() {
|
|
|
+ Map<String, Object> body = new HashMap<>();
|
|
|
+
|
|
|
+ Result<Boolean> result = controller.refundOrder(1L, body);
|
|
|
+
|
|
|
+ assertEquals(500, result.getCode());
|
|
|
+ assertEquals("订单号不能为空", result.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ===== 辅助方法 =====
|
|
|
+
|
|
|
+ private AssessmentOrder createOrder(Long id, String orderNo, Long userId, String status) {
|
|
|
+ AssessmentOrder order = new AssessmentOrder();
|
|
|
+ order.setId(id);
|
|
|
+ order.setOrderNo(orderNo);
|
|
|
+ order.setUserId(userId);
|
|
|
+ order.setStatus(status);
|
|
|
+ order.setActualPrice(98000L);
|
|
|
+ return order;
|
|
|
+ }
|
|
|
+}
|