package com.xiaopeng.automaticPilot.util; import com.xiaopeng.api.dto.automaticPilot.MqttPublishDto; import com.xiaopeng.api.feignClient.automaticPilot.VmpOpenServiceClient; import com.xiaopeng.api.feignClient.automaticPilot.XPUClient; import com.xiaopeng.api.vo.automaticPilot.MqttPublishVo; import com.xiaopeng.api.vo.automaticPilot.proto.down.GeoPoint; import com.xiaopeng.api.vo.automaticPilot.proto.down.ResponseMessage; import com.xiaopeng.api.vo.automaticPilot.proto.down.StatusCode; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudCreateOrder.*; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudOrderOperation.*; import com.xiaopeng.api.vo.automaticPilot.proto.down.cloudPushNavigation.RestoreNavigationData; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashMap; import java.util.Map; public class XPUUtilTest { private XPUUtil xpuUtil; private XPUClient xpuClient; private VmpOpenServiceClient vmpClient; @BeforeEach public void setUp() throws Exception { xpuUtil = new XPUUtil(); // Mock VmpOpenServiceClient vmpClient = Mockito.mock(VmpOpenServiceClient.class); Map mapping = new HashMap<>(); mapping.put(XPUUtil.XPU_ID_TYPE, "1234567890ABCDEFGHIJKL"); Mockito.when(vmpClient.getVehicleBindInfoByVin(Mockito.anyString(), Mockito.anyList())) .thenReturn(mapping); // Mock XPUClient xpuClient = Mockito.mock(XPUClient.class); Mockito.when(xpuClient.publish(Mockito.any(MqttPublishVo.class))) .thenReturn(new MqttPublishDto()); // Inject mocks Field vmpField = XPUUtil.class.getDeclaredField("vmpOpenServiceClient"); vmpField.setAccessible(true); vmpField.set(xpuUtil, vmpClient); Field xpuClientField = XPUUtil.class.getDeclaredField("xpuClient"); xpuClientField.setAccessible(true); xpuClientField.set(xpuUtil, xpuClient); Field topicField = XPUUtil.class.getDeclaredField("topicPrefix"); topicField.setAccessible(true); topicField.set(xpuUtil, "Robotaxi/Msg/Xpu"); } @Test public void testBuildTopicByVin() throws Exception { Method buildTopic = XPUUtil.class.getDeclaredMethod("buildTopicByVin", String.class); buildTopic.setAccessible(true); String result = (String) buildTopic.invoke(xpuUtil, "VIN123"); Assertions.assertEquals("Robotaxi/Msg/Xpu/ABCDEFGHIJKL00000000", result); } @Test public void testCloudCreateOrder() { String orderId = "1881347710714060802"; RTTask task = new RTTask(); task.setTask_id("task-123"); task.setOrder_id(orderId); task.setVin("VIN12345678900000"); task.setTask_type(TaskType.ROBOTAXI); task.setStatus(TaskStatus.PENDING); NavigationWaypoint point = new NavigationWaypoint(); point.setType(WaypointType.START_POINT); point.setAction(WaypointAction.PICK_UP); point.setSequence(1); GeoPoint geoPoint = new GeoPoint(); geoPoint.setLatitude(30.0); geoPoint.setLongitude(120.0); geoPoint.setPoi_name("Start Point"); point.setPoint(geoPoint); task.setPoints(Collections.singletonList(point)); String vin = "VIN12345678900000"; Long sequence = 1L; xpuUtil.cloudCreateOrder(task, vin, sequence); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/ABCDEFGHIJKL00000000", capturedVo.getTopic()); // Note: Current implementation serializes enum as ordinal. CLOUD_CREATE_ORDER is ordinal 2. Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\":2"), "Payload should contain cmd CLOUD_CREATE_ORDER (ordinal 2), but was: " + capturedVo.getPayload()); } @Test public void testCloudOrderOperation() { String orderId = "1881347710714060802"; OrderOperation operation = new OrderOperation(); operation.setOrder_id(orderId); operation.setTask_id("task-123"); operation.setOperation_type(OrderOperationType.CLOUD_CREATE_ORDER); operation.setOrder_type(OrderType.ROBOTAXI); Waypoint waypoint = new Waypoint(); waypoint.setWaypoint_id("wp-1"); waypoint.setPoint_type(PointType.WAY_POINT); waypoint.setAction_type(ActionType.WAIT); waypoint.setSequence(2); GeoPoint geoPoint = new GeoPoint(); geoPoint.setLatitude(30.1); geoPoint.setLongitude(120.1); geoPoint.setPoi_name("Way Point"); waypoint.setPoint(geoPoint); operation.setWaypoints(Collections.singletonList(waypoint)); TargetPoint targetPoint = new TargetPoint(); GeoPoint endGeoPoint = new GeoPoint(); endGeoPoint.setLatitude(30.2); endGeoPoint.setLongitude(120.2); endGeoPoint.setPoi_name("End Point"); targetPoint.setPoint(endGeoPoint); operation.setTarget_point(targetPoint); String vin = "VIN12345678900000"; Long sequence = 2L; xpuUtil.cloudOrderOperation(operation, vin, sequence); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/ABCDEFGHIJKL00000000", capturedVo.getTopic()); // Note: CLOUD_ORDER_OPERATION is ordinal 0. Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\":0"), "Payload should contain cmd CLOUD_ORDER_OPERATION (ordinal 0), but was: " + capturedVo.getPayload()); } @Test public void testResponseMessage() { ResponseMessage responseMessage = new ResponseMessage(); responseMessage.setRequest_seq(12345L); responseMessage.setCode(StatusCode.OK); responseMessage.setTimestamp(System.currentTimeMillis()); String vin = "VIN12345678900000"; xpuUtil.responseMessage(responseMessage, vin); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/ABCDEFGHIJKL00000000", capturedVo.getTopic()); // Note: CLOUD_TASK_CONTROL is ordinal 1. Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\":1"), "Payload should contain cmd CLOUD_TASK_CONTROL (ordinal 1), but was: " + capturedVo.getPayload()); } @Test public void testCloudPushNavigation() { RestoreNavigationData navigationData = new RestoreNavigationData(); navigationData.setRequest_id("req-123"); navigationData.setRoute_id("5939fa259ad6479cbdf8871ceed96b72"); String content = "{\"startPoint\":{\"location\":\"116.481028,39.989643\"},\"endPoint\":{\"location\":\"116.465302,40.004717\"},\"routeID\":\"xxxxxxxxxxxxx\",\"strategy\":17,\"type\":1,\"ferry\":0,\"disableEndDispatch\":1,\"viaInfo\":[{},{}],\"routeUserType\":2,\"bizScene\":2,\"plate\":\"京A12345\",\"vehicleType\":1}"; navigationData.setContent(content); navigationData.setTimestamp(System.currentTimeMillis()); String xpuId = "1234567890ABCDEFGHIJKL"; Long sequence = 3L; xpuUtil.cloudPushNavigation(navigationData, xpuId, sequence); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/ABCDEFGHIJKL00000000", capturedVo.getTopic()); // Note: CLOUD_NAVIGATION_RESPONSE is ordinal 5. Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\":5"), "Payload should contain cmd CLOUD_NAVIGATION_RESPONSE (ordinal 5), but was: " + capturedVo.getPayload()); } }