Files
baiyue-firstleg/integration-service/src/test/java/com/baiyue/integration/controller/LingxingInternalControllerTest.java
T

101 lines
5.4 KiB
Java

package com.baiyue.integration.controller;
import com.baiyue.common.web.GlobalExceptionHandler;
import com.baiyue.common.web.LongIdJacksonConfiguration;
import com.baiyue.integration.dto.lingxing.LingxingWmsDtos.OrderSummary;
import com.baiyue.integration.dto.lingxing.LingxingWmsDtos.PageResult;
import com.baiyue.integration.provider.lingxing.LingxingWmsClient;
import com.baiyue.integration.provider.lingxing.LingxingWmsException;
import com.baiyue.integration.security.InternalServiceTokenGuard;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;
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;
class LingxingInternalControllerTest {
private static final String PATH = "/internal/integrations/lingxing/wms/outbound-orders/query";
private static final String BODY = """
{"startTime":"2026-09-12T08:00:00","endTime":"2026-10-12T08:00:00","current":1,"size":1}
""";
private final String token = UUID.randomUUID().toString();
private LingxingWmsClient client;
private MockMvc mvc;
@BeforeEach
void setUp() {
var guard = new InternalServiceTokenGuard();
ReflectionTestUtils.setField(guard, "token", token);
ReflectionTestUtils.invokeMethod(guard, "initializeToken");
client = mock(LingxingWmsClient.class);
var builder = Jackson2ObjectMapperBuilder.json();
try (var context = new AnnotationConfigApplicationContext(LongIdJacksonConfiguration.class)) {
context.getBean(Jackson2ObjectMapperBuilderCustomizer.class).customize(builder);
}
mvc = MockMvcBuilders.standaloneSetup(new LingxingInternalController(guard, client))
.setMessageConverters(new MappingJackson2HttpMessageConverter(builder.build()))
.setControllerAdvice(new GlobalExceptionHandler()).build();
}
@Test
void missingOrWrongInternalTokenCannotCallProvider() throws Exception {
mvc.perform(post(PATH).contentType(MediaType.APPLICATION_JSON).content(BODY))
.andExpect(status().isOk()).andExpect(jsonPath("$.code").value("A0401"));
mvc.perform(post(PATH).header("X-Internal-Service-Token", "wrong")
.contentType(MediaType.APPLICATION_JSON).content(BODY))
.andExpect(status().isOk()).andExpect(jsonPath("$.code").value("A0401"));
verifyNoInteractions(client);
}
@Test
void authenticatedReadReturnsOnlyOutboundSummary() throws Exception {
when(client.queryPage(any())).thenReturn(new PageResult(
List.of(new OrderSummary("TEST-OUT-001", "TEST-SRC-001", "TEST-CUSTOMER", "TEST-WH", 100,
"2026-10-01 08:00:00", "2026-10-02 08:00:00")),
1L, 1, 1, 200, Instant.parse("2026-10-12T00:00:00Z")));
mvc.perform(post(PATH).header("X-Internal-Service-Token", token)
.contentType(MediaType.APPLICATION_JSON).content(BODY))
.andExpect(status().isOk()).andExpect(jsonPath("$.code").value("200"))
.andExpect(jsonPath("$.data.total").isString()).andExpect(jsonPath("$.data.total").value("1"))
.andExpect(jsonPath("$.data.records[0].deliveryNo").value("TEST-OUT-001"))
.andExpect(jsonPath("$.data.records[0].recipient").doesNotExist());
}
@Test
void invalidPageCannotReachProvider() throws Exception {
mvc.perform(post(PATH).header("X-Internal-Service-Token", token)
.contentType(MediaType.APPLICATION_JSON).content(BODY.replace("\"current\":1", "\"current\":0")))
.andExpect(status().isOk()).andExpect(jsonPath("$.code").value("A0422"));
verifyNoInteractions(client);
}
@Test
void providerFailureRemainsAnExplicitBusinessFailure() throws Exception {
when(client.queryPage(any())).thenThrow(new LingxingWmsException(
"LINGXING_WMS_HTTP_RATE_LIMITED", "领星 WMS 请求受到限流", true, 429, null));
mvc.perform(post(PATH).header("X-Internal-Service-Token", token)
.contentType(MediaType.APPLICATION_JSON).content(BODY))
.andExpect(status().isOk()).andExpect(jsonPath("$.code").value("S0503"))
.andExpect(jsonPath("$.data.errorCode").value("LINGXING_WMS_HTTP_RATE_LIMITED"))
.andExpect(jsonPath("$.data.upstreamStatus").value(429))
.andExpect(jsonPath("$.data.records").doesNotExist());
}
}