@@ -114,6 +114,100 @@ func TestSetServerColor_rejectsMalformed(t *testing.T) {
114114 }
115115}
116116
117+ // --- GET/POST /api/settings/instance-color ---
118+
119+ func getInstanceColorViaAPI (t * testing.T , router http.Handler ) * string {
120+ t .Helper ()
121+ req := httptest .NewRequest (http .MethodGet , "/api/settings/instance-color" , nil )
122+ rec := httptest .NewRecorder ()
123+ router .ServeHTTP (rec , req )
124+ if rec .Code != http .StatusOK {
125+ t .Fatalf ("GET status = %d, want %d; body=%s" , rec .Code , http .StatusOK , rec .Body .String ())
126+ }
127+ var result struct {
128+ Color * string `json:"color"`
129+ }
130+ if err := json .NewDecoder (rec .Body ).Decode (& result ); err != nil {
131+ t .Fatalf ("decode: %v" , err )
132+ }
133+ return result .Color
134+ }
135+
136+ func TestInstanceColor_getUnsetReturnsNull (t * testing.T ) {
137+ isolateSettings (t )
138+ router := newTestRouter (& mockSessionFetcher {}, & mockTmuxOps {})
139+
140+ if got := getInstanceColorViaAPI (t , router ); got != nil {
141+ t .Errorf ("color = %q, want null" , * got )
142+ }
143+ }
144+
145+ func TestSetInstanceColor_persistsAndRoundTrips (t * testing.T ) {
146+ isolateSettings (t )
147+ router := newTestRouter (& mockSessionFetcher {}, & mockTmuxOps {})
148+
149+ for _ , color := range []string {"5" , "1+3" } {
150+ body := `{"color":"` + color + `"}`
151+ req := httptest .NewRequest (http .MethodPost , "/api/settings/instance-color" , strings .NewReader (body ))
152+ req .Header .Set ("Content-Type" , "application/json" )
153+ rec := httptest .NewRecorder ()
154+ router .ServeHTTP (rec , req )
155+
156+ if rec .Code != http .StatusOK {
157+ t .Fatalf ("color %s: status = %d, want %d; body=%s" , color , rec .Code , http .StatusOK , rec .Body .String ())
158+ }
159+ if got := settings .GetInstanceColor (); got == nil || * got != color {
160+ t .Errorf ("persisted color = %v, want %q" , got , color )
161+ }
162+ if got := getInstanceColorViaAPI (t , router ); got == nil || * got != color {
163+ t .Errorf ("GET round-trip = %v, want %q" , got , color )
164+ }
165+ }
166+ }
167+
168+ func TestSetInstanceColor_nullClears (t * testing.T ) {
169+ isolateSettings (t )
170+ router := newTestRouter (& mockSessionFetcher {}, & mockTmuxOps {})
171+
172+ color := "4"
173+ if err := settings .SetInstanceColor (& color ); err != nil {
174+ t .Fatalf ("seed: %v" , err )
175+ }
176+
177+ body := `{"color":null}`
178+ req := httptest .NewRequest (http .MethodPost , "/api/settings/instance-color" , strings .NewReader (body ))
179+ req .Header .Set ("Content-Type" , "application/json" )
180+ rec := httptest .NewRecorder ()
181+ router .ServeHTTP (rec , req )
182+
183+ if rec .Code != http .StatusOK {
184+ t .Fatalf ("status = %d, want %d; body=%s" , rec .Code , http .StatusOK , rec .Body .String ())
185+ }
186+ if got := settings .GetInstanceColor (); got != nil {
187+ t .Errorf ("color after clear = %q, want nil" , * got )
188+ }
189+ if got := getInstanceColorViaAPI (t , router ); got != nil {
190+ t .Errorf ("GET after clear = %q, want null" , * got )
191+ }
192+ }
193+
194+ func TestSetInstanceColor_rejectsMalformed (t * testing.T ) {
195+ for _ , bad := range []string {`{"color":"99"}` , `{"color":"1+"}` , `{"color":"x"}` , `{"color":"1+2+3"}` } {
196+ isolateSettings (t )
197+ router := newTestRouter (& mockSessionFetcher {}, & mockTmuxOps {})
198+ req := httptest .NewRequest (http .MethodPost , "/api/settings/instance-color" , strings .NewReader (bad ))
199+ req .Header .Set ("Content-Type" , "application/json" )
200+ rec := httptest .NewRecorder ()
201+ router .ServeHTTP (rec , req )
202+ if rec .Code != http .StatusBadRequest {
203+ t .Errorf ("body %s: status = %d, want %d" , bad , rec .Code , http .StatusBadRequest )
204+ }
205+ if got := settings .GetInstanceColor (); got != nil {
206+ t .Errorf ("body %s: malformed value persisted as %q, want nil" , bad , * got )
207+ }
208+ }
209+ }
210+
117211func TestSetServerColor_missingServer (t * testing.T ) {
118212 isolateSettings (t )
119213 router := newTestRouter (& mockSessionFetcher {}, & mockTmuxOps {})
0 commit comments