新需求更新 同步更新
This commit is contained in:
+62
@@ -0,0 +1,62 @@
|
||||
package com.nanri.aiimage.modules.ziniao.controller;
|
||||
|
||||
import com.nanri.aiimage.common.exception.BusinessException;
|
||||
import com.nanri.aiimage.modules.ziniao.model.cache.ZiniaoShopIndexRefreshCursorDto;
|
||||
import com.nanri.aiimage.modules.admin.support.AdminAuthSupport;
|
||||
import com.nanri.aiimage.modules.ziniao.service.ZiniaoAuthService;
|
||||
import com.nanri.aiimage.modules.ziniao.service.ZiniaoShopIndexRefreshService;
|
||||
import com.nanri.aiimage.modules.ziniao.service.ZiniaoShopIndexService;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
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 ZiniaoAuthControllerTest {
|
||||
|
||||
@Test
|
||||
void manualIndexRefreshEndpointReturnsCompletedCursor() throws Exception {
|
||||
ZiniaoAuthService authService = mock(ZiniaoAuthService.class);
|
||||
ZiniaoShopIndexService indexService = mock(ZiniaoShopIndexService.class);
|
||||
ZiniaoShopIndexRefreshService refreshService = mock(ZiniaoShopIndexRefreshService.class);
|
||||
AdminAuthSupport adminAuthSupport = mock(AdminAuthSupport.class);
|
||||
ZiniaoShopIndexRefreshCursorDto cursor = new ZiniaoShopIndexRefreshCursorDto();
|
||||
cursor.setStatus("SUCCESS");
|
||||
cursor.setLastProcessedApiKeyCount(3);
|
||||
when(refreshService.refreshShopIndexManually()).thenReturn(cursor);
|
||||
ZiniaoAuthController controller = new ZiniaoAuthController(authService, indexService, refreshService, adminAuthSupport);
|
||||
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
|
||||
|
||||
mockMvc.perform(post("/api/ziniao/index-refresh")
|
||||
.header(HttpHeaders.AUTHORIZATION, "Bearer admin-token"))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.success").value(true))
|
||||
.andExpect(jsonPath("$.data.status").value("SUCCESS"))
|
||||
.andExpect(jsonPath("$.data.lastProcessedApiKeyCount").value(3));
|
||||
verify(adminAuthSupport).requireAdmin(org.mockito.ArgumentMatchers.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void manualIndexRefreshRequiresAdministrator() {
|
||||
ZiniaoAuthService authService = mock(ZiniaoAuthService.class);
|
||||
ZiniaoShopIndexService indexService = mock(ZiniaoShopIndexService.class);
|
||||
ZiniaoShopIndexRefreshService refreshService = mock(ZiniaoShopIndexRefreshService.class);
|
||||
AdminAuthSupport adminAuthSupport = mock(AdminAuthSupport.class);
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
BusinessException authFailure = new BusinessException(403, "需要管理员权限");
|
||||
when(adminAuthSupport.requireAdmin(request)).thenThrow(authFailure);
|
||||
ZiniaoAuthController controller = new ZiniaoAuthController(authService, indexService, refreshService, adminAuthSupport);
|
||||
|
||||
assertThatThrownBy(() -> controller.refreshShopIndex(request, null)).isSameAs(authFailure);
|
||||
verifyNoInteractions(refreshService);
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.nanri.aiimage.modules.ziniao.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.Wrapper;
|
||||
import com.baomidou.mybatisplus.core.MybatisConfiguration;
|
||||
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
|
||||
import com.nanri.aiimage.modules.shopkey.mapper.ShopKeyMapper;
|
||||
import com.nanri.aiimage.modules.shopkey.model.entity.ShopKeyEntity;
|
||||
import org.apache.ibatis.builder.MapperBuilderAssistant;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class ZiniaoApiKeyProviderTest {
|
||||
|
||||
@BeforeAll
|
||||
static void initializeMybatisMetadata() {
|
||||
TableInfoHelper.initTableInfo(
|
||||
new MapperBuilderAssistant(new MybatisConfiguration(), "ziniao-api-key-provider-test"),
|
||||
ShopKeyEntity.class
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void duplicateNormalizedTokensShareOneRefreshAccountAndAllRecordIds() {
|
||||
ShopKeyMapper mapper = mock(ShopKeyMapper.class);
|
||||
ShopKeyEntity latest = shopKey(12L, " Bearer duplicate-key ", "最新账号");
|
||||
ShopKeyEntity older = shopKey(8L, "duplicate-key", "旧账号");
|
||||
when(mapper.selectList(any())).thenReturn(List.of(latest, older));
|
||||
|
||||
ZiniaoApiKeyProvider provider = new ZiniaoApiKeyProvider(mapper);
|
||||
|
||||
List<ZiniaoApiKeyProvider.ApiKeyAccount> accounts = provider.listApiKeyAccounts();
|
||||
|
||||
assertEquals(1, accounts.size());
|
||||
assertEquals("duplicate-key", accounts.getFirst().apiKey());
|
||||
assertEquals("最新账号", accounts.getFirst().accountName());
|
||||
assertEquals(List.of(12L, 8L), accounts.getFirst().shopKeyIds());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whitelistResultUpdatesEveryRecordForTheNormalizedToken() {
|
||||
ShopKeyMapper mapper = mock(ShopKeyMapper.class);
|
||||
ZiniaoApiKeyProvider provider = new ZiniaoApiKeyProvider(mapper);
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount account = new ZiniaoApiKeyProvider.ApiKeyAccount(
|
||||
"duplicate-key",
|
||||
"账号",
|
||||
List.of(12L, 8L)
|
||||
);
|
||||
|
||||
provider.markIpWhitelistBlocked(account, "当前服务器 IP 未加入紫鸟白名单");
|
||||
|
||||
verify(mapper).update(isNull(), any(Wrapper.class));
|
||||
}
|
||||
|
||||
private ShopKeyEntity shopKey(long id, String token, String accountName) {
|
||||
ShopKeyEntity entity = new ShopKeyEntity();
|
||||
entity.setId(id);
|
||||
entity.setZiniaoToken(token);
|
||||
entity.setZiniaoAccountName(accountName);
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.nanri.aiimage.modules.ziniao.service;
|
||||
|
||||
import com.nanri.aiimage.common.exception.BusinessException;
|
||||
import com.nanri.aiimage.common.service.DistributedJobLockService;
|
||||
import com.nanri.aiimage.modules.ziniao.model.cache.ZiniaoShopIndexRefreshCursorDto;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class ZiniaoShopIndexRefreshServiceTest {
|
||||
|
||||
@Test
|
||||
void manualRefreshRunsUnderDistributedLockAndReturnsCursor() {
|
||||
ZiniaoShopIndexService indexService = mock(ZiniaoShopIndexService.class);
|
||||
DistributedJobLockService lockService = mock(DistributedJobLockService.class);
|
||||
DistributedJobLockService.LockHandle lockHandle = mock(DistributedJobLockService.LockHandle.class);
|
||||
ZiniaoShopIndexRefreshCursorDto cursor = new ZiniaoShopIndexRefreshCursorDto();
|
||||
cursor.setStatus("SUCCESS");
|
||||
when(lockService.tryLock("ziniao:shop-index-refresh", Duration.ofMinutes(30))).thenReturn(lockHandle);
|
||||
when(indexService.getRefreshCursor()).thenReturn(cursor);
|
||||
ZiniaoShopIndexRefreshService service = new ZiniaoShopIndexRefreshService(indexService, lockService);
|
||||
|
||||
ZiniaoShopIndexRefreshCursorDto result = service.refreshShopIndexManually();
|
||||
|
||||
assertThat(result).isSameAs(cursor);
|
||||
verify(indexService).refreshAllShopIndex();
|
||||
verify(lockHandle).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void manualRefreshRejectsConcurrentExecution() {
|
||||
ZiniaoShopIndexService indexService = mock(ZiniaoShopIndexService.class);
|
||||
DistributedJobLockService lockService = mock(DistributedJobLockService.class);
|
||||
when(lockService.tryLock("ziniao:shop-index-refresh", Duration.ofMinutes(30))).thenReturn(null);
|
||||
ZiniaoShopIndexRefreshService service = new ZiniaoShopIndexRefreshService(indexService, lockService);
|
||||
|
||||
assertThatThrownBy(service::refreshShopIndexManually)
|
||||
.isInstanceOf(BusinessException.class)
|
||||
.hasMessageContaining("正在刷新");
|
||||
verify(indexService, never()).refreshAllShopIndex();
|
||||
}
|
||||
}
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
package com.nanri.aiimage.modules.ziniao.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.nanri.aiimage.common.exception.BusinessException;
|
||||
import com.nanri.aiimage.config.ZiniaoProperties;
|
||||
import com.nanri.aiimage.modules.ziniao.memory.service.ZiniaoMemoryStoreService;
|
||||
import com.nanri.aiimage.modules.ziniao.memory.service.ZiniaoTransientCacheService;
|
||||
import com.nanri.aiimage.modules.ziniao.model.cache.ZiniaoShopIndexEntryDto;
|
||||
import com.nanri.aiimage.modules.ziniao.model.cache.ZiniaoShopIndexRefreshCursorDto;
|
||||
import com.nanri.aiimage.modules.ziniao.model.cache.ZiniaoShopCacheDto;
|
||||
import com.nanri.aiimage.modules.ziniao.model.vo.ZiniaoStaffItemVo;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class ZiniaoShopIndexServiceTest {
|
||||
|
||||
@Mock
|
||||
private ZiniaoMemoryStoreService ziniaoMemoryStoreService;
|
||||
@Mock
|
||||
private ZiniaoTransientCacheService ziniaoTransientCacheService;
|
||||
@Mock
|
||||
private ZiniaoApiKeyProvider ziniaoApiKeyProvider;
|
||||
@Mock
|
||||
private ZiniaoAuthService ziniaoAuthService;
|
||||
|
||||
private ZiniaoShopIndexService service;
|
||||
private ZiniaoProperties properties;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
properties = new ZiniaoProperties();
|
||||
properties.setShopIndexEntryTtlHours(12);
|
||||
properties.setShopIndexRefreshBatchSize(100);
|
||||
service = new ZiniaoShopIndexService(
|
||||
ziniaoMemoryStoreService,
|
||||
ziniaoTransientCacheService,
|
||||
ziniaoApiKeyProvider,
|
||||
ziniaoAuthService,
|
||||
properties,
|
||||
new ObjectMapper()
|
||||
);
|
||||
when(ziniaoTransientCacheService.get(
|
||||
"SHOP_INDEX_REFRESH_CURSOR",
|
||||
"global",
|
||||
ZiniaoShopIndexRefreshCursorDto.class
|
||||
)).thenReturn(Optional.empty());
|
||||
}
|
||||
|
||||
@Test
|
||||
void companyWhitelistFailureSkipsCurrentApiKeyAndRefreshesNextApiKey() {
|
||||
stubIpWhitelistDetection();
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount blocked = new ZiniaoApiKeyProvider.ApiKeyAccount("blocked-key", "blocked-account");
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount allowed = new ZiniaoApiKeyProvider.ApiKeyAccount("allowed-key", "allowed-account");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(blocked, allowed));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("blocked-key"))
|
||||
.thenThrow(new BusinessException("当前服务器 IP 未加入紫鸟白名单"));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("allowed-key")).thenReturn(2L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("allowed-key", 2L)).thenReturn(List.of(staff(22L)));
|
||||
when(ziniaoAuthService.getOrLoadUserStoresForIndex("allowed-key", 2L, 22L))
|
||||
.thenReturn(List.of(shop("shop-2", "店铺B")));
|
||||
|
||||
service.refreshShopIndex();
|
||||
|
||||
verify(ziniaoMemoryStoreService).put(
|
||||
eq(ZiniaoMemoryStoreService.CACHE_TYPE_SHOP_INDEX_ENTRY),
|
||||
eq("s:shop-2"),
|
||||
argThat(value -> value instanceof ZiniaoShopIndexEntryDto entry
|
||||
&& "shop-2".equals(entry.getShopId())),
|
||||
any(Duration.class)
|
||||
);
|
||||
verify(ziniaoMemoryStoreService).put(
|
||||
eq(ZiniaoMemoryStoreService.CACHE_TYPE_SHOP_INDEX_ENTRY),
|
||||
eq("n:店铺B"),
|
||||
any(ZiniaoShopIndexEntryDto.class),
|
||||
any(Duration.class)
|
||||
);
|
||||
verify(ziniaoMemoryStoreService, never()).listAliveEntitiesByType(any(), anyInt());
|
||||
verify(ziniaoApiKeyProvider).markIpWhitelistBlocked(
|
||||
eq(blocked),
|
||||
eq("当前服务器 IP 未加入紫鸟白名单")
|
||||
);
|
||||
verify(ziniaoApiKeyProvider).markIpWhitelistAllowed(allowed);
|
||||
|
||||
ZiniaoShopIndexRefreshCursorDto cursor = capturedCursor();
|
||||
assertEquals("SUCCESS", cursor.getStatus());
|
||||
assertEquals(Integer.valueOf(1), cursor.getLastProcessedApiKeyCount());
|
||||
assertTrue(cursor.getMessage().contains("IP 白名单: 1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void whitelistFailureAfterPartialApiKeyScanDiscardsPartialEntriesAndContinues() {
|
||||
stubIpWhitelistDetection();
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount partiallyBlocked = new ZiniaoApiKeyProvider.ApiKeyAccount("partial-key", "partial-account");
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount allowed = new ZiniaoApiKeyProvider.ApiKeyAccount("allowed-key", "allowed-account");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(partiallyBlocked, allowed));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("partial-key")).thenReturn(1L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("partial-key", 1L))
|
||||
.thenReturn(List.of(staff(11L), staff(12L)));
|
||||
when(ziniaoAuthService.getOrLoadUserStoresForIndex("partial-key", 1L, 11L))
|
||||
.thenReturn(List.of(shop("partial-shop", "半成品店铺")));
|
||||
when(ziniaoAuthService.getOrLoadUserStoresForIndex("partial-key", 1L, 12L))
|
||||
.thenThrow(new BusinessException("当前服务器 IP 未加入紫鸟白名单"));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("allowed-key")).thenReturn(2L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("allowed-key", 2L)).thenReturn(List.of(staff(22L)));
|
||||
when(ziniaoAuthService.getOrLoadUserStoresForIndex("allowed-key", 2L, 22L))
|
||||
.thenReturn(List.of(shop("allowed-shop", "正常店铺")));
|
||||
|
||||
service.refreshShopIndex();
|
||||
|
||||
verify(ziniaoMemoryStoreService, never()).put(
|
||||
eq(ZiniaoMemoryStoreService.CACHE_TYPE_SHOP_INDEX_ENTRY),
|
||||
eq("s:partial-shop"),
|
||||
any(),
|
||||
any(Duration.class)
|
||||
);
|
||||
verify(ziniaoMemoryStoreService, never()).put(
|
||||
eq(ZiniaoMemoryStoreService.CACHE_TYPE_SHOP_INDEX_ENTRY),
|
||||
eq("n:半成品店铺"),
|
||||
any(),
|
||||
any(Duration.class)
|
||||
);
|
||||
verify(ziniaoMemoryStoreService).put(
|
||||
eq(ZiniaoMemoryStoreService.CACHE_TYPE_SHOP_INDEX_ENTRY),
|
||||
eq("s:allowed-shop"),
|
||||
any(ZiniaoShopIndexEntryDto.class),
|
||||
any(Duration.class)
|
||||
);
|
||||
verify(ziniaoMemoryStoreService, never()).listAliveEntitiesByType(any(), anyInt());
|
||||
verify(ziniaoApiKeyProvider).markIpWhitelistBlocked(
|
||||
eq(partiallyBlocked),
|
||||
eq("当前服务器 IP 未加入紫鸟白名单")
|
||||
);
|
||||
verify(ziniaoApiKeyProvider).markIpWhitelistAllowed(allowed);
|
||||
verify(ziniaoApiKeyProvider, never()).markIpWhitelistAllowed(partiallyBlocked);
|
||||
}
|
||||
|
||||
@Test
|
||||
void nonWhitelistCompanyFailureDoesNotOverwriteWhitelistStatus() {
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount failed = new ZiniaoApiKeyProvider.ApiKeyAccount("failed-key", "failed-account");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(failed));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("failed-key"))
|
||||
.thenThrow(new BusinessException("紫鸟接口临时不可用"));
|
||||
when(ziniaoAuthService.isIpWhitelistError(any(BusinessException.class))).thenReturn(false);
|
||||
|
||||
service.refreshShopIndex();
|
||||
|
||||
verify(ziniaoApiKeyProvider, never()).markIpWhitelistBlocked(any(), any());
|
||||
verify(ziniaoApiKeyProvider, never()).markIpWhitelistAllowed(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whitelistStatusWriteFailureDoesNotStopNextApiKey() {
|
||||
stubIpWhitelistDetection();
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount blocked = new ZiniaoApiKeyProvider.ApiKeyAccount("blocked-key", "blocked-account");
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount allowed = new ZiniaoApiKeyProvider.ApiKeyAccount("allowed-key", "allowed-account");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(blocked, allowed));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("blocked-key"))
|
||||
.thenThrow(new BusinessException("当前服务器 IP 未加入紫鸟白名单"));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("allowed-key")).thenReturn(2L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("allowed-key", 2L)).thenReturn(List.of());
|
||||
doThrow(new IllegalStateException("数据库暂时不可用"))
|
||||
.when(ziniaoApiKeyProvider)
|
||||
.markIpWhitelistBlocked(blocked, "当前服务器 IP 未加入紫鸟白名单");
|
||||
|
||||
service.refreshShopIndex();
|
||||
|
||||
verify(ziniaoAuthService).resolveCompanyIdForIndex("allowed-key");
|
||||
verify(ziniaoApiKeyProvider).markIpWhitelistAllowed(allowed);
|
||||
}
|
||||
|
||||
@Test
|
||||
void fullRefreshIgnoresScheduledBatchLimit() {
|
||||
properties.setShopIndexRefreshBatchSize(1);
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount first = new ZiniaoApiKeyProvider.ApiKeyAccount("first-key", "first-account");
|
||||
ZiniaoApiKeyProvider.ApiKeyAccount second = new ZiniaoApiKeyProvider.ApiKeyAccount("second-key", "second-account");
|
||||
when(ziniaoApiKeyProvider.listApiKeyAccounts()).thenReturn(List.of(first, second));
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("first-key")).thenReturn(1L);
|
||||
when(ziniaoAuthService.resolveCompanyIdForIndex("second-key")).thenReturn(2L);
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("first-key", 1L)).thenReturn(List.of());
|
||||
when(ziniaoAuthService.getOrLoadStaffForIndex("second-key", 2L)).thenReturn(List.of());
|
||||
|
||||
service.refreshAllShopIndex();
|
||||
|
||||
verify(ziniaoAuthService).resolveCompanyIdForIndex("first-key");
|
||||
verify(ziniaoAuthService).resolveCompanyIdForIndex("second-key");
|
||||
ZiniaoShopIndexRefreshCursorDto cursor = capturedCursor();
|
||||
assertEquals(Integer.valueOf(2), cursor.getLastProcessedApiKeyCount());
|
||||
assertEquals(Integer.valueOf(0), cursor.getNextApiKeyOffset());
|
||||
}
|
||||
|
||||
private ZiniaoShopIndexRefreshCursorDto capturedCursor() {
|
||||
ArgumentCaptor<Object> captor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(ziniaoTransientCacheService, times(2)).put(
|
||||
eq("SHOP_INDEX_REFRESH_CURSOR"),
|
||||
eq("global"),
|
||||
captor.capture(),
|
||||
any(Duration.class)
|
||||
);
|
||||
return (ZiniaoShopIndexRefreshCursorDto) captor.getAllValues().getLast();
|
||||
}
|
||||
|
||||
private void stubIpWhitelistDetection() {
|
||||
when(ziniaoAuthService.isIpWhitelistError(any(BusinessException.class)))
|
||||
.thenAnswer(invocation -> invocation.<BusinessException>getArgument(0).getMessage().contains("白名单"));
|
||||
}
|
||||
|
||||
private ZiniaoStaffItemVo staff(long userId) {
|
||||
ZiniaoStaffItemVo staff = new ZiniaoStaffItemVo();
|
||||
staff.setUserId(userId);
|
||||
return staff;
|
||||
}
|
||||
|
||||
private ZiniaoShopCacheDto shop(String shopId, String shopName) {
|
||||
ZiniaoShopCacheDto shop = new ZiniaoShopCacheDto();
|
||||
shop.setShopId(shopId);
|
||||
shop.setShopName(shopName);
|
||||
shop.setPlatform("亚马逊");
|
||||
return shop;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user