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.protobuf.*; 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.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, "c47b405bee79000f282a36e800000000"); 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/c47b405bee79000f282a36e800000000", result); } @Test public void testCloudCreateOrder() { String orderId = "1881347710714060802"; RtTask.Builder taskBuilder = RtTask.newBuilder(); taskBuilder.setTaskId("task-123"); taskBuilder.setOrderId(orderId); taskBuilder.setTaskType(OrderType.ORDER_TYPE_ROBOTAXI); Waypoint.Builder pointBuilder = Waypoint.newBuilder(); pointBuilder.setPointType(PointType.START_POINT); pointBuilder.setActionType(ActionType.PICK_UP); pointBuilder.setSequence(1); GeoPoint.Builder geoPointBuilder = GeoPoint.newBuilder(); geoPointBuilder.setLatitude(30.0); geoPointBuilder.setLongitude(120.0); // geoPointBuilder.setPoiName("Start Point"); // GeoPoint might not have poi_name pointBuilder.setPoint(geoPointBuilder.build()); taskBuilder.addPoints(pointBuilder); RtTaskList.Builder taskListBuilder = RtTaskList.newBuilder(); taskListBuilder.addTasks(taskBuilder.build()); String vin = "VIN12345678900000"; Long sequence = 1L; xpuUtil.cloudCreateOrder(taskListBuilder.build(), vin, sequence); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/c47b405bee79000f282a36e800000000", capturedVo.getTopic()); // Note: Current implementation serializes enum as ordinal. Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\": 10003"), "Payload should contain cmd CLOUD_CREATE_ORDER (10003), but was: " + capturedVo.getPayload()); } @Test public void testCloudOrderOperation() { String orderId = "1881347710714060802"; OrderOperation.Builder operationBuilder = OrderOperation.newBuilder(); operationBuilder.setOrderId(orderId); operationBuilder.setTaskId("task-123"); operationBuilder.setOperationType(OrderOperationType.CLOUD_CREATE_ORDER); operationBuilder.setOrderType(OrderType.ORDER_TYPE_ROBOTAXI); Waypoint.Builder waypointBuilder = Waypoint.newBuilder(); waypointBuilder.setWaypointId("wp-1"); waypointBuilder.setPointType(PointType.WAY_POINT); waypointBuilder.setActionType(ActionType.PICK_UP); // Use valid enum waypointBuilder.setSequence(2); GeoPoint.Builder geoPointBuilder = GeoPoint.newBuilder(); geoPointBuilder.setLatitude(30.1); geoPointBuilder.setLongitude(120.1); // geoPointBuilder.setPoiName("Way Point"); waypointBuilder.setPoint(geoPointBuilder.build()); operationBuilder.addWaypoints(waypointBuilder.build()); // TargetPoint targetPoint = new TargetPoint(); // OrderOperation uses Waypoint for target_point in proto? // Check proto: Waypoint target_point = 6; Waypoint.Builder targetPointBuilder = Waypoint.newBuilder(); GeoPoint.Builder endGeoPointBuilder = GeoPoint.newBuilder(); endGeoPointBuilder.setLatitude(30.2); endGeoPointBuilder.setLongitude(120.2); targetPointBuilder.setPoint(endGeoPointBuilder.build()); operationBuilder.setTargetPoint(targetPointBuilder.build()); String vin = "VIN12345678900000"; Long sequence = 2L; xpuUtil.cloudOrderOperation(operationBuilder.build(), vin, sequence); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/c47b405bee79000f282a36e800000000", capturedVo.getTopic()); // Note: CLOUD_ORDER_OPERATION is 10001 Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\": 10001"), "Payload should contain cmd CLOUD_ORDER_OPERATION (10001), but was: " + capturedVo.getPayload()); } @Test public void testResponseMessage() { ResponseMessage.Builder responseMessageBuilder = ResponseMessage.newBuilder(); responseMessageBuilder.setRequestSeq(12345L); responseMessageBuilder.setCode(StatusCode.OK); responseMessageBuilder.setTimestamp(System.currentTimeMillis()); String vin = "VIN12345678900000"; xpuUtil.responseMessage(responseMessageBuilder.build(), vin); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/c47b405bee79000f282a36e800000000", capturedVo.getTopic()); // Note: CLOUD_TASK_CONTROL (used in responseMessage method? check code) // In XPUUtil.java: headerBuilder.setCmd(RTCmdType.CLOUD_TASK_CONTROL.getValue()); // CLOUD_TASK_CONTROL is 10002 Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\": 10002"), "Payload should contain cmd CLOUD_TASK_CONTROL (10002), but was: " + capturedVo.getPayload()); } @Test public void testCloudPushNavigation() { RestoreNavigationData.Builder navigationDataBuilder = RestoreNavigationData.newBuilder(); navigationDataBuilder.setRequestId("req-123"); navigationDataBuilder.setRouteId("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}"; navigationDataBuilder.setContent(content); navigationDataBuilder.setTimestamp(System.currentTimeMillis()); String xpuId = "c47b405bee79000f282a36e800000000"; Long sequence = 3L; xpuUtil.cloudPushNavigation(navigationDataBuilder.build(), xpuId, sequence); ArgumentCaptor captor = ArgumentCaptor.forClass(MqttPublishVo.class); Mockito.verify(xpuClient).publish(captor.capture()); MqttPublishVo capturedVo = captor.getValue(); Assertions.assertEquals("Robotaxi/Msg/Xpu/c47b405bee79000f282a36e800000000", capturedVo.getTopic()); // Note: CLOUD_NAVIGATION_RESPONSE is 10006 Assertions.assertTrue(capturedVo.getPayload().contains("\"cmd\": 10006"), "Payload should contain cmd CLOUD_NAVIGATION_RESPONSE (10006), but was: " + capturedVo.getPayload()); } }