diff options
Diffstat (limited to 'tests/unit/test_mcp_handler.c')
| -rw-r--r-- | tests/unit/test_mcp_handler.c | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/tests/unit/test_mcp_handler.c b/tests/unit/test_mcp_handler.c index aaa199d..05e9e38 100644 --- a/tests/unit/test_mcp_handler.c +++ b/tests/unit/test_mcp_handler.c | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include "test_framework.h" | 1 | #include "test_framework.h" |
| 2 | #include "mcp_handler.h" | 2 | #include "mcp_handler.h" |
| 3 | #include "config.h" | 3 | #include "config.h" |
| 4 | #include "session.h" | ||
| 4 | #include "nucula_wallet.h" | 5 | #include "nucula_wallet.h" |
| 5 | #include "cJSON.h" | 6 | #include "cJSON.h" |
| 6 | #include <string.h> | 7 | #include <string.h> |
| @@ -11,6 +12,7 @@ static uint64_t g_wallet_balance = 0; | |||
| 11 | static int g_wallet_proof_count = 0; | 12 | static int g_wallet_proof_count = 0; |
| 12 | static int g_wallet_send_rc = 0; | 13 | static int g_wallet_send_rc = 0; |
| 13 | static char g_wallet_send_token[256] = "cashuA_test_token"; | 14 | static char g_wallet_send_token[256] = "cashuA_test_token"; |
| 15 | static esp_err_t g_wallet_melt_rc = ESP_OK; | ||
| 14 | 16 | ||
| 15 | const tollgate_config_t *tollgate_config_get(void) { | 17 | const tollgate_config_t *tollgate_config_get(void) { |
| 16 | return &g_test_config; | 18 | return &g_test_config; |
| @@ -33,6 +35,23 @@ int nucula_wallet_send(uint64_t amount, char *token_out, size_t token_max) { | |||
| 33 | return g_wallet_send_rc; | 35 | return g_wallet_send_rc; |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 38 | esp_err_t nucula_wallet_melt(const char *bolt11, uint64_t max_fee) { | ||
| 39 | (void)bolt11; | ||
| 40 | (void)max_fee; | ||
| 41 | return g_wallet_melt_rc; | ||
| 42 | } | ||
| 43 | |||
| 44 | static session_t g_test_sessions[SESSION_MAX_CLIENTS]; | ||
| 45 | static int g_test_session_count = 0; | ||
| 46 | |||
| 47 | session_t *cvm_get_sessions_array(void) { | ||
| 48 | return g_test_sessions; | ||
| 49 | } | ||
| 50 | |||
| 51 | int cvm_get_sessions_count(void) { | ||
| 52 | return SESSION_MAX_CLIENTS; | ||
| 53 | } | ||
| 54 | |||
| 36 | static void test_mcp_parse_tool(void) | 55 | static void test_mcp_parse_tool(void) |
| 37 | { | 56 | { |
| 38 | printf("\n=== MCP tool parsing ===\n"); | 57 | printf("\n=== MCP tool parsing ===\n"); |
| @@ -40,6 +59,12 @@ static void test_mcp_parse_tool(void) | |||
| 40 | ASSERT_EQ_INT(MCP_TOOL_SET_CONFIG, mcp_parse_tool("set_config"), "set_config"); | 59 | ASSERT_EQ_INT(MCP_TOOL_SET_CONFIG, mcp_parse_tool("set_config"), "set_config"); |
| 41 | ASSERT_EQ_INT(MCP_TOOL_GET_BALANCE, mcp_parse_tool("get_balance"), "get_balance"); | 60 | ASSERT_EQ_INT(MCP_TOOL_GET_BALANCE, mcp_parse_tool("get_balance"), "get_balance"); |
| 42 | ASSERT_EQ_INT(MCP_TOOL_WALLET_SEND, mcp_parse_tool("wallet_send"), "wallet_send"); | 61 | ASSERT_EQ_INT(MCP_TOOL_WALLET_SEND, mcp_parse_tool("wallet_send"), "wallet_send"); |
| 62 | ASSERT_EQ_INT(MCP_TOOL_GET_SESSIONS, mcp_parse_tool("get_sessions"), "get_sessions"); | ||
| 63 | ASSERT_EQ_INT(MCP_TOOL_GET_USAGE, mcp_parse_tool("get_usage"), "get_usage"); | ||
| 64 | ASSERT_EQ_INT(MCP_TOOL_SET_PAYOUT, mcp_parse_tool("set_payout"), "set_payout"); | ||
| 65 | ASSERT_EQ_INT(MCP_TOOL_SET_METRIC, mcp_parse_tool("set_metric"), "set_metric"); | ||
| 66 | ASSERT_EQ_INT(MCP_TOOL_SET_PRICE, mcp_parse_tool("set_price"), "set_price"); | ||
| 67 | ASSERT_EQ_INT(MCP_TOOL_WALLET_MELT, mcp_parse_tool("wallet_melt"), "wallet_melt"); | ||
| 43 | ASSERT_EQ_INT(MCP_TOOL_UNKNOWN, mcp_parse_tool("foo"), "unknown tool"); | 68 | ASSERT_EQ_INT(MCP_TOOL_UNKNOWN, mcp_parse_tool("foo"), "unknown tool"); |
| 44 | ASSERT_EQ_INT(MCP_TOOL_UNKNOWN, mcp_parse_tool(NULL), "NULL tool"); | 69 | ASSERT_EQ_INT(MCP_TOOL_UNKNOWN, mcp_parse_tool(NULL), "NULL tool"); |
| 45 | } | 70 | } |
| @@ -135,6 +160,121 @@ static void test_mcp_dispatch(void) | |||
| 135 | ASSERT(!resp.success, "NULL request dispatch fails"); | 160 | ASSERT(!resp.success, "NULL request dispatch fails"); |
| 136 | } | 161 | } |
| 137 | 162 | ||
| 163 | static void test_mcp_get_sessions(void) | ||
| 164 | { | ||
| 165 | printf("\n=== MCP get_sessions ===\n"); | ||
| 166 | memset(g_test_sessions, 0, sizeof(g_test_sessions)); | ||
| 167 | |||
| 168 | mcp_response_t resp = mcp_handle_get_sessions(); | ||
| 169 | ASSERT(resp.success, "get_sessions succeeds"); | ||
| 170 | cJSON *result = cJSON_Parse(resp.result_json); | ||
| 171 | ASSERT(result != NULL, "result is valid JSON array"); | ||
| 172 | ASSERT(cJSON_IsArray(result), "result is an array"); | ||
| 173 | ASSERT_EQ_INT(0, cJSON_GetArraySize(result), "empty sessions"); | ||
| 174 | cJSON_Delete(result); | ||
| 175 | |||
| 176 | g_test_sessions[0].active = true; | ||
| 177 | g_test_sessions[0].client_ip = 0x0100000A; | ||
| 178 | strncpy(g_test_sessions[0].mac, "AA:BB:CC:DD:EE:FF", sizeof(g_test_sessions[0].mac) - 1); | ||
| 179 | g_test_sessions[0].allotment_ms = 60000; | ||
| 180 | |||
| 181 | resp = mcp_handle_get_sessions(); | ||
| 182 | ASSERT(resp.success, "get_sessions with data succeeds"); | ||
| 183 | result = cJSON_Parse(resp.result_json); | ||
| 184 | ASSERT_EQ_INT(1, cJSON_GetArraySize(result), "one active session"); | ||
| 185 | cJSON *s = cJSON_GetArrayItem(result, 0); | ||
| 186 | ASSERT_EQ_STR("AA:BB:CC:DD:EE:FF", cJSON_GetObjectItem(s, "mac")->valuestring, "mac matches"); | ||
| 187 | cJSON_Delete(result); | ||
| 188 | g_test_sessions[0].active = false; | ||
| 189 | } | ||
| 190 | |||
| 191 | static void test_mcp_get_usage(void) | ||
| 192 | { | ||
| 193 | printf("\n=== MCP get_usage ===\n"); | ||
| 194 | memset(&g_test_config, 0, sizeof(g_test_config)); | ||
| 195 | strncpy(g_test_config.metric, "milliseconds", sizeof(g_test_config.metric) - 1); | ||
| 196 | g_test_config.price_per_step = 21; | ||
| 197 | g_test_config.step_size_ms = 60000; | ||
| 198 | g_test_config.step_size_bytes = 22020096; | ||
| 199 | |||
| 200 | mcp_response_t resp = mcp_handle_get_usage(); | ||
| 201 | ASSERT(resp.success, "get_usage succeeds"); | ||
| 202 | cJSON *result = cJSON_Parse(resp.result_json); | ||
| 203 | ASSERT(result != NULL, "result is valid JSON"); | ||
| 204 | ASSERT_EQ_STR("milliseconds", cJSON_GetObjectItem(result, "metric")->valuestring, "metric matches"); | ||
| 205 | ASSERT_EQ_INT(21, cJSON_GetObjectItem(result, "price_per_step")->valueint, "price matches"); | ||
| 206 | cJSON_Delete(result); | ||
| 207 | } | ||
| 208 | |||
| 209 | static void test_mcp_set_payout(void) | ||
| 210 | { | ||
| 211 | printf("\n=== MCP set_payout ===\n"); | ||
| 212 | memset(&g_test_config, 0, sizeof(g_test_config)); | ||
| 213 | |||
| 214 | const char *params = "{\"enabled\":true,\"recipients\":[{\"lightning_address\":\"test@coinos.io\",\"factor\":0.5}]}"; | ||
| 215 | mcp_response_t resp = mcp_handle_set_payout(params); | ||
| 216 | ASSERT(resp.success, "set_payout succeeds"); | ||
| 217 | ASSERT(g_test_config.payout.enabled, "payout enabled"); | ||
| 218 | ASSERT_EQ_INT(1, g_test_config.payout.recipient_count, "1 recipient"); | ||
| 219 | ASSERT_EQ_STR("test@coinos.io", g_test_config.payout.recipients[0].lightning_address, "address matches"); | ||
| 220 | |||
| 221 | resp = mcp_handle_set_payout("not json"); | ||
| 222 | ASSERT(!resp.success, "invalid JSON fails"); | ||
| 223 | } | ||
| 224 | |||
| 225 | static void test_mcp_set_metric(void) | ||
| 226 | { | ||
| 227 | printf("\n=== MCP set_metric ===\n"); | ||
| 228 | memset(&g_test_config, 0, sizeof(g_test_config)); | ||
| 229 | |||
| 230 | mcp_response_t resp = mcp_handle_set_metric("{\"metric\":\"bytes\"}"); | ||
| 231 | ASSERT(resp.success, "set_metric bytes succeeds"); | ||
| 232 | ASSERT_EQ_STR("bytes", g_test_config.metric, "metric updated to bytes"); | ||
| 233 | |||
| 234 | resp = mcp_handle_set_metric("{\"metric\":\"milliseconds\"}"); | ||
| 235 | ASSERT(resp.success, "set_metric milliseconds succeeds"); | ||
| 236 | ASSERT_EQ_STR("milliseconds", g_test_config.metric, "metric updated to milliseconds"); | ||
| 237 | |||
| 238 | resp = mcp_handle_set_metric("{\"metric\":\"invalid\"}"); | ||
| 239 | ASSERT(!resp.success, "invalid metric rejected"); | ||
| 240 | |||
| 241 | resp = mcp_handle_set_metric("{}"); | ||
| 242 | ASSERT(!resp.success, "missing metric rejected"); | ||
| 243 | } | ||
| 244 | |||
| 245 | static void test_mcp_set_price(void) | ||
| 246 | { | ||
| 247 | printf("\n=== MCP set_price ===\n"); | ||
| 248 | memset(&g_test_config, 0, sizeof(g_test_config)); | ||
| 249 | g_test_config.price_per_step = 21; | ||
| 250 | |||
| 251 | mcp_response_t resp = mcp_handle_set_price("{\"price_per_step\":50}"); | ||
| 252 | ASSERT(resp.success, "set_price succeeds"); | ||
| 253 | ASSERT_EQ_INT(50, g_test_config.price_per_step, "price updated to 50"); | ||
| 254 | |||
| 255 | resp = mcp_handle_set_price("{\"price_per_step\":0}"); | ||
| 256 | ASSERT(!resp.success, "zero price rejected"); | ||
| 257 | |||
| 258 | resp = mcp_handle_set_price("{}"); | ||
| 259 | ASSERT(!resp.success, "missing price rejected"); | ||
| 260 | } | ||
| 261 | |||
| 262 | static void test_mcp_wallet_melt(void) | ||
| 263 | { | ||
| 264 | printf("\n=== MCP wallet_melt ===\n"); | ||
| 265 | g_wallet_melt_rc = ESP_OK; | ||
| 266 | |||
| 267 | mcp_response_t resp = mcp_handle_wallet_melt("{\"bolt11\":\"lnbc100n1...\"}"); | ||
| 268 | ASSERT(resp.success, "wallet_melt succeeds"); | ||
| 269 | |||
| 270 | g_wallet_melt_rc = ESP_FAIL; | ||
| 271 | resp = mcp_handle_wallet_melt("{\"bolt11\":\"lnbc100n1...\"}"); | ||
| 272 | ASSERT(!resp.success, "melt failure reported"); | ||
| 273 | |||
| 274 | resp = mcp_handle_wallet_melt("{}"); | ||
| 275 | ASSERT(!resp.success, "missing bolt11 fails"); | ||
| 276 | } | ||
| 277 | |||
| 138 | int main(void) | 278 | int main(void) |
| 139 | { | 279 | { |
| 140 | printf("=== test_mcp_handler ===\n"); | 280 | printf("=== test_mcp_handler ===\n"); |
| @@ -143,6 +283,12 @@ int main(void) | |||
| 143 | test_mcp_set_config(); | 283 | test_mcp_set_config(); |
| 144 | test_mcp_get_balance(); | 284 | test_mcp_get_balance(); |
| 145 | test_mcp_wallet_send(); | 285 | test_mcp_wallet_send(); |
| 286 | test_mcp_get_sessions(); | ||
| 287 | test_mcp_get_usage(); | ||
| 288 | test_mcp_set_payout(); | ||
| 289 | test_mcp_set_metric(); | ||
| 290 | test_mcp_set_price(); | ||
| 291 | test_mcp_wallet_melt(); | ||
| 146 | test_mcp_dispatch(); | 292 | test_mcp_dispatch(); |
| 147 | TEST_SUMMARY(); | 293 | TEST_SUMMARY(); |
| 148 | } | 294 | } |