From fe5cf910e184d7e6b60ce7d611f13b6e306643b6 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 27 Oct 2026 07:29:48 +0100 Subject: [PATCH] test(chat): cover preference read errors and all queued sound form values --- tests/test_chat_preferences.c | 23 ++++++++++++++++++++++- tools/chatgui/tests/test_group_edits.cpp | 15 +++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/tests/test_chat_preferences.c b/tests/test_chat_preferences.c index f51f365a..cba7e962 100644 --- a/tests/test_chat_preferences.c +++ b/tests/test_chat_preferences.c @@ -111,6 +111,27 @@ static void write_faults(struct UTUN_INSTANCE* inst, int sound) { static int veto(void* arg) { (*(unsigned*)arg)++; return 1; } +static void read_faults(struct UTUN_INSTANCE* inst) { + assert(!chat_core_set_sound_on_message(inst, channel, 0)); unsigned count = broadcasts, cases = 0; + target = "SELECT value FROM ui_state"; + for (enum fault point = F_PREPARE; point <= F_TEXT; point++) { + if (point == F_CHANGES || point == F_EXEC) continue; + fault = point; argument = point == F_TEXT ? 0 : 1; + assert(chat_core_get_sound_on_message(inst, channel) < 0 && fault == F_NONE); + assert(chat_core_get_sound_on_message(inst, channel) == 0 && broadcasts == count); cases++; + } + const char* bad[] = {"'yes'", "'2'", "NULL", "X'31'", "CAST(X'3100' AS TEXT)"}; + for (size_t i = 0; i < sizeof(bad) / sizeof(bad[0]); i++) { + char sql[256]; snprintf(sql, sizeof(sql), "UPDATE ui_state SET value=%s WHERE key='ch_%s_sound_on_message'", bad[i], channel); + assert(sqlite3_exec(inst->topo_sqlite_db, sql, NULL, NULL, NULL) == SQLITE_OK && chat_core_get_sound_on_message(inst, channel) < 0); + } + char sql[256]; snprintf(sql, sizeof(sql), "UPDATE ui_state SET value='0' WHERE key='ch_%s_sound_on_message'", channel); + assert(sqlite3_exec(inst->topo_sqlite_db, sql, NULL, NULL, NULL) == SQLITE_OK && chat_core_get_sound_on_message(inst, channel) == 0); + assert(chat_core_get_sound_on_message(NULL, channel) < 0 && chat_core_set_sound_on_message(inst, "01", 1) < 0); + assert(broadcasts == count); + printf("PASS preferences reader:%u SQL faults/retries;invalid booleans,types,NUL,and channel rejected\n", cases); +} + static void semantics(struct UTUN_INSTANCE* inst) { assert(!chat_core_save_ui_state(inst, "preferences-test", "old") && !chat_core_set_sound_on_message(inst, channel, 1)); unsigned commits = 0, count = broadcasts; sqlite3_commit_hook(inst->topo_sqlite_db, veto, &commits); @@ -164,7 +185,7 @@ int main(void) { value_is(reader, "old"); uint64_t group = chat_core_create_channel_auto(inst, "preferences"); assert(group); snprintf(channel, sizeof(channel), "%llu", (unsigned long long)group); observe_sound = 1; - assert(chat_core_get_sound_on_message(inst, channel) == 1); write_faults(inst, 0); write_faults(inst, 1); semantics(inst); + assert(chat_core_get_sound_on_message(inst, channel) == 1); write_faults(inst, 0); write_faults(inst, 1); read_faults(inst); semantics(inst); assert(!chat_core_save_ui_state(inst, "preferences-test", "old")); target = "COMMIT /* ui_state */"; fault = F_EXEC; fail_rollback = 1; inst->running = 1; assert(chat_core_save_ui_state(inst, "preferences-test", "uncommitted") < 0 && !fail_rollback && !inst->running); diff --git a/tools/chatgui/tests/test_group_edits.cpp b/tools/chatgui/tests/test_group_edits.cpp index d75a1fc3..cc37966d 100644 --- a/tools/chatgui/tests/test_group_edits.cpp +++ b/tools/chatgui/tests/test_group_edits.cpp @@ -4,6 +4,7 @@ #include "../src/messagedelegate.h" #include "../src/chatview.h" #include "../src/inputbar.h" +#include "../src/soundsettingspage.h" #include "../db/db_manager.h" #include "../transport/utun_node.h" #include "../transport/gui_bridge.h" @@ -12,6 +13,8 @@ #include #include #include +#include +#include #include #include #include @@ -108,6 +111,18 @@ private slots: QTRY_COMPARE(failures.size(), 1); QCOMPARE(editor->toPlainText(), QString("Stale editor draft")); QCOMPARE(indexFor(id).data(MsgTextRole).toString(), QString("Remote edit")); QCOMPARE(newMessages, 0); QTest::keyClick(editor, Qt::Key_Escape); QCOMPARE(editor->toPlainText(), QString("Unsent draft")); + SoundSettingsPage sounds(&db); sounds.loadFromDb(); + const auto checks = sounds.findChildren(); const auto sliders = sounds.findChildren(); + QCOMPARE(checks.size(), 9); QCOMPARE(sliders.size(), 9); + for (int i = 0; i < 9; i++) { checks[i]->setChecked(i % 2 == 0); sliders[i]->setValue(20 + i); } + checks[0]->setChecked(false); sounds.applyAndSave(); + QCOMPARE(inCore([](UTUN_INSTANCE*) { return 0; }), 0); + QCOMPARE(db.getUiStateInt("sound_enabled", -1), 0); QCOMPARE(db.getUiStateInt("sound_volume", -1), 20); + const char* events[] = {"msg_incoming", "msg_outgoing", "connect", "disconnect", "call_incoming", "call_connecting", "call_ringing", "radio_incoming"}; + for (int i = 0; i < 8; i++) { + QCOMPARE(db.getUiStateInt(QString("sound_%1_on").arg(events[i]), -1), (i + 1) % 2 == 0 ? 1 : 0); + QCOMPARE(db.getUiStateInt(QString("sound_%1_vol").arg(events[i]), -1), 21 + i); + } gui_bridge_set_msg_received_cb(nullptr); } };