test: add comprehensive tests for WASM functions including registration, stats retrieval, connection status, and message handling
This commit is contained in:
174
pkg/wasm/wasm_test.go
Normal file
174
pkg/wasm/wasm_test.go
Normal file
@@ -0,0 +1,174 @@
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package wasm
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"syscall/js"
|
||||
"testing"
|
||||
|
||||
"git.quad4.io/Networks/Reticulum-Go/pkg/identity"
|
||||
)
|
||||
|
||||
func TestRegisterJSFunctions(t *testing.T) {
|
||||
RegisterJSFunctions()
|
||||
|
||||
reticulum := js.Global().Get("reticulum")
|
||||
if reticulum.IsUndefined() {
|
||||
t.Fatal("reticulum object not registered in global scope")
|
||||
}
|
||||
|
||||
functions := []string{
|
||||
"init", "getIdentity", "getDestination", "announce",
|
||||
"connect", "disconnect", "isConnected", "sendMessage", "getStats",
|
||||
}
|
||||
|
||||
for _, fn := range functions {
|
||||
if reticulum.Get(fn).Type() != js.TypeFunction {
|
||||
t.Errorf("function %s not registered or not a function", fn)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStats(t *testing.T) {
|
||||
// Reset stats
|
||||
stats.packetsSent = 10
|
||||
stats.packetsReceived = 5
|
||||
stats.bytesSent = 100
|
||||
stats.bytesReceived = 50
|
||||
|
||||
result := GetStats(js.Undefined(), nil)
|
||||
val := result.(js.Value)
|
||||
|
||||
if val.Get("packetsSent").Int() != 10 {
|
||||
t.Errorf("expected packetsSent 10, got %d", val.Get("packetsSent").Int())
|
||||
}
|
||||
if val.Get("packetsReceived").Int() != 5 {
|
||||
t.Errorf("expected packetsReceived 5, got %d", val.Get("packetsReceived").Int())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsConnected(t *testing.T) {
|
||||
reticulumTransport = nil
|
||||
connected := IsConnected(js.Undefined(), nil).(js.Value).Bool()
|
||||
if connected {
|
||||
t.Error("expected connected to be false when transport is nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitReticulum(t *testing.T) {
|
||||
// Mock JS global functions
|
||||
js.Global().Set("onChatMessage", js.FuncOf(func(this js.Value, args []js.Value) interface{} { return nil }))
|
||||
js.Global().Set("log", js.FuncOf(func(this js.Value, args []js.Value) interface{} { return nil }))
|
||||
js.Global().Set("onPeerDiscovered", js.FuncOf(func(this js.Value, args []js.Value) interface{} { return nil }))
|
||||
|
||||
// Test without arguments
|
||||
result := InitReticulum(js.Undefined(), []js.Value{})
|
||||
val := result.(js.Value)
|
||||
if val.Get("error").IsUndefined() || val.Get("error").String() != "WebSocket URL required" {
|
||||
t.Errorf("expected error 'WebSocket URL required', got %v", val.Get("error"))
|
||||
}
|
||||
|
||||
// Test with valid URL and username
|
||||
wsURL := "ws://localhost:8080"
|
||||
username := "testuser"
|
||||
result = InitReticulum(js.Undefined(), []js.Value{js.ValueOf(wsURL), js.ValueOf(username)})
|
||||
val = result.(js.Value)
|
||||
|
||||
if !val.Get("success").Bool() {
|
||||
t.Errorf("InitReticulum failed: %v", val.Get("error"))
|
||||
}
|
||||
|
||||
if reticulumIdentity == nil {
|
||||
t.Fatal("reticulumIdentity should not be nil after successful init")
|
||||
}
|
||||
|
||||
if userName != username {
|
||||
t.Errorf("expected userName %s, got %s", username, userName)
|
||||
}
|
||||
|
||||
// Test with provided identity
|
||||
id, _ := identity.NewIdentity()
|
||||
idHex := id.GetHexHash()
|
||||
// InitReticulum expects the FULL identity bytes in hex (64 bytes).
|
||||
idBytes := id.GetPrivateKey()
|
||||
idHexFull := hex.EncodeToString(idBytes)
|
||||
|
||||
result = InitReticulum(js.Undefined(), []js.Value{js.ValueOf(wsURL), js.ValueOf(username), js.ValueOf(idHexFull)})
|
||||
val = result.(js.Value)
|
||||
|
||||
if !val.Get("success").Bool() {
|
||||
t.Errorf("InitReticulum with identity failed: %v", val.Get("error"))
|
||||
}
|
||||
|
||||
if reticulumIdentity.GetHexHash() != idHex {
|
||||
t.Errorf("expected identity hash %s, got %s", idHex, reticulumIdentity.GetHexHash())
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdentityAndDestination(t *testing.T) {
|
||||
// Ensure initialized
|
||||
js.Global().Set("onChatMessage", js.FuncOf(func(this js.Value, args []js.Value) interface{} { return nil }))
|
||||
js.Global().Set("log", js.FuncOf(func(this js.Value, args []js.Value) interface{} { return nil }))
|
||||
js.Global().Set("onPeerDiscovered", js.FuncOf(func(this js.Value, args []js.Value) interface{} { return nil }))
|
||||
InitReticulum(js.Undefined(), []js.Value{js.ValueOf("ws://localhost")})
|
||||
|
||||
idResult := GetIdentity(js.Undefined(), nil).(js.Value)
|
||||
if idResult.Get("hash").String() != reticulumIdentity.GetHexHash() {
|
||||
t.Error("GetIdentity returned wrong hash")
|
||||
}
|
||||
|
||||
destResult := GetDestination(js.Undefined(), nil).(js.Value)
|
||||
expectedDest := fmt.Sprintf("%x", reticulumDest.GetHash())
|
||||
if destResult.Get("hash").String() != expectedDest {
|
||||
t.Errorf("GetDestination returned wrong hash, expected %s got %s", expectedDest, destResult.Get("hash").String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnnounce(t *testing.T) {
|
||||
// Ensure initialized
|
||||
InitReticulum(js.Undefined(), []js.Value{js.ValueOf("ws://localhost")})
|
||||
|
||||
result := SendAnnounce(js.Undefined(), []js.Value{js.ValueOf("new_username")}).(js.Value)
|
||||
if !result.Get("success").Bool() {
|
||||
t.Errorf("SendAnnounce failed: %v", result.Get("error"))
|
||||
}
|
||||
|
||||
if userName != "new_username" {
|
||||
t.Errorf("userName should have been updated to 'new_username', got %s", userName)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSendMessage(t *testing.T) {
|
||||
// Ensure initialized
|
||||
InitReticulum(js.Undefined(), []js.Value{js.ValueOf("ws://localhost")})
|
||||
|
||||
// Create a mock peer
|
||||
peerId, _ := identity.NewIdentity()
|
||||
peerHash := peerId.Hash()
|
||||
peerHashHex := hex.EncodeToString(peerHash)
|
||||
|
||||
// Manually add to known destinations so Recall works
|
||||
identity.Remember([]byte("mock_packet"), peerHash, peerId.GetPublicKey(), []byte("peer_app_data"))
|
||||
|
||||
// Test SendMessage
|
||||
msg := "Hello Peer!"
|
||||
result := SendMessage(js.Undefined(), []js.Value{js.ValueOf(peerHashHex), js.ValueOf(msg)}).(js.Value)
|
||||
|
||||
if !result.Get("error").IsUndefined() {
|
||||
errStr := result.Get("error").String()
|
||||
if errStr != "Packet sending failed: no path to destination" {
|
||||
t.Errorf("SendMessage failed with unexpected error: %s", errStr)
|
||||
} else {
|
||||
t.Log("SendMessage correctly failed with 'no path to destination' (as expected in test environment)")
|
||||
}
|
||||
} else if !result.Get("success").Bool() {
|
||||
t.Errorf("SendMessage failed without error message")
|
||||
} else {
|
||||
if stats.packetsSent != 1 {
|
||||
t.Errorf("expected 1 packet sent, got %d", stats.packetsSent)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user