package com.talentcard.server.business.admin; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatCode; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import com.talentcard.server.common.BusinessException; import java.util.List; import org.mockito.ArgumentCaptor; import org.junit.jupiter.api.Test; import org.springframework.jdbc.core.JdbcTemplate; class AdminBusinessServiceTests { private final AdminBusinessService service = new AdminBusinessService(mock(JdbcTemplate.class)); @Test void apartmentMerchantAllowsBlankAddress() { assertThatCode(() -> service.validateMerchantAddress("公寓租赁", "")) .doesNotThrowAnyException(); } @Test void otherMerchantTypesStillRequireAddress() { assertThatThrownBy(() -> service.validateMerchantAddress("酒店服务", " ")) .isInstanceOf(BusinessException.class) .hasMessageContaining("请输入商家地址"); } @Test void supportsMerchantAppLoginForConfiguredServiceTypes() { assertThat(service.supportsMerchantAppLogin("数码服务")).isTrue(); assertThat(service.supportsMerchantAppLogin("文化服务")).isTrue(); assertThat(service.supportsMerchantAppLogin("电信服务")).isTrue(); assertThat(service.supportsMerchantAppLogin("口腔治疗保健")).isTrue(); assertThat(service.supportsMerchantAppLogin("家电服务")).isTrue(); assertThat(service.supportsMerchantAppLogin("购房优惠")).isTrue(); assertThat(service.supportsMerchantAppLogin("购车服务")).isTrue(); assertThat(service.supportsMerchantAppLogin("加油服务")).isTrue(); } @Test void supportsMerchantAppLoginForHotelMerchants() { assertThat(service.supportsMerchantAppLogin("酒店服务")).isTrue(); } @Test void productSalesCountComesFromValidOrders() { // 商品表上的 sales_count 只有部分流程会累加,销量必须按有效订单算,否则后台列表一直是空的。 String salesSelect = service.salesCountSelect("r.product_id", "p"); assertThat(salesSelect) .contains("greatest") .contains("from benefit_order bo") .contains("bo.product_id = r.product_id") .contains("bo.order_status = 1") .contains("bo.refund_status is null or bo.refund_status = 0") .endsWith("as sales_count"); } @Test void productAuditListOnlyKeepsTheLatestRecordPerProduct() { // 同一个团单修改后再次提交会插入新的审核记录;列表只保留每个团单最新的一条, // 否则同一个团单会出现多行、销量被重复统计。 JdbcTemplate jdbc = mock(JdbcTemplate.class); AdminBusinessService adminService = new AdminBusinessService(jdbc); when(jdbc.queryForObject(anyString(), eq(Long.class), any(Object[].class))).thenReturn(1L); when(jdbc.queryForList(anyString(), any(Object[].class))).thenReturn(List.of()); adminService.products(null, null, null, null, null, null, null, null, 1, 10); ArgumentCaptor sql = ArgumentCaptor.forClass(String.class); verify(jdbc).queryForList(sql.capture(), any(Object[].class)); assertThat(sql.getValue()) .contains("from merchant_product_audit_record r") .contains("select max(newer.id) from merchant_product_audit_record newer"); } }