github.com/prebid/prebid-server/v2@v2.18.0/analytics/pubstack/configupdate_test.go (about) 1 package pubstack 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "sync" 7 "testing" 8 "time" 9 10 "github.com/stretchr/testify/assert" 11 "github.com/stretchr/testify/require" 12 ) 13 14 func TestNewConfigUpdateHttpTask(t *testing.T) { 15 // configure test config endpoint 16 var isFirstQuery bool = true 17 var isFirstQueryMutex sync.Mutex 18 mux := http.NewServeMux() 19 mux.HandleFunc("/", func(res http.ResponseWriter, req *http.Request) { 20 isFirstQueryMutex.Lock() 21 defer isFirstQueryMutex.Unlock() 22 23 defer req.Body.Close() 24 25 if isFirstQuery { 26 res.Write([]byte(`{ "scopeId": "scope1", "endpoint": "https://pubstack.io", "features": { "auction": true, "cookiesync": true }}`)) 27 } else { 28 res.Write([]byte(`{ "scopeId": "scope2", "endpoint": "https://pubstack.io", "features": { "auction": false, "cookiesync": false }}`)) 29 } 30 31 isFirstQuery = false 32 }) 33 server := httptest.NewServer(mux) 34 client := server.Client() 35 36 // create task 37 task, err := NewConfigUpdateHttpTask(client, "scope", server.URL, "5ms") 38 require.NoError(t, err, "create config task") 39 40 // start task 41 stopChan := make(chan struct{}) 42 configChan := task.Start(stopChan) 43 44 // read initial config 45 expectedInitialConfig := &Configuration{ScopeID: "scope1", Endpoint: "https://pubstack.io", Features: map[string]bool{"auction": true, "cookiesync": true}} 46 assertConfigChanOne(t, configChan, expectedInitialConfig, "initial config") 47 48 // read updated config 49 expectedUpdatedConfig := &Configuration{ScopeID: "scope2", Endpoint: "https://pubstack.io", Features: map[string]bool{"auction": false, "cookiesync": false}} 50 assertConfigChanOne(t, configChan, expectedUpdatedConfig, "updated config") 51 52 // stop task 53 close(stopChan) 54 55 // no further updates 56 assertConfigChanNone(t, configChan) 57 } 58 59 func TestNewConfigUpdateHttpTaskErrors(t *testing.T) { 60 tests := []struct { 61 description string 62 givenEndpoint string 63 givenRefreshInterval string 64 expectedError string 65 }{ 66 { 67 description: "refresh interval invalid", 68 givenEndpoint: "http://valid.com", 69 givenRefreshInterval: "invalid", 70 expectedError: `fail to parse the module args, arg=analytics.pubstack.configuration_refresh_delay: time: invalid duration "invalid"`, 71 }, 72 { 73 description: "endpoint invalid", 74 givenEndpoint: "://invalid.com", 75 givenRefreshInterval: "10ms", 76 expectedError: `parse "://invalid.com/bootstrap?scopeId=anyScope": missing protocol scheme`, 77 }, 78 } 79 80 for _, test := range tests { 81 task, err := NewConfigUpdateHttpTask(nil, "anyScope", test.givenEndpoint, test.givenRefreshInterval) 82 assert.Nil(t, task, test.description) 83 assert.EqualError(t, err, test.expectedError, test.description) 84 } 85 } 86 87 func assertConfigChanNone(t *testing.T, c <-chan *Configuration) bool { 88 t.Helper() 89 select { 90 case <-c: 91 return assert.Fail(t, "received a unexpected configuration channel event") 92 case <-time.After(200 * time.Millisecond): 93 return true 94 } 95 } 96 97 func assertConfigChanOne(t *testing.T, c <-chan *Configuration, expectedConfig *Configuration, msgAndArgs ...interface{}) bool { 98 t.Helper() 99 select { 100 case v := <-c: 101 return assert.Equal(t, expectedConfig, v, msgAndArgs...) 102 case <-time.After(200 * time.Millisecond): 103 return assert.Fail(t, "Should receive an event, but did NOT", msgAndArgs...) 104 } 105 }