package node import ( "testing" ) // TestProtocol_ValidateResponse_Good verifies ValidateResponse accepts a well-formed matching response. // // msg, _ := NewMessage(MsgStats, "sender", "receiver", StatsPayload{NodeID: "test"}) // if err := ValidateResponse(msg, MsgStats); err != nil { t.Fatal(err) } func TestProtocol_ValidateResponse_Good(t *testing.T) { handler := &ResponseHandler{} msg, _ := NewMessage(MsgStats, "sender", "receiver", StatsPayload{NodeID: "test"}) if err := handler.ValidateResponse(msg, MsgStats); err != nil { t.Errorf("ValidateResponse failed for valid response: %v", err) } } // TestProtocol_ValidateResponse_Bad verifies ValidateResponse rejects nil responses and error payloads. // // err := handler.ValidateResponse(nil, MsgStats) // if err == nil { t.Error("expected error for nil response") } func TestProtocol_ValidateResponse_Bad(t *testing.T) { handler := &ResponseHandler{} // Nil response must return an error err := handler.ValidateResponse(nil, MsgStats) if err == nil { t.Error("expected error for nil response") } // Error response must return a ProtocolError errMsg, _ := NewErrorMessage("sender", "receiver", ErrCodeOperationFailed, "operation failed", "") err = handler.ValidateResponse(errMsg, MsgStats) if err == nil { t.Fatal("expected error for error response") } if !IsProtocolError(err) { t.Errorf("expected ProtocolError, got %T", err) } if GetProtocolErrorCode(err) != ErrCodeOperationFailed { t.Errorf("expected code %d, got %d", ErrCodeOperationFailed, GetProtocolErrorCode(err)) } } // TestProtocol_ValidateResponse_Ugly verifies ValidateResponse rejects a response with the wrong MessageType. // // msg, _ := NewMessage(MsgPong, "sender", "receiver", nil) // err := handler.ValidateResponse(msg, MsgStats) // if !IsProtocolError(err) { t.Error("type mismatch must be a ProtocolError") } func TestProtocol_ValidateResponse_Ugly(t *testing.T) { handler := &ResponseHandler{} msg, _ := NewMessage(MsgPong, "sender", "receiver", nil) err := handler.ValidateResponse(msg, MsgStats) if err == nil { t.Error("expected error for wrong type") } if !IsProtocolError(err) { t.Error("type mismatch must produce a ProtocolError") } } // TestProtocol_ParseResponse_Good verifies ParseResponse correctly unmarshals a well-formed payload. // // var parsed StatsPayload // if err := handler.ParseResponse(msg, MsgStats, &parsed); err != nil { t.Fatal(err) } func TestProtocol_ParseResponse_Good(t *testing.T) { handler := &ResponseHandler{} payload := StatsPayload{ NodeID: "node-123", NodeName: "Test Node", Uptime: 3600, } msg, _ := NewMessage(MsgStats, "sender", "receiver", payload) var parsed StatsPayload if err := handler.ParseResponse(msg, MsgStats, &parsed); err != nil { t.Fatalf("unexpected error: %v", err) } if parsed.NodeID != "node-123" { t.Errorf("expected NodeID 'node-123', got '%s'", parsed.NodeID) } if parsed.Uptime != 3600 { t.Errorf("expected Uptime 3600, got %d", parsed.Uptime) } } // TestProtocol_ParseResponse_Bad verifies ParseResponse surfaces a ProtocolError from an error response. // // err := handler.ParseResponse(errMsg, MsgStats, &parsed) // if !IsProtocolError(err) { t.Error("expected ProtocolError") } func TestProtocol_ParseResponse_Bad(t *testing.T) { handler := &ResponseHandler{} errMsg, _ := NewErrorMessage("sender", "receiver", ErrCodeNotFound, "not found", "") var parsed StatsPayload err := handler.ParseResponse(errMsg, MsgStats, &parsed) if err == nil { t.Error("expected error for error response") } if !IsProtocolError(err) { t.Errorf("expected ProtocolError, got %T", err) } } // TestProtocol_ParseResponse_Ugly verifies ParseResponse accepts a nil target without error. // // msg, _ := NewMessage(MsgPong, "sender", "receiver", nil) // if err := handler.ParseResponse(msg, MsgPong, nil); err != nil { t.Fatal(err) } func TestProtocol_ParseResponse_Ugly(t *testing.T) { handler := &ResponseHandler{} msg, _ := NewMessage(MsgPong, "sender", "receiver", nil) if err := handler.ParseResponse(msg, MsgPong, nil); err != nil { t.Errorf("unexpected error with nil target: %v", err) } // Pong with MinerAck target type also parsed without panic payload := MinerAckPayload{Success: true, MinerName: "xmrig-1"} msg2, _ := NewMessage(MsgMinerAck, "sender", "receiver", payload) var parsedAck MinerAckPayload if err := handler.ParseResponse(msg2, MsgMinerAck, &parsedAck); err != nil { t.Fatalf("unexpected error: %v", err) } if !parsedAck.Success { t.Error("expected Success to be true") } if parsedAck.MinerName != "xmrig-1" { t.Errorf("expected MinerName 'xmrig-1', got '%s'", parsedAck.MinerName) } } // TestProtocol_ProtocolError_Good verifies ProtocolError formats its message correctly. // // err := &ProtocolError{Code: 1001, Message: "test error"} // if err.Error() != "remote error (1001): test error" { t.Fatal("wrong format") } func TestProtocol_ProtocolError_Good(t *testing.T) { err := &ProtocolError{Code: 1001, Message: "test error"} if err.Error() != "remote error (1001): test error" { t.Errorf("unexpected error message: %s", err.Error()) } if !IsProtocolError(err) { t.Error("IsProtocolError should return true") } if GetProtocolErrorCode(err) != 1001 { t.Errorf("expected code 1001, got %d", GetProtocolErrorCode(err)) } } // TestProtocol_ProtocolError_Bad verifies IsProtocolError and GetProtocolErrorCode handle non-ProtocolError values. // // err := errors.New("plain error") // if IsProtocolError(err) { t.Error("should be false") } // if GetProtocolErrorCode(err) != 0 { t.Error("should be 0") } func TestProtocol_ProtocolError_Bad(t *testing.T) { err := &testErr{"regular error"} if IsProtocolError(err) { t.Error("IsProtocolError should return false for non-ProtocolError") } if GetProtocolErrorCode(err) != 0 { t.Error("expected 0 for non-ProtocolError") } } // TestProtocol_DefaultHandler_Good verifies the package-level convenience functions delegate to DefaultResponseHandler. // // msg, _ := NewMessage(MsgStats, "sender", "receiver", StatsPayload{NodeID: "test"}) // if err := ValidateResponse(msg, MsgStats); err != nil { t.Fatal(err) } func TestProtocol_DefaultHandler_Good(t *testing.T) { msg, _ := NewMessage(MsgStats, "sender", "receiver", StatsPayload{NodeID: "test"}) if err := ValidateResponse(msg, MsgStats); err != nil { t.Errorf("ValidateResponse failed: %v", err) } var parsed StatsPayload if err := ParseResponse(msg, MsgStats, &parsed); err != nil { t.Errorf("ParseResponse failed: %v", err) } if parsed.NodeID != "test" { t.Errorf("expected NodeID 'test', got '%s'", parsed.NodeID) } } // testErr is a plain error type used to verify behaviour with non-ProtocolError values. // // err := &testErr{"context: operation failed"} type testErr struct{ message string } func (e *testErr) Error() string { return e.message }