SHA256
23 12 25
Сессии работают пользователи добавляются. Плюс сделал автоматические тесты как положенно
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -13,19 +13,30 @@ public class AddUserIT {
|
||||
try (WsTestClient client = new WsTestClient(TestConfig.WS_URI)) {
|
||||
|
||||
String reqId = "it-adduser-1";
|
||||
String resp = client.request(reqId, JsonBuilders.addUser(reqId), Duration.ofSeconds(5));
|
||||
String reqJson = JsonBuilders.addUser(reqId);
|
||||
|
||||
TestLog.section("AddUserIT: AddUser");
|
||||
TestLog.req("AddUser requestId=" + reqId, reqJson);
|
||||
|
||||
String resp = client.request(reqId, reqJson, Duration.ofSeconds(5));
|
||||
TestLog.resp("AddUser responseId=" + reqId, resp);
|
||||
|
||||
int st = JsonParsers.status(resp);
|
||||
|
||||
// ВАЖНО: тут подставь свой реальный код "уже существует", если он не 200.
|
||||
// Я оставляю пример: 409.
|
||||
boolean created = (st == 200);
|
||||
boolean already = (st == 409);
|
||||
|
||||
if (already) {
|
||||
String code = JsonParsers.errorCode(resp);
|
||||
// если сервер кладет code в payload.code — парсер должен это поддерживать (см. ниже)
|
||||
assertEquals("USER_ALREADY_EXISTS", code,
|
||||
"Expected errorCode=USER_ALREADY_EXISTS, but got: " + code + ", resp=" + resp);
|
||||
}
|
||||
|
||||
if (created) {
|
||||
System.out.println("✅ AddUser: создан/добавлен (status=200)");
|
||||
} else if (already) {
|
||||
System.out.println("✅ AddUser: возможно уже есть в базе (status=409)");
|
||||
System.out.println("✅ AddUser: уже есть в системе (status=409, USER_ALREADY_EXISTS)");
|
||||
} else {
|
||||
fail("❌ AddUser: неожиданный status=" + st + ", resp=" + resp);
|
||||
}
|
||||
|
||||
@@ -79,4 +79,25 @@ public final class JsonParsers {
|
||||
} catch (Exception ignored) {}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static String errorCode(String json) {
|
||||
try {
|
||||
JsonNode root = MAPPER.readTree(json);
|
||||
|
||||
// поддержка старого формата (верхний уровень)
|
||||
if (root.has("errorCode")) return root.get("errorCode").asText();
|
||||
// поддержка нового формата (верхний уровень)
|
||||
if (root.has("code")) return root.get("code").asText();
|
||||
|
||||
JsonNode payload = root.get("payload");
|
||||
if (payload != null) {
|
||||
// поддержка старого формата (внутри payload)
|
||||
if (payload.has("errorCode")) return payload.get("errorCode").asText();
|
||||
// поддержка нового формата (внутри payload)
|
||||
if (payload.has("code")) return payload.get("code").asText();
|
||||
}
|
||||
} catch (Exception ignored) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package test.it;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.WebSocket;
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public final class WsTestClient implements AutoCloseable {
|
||||
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
private final WebSocket ws;
|
||||
private final Map<String, CompletableFuture<String>> pending = new ConcurrentHashMap<>();
|
||||
|
||||
public WsTestClient(String wsUri) {
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
this.ws = client.newWebSocketBuilder()
|
||||
.connectTimeout(Duration.ofSeconds(5))
|
||||
.buildAsync(URI.create(wsUri), new WebSocket.Listener() {
|
||||
@Override
|
||||
public CompletionStage<?> onText(WebSocket webSocket, CharSequence data, boolean last) {
|
||||
String msg = data.toString();
|
||||
String requestId = extractRequestId(msg);
|
||||
if (requestId != null) {
|
||||
CompletableFuture<String> f = pending.remove(requestId);
|
||||
if (f != null) f.complete(msg);
|
||||
}
|
||||
webSocket.request(1);
|
||||
return CompletableFuture.completedFuture(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(WebSocket webSocket, Throwable error) {
|
||||
// Завалим все ожидания, чтобы тест корректно упал
|
||||
pending.forEach((k, f) -> f.completeExceptionally(error));
|
||||
pending.clear();
|
||||
}
|
||||
}).join();
|
||||
|
||||
this.ws.request(1);
|
||||
}
|
||||
|
||||
public String request(String requestId, String json, Duration timeout) {
|
||||
CompletableFuture<String> fut = new CompletableFuture<>();
|
||||
pending.put(requestId, fut);
|
||||
ws.sendText(json, true);
|
||||
try {
|
||||
return fut.get(timeout.toMillis(), TimeUnit.MILLISECONDS);
|
||||
} catch (Exception e) {
|
||||
pending.remove(requestId);
|
||||
throw new RuntimeException("Timeout/Fail waiting response requestId=" + requestId, e);
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractRequestId(String json) {
|
||||
try {
|
||||
JsonNode root = MAPPER.readTree(json);
|
||||
JsonNode id = root.get("requestId");
|
||||
return id != null && !id.isNull() ? id.asText() : null;
|
||||
} catch (Exception ignored) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
ws.sendClose(WebSocket.NORMAL_CLOSURE, "bye").join();
|
||||
} catch (Exception ignored) {}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user