08 01 25
Вынес константы, начал переделаывать тесты
This commit is contained in:
parent
f1af2bd4d4
commit
e2b89da2fa
1
DOC/TODO то что пока отложенно на будущее.md
Normal file
1
DOC/TODO то что пока отложенно на будущее.md
Normal file
@ -0,0 +1 @@
|
||||
Сделать возможность убрать свой лайк. (пока не надо а сложность что надо больше проверок)
|
||||
@ -21,12 +21,12 @@ import java.util.Objects;
|
||||
* 1 = новое сообщение (начало ветки)
|
||||
* 2 = ответ на сообщение (reply)
|
||||
* 3 = репост (repost)
|
||||
* 4 = редактирование (edit)
|
||||
* 10 = редактирование (edit) <-- ВАЖНО: как на сервере/в БД-триггере
|
||||
*
|
||||
* [2] textLenBytes (uint16) — длина текста в байтах UTF-8
|
||||
* [N] text UTF-8
|
||||
*
|
||||
* Далее ТОЛЬКО если subType == 2 или subType == 3 или subType == 4:
|
||||
* Далее ТОЛЬКО если subType == 2 или subType == 3 или subType == 10:
|
||||
* [1] toBlockchainNameLen (uint8)
|
||||
* [N] toBlockchainName UTF-8
|
||||
* [4] toBlockGlobalNumber (int32)
|
||||
@ -46,9 +46,11 @@ public final class TextBody implements BodyRecord, BodyHasTarget {
|
||||
public static final short SUB_NEW = 1;
|
||||
public static final short SUB_REPLY = 2;
|
||||
public static final short SUB_REPOST = 3;
|
||||
public static final short SUB_EDIT = 4;
|
||||
|
||||
/** Подтип текстового сообщения (1/2/3/4). */
|
||||
/** ВАЖНО: EDIT как на сервере (и как ожидает trg_blocks_edit_apply_ai). */
|
||||
public static final short SUB_EDIT = 10;
|
||||
|
||||
/** Подтип текстового сообщения (1/2/3/10). */
|
||||
public final short subType;
|
||||
|
||||
/** Текст сообщения (строго валидный UTF-8, не пустой/не blank). */
|
||||
@ -181,7 +183,7 @@ public final class TextBody implements BodyRecord, BodyHasTarget {
|
||||
this.toBlockHash32 = null;
|
||||
}
|
||||
|
||||
/** Сообщение subType=REPLY (2) или subType=REPOST (3) или subType=EDIT (4) со ссылкой на блок. */
|
||||
/** Сообщение subType=REPLY (2) или subType=REPOST (3) или subType=EDIT (10) со ссылкой на блок. */
|
||||
public TextBody(short subType,
|
||||
String message,
|
||||
String toBlockchainName,
|
||||
@ -303,7 +305,7 @@ public final class TextBody implements BodyRecord, BodyHasTarget {
|
||||
case SUB_NEW -> "NEW (1)";
|
||||
case SUB_REPLY -> "REPLY (2)";
|
||||
case SUB_REPOST -> "REPOST (3)";
|
||||
case SUB_EDIT -> "EDIT (4)";
|
||||
case SUB_EDIT -> "EDIT (10)";
|
||||
default -> "UNKNOWN";
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package shine.db;
|
||||
|
||||
import utils.config.AppConfig;
|
||||
import utils.config.MsgSubType;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
@ -185,6 +186,7 @@ public class DatabaseInitializer {
|
||||
FOREIGN KEY (login) REFERENCES solana_users(login)
|
||||
);
|
||||
""");
|
||||
|
||||
st.executeUpdate("""
|
||||
CREATE INDEX IF NOT EXISTS idx_blockchain_state_login
|
||||
ON blockchain_state (login);
|
||||
@ -271,7 +273,7 @@ public class DatabaseInitializer {
|
||||
ON connections_state (login, to_login);
|
||||
""");
|
||||
|
||||
// 8) Trigger: connection state (логика та же)
|
||||
// 8) Trigger: connection state
|
||||
st.executeUpdate("""
|
||||
CREATE TRIGGER IF NOT EXISTS trg_blocks_connection_state_ai
|
||||
AFTER INSERT ON blocks
|
||||
@ -288,7 +290,7 @@ public class DatabaseInitializer {
|
||||
NEW.to_bch_name,
|
||||
NEW.to_block_global_number,
|
||||
NEW.to_block_hashe
|
||||
WHERE NEW.msg_sub_type IN (10, 20, 30)
|
||||
WHERE NEW.msg_sub_type IN (%d, %d, %d)
|
||||
AND NEW.to_login IS NOT NULL
|
||||
AND NEW.to_bch_name IS NOT NULL
|
||||
ON CONFLICT(login, rel_type, to_login)
|
||||
@ -301,15 +303,27 @@ public class DatabaseInitializer {
|
||||
WHERE login = NEW.login
|
||||
AND to_login = NEW.to_login
|
||||
AND rel_type = CASE NEW.msg_sub_type
|
||||
WHEN 11 THEN 10
|
||||
WHEN 21 THEN 20
|
||||
WHEN 31 THEN 30
|
||||
WHEN %d THEN %d
|
||||
WHEN %d THEN %d
|
||||
WHEN %d THEN %d
|
||||
ELSE rel_type
|
||||
END
|
||||
AND NEW.msg_sub_type IN (11, 21, 31);
|
||||
AND NEW.msg_sub_type IN (%d, %d, %d);
|
||||
|
||||
END;
|
||||
""");
|
||||
""".formatted(
|
||||
(int) MsgSubType.CONNECTION_FRIEND,
|
||||
(int) MsgSubType.CONNECTION_FOLLOW,
|
||||
(int) MsgSubType.CONNECTION_BLOCK,
|
||||
|
||||
(int) MsgSubType.CONNECTION_UNFRIEND, (int) MsgSubType.CONNECTION_FRIEND,
|
||||
(int) MsgSubType.CONNECTION_UNFOLLOW, (int) MsgSubType.CONNECTION_FOLLOW,
|
||||
(int) MsgSubType.CONNECTION_UNBLOCK, (int) MsgSubType.CONNECTION_BLOCK,
|
||||
|
||||
(int) MsgSubType.CONNECTION_UNFRIEND,
|
||||
(int) MsgSubType.CONNECTION_UNFOLLOW,
|
||||
(int) MsgSubType.CONNECTION_UNBLOCK
|
||||
));
|
||||
|
||||
// 9) message_stats (to_block_hash -> BLOB)
|
||||
st.executeUpdate("""
|
||||
@ -341,11 +355,11 @@ public class DatabaseInitializer {
|
||||
ON message_stats (to_login);
|
||||
""");
|
||||
|
||||
// 10) Trigger: LIKE (to_block_hashe -> to_block_hash BLOB)
|
||||
// 10) Trigger: LIKE
|
||||
st.executeUpdate("""
|
||||
CREATE TRIGGER IF NOT EXISTS trg_blocks_message_stats_like_ai
|
||||
AFTER INSERT ON blocks
|
||||
WHEN NEW.msg_type = 2 AND NEW.msg_sub_type = 1
|
||||
WHEN NEW.msg_type = 2 AND NEW.msg_sub_type = %d
|
||||
BEGIN
|
||||
INSERT INTO message_stats (
|
||||
to_login,
|
||||
@ -370,13 +384,13 @@ public class DatabaseInitializer {
|
||||
DO UPDATE SET
|
||||
likes_count = message_stats.likes_count + 1;
|
||||
END;
|
||||
""");
|
||||
""".formatted((int) MsgSubType.REACTION_LIKE));
|
||||
|
||||
// 11) Trigger: REPLY (to_block_hashe -> to_block_hash BLOB)
|
||||
// 11) Trigger: REPLY
|
||||
st.executeUpdate("""
|
||||
CREATE TRIGGER IF NOT EXISTS trg_blocks_message_stats_reply_ai
|
||||
AFTER INSERT ON blocks
|
||||
WHEN NEW.msg_type = 1 AND NEW.msg_sub_type = 2
|
||||
WHEN NEW.msg_type = 1 AND NEW.msg_sub_type = %d
|
||||
BEGIN
|
||||
INSERT INTO message_stats (
|
||||
to_login,
|
||||
@ -401,13 +415,13 @@ public class DatabaseInitializer {
|
||||
DO UPDATE SET
|
||||
replies_count = message_stats.replies_count + 1;
|
||||
END;
|
||||
""");
|
||||
""".formatted((int) MsgSubType.TEXT_REPLY));
|
||||
|
||||
// 12) Trigger: EDIT — пометить исходный блок
|
||||
st.executeUpdate("""
|
||||
CREATE TRIGGER IF NOT EXISTS trg_blocks_edit_apply_ai
|
||||
AFTER INSERT ON blocks
|
||||
WHEN NEW.msg_type = 1 AND NEW.msg_sub_type = 10
|
||||
WHEN NEW.msg_type = 1 AND NEW.msg_sub_type = %d
|
||||
BEGIN
|
||||
UPDATE blocks
|
||||
SET edited_by_block_global_number = NEW.block_global_number
|
||||
@ -415,7 +429,7 @@ public class DatabaseInitializer {
|
||||
AND bch_name = NEW.bch_name
|
||||
AND block_global_number = NEW.to_block_global_number;
|
||||
END;
|
||||
""");
|
||||
""".formatted((int) MsgSubType.TEXT_EDIT));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,6 @@ public class IT_01_AddUser {
|
||||
public static void main(String[] args) {
|
||||
// чтобы тест можно было запускать вообще без JUnit
|
||||
int failed = run();
|
||||
// System.exit(failed);
|
||||
}
|
||||
|
||||
/** Запуск одного теста (standalone). Возвращает 0 если ок, 1 если упал. */
|
||||
|
||||
@ -27,7 +27,6 @@ public class IT_02_Sessions {
|
||||
public static void main(String[] args) {
|
||||
ItRunContext.initIfNeeded();
|
||||
int failed = run();
|
||||
System.exit(failed);
|
||||
}
|
||||
|
||||
/** Запуск одного теста (standalone). Возвращает 0 если ок, 1 если упал. */
|
||||
|
||||
@ -12,7 +12,6 @@ import test.it.utils.*;
|
||||
import utils.crypto.Ed25519Util;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Base64;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@ -23,8 +22,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
* чтобы "четвёртый" сценарий гарантированно запускался сразу после "третьего".
|
||||
*
|
||||
* Сценарий:
|
||||
* 1) AddUser(USER1) 200 или 409 USER_ALREADY_EXISTS
|
||||
* 2) AddUser(USER2) 200 или 409 USER_ALREADY_EXISTS
|
||||
* 1) (УБРАНО) AddUser(USER1) — создаётся раньше в первом тесте
|
||||
* 2) (УБРАНО) AddUser(USER2) — создаётся раньше в первом тесте
|
||||
*
|
||||
* 3) USER1: HEADER + 3 NEW + 2 REPLY + 2 REACT + 3 EDIT (добавили)
|
||||
* - редактируем два ранее написанных сообщения
|
||||
@ -49,7 +48,6 @@ public class IT_03_AddBlock_NoAuth {
|
||||
|
||||
public static void main(String[] args) {
|
||||
int failed = run();
|
||||
// System.exit(failed);
|
||||
}
|
||||
|
||||
public static int run() {
|
||||
@ -69,36 +67,9 @@ public class IT_03_AddBlock_NoAuth {
|
||||
Duration t = Duration.ofSeconds(1);
|
||||
|
||||
// =========================================================
|
||||
// 1) AddUser(USER1)
|
||||
// USER2 keys (детерминированно из login, как твой ItRunContext)
|
||||
// =========================================================
|
||||
addUserOr409AlreadyExists(
|
||||
"USER1",
|
||||
TestConfig.LOGIN(),
|
||||
TestConfig.BCH_NAME(),
|
||||
TestConfig.LOGIN_PUBKEY_B64(),
|
||||
TestConfig.DEVICE_PUBKEY_B64()
|
||||
);
|
||||
|
||||
// =========================================================
|
||||
// 2) AddUser(USER2)
|
||||
// =========================================================
|
||||
// Генерим ключи детерминированно из login (как твой ItRunContext)
|
||||
byte[] user2LoginPriv = Ed25519Util.generatePrivateKeyFromString(USER2_LOGIN);
|
||||
byte[] user2LoginPub = Ed25519Util.derivePublicKey(user2LoginPriv);
|
||||
|
||||
byte[] user2DevPriv = Ed25519Util.generatePrivateKeyFromString(USER2_LOGIN + "#device");
|
||||
byte[] user2DevPub = Ed25519Util.derivePublicKey(user2DevPriv);
|
||||
|
||||
String user2LoginPubB64 = Base64.getEncoder().encodeToString(user2LoginPub);
|
||||
String user2DevPubB64 = Base64.getEncoder().encodeToString(user2DevPub);
|
||||
|
||||
addUserOr409AlreadyExists(
|
||||
"USER2",
|
||||
USER2_LOGIN,
|
||||
USER2_BCH,
|
||||
user2LoginPubB64,
|
||||
user2DevPubB64
|
||||
);
|
||||
|
||||
// =========================================================
|
||||
// 3) USER1 блоки (под message_stats + edits)
|
||||
@ -179,6 +150,7 @@ public class IT_03_AddBlock_NoAuth {
|
||||
), t);
|
||||
|
||||
// 3 EDIT (два сообщения исправляем, одно — два раза)
|
||||
// ВАЖНО: subType EDIT берём из TextBody.SUB_EDIT (единая константа = 10)
|
||||
if (TestConfig.DEBUG()) TestLog.stepTitle("USER1: TEXT#6 (EDIT -> TEXT#2) (исправление #1)");
|
||||
sender1.send(new TextBody(
|
||||
TextBody.SUB_EDIT,
|
||||
@ -281,59 +253,4 @@ public class IT_03_AddBlock_NoAuth {
|
||||
|
||||
TestLog.pass("IT_03_AddBlock_NoAuth (combined): OK");
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
// helpers
|
||||
// ======================================================================
|
||||
|
||||
private static void addUserOr409AlreadyExists(String label,
|
||||
String login,
|
||||
String blockchainName,
|
||||
String loginPubKeyB64,
|
||||
String devicePubKeyB64) {
|
||||
|
||||
TestLog.title(label + ": AddUser (200 OK) или 409 USER_ALREADY_EXISTS");
|
||||
TestLog.info(" login = " + login);
|
||||
TestLog.info(" blockchainName = " + blockchainName);
|
||||
|
||||
String reqId = "it-adduser-" + label.toLowerCase();
|
||||
|
||||
String reqJson = """
|
||||
{
|
||||
"op": "AddUser",
|
||||
"requestId": "%s",
|
||||
"payload": {
|
||||
"login": "%s",
|
||||
"blockchainName": "%s",
|
||||
"loginKey": "%s",
|
||||
"deviceKey": "%s",
|
||||
"bchLimit": %d
|
||||
}
|
||||
}
|
||||
""".formatted(
|
||||
reqId,
|
||||
login,
|
||||
blockchainName,
|
||||
loginPubKeyB64,
|
||||
devicePubKeyB64,
|
||||
TestConfig.TEST_BCH_LIMIT
|
||||
);
|
||||
|
||||
try (WsTestClient client = new WsTestClient(TestConfig.WS_URI)) {
|
||||
TestLog.send("AddUser(" + label + ")", reqJson);
|
||||
String resp = client.request(reqId, reqJson, Duration.ofSeconds(5));
|
||||
TestLog.recv("AddUser(" + label + ")", resp);
|
||||
|
||||
int st = JsonParsers.status(resp);
|
||||
if (st == 200) {
|
||||
TestLog.ok(label + ": создан/добавлен (status=200)");
|
||||
} else if (st == 409) {
|
||||
String code = JsonParsers.errorCode(resp);
|
||||
assertEquals("USER_ALREADY_EXISTS", code, label + ": expected USER_ALREADY_EXISTS, resp=" + resp);
|
||||
TestLog.ok(label + ": уже есть (status=409, USER_ALREADY_EXISTS)");
|
||||
} else {
|
||||
fail(label + ": неожиданный status=" + st + ", resp=" + resp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,6 @@ public class IT_RunAllMain {
|
||||
ItRunContext.initIfNeeded();
|
||||
|
||||
int failed = runAll();
|
||||
System.exit(failed);
|
||||
}
|
||||
|
||||
public static int runAll() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user