//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", "requestPath", "getStats", "setPacketCallback", "setAnnounceCallback", "sendData", } 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("log", 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 app name wsURL := "ws://localhost:8080" appName := "test_app" result = InitReticulum(js.Undefined(), []js.Value{js.ValueOf(wsURL), js.ValueOf(appName)}) 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") } // 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(appName), 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("log", 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 TestSendDataJS(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 SendDataJS with string data := "Hello Peer!" result := SendDataJS(js.Undefined(), []js.Value{js.ValueOf(peerHashHex), js.ValueOf(data)}).(js.Value) if !result.Get("error").IsUndefined() { errStr := result.Get("error").String() if errStr != "Packet sending failed: no path to destination" { t.Errorf("SendDataJS failed with unexpected error: %s", errStr) } } else if !result.Get("success").Bool() { t.Errorf("SendDataJS failed without error message") } }