|
|
|
@@ -17,8 +17,12 @@ import com.starry.admin.utils.SecurityUtils;
|
|
|
|
import com.starry.common.utils.IdUtils;
|
|
|
|
import com.starry.common.utils.IdUtils;
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.time.LocalDateTime;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
|
|
|
|
import java.util.Comparator;
|
|
|
|
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
import java.util.concurrent.ThreadLocalRandom;
|
|
|
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
import org.junit.jupiter.api.AfterEach;
|
|
|
|
import org.junit.jupiter.api.AfterEach;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
|
@@ -37,6 +41,13 @@ class PlayClerkUserInfoApiTest extends AbstractApiTest {
|
|
|
|
|
|
|
|
|
|
|
|
private final List<String> levelIdsToCleanup = new ArrayList<>();
|
|
|
|
private final List<String> levelIdsToCleanup = new ArrayList<>();
|
|
|
|
private final List<String> clerkIdsToCleanup = new ArrayList<>();
|
|
|
|
private final List<String> clerkIdsToCleanup = new ArrayList<>();
|
|
|
|
|
|
|
|
private int scenarioSequence = 0;
|
|
|
|
|
|
|
|
private static final Comparator<ClerkScenario> BACKEND_ORDERING = Comparator
|
|
|
|
|
|
|
|
.comparing(ClerkScenario::isOnline).reversed()
|
|
|
|
|
|
|
|
.thenComparing(ClerkScenario::isPinned).reversed()
|
|
|
|
|
|
|
|
.thenComparingLong(ClerkScenario::getLevelOrder)
|
|
|
|
|
|
|
|
.thenComparingInt(ClerkScenario::getSequence)
|
|
|
|
|
|
|
|
.thenComparing(ClerkScenario::getId);
|
|
|
|
|
|
|
|
|
|
|
|
@AfterEach
|
|
|
|
@AfterEach
|
|
|
|
void tearDown() {
|
|
|
|
void tearDown() {
|
|
|
|
@@ -83,9 +94,10 @@ class PlayClerkUserInfoApiTest extends AbstractApiTest {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
assertThat(orderedIds).contains(lowOrderClerkId, highOrderClerkId);
|
|
|
|
assertThat(orderedIds).contains(lowOrderClerkId, highOrderClerkId);
|
|
|
|
assertThat(orderedIds.indexOf(lowOrderClerkId))
|
|
|
|
assertThat(orderedIds.indexOf(highOrderClerkId))
|
|
|
|
.withFailMessage("Unexpected order for token %s: %s", filterToken, orderedIds)
|
|
|
|
.withFailMessage("Online clerk should appear before offline regardless of level. token=%s list=%s",
|
|
|
|
.isLessThan(orderedIds.indexOf(highOrderClerkId));
|
|
|
|
filterToken, orderedIds)
|
|
|
|
|
|
|
|
.isLessThan(orderedIds.indexOf(lowOrderClerkId));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
@Test
|
|
|
|
@@ -351,17 +363,96 @@ class PlayClerkUserInfoApiTest extends AbstractApiTest {
|
|
|
|
orderedIds.add(record.path("id").asText());
|
|
|
|
orderedIds.add(record.path("id").asText());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
assertThat(orderedIds.indexOf(pinnedOnline))
|
|
|
|
Map<String, ClerkScenario> expectedScenarios = new HashMap<>();
|
|
|
|
.isLessThan(orderedIds.indexOf(pinnedOffline));
|
|
|
|
expectedScenarios.put(pinnedOnline, new ClerkScenario(pinnedOnline, 1L, true, true, 0));
|
|
|
|
assertThat(orderedIds.indexOf(pinnedOffline))
|
|
|
|
expectedScenarios.put(online1, new ClerkScenario(online1, 1L, true, false, 1));
|
|
|
|
.isLessThan(orderedIds.indexOf(online1));
|
|
|
|
expectedScenarios.put(online2, new ClerkScenario(online2, 1L, true, false, 2));
|
|
|
|
assertThat(orderedIds.indexOf(online1))
|
|
|
|
expectedScenarios.put(pinnedOffline, new ClerkScenario(pinnedOffline, 1L, false, true, 3));
|
|
|
|
.isLessThan(orderedIds.indexOf(offline));
|
|
|
|
expectedScenarios.put(offline, new ClerkScenario(offline, 1L, false, false, 4));
|
|
|
|
assertThat(orderedIds.indexOf(online1))
|
|
|
|
|
|
|
|
.withFailMessage("Created time fallback should maintain order, list=%s", orderedIds)
|
|
|
|
List<ClerkScenario> actualScenarios = orderedIds.stream()
|
|
|
|
.isLessThan(orderedIds.indexOf(online2));
|
|
|
|
.map(expectedScenarios::get)
|
|
|
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i < actualScenarios.size(); i++) {
|
|
|
|
|
|
|
|
ClerkScenario previous = actualScenarios.get(i - 1);
|
|
|
|
|
|
|
|
ClerkScenario current = actualScenarios.get(i);
|
|
|
|
|
|
|
|
assertThat(previous).isNotNull();
|
|
|
|
|
|
|
|
assertThat(current).isNotNull();
|
|
|
|
|
|
|
|
assertThat(BACKEND_ORDERING.compare(previous, current))
|
|
|
|
|
|
|
|
.withFailMessage("Ordering violation between %s and %s, list=%s", previous.getId(), current.getId(),
|
|
|
|
|
|
|
|
orderedIds)
|
|
|
|
|
|
|
|
.isLessThanOrEqualTo(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
|
|
|
void listOrderingHandlesBulkDataset() throws Exception {
|
|
|
|
|
|
|
|
ensureTenantContext();
|
|
|
|
|
|
|
|
String token = "bulk-" + IdUtils.getUuid().substring(0, 6);
|
|
|
|
|
|
|
|
PlayClerkLevelInfoEntity gold = createClerkLevel(token + "-gold", 1L, 90);
|
|
|
|
|
|
|
|
PlayClerkLevelInfoEntity silver = createClerkLevel(token + "-silver", 2L, 80);
|
|
|
|
|
|
|
|
PlayClerkLevelInfoEntity iron = createClerkLevel(token + "-iron", 3L, 70);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<ClerkScenario> scenarios = new ArrayList<>();
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "G-Pin-ON", gold, true, true));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "G-UnPin-ON", gold, true, false));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "G-Pin-Off", gold, false, true));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "G-UnPin-Off", gold, false, false));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "S-Pin-ON", silver, true, true));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "S-UnPin-ON", silver, true, false));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "S-Pin-Off", silver, false, true));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "S-UnPin-Off", silver, false, false));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "I-Pin-ON", iron, true, true));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "I-UnPin-ON", iron, true, false));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "I-Pin-Off", iron, false, true));
|
|
|
|
|
|
|
|
scenarios.add(buildScenario(token, "I-UnPin-Off", iron, false, false));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MvcResult result = mockMvc.perform(get("/clerk/user/list")
|
|
|
|
|
|
|
|
.param("pageNum", "1")
|
|
|
|
|
|
|
|
.param("pageSize", "80")
|
|
|
|
|
|
|
|
.param("nickname", token)
|
|
|
|
|
|
|
|
.header(TENANT_HEADER, DEFAULT_TENANT)
|
|
|
|
|
|
|
|
.header(USER_HEADER, DEFAULT_USER))
|
|
|
|
|
|
|
|
.andExpect(status().isOk())
|
|
|
|
|
|
|
|
.andReturn();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JsonNode root = objectMapper.readTree(result.getResponse().getContentAsString());
|
|
|
|
|
|
|
|
JsonNode records = root.path("data");
|
|
|
|
|
|
|
|
List<String> orderedIds = new ArrayList<>();
|
|
|
|
|
|
|
|
for (JsonNode record : records) {
|
|
|
|
|
|
|
|
orderedIds.add(record.path("id").asText());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Map<String, ClerkScenario> scenarioById = scenarios.stream()
|
|
|
|
|
|
|
|
.collect(Collectors.toMap(ClerkScenario::getId, scenario -> scenario));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertThat(orderedIds).containsExactlyInAnyOrderElementsOf(scenarioById.keySet());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
List<ClerkScenario> orderedScenarios = orderedIds.stream()
|
|
|
|
|
|
|
|
.map(scenarioById::get)
|
|
|
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
|
|
|
for (int i = 1; i < orderedScenarios.size(); i++) {
|
|
|
|
|
|
|
|
ClerkScenario previous = orderedScenarios.get(i - 1);
|
|
|
|
|
|
|
|
ClerkScenario current = orderedScenarios.get(i);
|
|
|
|
|
|
|
|
assertThat(BACKEND_ORDERING.compare(previous, current))
|
|
|
|
|
|
|
|
.withFailMessage("Ordering violation between %s and %s, list=%s",
|
|
|
|
|
|
|
|
previous.getId(), current.getId(), orderedIds)
|
|
|
|
|
|
|
|
.isLessThanOrEqualTo(0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private ClerkScenario buildScenario(String token, String suffix, PlayClerkLevelInfoEntity level, boolean online, boolean pinned) {
|
|
|
|
|
|
|
|
String id = createClerk(token + "-" + suffix, level.getId(), online ? "1" : "0");
|
|
|
|
|
|
|
|
if (pinned) {
|
|
|
|
|
|
|
|
togglePin(id, "1");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
long levelOrder = level.getOrderNumber() == null ? Long.MAX_VALUE : level.getOrderNumber();
|
|
|
|
|
|
|
|
ClerkScenario scenario = new ClerkScenario(id, levelOrder, online, pinned, scenarioSequence++);
|
|
|
|
|
|
|
|
pause(15);
|
|
|
|
|
|
|
|
return scenario;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void togglePin(String clerkId, String pinState) {
|
|
|
|
private void togglePin(String clerkId, String pinState) {
|
|
|
|
ensureTenantContext();
|
|
|
|
ensureTenantContext();
|
|
|
|
@@ -378,4 +469,40 @@ class PlayClerkUserInfoApiTest extends AbstractApiTest {
|
|
|
|
Thread.currentThread().interrupt();
|
|
|
|
Thread.currentThread().interrupt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static class ClerkScenario {
|
|
|
|
|
|
|
|
private final String id;
|
|
|
|
|
|
|
|
private final long levelOrder;
|
|
|
|
|
|
|
|
private final boolean online;
|
|
|
|
|
|
|
|
private final boolean pinned;
|
|
|
|
|
|
|
|
private final int sequence;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ClerkScenario(String id, long levelOrder, boolean online, boolean pinned, int sequence) {
|
|
|
|
|
|
|
|
this.id = id;
|
|
|
|
|
|
|
|
this.levelOrder = levelOrder;
|
|
|
|
|
|
|
|
this.online = online;
|
|
|
|
|
|
|
|
this.pinned = pinned;
|
|
|
|
|
|
|
|
this.sequence = sequence;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String getId() {
|
|
|
|
|
|
|
|
return id;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
long getLevelOrder() {
|
|
|
|
|
|
|
|
return levelOrder;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boolean isOnline() {
|
|
|
|
|
|
|
|
return online;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
boolean isPinned() {
|
|
|
|
|
|
|
|
return pinned;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int getSequence() {
|
|
|
|
|
|
|
|
return sequence;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|