@@ -5,12 +5,22 @@ import (
55 "net/http"
66 "net/http/httptest"
77 "os"
8+ "sync"
89 "testing"
910
1011 "github.com/stretchr/testify/assert"
1112 "github.com/stretchr/testify/require"
1213)
1314
15+ // Because getConfig in config.go calls sync.OnceValues, the new values set to
16+ // SERVERADMIN_BASE_URL between test runs is never changed, as getConfig returns
17+ // cached values.
18+ // We use resetConfig() to reinitialize things, forcing getConfig() to return the
19+ // values from the new env variables.
20+ func resetConfig () {
21+ getConfig = sync .OnceValues (loadConfig )
22+ }
23+
1424func TestFakeServer (t * testing.T ) {
1525 server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
1626 req , _ := io .ReadAll (r .Body )
@@ -26,6 +36,7 @@ func TestFakeServer(t *testing.T) {
2636 }))
2737 defer server .Close ()
2838
39+ resetConfig ()
2940 os .Clearenv ()
3041 _ = os .Setenv ("SERVERADMIN_TOKEN" , "1234567890" )
3142 _ = os .Setenv ("SERVERADMIN_BASE_URL" , server .URL )
@@ -104,3 +115,64 @@ func BenchmarkCalcSecurityToken(b *testing.B) {
104115 calcSecurityToken (authToken , now , message )
105116 }
106117}
118+
119+ // TestHTTPErrorHandling verifies that HTTP error codes are properly captured and reported
120+ func TestHTTPErrorHandling (t * testing.T ) {
121+ testCases := []struct {
122+ name string
123+ statusCode int
124+ responseBody string
125+ expectedError string
126+ }{
127+ {
128+ name : "400 Bad Request - ValidationError" ,
129+ statusCode : 400 ,
130+ responseBody : `{"error": {"message": "Bad Request: Invalid filter format"}}` ,
131+ expectedError : "HTTP error 400 Bad Request: Bad Request: Invalid filter format" ,
132+ },
133+ {
134+ name : "400 Bad Request - FilterValueError" ,
135+ statusCode : 400 ,
136+ responseBody : `{"error": {"message": "Bad Request: hostname must be a string"}}` ,
137+ expectedError : "HTTP error 400 Bad Request: Bad Request: hostname must be a string" ,
138+ },
139+ {
140+ name : "403 Forbidden - PermissionDenied" ,
141+ statusCode : 403 ,
142+ responseBody : `{"error": {"message": "Forbidden: No known public key found"}}` ,
143+ expectedError : "HTTP error 403 Forbidden: Forbidden: No known public key found" ,
144+ },
145+ {
146+ name : "404 Not Found - ObjectDoesNotExist" ,
147+ statusCode : 404 ,
148+ responseBody : `{"error": {"message": "Not Found: Server object with id 12345 does not exist"}}` ,
149+ expectedError : "HTTP error 404 Not Found: Not Found: Server object with id 12345 does not exist" ,
150+ },
151+ }
152+
153+ for _ , tc := range testCases {
154+ t .Run (tc .name , func (t * testing.T ) {
155+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , _ * http.Request ) {
156+ w .WriteHeader (tc .statusCode )
157+ _ , _ = w .Write ([]byte (tc .responseBody ))
158+ }))
159+ defer server .Close ()
160+
161+ resetConfig ()
162+ os .Clearenv ()
163+ _ = os .Setenv ("SERVERADMIN_TOKEN" , "1234567890" )
164+ _ = os .Setenv ("SERVERADMIN_BASE_URL" , server .URL )
165+
166+ query := NewQuery (Filters {
167+ "hostname" : Regexp ("test.local" ),
168+ })
169+ query .SetAttributes ([]string {"hostname" })
170+
171+ servers , err := query .All ()
172+ require .Error (t , err )
173+ assert .Nil (t , servers )
174+ assert .Contains (t , err .Error (), tc .expectedError )
175+ assert .NotContains (t , err .Error (), "expected exactly one server object" )
176+ })
177+ }
178+ }
0 commit comments