|
@@ -0,0 +1,106 @@
|
|
|
|
|
+package com.ruoyi.app.flashdelivery.route;
|
|
|
|
|
+
|
|
|
|
|
+import com.ruoyi.common.core.domain.entity.SysDictData;
|
|
|
|
|
+import com.ruoyi.common.utils.DictUtils;
|
|
|
|
|
+import org.junit.jupiter.api.Test;
|
|
|
|
|
+import org.mockito.MockedStatic;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+
|
|
|
|
|
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
|
+import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
|
|
|
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
|
+
|
|
|
|
|
+import static org.mockito.Mockito.mock;
|
|
|
|
|
+import static org.mockito.Mockito.mockStatic;
|
|
|
|
|
+import static org.mockito.Mockito.verify;
|
|
|
|
|
+import static org.mockito.Mockito.verifyNoMoreInteractions;
|
|
|
|
|
+import static org.mockito.Mockito.when;
|
|
|
|
|
+
|
|
|
|
|
+/** 距离来源开关单测(032 FR-001):缺省走 Google,SELF_HOSTED 切自部署,逐请求生效。 */
|
|
|
|
|
+class DistanceSourceRouteProviderTest {
|
|
|
|
|
+
|
|
|
|
|
+ private final GoogleRoutesDistanceProvider google = mock(GoogleRoutesDistanceProvider.class);
|
|
|
|
|
+ private final SelfHostedRouteDistanceProvider selfHosted = mock(SelfHostedRouteDistanceProvider.class);
|
|
|
|
|
+
|
|
|
|
|
+ private DistanceSourceRouteProvider router(boolean enabled) {
|
|
|
|
|
+ return new DistanceSourceRouteProvider(google, selfHosted) {
|
|
|
|
|
+ @Override
|
|
|
|
|
+ boolean selfHostedEnabled() {
|
|
|
|
|
+ return enabled;
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void defaultsToGoogleWhenSwitchOff() {
|
|
|
|
|
+ when(google.route(List.of(new GeoPoint(new java.math.BigDecimal("25"), new java.math.BigDecimal("121")),
|
|
|
|
|
+ new GeoPoint(new java.math.BigDecimal("25.1"), new java.math.BigDecimal("121.1"))), null))
|
|
|
|
|
+ .thenReturn(new RouteDistance(100, 60, "ROUTE"));
|
|
|
|
|
+ List<GeoPoint> points = List.of(new GeoPoint(new java.math.BigDecimal("25"), new java.math.BigDecimal("121")),
|
|
|
|
|
+ new GeoPoint(new java.math.BigDecimal("25.1"), new java.math.BigDecimal("121.1")));
|
|
|
|
|
+
|
|
|
|
|
+ assertEquals(new RouteDistance(100, 60, "ROUTE"), router(false).route(points, null));
|
|
|
|
|
+
|
|
|
|
|
+ verify(google).route(points, null);
|
|
|
|
|
+ verifyNoMoreInteractions(google, selfHosted);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void switchOnDelegatesToSelfHosted() {
|
|
|
|
|
+ List<GeoPoint> points = List.of(new GeoPoint(new java.math.BigDecimal("25"), new java.math.BigDecimal("121")),
|
|
|
|
|
+ new GeoPoint(new java.math.BigDecimal("25.1"), new java.math.BigDecimal("121.1")));
|
|
|
|
|
+ when(selfHosted.route(points, null)).thenReturn(new RouteDistance(200, 120, "ROUTE"));
|
|
|
|
|
+
|
|
|
|
|
+ assertEquals(new RouteDistance(200, 120, "ROUTE"), router(true).route(points, null));
|
|
|
|
|
+
|
|
|
|
|
+ verify(selfHosted).route(points, null);
|
|
|
|
|
+ verifyNoMoreInteractions(google, selfHosted);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void twoPointOverloadFollowsTheSameSwitch() {
|
|
|
|
|
+ java.math.BigDecimal lat = new java.math.BigDecimal("25");
|
|
|
|
|
+ java.math.BigDecimal lng = new java.math.BigDecimal("121");
|
|
|
|
|
+ when(selfHosted.route(lat, lng, new java.math.BigDecimal("25.1"), new java.math.BigDecimal("121.1"), 2))
|
|
|
|
|
+ .thenReturn(new RouteDistance(300, 180, "ROUTE"));
|
|
|
|
|
+
|
|
|
|
|
+ assertEquals(300, router(true).route(lat, lng, new java.math.BigDecimal("25.1"),
|
|
|
|
|
+ new java.math.BigDecimal("121.1"), 2).distanceMeters());
|
|
|
|
|
+
|
|
|
|
|
+ verify(selfHosted).route(lat, lng, new java.math.BigDecimal("25.1"), new java.math.BigDecimal("121.1"), 2);
|
|
|
|
|
+ verifyNoMoreInteractions(google);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void readsUniqueDefaultRatherThanFirstDictionaryRow() {
|
|
|
|
|
+ DistanceSourceRouteProvider provider = new DistanceSourceRouteProvider(google, selfHosted);
|
|
|
|
|
+ try (MockedStatic<DictUtils> dictionaries = mockStatic(DictUtils.class)) {
|
|
|
|
|
+ dictionaries.when(() -> DictUtils.getDictCache("sys_map_distance_source"))
|
|
|
|
|
+ .thenReturn(List.of(row("GOOGLE", "N"), row("SELF_HOSTED", "Y")));
|
|
|
|
|
+
|
|
|
|
|
+ assertTrue(provider.selfHostedEnabled());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Test
|
|
|
|
|
+ void missingOrAmbiguousDefaultFallsBackToGoogle() {
|
|
|
|
|
+ DistanceSourceRouteProvider provider = new DistanceSourceRouteProvider(google, selfHosted);
|
|
|
|
|
+ try (MockedStatic<DictUtils> dictionaries = mockStatic(DictUtils.class)) {
|
|
|
|
|
+ dictionaries.when(() -> DictUtils.getDictCache("sys_map_distance_source"))
|
|
|
|
|
+ .thenReturn(List.of(row("SELF_HOSTED", "N"), row("GOOGLE", "N")),
|
|
|
|
|
+ List.of(row("SELF_HOSTED", "Y"), row("GOOGLE", "Y")), null);
|
|
|
|
|
+
|
|
|
|
|
+ assertFalse(provider.selfHostedEnabled());
|
|
|
|
|
+ assertFalse(provider.selfHostedEnabled());
|
|
|
|
|
+ assertFalse(provider.selfHostedEnabled());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static SysDictData row(String value, String isDefault) {
|
|
|
|
|
+ SysDictData row = new SysDictData();
|
|
|
|
|
+ row.setDictValue(value);
|
|
|
|
|
+ row.setIsDefault(isDefault);
|
|
|
|
|
+ return row;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|