package com.tcm.training.admin.statistics.service;
|
|
import com.tcm.training.admin.statistics.mapper.RevenueStatisticsMapper;
|
import com.tcm.training.admin.statistics.row.RevenueStatisticsDailyRow;
|
import com.tcm.training.admin.statistics.vo.RevenueStatisticsVO;
|
import com.tcm.training.admin.trade.service.PaymentFlowAppService;
|
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.mockito.InjectMocks;
|
import org.mockito.Mock;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
|
import java.math.BigDecimal;
|
import java.time.LocalDate;
|
import java.time.LocalDateTime;
|
import java.time.LocalTime;
|
import java.util.Collections;
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.when;
|
|
@ExtendWith(MockitoExtension.class)
|
class RevenueStatisticsAppServiceTest {
|
|
@Mock
|
private RevenueStatisticsMapper revenueStatisticsMapper;
|
|
@Mock
|
private PaymentFlowAppService paymentFlowAppService;
|
|
@InjectMocks
|
private RevenueStatisticsAppService revenueStatisticsAppService;
|
|
@Test
|
void statisticsShouldBuildOverviewAndFillMissingDates() {
|
RevenueStatisticsDailyRow row = new RevenueStatisticsDailyRow();
|
row.setStatDate(LocalDate.of(2026, 3, 1));
|
row.setHealthIncome(new BigDecimal("100.00"));
|
row.setMemberIncome(new BigDecimal("50.00"));
|
row.setHealthRefundAmount(new BigDecimal("12.00"));
|
row.setMemberRefundAmount(new BigDecimal("8.00"));
|
when(revenueStatisticsMapper.selectDailyStatistics(
|
eq(null),
|
eq(LocalDateTime.of(2026, 3, 1, 0, 0, 0)),
|
eq(LocalDateTime.of(2026, 3, 3, LocalTime.MAX.getHour(), LocalTime.MAX.getMinute(), LocalTime.MAX.getSecond(), LocalTime.MAX.getNano()))
|
)).thenReturn(Collections.singletonList(row));
|
|
RevenueStatisticsVO result = revenueStatisticsAppService.statistics(
|
"ALL",
|
LocalDate.of(2026, 3, 1),
|
LocalDate.of(2026, 3, 3)
|
);
|
|
verify(paymentFlowAppService).syncFlows();
|
assertEquals(3, result.getTrend().size());
|
assertEquals(new BigDecimal("150.00"), result.getOverview().getTotalIncome());
|
assertEquals(new BigDecimal("100.00"), result.getOverview().getHealthIncome());
|
assertEquals(new BigDecimal("50.00"), result.getOverview().getMemberIncome());
|
assertEquals(new BigDecimal("20.00"), result.getOverview().getRefundAmount());
|
assertEquals(new BigDecimal("130.00"), result.getOverview().getProfit());
|
assertEquals(new BigDecimal("0"), result.getTrend().get(1).getTotalIncome());
|
assertEquals(new BigDecimal("12.00"), result.getTrend().get(0).getHealthRefundAmount());
|
assertEquals(new BigDecimal("8.00"), result.getTrend().get(0).getMemberRefundAmount());
|
}
|
|
@Test
|
void statisticsShouldUseHealthTypeFilter() {
|
RevenueStatisticsDailyRow row = new RevenueStatisticsDailyRow();
|
row.setStatDate(LocalDate.of(2026, 3, 5));
|
row.setHealthIncome(new BigDecimal("88.00"));
|
row.setMemberIncome(BigDecimal.ZERO);
|
row.setHealthRefundAmount(new BigDecimal("8.00"));
|
row.setMemberRefundAmount(BigDecimal.ZERO);
|
when(revenueStatisticsMapper.selectDailyStatistics(
|
eq("COURSE_PURCHASE"),
|
eq(LocalDateTime.of(2026, 3, 5, 0, 0, 0)),
|
eq(LocalDateTime.of(2026, 3, 5, LocalTime.MAX.getHour(), LocalTime.MAX.getMinute(), LocalTime.MAX.getSecond(), LocalTime.MAX.getNano()))
|
)).thenReturn(Collections.singletonList(row));
|
|
RevenueStatisticsVO result = revenueStatisticsAppService.statistics(
|
"HEALTH",
|
LocalDate.of(2026, 3, 5),
|
LocalDate.of(2026, 3, 5)
|
);
|
|
assertEquals(new BigDecimal("88.00"), result.getOverview().getTotalIncome());
|
assertEquals(new BigDecimal("88.00"), result.getOverview().getHealthIncome());
|
assertEquals(new BigDecimal("0"), result.getOverview().getMemberIncome());
|
assertEquals(new BigDecimal("8.00"), result.getOverview().getRefundAmount());
|
assertEquals(new BigDecimal("80.00"), result.getOverview().getProfit());
|
}
|
|
@Test
|
void statisticsShouldRejectInvalidType() {
|
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
|
() -> revenueStatisticsAppService.statistics("OTHER", LocalDate.of(2026, 3, 1), LocalDate.of(2026, 3, 1)));
|
|
assertEquals("统计类型不合法", exception.getMessage());
|
}
|
|
@Test
|
void statisticsShouldRejectInvalidDateRange() {
|
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
|
() -> revenueStatisticsAppService.statistics("ALL", LocalDate.of(2026, 3, 10), LocalDate.of(2026, 3, 1)));
|
|
assertEquals("开始日期不能晚于结束日期", exception.getMessage());
|
}
|
}
|