nip/tests/test_nexter_comm.nim

168 lines
6.5 KiB
Nim

## 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"