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  }