101 lines
5.4 KiB
Java
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());
|
|
}
|
|
}
|