@@ -124,13 +124,9 @@ func TestDefaultCmabClient_FetchDecision(t *testing.T) {
124124 HTTPClient : & http.Client {
125125 Timeout : 5 * time .Second ,
126126 },
127+ PredictionEndpointTemplate : server .URL + "/%s" ,
127128 })
128129
129- // Override the endpoint for testing
130- originalEndpoint := CMABPredictionEndpoint
131- CMABPredictionEndpoint = server .URL + "/%s"
132- defer func () { CMABPredictionEndpoint = originalEndpoint }()
133-
134130 // Test with various attribute types
135131 attributes := map [string ]interface {}{
136132 "string_attr" : "string value" ,
@@ -205,13 +201,9 @@ func TestDefaultCmabClient_FetchDecision_WithRetry(t *testing.T) {
205201 MaxBackoff : 100 * time .Millisecond ,
206202 BackoffMultiplier : 2.0 ,
207203 },
204+ PredictionEndpointTemplate : server .URL + "/%s" ,
208205 })
209206
210- // Override the endpoint for testing
211- originalEndpoint := CMABPredictionEndpoint
212- CMABPredictionEndpoint = server .URL + "/%s"
213- defer func () { CMABPredictionEndpoint = originalEndpoint }()
214-
215207 // Test fetch decision with retry
216208 attributes := map [string ]interface {}{
217209 "browser" : "chrome" ,
@@ -253,13 +245,9 @@ func TestDefaultCmabClient_FetchDecision_ExhaustedRetries(t *testing.T) {
253245 MaxBackoff : 100 * time .Millisecond ,
254246 BackoffMultiplier : 2.0 ,
255247 },
248+ PredictionEndpointTemplate : server .URL + "/%s" ,
256249 })
257250
258- // Override the endpoint for testing
259- originalEndpoint := CMABPredictionEndpoint
260- CMABPredictionEndpoint = server .URL + "/%s"
261- defer func () { CMABPredictionEndpoint = originalEndpoint }()
262-
263251 // Test fetch decision with exhausted retries
264252 attributes := map [string ]interface {}{
265253 "browser" : "chrome" ,
@@ -300,14 +288,10 @@ func TestDefaultCmabClient_FetchDecision_NoRetryConfig(t *testing.T) {
300288 HTTPClient : & http.Client {
301289 Timeout : 5 * time .Second ,
302290 },
303- RetryConfig : nil , // Explicitly set to nil to override default
291+ RetryConfig : nil , // Explicitly set to nil to override default
292+ PredictionEndpointTemplate : server .URL + "/%s" ,
304293 })
305294
306- // Override the endpoint for testing
307- originalEndpoint := CMABPredictionEndpoint
308- CMABPredictionEndpoint = server .URL + "/%s"
309- defer func () { CMABPredictionEndpoint = originalEndpoint }()
310-
311295 // Test fetch decision without retry config
312296 attributes := map [string ]interface {}{
313297 "browser" : "chrome" ,
@@ -364,13 +348,9 @@ func TestDefaultCmabClient_FetchDecision_InvalidResponse(t *testing.T) {
364348 HTTPClient : & http.Client {
365349 Timeout : 5 * time .Second ,
366350 },
351+ PredictionEndpointTemplate : server .URL + "/%s" ,
367352 })
368353
369- // Override the endpoint for testing
370- originalEndpoint := CMABPredictionEndpoint
371- CMABPredictionEndpoint = server .URL + "/%s"
372- defer func () { CMABPredictionEndpoint = originalEndpoint }()
373-
374354 // Test fetch decision with invalid response
375355 attributes := map [string ]interface {}{
376356 "browser" : "chrome" ,
@@ -407,14 +387,10 @@ func TestDefaultCmabClient_FetchDecision_NetworkErrors(t *testing.T) {
407387 MaxBackoff : 100 * time .Millisecond ,
408388 BackoffMultiplier : 2.0 ,
409389 },
410- Logger : mockLogger ,
390+ Logger : mockLogger ,
391+ PredictionEndpointTemplate : "http://non-existent-server.example.com/%s" ,
411392 })
412393
413- // Set endpoint to a non-existent server
414- originalEndpoint := CMABPredictionEndpoint
415- CMABPredictionEndpoint = "http://non-existent-server.example.com/%s"
416- defer func () { CMABPredictionEndpoint = originalEndpoint }()
417-
418394 // Test fetch decision with network error
419395 attributes := map [string ]interface {}{
420396 "browser" : "chrome" ,
@@ -468,13 +444,9 @@ func TestDefaultCmabClient_ExponentialBackoff(t *testing.T) {
468444 MaxBackoff : 1 * time .Second ,
469445 BackoffMultiplier : 2.0 ,
470446 },
447+ PredictionEndpointTemplate : server .URL + "/%s" ,
471448 })
472449
473- // Override the endpoint for testing
474- originalEndpoint := CMABPredictionEndpoint
475- CMABPredictionEndpoint = server .URL + "/%s"
476- defer func () { CMABPredictionEndpoint = originalEndpoint }()
477-
478450 // Test fetch decision with exponential backoff
479451 attributes := map [string ]interface {}{
480452 "browser" : "chrome" ,
@@ -555,14 +527,10 @@ func TestDefaultCmabClient_LoggingBehavior(t *testing.T) {
555527 MaxBackoff : 100 * time .Millisecond ,
556528 BackoffMultiplier : 2.0 ,
557529 },
558- Logger : mockLogger ,
530+ Logger : mockLogger ,
531+ PredictionEndpointTemplate : server .URL + "/%s" ,
559532 })
560533
561- // Override the endpoint for testing
562- originalEndpoint := CMABPredictionEndpoint
563- CMABPredictionEndpoint = server .URL + "/%s"
564- defer func () { CMABPredictionEndpoint = originalEndpoint }()
565-
566534 // Test fetch decision
567535 attributes := map [string ]interface {}{
568536 "browser" : "chrome" ,
@@ -618,14 +586,10 @@ func TestDefaultCmabClient_NonSuccessStatusCode(t *testing.T) {
618586 HTTPClient : & http.Client {
619587 Timeout : 5 * time .Second ,
620588 },
589+ PredictionEndpointTemplate : server .URL + "/%s" ,
621590 // No retry config to simplify the test
622591 })
623592
624- // Override the endpoint for testing
625- originalEndpoint := CMABPredictionEndpoint
626- CMABPredictionEndpoint = server .URL + "/%s"
627- defer func () { CMABPredictionEndpoint = originalEndpoint }()
628-
629593 // Test fetch decision
630594 attributes := map [string ]interface {}{
631595 "browser" : "chrome" ,
@@ -641,3 +605,57 @@ func TestDefaultCmabClient_NonSuccessStatusCode(t *testing.T) {
641605 })
642606 }
643607}
608+ func TestDefaultCmabClient_CustomPredictionEndpoint (t * testing.T ) {
609+ // Setup test server
610+ customEndpointCalled := false
611+ server := httptest .NewServer (http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
612+ customEndpointCalled = true
613+ // Verify the URL path contains the rule ID
614+ assert .Contains (t , r .URL .Path , "rule456" )
615+
616+ // Return a valid response
617+ response := Response {
618+ Predictions : []Prediction {
619+ {VariationID : "variation789" },
620+ },
621+ }
622+ json .NewEncoder (w ).Encode (response )
623+ }))
624+ defer server .Close ()
625+
626+ // Create client with custom prediction endpoint
627+ customEndpoint := server .URL + "/custom/predict/%s"
628+ client := NewDefaultCmabClient (ClientOptions {
629+ PredictionEndpointTemplate : customEndpoint ,
630+ })
631+
632+ // Test fetch decision
633+ attributes := map [string ]interface {}{
634+ "age" : 25 ,
635+ }
636+
637+ variationID , err := client .FetchDecision ("rule456" , "user123" , attributes , "test-uuid" )
638+
639+ // Verify results
640+ assert .NoError (t , err )
641+ assert .Equal (t , "variation789" , variationID )
642+ assert .True (t , customEndpointCalled , "Custom endpoint should have been called" )
643+ }
644+
645+ func TestDefaultCmabClient_DefaultPredictionEndpointTemplate (t * testing.T ) {
646+ // Create client without specifying prediction endpoint
647+ client := NewDefaultCmabClient (ClientOptions {})
648+
649+ // Verify it uses the default endpoint
650+ assert .Equal (t , DefaultPredictionEndpointTemplate , client .predictionEndpoint )
651+ }
652+
653+ func TestDefaultCmabClient_EmptyPredictionEndpointUsesDefault (t * testing.T ) {
654+ // Create client with empty prediction endpoint
655+ client := NewDefaultCmabClient (ClientOptions {
656+ PredictionEndpointTemplate : "" ,
657+ })
658+
659+ // Verify it uses the default endpoint when empty string is provided
660+ assert .Equal (t , DefaultPredictionEndpointTemplate , client .predictionEndpoint )
661+ }
0 commit comments