## tests/test_nexter_comm.nim ## Tests for Nippel-Nexter Communication import std/[unittest, json, times, tables, asyncdispatch, options, strutils] import ../src/nimpak/nexter_comm import ../src/nimpak/utils/resultutils suite "Nippel-Nexter Communication": test "Message ID generation": let id1 = newMessageId() let id2 = newMessageId() check id1.len > 0 check id2.len > 0 check id1 != id2 test "Message header creation": let header = newMessageHeader(ServiceRequest, "sender", "recipient", High) check header.messageType == ServiceRequest check header.sender == "sender" check header.recipient == "recipient" check header.priority == High check header.messageId.len > 0 check header.ttl == 300 test "Complete message creation": let content = %*{"service": "test", "data": 42} let msg = newCommMessage(ServiceRequest, "test-sender", content, "test-recipient", Critical) check msg.header.messageType == ServiceRequest check msg.header.sender == "test-sender" check msg.header.recipient == "test-recipient" check msg.header.priority == Critical check msg.body.content == content check msg.signature == "" test "Message JSON serialization": let content = %*{"test": "serialization"} let msg = newCommMessage(ServiceRequest, "sender", content) let json = msg.toJson() check json.hasKey("header") check json.hasKey("body") check json.hasKey("signature") check json["header"]["messageType"].getStr() == "ServiceRequest" check json["header"]["sender"].getStr() == "sender" check json["body"]["content"] == content test "Message JSON deserialization": let originalContent = %*{"test": "deserialization", "number": 123} let originalMsg = newCommMessage(ServiceResponse, "test-sender", originalContent) let json = originalMsg.toJson() let deserializedResult = fromJson(json) check deserializedResult.isOk let deserializedMsg = deserializedResult.value check deserializedMsg.header.messageType == ServiceResponse check deserializedMsg.header.sender == "test-sender" check deserializedMsg.body.content == originalContent test "Communication manager creation": let manager = newCommManager("test-nippel") check manager.nippelName == "test-nippel" check manager.knownNexters.len == 0 check manager.authContext.isNone check manager.messageHandlers.len == 0 check manager.discoveryInterval == 30 test "Message validation - valid message": let msg = newCommMessage(ServiceRequest, "sender", %*{"test": true}) let result = validateMessage(msg) check result.isOk check result.value == true test "Message validation - empty sender": var msg = newCommMessage(ServiceRequest, "", %*{"test": true}) let result = validateMessage(msg) check result.isErr check result.error.contains("Sender cannot be empty") test "Message expiration check": var msg = newCommMessage(ServiceRequest, "sender", %*{"test": true}) check not isMessageExpired(msg) msg.header.timestamp = now() - 400.seconds check isMessageExpired(msg) test "Service finding - not found": let manager = newCommManager("test-nippel") let service = manager.findService(FileSystem, "test-service") check service.isNone test "Authentication context creation": let auth = createAuthContext(Token, "test-token-123", "", 1800) check auth.authMethod == Token check auth.token == "test-token-123" check auth.certificate == "" check auth.permissions.len == 0 check isAuthValid(auth) test "Message authentication - no auth required": let manager = newCommManager("test-nippel") var msg = newCommMessage(ServiceRequest, "sender", %*{"test": true}) let result = manager.authenticateMessage(msg) check result.isOk check result.value == true test "Message authentication - with token": let manager = newCommManager("test-nippel") let auth = createAuthContext(Token, "secret-token") manager.authContext = some(auth) var msg = newCommMessage(ServiceRequest, "sender", %*{"test": true}) let result = manager.authenticateMessage(msg) check result.isOk check msg.signature == "secret-token" test "Message routing - with handler": let manager = newCommManager("test-nippel") proc echoHandler(msg: CommMessage): Future[CommMessage] {.async.} = return newCommMessage(ServiceResponse, "handler", %*{"echo": msg.body.content}) manager.registerMessageHandler(ServiceRequest, echoHandler) proc testRouting() {.async.} = let msg = newCommMessage(ServiceRequest, "sender", %*{"data": "test"}) let result = await manager.routeMessage(msg) check result.isOk let response = result.value check response.header.messageType == ServiceResponse check response.body.content["echo"]["data"].getStr() == "test" waitFor testRouting() test "Error message creation": let originalMsg = newCommMessage(ServiceRequest, "client", %*{"request": "data"}, "server") let errorMsg = createErrorMessage(originalMsg, ServiceNotFound, "The requested service was not found") check errorMsg.header.messageType == ErrorMessage check errorMsg.header.sender == "server" check errorMsg.header.recipient == "client" check errorMsg.header.priority == High check errorMsg.header.correlationId == originalMsg.header.messageId let errorInfo = errorMsg.body.content["error"] check errorInfo["code"].getInt() == ord(ServiceNotFound) check errorInfo["message"].getStr() == "The requested service was not found" test "Complete message flow": let manager = newCommManager("test-nippel") proc serviceHandler(msg: CommMessage): Future[CommMessage] {.async.} = let request = msg.body.content let response = %*{ "status": "success", "result": "Processed: " & request["data"].getStr() } return newCommMessage(ServiceResponse, "service", response) manager.registerMessageHandler(ServiceRequest, serviceHandler) proc testFlow() {.async.} = let msg = newCommMessage(ServiceRequest, "client", %*{"data": "test-data"}) let result = await manager.sendMessage(msg) check result.isOk let response = result.value check response.header.messageType == ServiceResponse check response.body.content["status"].getStr() == "success" check response.body.content["result"].getStr().contains("Processed: test-data") waitFor testFlow() echo "✓ All Nippel-Nexter Communication tests completed"