package main import ( "encoding/json" "testing" ) // --- Client-to-server message type tests --- func TestAttachMsgJSON(t *testing.T) { msg := AttachMsg{Attach: "my-session"} data, err := json.Marshal(msg) if err != nil { t.Fatalf("marshal AttachMsg: %v", err) } var m map[string]interface{} json.Unmarshal(data, &m) if m["attach"] != "my-session" { t.Errorf("expected attach=my-session, got %v", m["attach"]) } } func TestResizeMsgJSON(t *testing.T) { msg := ResizeMsg{Resize: struct { Cols int `json:"cols"` Rows int `json:"rows"` }{Cols: 80, Rows: 24}} data, err := json.Marshal(msg) if err != nil { t.Fatalf("marshal ResizeMsg: %v", err) } var m map[string]interface{} json.Unmarshal(data, &m) resize, ok := m["resize"].(map[string]interface{}) if !ok { t.Fatalf("expected resize to be a map, got %T", m["resize"]) } if resize["cols"].(float64) != 80 { t.Errorf("expected cols=80, got %v", resize["cols"]) } if resize["rows"].(float64) != 24 { t.Errorf("expected rows=24, got %v", resize["rows"]) } } func TestDetachMsgJSON(t *testing.T) { msg := DetachMsg{Detach: true} data, err := json.Marshal(msg) if err != nil { t.Fatalf("marshal DetachMsg: %v", err) } var m map[string]interface{} json.Unmarshal(data, &m) if m["detach"] != true { t.Errorf("expected detach=true, got %v", m["detach"]) } } // --- Server-to-client message type tests --- func TestAttachedMsgJSON(t *testing.T) { msg := AttachedMsg{Attached: "sess1"} data, err := json.Marshal(msg) if err != nil { t.Fatalf("marshal AttachedMsg: %v", err) } var m map[string]interface{} json.Unmarshal(data, &m) if m["attached"] != "sess1" { t.Errorf("expected attached=sess1, got %v", m["attached"]) } } func TestErrorMsgJSON(t *testing.T) { msg := ErrorMsg{Error: "something broke"} data, err := json.Marshal(msg) if err != nil { t.Fatalf("marshal ErrorMsg: %v", err) } var m map[string]interface{} json.Unmarshal(data, &m) if m["error"] != "something broke" { t.Errorf("expected error='something broke', got %v", m["error"]) } } func TestExitedMsgJSON(t *testing.T) { msg := ExitedMsg{Exited: "sess1"} data, err := json.Marshal(msg) if err != nil { t.Fatalf("marshal ExitedMsg: %v", err) } var m map[string]interface{} json.Unmarshal(data, &m) if m["exited"] != "sess1" { t.Errorf("expected exited=sess1, got %v", m["exited"]) } } // --- ParseControlMessage tests --- func TestParseControlMessage_Attach(t *testing.T) { data := []byte(`{"attach":"dev"}`) kind, val := ParseControlMessage(data) if kind != "attach" { t.Fatalf("expected kind=attach, got %q", kind) } msg, ok := val.(*AttachMsg) if !ok { t.Fatalf("expected *AttachMsg, got %T", val) } if msg.Attach != "dev" { t.Errorf("expected Attach=dev, got %q", msg.Attach) } } func TestParseControlMessage_Resize(t *testing.T) { data := []byte(`{"resize":{"cols":120,"rows":40}}`) kind, val := ParseControlMessage(data) if kind != "resize" { t.Fatalf("expected kind=resize, got %q", kind) } msg, ok := val.(*ResizeMsg) if !ok { t.Fatalf("expected *ResizeMsg, got %T", val) } if msg.Resize.Cols != 120 || msg.Resize.Rows != 40 { t.Errorf("expected 120x40, got %dx%d", msg.Resize.Cols, msg.Resize.Rows) } } func TestParseControlMessage_Detach(t *testing.T) { data := []byte(`{"detach":true}`) kind, val := ParseControlMessage(data) if kind != "detach" { t.Fatalf("expected kind=detach, got %q", kind) } msg, ok := val.(*DetachMsg) if !ok { t.Fatalf("expected *DetachMsg, got %T", val) } if !msg.Detach { t.Errorf("expected Detach=true") } } func TestParseControlMessage_Unknown(t *testing.T) { data := []byte(`{"foo":"bar"}`) kind, val := ParseControlMessage(data) if kind != "unknown" { t.Errorf("expected kind=unknown, got %q", kind) } if val != nil { t.Errorf("expected nil val for unknown, got %v", val) } } func TestParseControlMessage_Invalid(t *testing.T) { data := []byte(`not json at all`) kind, val := ParseControlMessage(data) if kind != "invalid" { t.Errorf("expected kind=invalid, got %q", kind) } if val != nil { t.Errorf("expected nil val for invalid, got %v", val) } } // --- Marshal function tests --- func TestMarshalAttached(t *testing.T) { data := MarshalAttached("sess1") var m map[string]interface{} if err := json.Unmarshal(data, &m); err != nil { t.Fatalf("unmarshal: %v", err) } if m["attached"] != "sess1" { t.Errorf("expected attached=sess1, got %v", m["attached"]) } } func TestMarshalError(t *testing.T) { data := MarshalError("bad thing") var m map[string]interface{} if err := json.Unmarshal(data, &m); err != nil { t.Fatalf("unmarshal: %v", err) } if m["error"] != "bad thing" { t.Errorf("expected error='bad thing', got %v", m["error"]) } } func TestMarshalExited(t *testing.T) { data := MarshalExited("sess1") var m map[string]interface{} if err := json.Unmarshal(data, &m); err != nil { t.Fatalf("unmarshal: %v", err) } if m["exited"] != "sess1" { t.Errorf("expected exited=sess1, got %v", m["exited"]) } }