package com.starry.admin.api; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.starry.admin.common.apitest.ApiTestDataSeeder; import com.starry.admin.modules.clerk.module.entity.PlayClerkUserInfoEntity; import com.starry.admin.modules.clerk.module.entity.PlayClerkWagesInfoEntity; import com.starry.admin.modules.clerk.service.IPlayClerkUserInfoService; import com.starry.admin.modules.clerk.service.IPlayClerkWagesDetailsInfoService; import com.starry.admin.modules.clerk.service.IPlayClerkWagesInfoService; import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity; import com.starry.admin.modules.order.service.IPlayOrderInfoService; import com.starry.admin.modules.weichat.service.WxTokenService; import com.starry.admin.utils.SecurityUtils; import com.starry.common.constant.Constants; import com.starry.common.utils.IdUtils; import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; class WxClerkWagesControllerApiTest extends AbstractApiTest { @Autowired private WxTokenService wxTokenService; @Autowired private IPlayClerkUserInfoService clerkUserInfoService; @Autowired private IPlayOrderInfoService orderInfoService; @Autowired private IPlayClerkWagesInfoService wagesInfoService; @Autowired private IPlayClerkWagesDetailsInfoService wagesDetailsInfoService; private final java.util.List orderIdsToCleanup = new java.util.ArrayList<>(); private final java.util.List wagesIdsToCleanup = new java.util.ArrayList<>(); private String clerkToken; private String clerkId; @BeforeEach void setUp() { SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); String suffix = Long.toString(System.nanoTime(), 36); clerkId = "apitest-wage-clerk-" + suffix; String openId = "openid-" + clerkId; clerkToken = wxTokenService.createWxUserToken(clerkId); ensureActiveClerk(clerkId, openId, clerkToken); wagesDetailsInfoService.lambdaUpdate() .eq(com.starry.admin.modules.clerk.module.entity.PlayClerkWagesDetailsInfoEntity::getClerkId, clerkId) .remove(); wagesInfoService.lambdaUpdate() .eq(PlayClerkWagesInfoEntity::getClerkId, clerkId) .remove(); } @AfterEach void tearDown() { SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); if (!orderIdsToCleanup.isEmpty()) { orderInfoService.removeByIds(orderIdsToCleanup); orderIdsToCleanup.clear(); } if (!wagesIdsToCleanup.isEmpty()) { wagesInfoService.removeByIds(wagesIdsToCleanup); wagesIdsToCleanup.clear(); } } @Test void queryUnsettledWagesSumsOrdersForClerk__covers_WAGE_001() throws Exception { SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); String orderA = insertUnsettledOrder(new BigDecimal("10.00"), new BigDecimal("3.00")); String orderB = insertUnsettledOrder(new BigDecimal("20.50"), new BigDecimal("6.50")); orderIdsToCleanup.add(orderA); orderIdsToCleanup.add(orderB); mockMvc.perform(get("/wx/wages/clerk/queryUnsettledWages") .header(USER_HEADER, DEFAULT_USER) .header(TENANT_HEADER, DEFAULT_TENANT) .header(Constants.CLERK_USER_LOGIN_TOKEN, Constants.TOKEN_PREFIX + clerkToken)) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(200)) .andExpect(jsonPath("$.data.orderNumber").value(2)) .andExpect(jsonPath("$.data.orderMoney").value(30.50)) .andExpect(jsonPath("$.data.estimatedRevenue").value(9.50)); } @Test void queryCurrentPeriodWagesReturnsZerosWhenNoRow__covers_WAGE_002() throws Exception { SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); mockMvc.perform(get("/wx/wages/clerk/queryCurrentPeriodWages") .header(USER_HEADER, DEFAULT_USER) .header(TENANT_HEADER, DEFAULT_TENANT) .header(Constants.CLERK_USER_LOGIN_TOKEN, Constants.TOKEN_PREFIX + clerkToken)) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(200)) .andExpect(jsonPath("$.data.totalMoney").value(0)) .andExpect(jsonPath("$.data.orderWages.orderNumber").value(0)) .andExpect(jsonPath("$.data.startCountDate").value(LocalDate.now().toString())) .andExpect(jsonPath("$.data.endCountDate").value(LocalDate.now().toString())); } @Test void queryHistoricalWagesReturnsHardcodedPageMeta__covers_WAGE_003() throws Exception { SecurityUtils.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); insertHistoricalWages("apitest-wage-his-1", new BigDecimal("12.34")); insertHistoricalWages("apitest-wage-his-2", new BigDecimal("56.78")); mockMvc.perform(post("/wx/wages/clerk/queryHistoricalWages") .header(USER_HEADER, DEFAULT_USER) .header(TENANT_HEADER, DEFAULT_TENANT) .header(Constants.CLERK_USER_LOGIN_TOKEN, Constants.TOKEN_PREFIX + clerkToken) .contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.code").value(200)) .andExpect(jsonPath("$.total").value(5)) .andExpect(jsonPath("$.pageInfo.pageSize").value(10)) .andExpect(jsonPath("$.pageInfo.totalPage").value(1)) .andExpect(jsonPath("$.data").isArray()) .andExpect(jsonPath("$.data.length()").value(2)); } private String insertUnsettledOrder(BigDecimal finalAmount, BigDecimal estimatedRevenue) { PlayOrderInfoEntity entity = new PlayOrderInfoEntity(); String id = "apitest-wage-" + IdUtils.getUuid(); entity.setId(id); entity.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); entity.setAcceptBy(clerkId); entity.setOrderSettlementState("0"); entity.setFinalAmount(finalAmount); entity.setEstimatedRevenue(estimatedRevenue); entity.setDeleted(false); orderInfoService.save(entity); return id; } private void insertHistoricalWages(String idPrefix, BigDecimal finalAmount) { PlayClerkWagesInfoEntity entity = new PlayClerkWagesInfoEntity(); String id = idPrefix + "-" + IdUtils.getUuid(); entity.setId(id); entity.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); entity.setClerkId(clerkId); entity.setHistoricalStatistics("1"); entity.setStartCountDate(LocalDate.now().minusDays(7)); entity.setEndCountDate(LocalDate.now().minusDays(1)); entity.setSettlementDate(LocalDate.now().minusDays(1)); entity.setOrderNumber(1); entity.setFinalAmount(finalAmount); entity.setEstimatedRevenue(finalAmount); entity.setCreatedTime(java.sql.Timestamp.valueOf(LocalDateTime.now())); entity.setUpdatedTime(java.sql.Timestamp.valueOf(LocalDateTime.now())); entity.setDeleted(false); wagesInfoService.save(entity); wagesIdsToCleanup.add(id); } private void ensureActiveClerk(String clerkId, String openId, String token) { PlayClerkUserInfoEntity existing = clerkUserInfoService.getById(clerkId); if (existing == null) { PlayClerkUserInfoEntity entity = new PlayClerkUserInfoEntity(); entity.setId(clerkId); entity.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); entity.setOpenid(openId); entity.setNickname("API Test Wages Clerk"); entity.setAvatar("https://example.com/avatar.png"); entity.setSysUserId(""); entity.setOnboardingState("1"); entity.setListingState("1"); entity.setClerkState("1"); entity.setOnlineState("1"); entity.setToken(token); clerkUserInfoService.save(entity); return; } PlayClerkUserInfoEntity patch = new PlayClerkUserInfoEntity(); patch.setId(clerkId); patch.setTenantId(ApiTestDataSeeder.DEFAULT_TENANT_ID); patch.setOpenid(openId); patch.setSysUserId(""); patch.setOnboardingState("1"); patch.setListingState("1"); patch.setClerkState("1"); patch.setOnlineState("1"); patch.setDeleted(Boolean.FALSE); patch.setToken(token); clerkUserInfoService.updateById(patch); } }