SelfHostedRouteDistanceProviderTest.java 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. package com.ruoyi.app.flashdelivery.route;
  2. import com.alibaba.fastjson2.JSONObject;
  3. import org.junit.jupiter.api.Test;
  4. import java.math.BigDecimal;
  5. import java.util.List;
  6. import static org.junit.jupiter.api.Assertions.assertEquals;
  7. import static org.junit.jupiter.api.Assertions.assertThrows;
  8. /** 自部署地图路线 Provider 单测:响应解析、单次多站点请求保持用户顺序、越界不降级语义。 */
  9. class SelfHostedRouteDistanceProviderTest {
  10. @Test
  11. void realRequestMustSelectMotorcycleInsteadOfMapDefaultCar() throws Exception {
  12. com.sun.net.httpserver.HttpServer server = com.sun.net.httpserver.HttpServer.create(
  13. new java.net.InetSocketAddress("127.0.0.1", 0), 0);
  14. server.createContext("/route/multi", exchange -> {
  15. boolean motorcycle = exchange.getRequestURI().getQuery().contains("profile=motorcycle");
  16. byte[] body = ("{\"distance_meters\":" + (motorcycle ? 1000 : 2000)
  17. + ",\"duration_seconds\":120}").getBytes(java.nio.charset.StandardCharsets.UTF_8);
  18. exchange.sendResponseHeaders(200, body.length);
  19. try (var output = exchange.getResponseBody()) { output.write(body); }
  20. });
  21. server.start();
  22. try {
  23. com.ruoyi.app.map.SelfHostedMapClient client = new com.ruoyi.app.map.SelfHostedMapClient();
  24. SelfHostedRouteDistanceProvider provider = new SelfHostedRouteDistanceProvider(client);
  25. org.springframework.test.util.ReflectionTestUtils.setField(client, "baseUrl",
  26. "http://127.0.0.1:" + server.getAddress().getPort());
  27. assertEquals(1000, provider.route(List.of(point("25", "121"), point("25.1", "121.1")), 1).distanceMeters());
  28. } finally {
  29. server.stop(0);
  30. }
  31. }
  32. /** 捕获请求站点并返回固定响应,替代 HTTP。 */
  33. static class StubProvider extends SelfHostedRouteDistanceProvider {
  34. StubProvider() { super(org.mockito.Mockito.mock(com.ruoyi.app.map.SelfHostedMapClient.class)); }
  35. JSONObject response;
  36. RuntimeException error;
  37. List<GeoPoint> requestedPoints;
  38. @Override
  39. JSONObject fetchRoute(List<GeoPoint> points, Integer vehicleType) {
  40. requestedPoints = points;
  41. if (error != null) throw error;
  42. return response;
  43. }
  44. }
  45. private static GeoPoint point(String lat, String lng) {
  46. return new GeoPoint(new BigDecimal(lat), new BigDecimal(lng));
  47. }
  48. @Test
  49. void parsesOsmDistanceAndDurationAsRouteSource() {
  50. JSONObject response = new JSONObject();
  51. response.put("distance_meters", 1234);
  52. response.put("duration_seconds", 567);
  53. StubProvider provider = new StubProvider();
  54. provider.response = response;
  55. assertEquals(new RouteDistance(1234, 567, "ROUTE"),
  56. provider.route(List.of(point("25.0", "121.0"), point("25.1", "121.1")), null));
  57. }
  58. @Test
  59. void invalidDistanceFailsInsteadOfFabricating() {
  60. JSONObject response = new JSONObject();
  61. response.put("distance_meters", -1);
  62. assertThrows(IllegalStateException.class,
  63. () -> new StubProvider().parseRoute(response));
  64. assertThrows(IllegalStateException.class, () -> new StubProvider().parseRoute(null));
  65. }
  66. @Test
  67. void multiStopGoesInOneRequestPreservingUserOrder() {
  68. JSONObject response = new JSONObject();
  69. response.put("distance_meters", 3500);
  70. response.put("duration_seconds", 400);
  71. List<GeoPoint> points = List.of(point("25.0", "121.0"), point("25.1", "121.0"), point("25.1", "121.1"));
  72. StubProvider provider = new StubProvider();
  73. provider.response = response;
  74. assertEquals(new RouteDistance(3500, 400, "ROUTE"), provider.route(points, null));
  75. // 全部站点一次提交、顺序不变,由地图计算整线道路距离
  76. assertEquals(points, provider.requestedPoints);
  77. }
  78. @Test
  79. void anyMapFailureFailsTheWholeRoute() {
  80. StubProvider provider = new StubProvider();
  81. provider.error = new IllegalStateException("self hosted map http status 502");
  82. assertThrows(IllegalStateException.class,
  83. () -> provider.route(List.of(point("25.0", "121.0"), point("25.1", "121.0"),
  84. point("25.1", "121.1")), null));
  85. }
  86. @Test
  87. void outsideRegionErrorIsTypedForNonDegradation() {
  88. StubProvider provider = new StubProvider();
  89. provider.error = new RouteOutsideRegionException("outside");
  90. assertThrows(RouteOutsideRegionException.class,
  91. () -> provider.route(List.of(point("25.0", "121.0"), point("30.0", "124.0")), null));
  92. }
  93. }