github.com/prebid/prebid-server/v2@v2.18.0/usersync/bidderchooser_test.go (about)

     1  package usersync
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/assert"
     7  )
     8  
     9  // These tests use a deterministic version of the shuffler, where the order
    10  // is reversed rather than randomized. Most tests specify at least 2 elements
    11  // to implicitly verify the shuffler is invoked (or not invoked).
    12  
    13  func TestBidderChooserChoose(t *testing.T) {
    14  	shuffler := reverseShuffler{}
    15  	available := []string{"a1", "a2"}
    16  
    17  	testCases := []struct {
    18  		description      string
    19  		givenRequested   []string
    20  		givenCooperative Cooperative
    21  		expected         []string
    22  	}{
    23  		{
    24  			description:      "No Coop - Nil",
    25  			givenRequested:   nil,
    26  			givenCooperative: Cooperative{Enabled: false},
    27  			expected:         []string{"a2", "a1"},
    28  		},
    29  		{
    30  			description:      "No Coop - Empty",
    31  			givenRequested:   []string{},
    32  			givenCooperative: Cooperative{Enabled: false},
    33  			expected:         []string{"a2", "a1"},
    34  		},
    35  		{
    36  			description:      "No Coop - One",
    37  			givenRequested:   []string{"r"},
    38  			givenCooperative: Cooperative{Enabled: false},
    39  			expected:         []string{"r"},
    40  		},
    41  		{
    42  			description:      "No Coop - Many",
    43  			givenRequested:   []string{"r1", "r2"},
    44  			givenCooperative: Cooperative{Enabled: false},
    45  			expected:         []string{"r2", "r1"},
    46  		},
    47  		{
    48  			description:      "Coop - Nil",
    49  			givenRequested:   nil,
    50  			givenCooperative: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}},
    51  			expected:         []string{"pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"},
    52  		},
    53  		{
    54  			description:      "Coop - Empty",
    55  			givenRequested:   nil,
    56  			givenCooperative: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}},
    57  			expected:         []string{"pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"},
    58  		},
    59  		{
    60  			description:      "Coop - Integration Test",
    61  			givenRequested:   []string{"r1", "r2"},
    62  			givenCooperative: Cooperative{Enabled: true, PriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}}},
    63  			expected:         []string{"r2", "r1", "pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"},
    64  		},
    65  	}
    66  
    67  	for _, test := range testCases {
    68  		chooser := standardBidderChooser{shuffler: shuffler}
    69  		result := chooser.choose(test.givenRequested, available, test.givenCooperative)
    70  
    71  		assert.Equal(t, test.expected, result, test.description)
    72  	}
    73  }
    74  
    75  func TestBidderChooserCooperative(t *testing.T) {
    76  	shuffler := reverseShuffler{}
    77  	available := []string{"a1", "a2"}
    78  
    79  	testCases := []struct {
    80  		description         string
    81  		givenRequested      []string
    82  		givenPriorityGroups [][]string
    83  		expected            []string
    84  	}{
    85  		{
    86  			description:         "Nil",
    87  			givenRequested:      nil,
    88  			givenPriorityGroups: nil,
    89  			expected:            []string{"a2", "a1"},
    90  		},
    91  		{
    92  			description:         "Empty",
    93  			givenRequested:      []string{},
    94  			givenPriorityGroups: [][]string{},
    95  			expected:            []string{"a2", "a1"},
    96  		},
    97  		{
    98  			description:         "Requested",
    99  			givenRequested:      []string{"r1", "r2"},
   100  			givenPriorityGroups: nil,
   101  			expected:            []string{"r2", "r1", "a2", "a1"},
   102  		},
   103  		{
   104  			description:         "Priority Groups - One",
   105  			givenRequested:      nil,
   106  			givenPriorityGroups: [][]string{{"pr1A", "pr1B"}},
   107  			expected:            []string{"pr1B", "pr1A", "a2", "a1"},
   108  		},
   109  		{
   110  			description:         "Priority Groups - Many",
   111  			givenRequested:      nil,
   112  			givenPriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}},
   113  			expected:            []string{"pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"},
   114  		},
   115  		{
   116  			description:         "Requested + Priority Groups",
   117  			givenRequested:      []string{"r1", "r2"},
   118  			givenPriorityGroups: [][]string{{"pr1A", "pr1B"}, {"pr2A", "pr2B"}},
   119  			expected:            []string{"r2", "r1", "pr1B", "pr1A", "pr2B", "pr2A", "a2", "a1"},
   120  		},
   121  	}
   122  
   123  	for _, test := range testCases {
   124  		chooser := standardBidderChooser{shuffler: shuffler}
   125  		result := chooser.chooseCooperative(test.givenRequested, available, test.givenPriorityGroups)
   126  
   127  		assert.Equal(t, test.expected, result, test.description)
   128  	}
   129  }
   130  
   131  func TestBidderChooserShuffledCopy(t *testing.T) {
   132  	shuffler := reverseShuffler{}
   133  
   134  	testCases := []struct {
   135  		description string
   136  		given       []string
   137  		expected    []string
   138  	}{
   139  		{
   140  			description: "Empty",
   141  			given:       []string{},
   142  			expected:    []string{},
   143  		},
   144  		{
   145  			description: "One",
   146  			given:       []string{"a"},
   147  			expected:    []string{"a"},
   148  		},
   149  		{
   150  			description: "Many",
   151  			given:       []string{"a", "b"},
   152  			expected:    []string{"b", "a"},
   153  		},
   154  	}
   155  
   156  	for _, test := range testCases {
   157  		givenCopy := copySlice(test.given)
   158  
   159  		chooser := standardBidderChooser{shuffler: shuffler}
   160  		result := chooser.shuffledCopy(test.given)
   161  
   162  		assert.Equal(t, givenCopy, test.given, test.description+":input")
   163  		assert.Equal(t, test.expected, result, test.description+":result")
   164  	}
   165  }
   166  
   167  func TestBidderChooserShuffledAppend(t *testing.T) {
   168  	shuffler := reverseShuffler{}
   169  
   170  	testCases := []struct {
   171  		description string
   172  		givenA      []string
   173  		givenB      []string
   174  		expected    []string
   175  	}{
   176  		{
   177  			description: "Empty - Append Nil",
   178  			givenA:      []string{},
   179  			givenB:      nil,
   180  			expected:    []string{},
   181  		},
   182  		{
   183  			description: "Empty - Append Empty",
   184  			givenA:      []string{},
   185  			givenB:      []string{},
   186  			expected:    []string{},
   187  		},
   188  		{
   189  			description: "Empty - Append One",
   190  			givenA:      []string{},
   191  			givenB:      []string{"b"},
   192  			expected:    []string{"b"},
   193  		},
   194  		{
   195  			description: "Empty - Append Many",
   196  			givenA:      []string{},
   197  			givenB:      []string{"b1", "b2"},
   198  			expected:    []string{"b2", "b1"},
   199  		},
   200  		{
   201  			description: "One - Append Nil",
   202  			givenA:      []string{"a"},
   203  			givenB:      nil,
   204  			expected:    []string{"a"},
   205  		},
   206  		{
   207  			description: "One - Append Empty",
   208  			givenA:      []string{"a"},
   209  			givenB:      []string{},
   210  			expected:    []string{"a"},
   211  		},
   212  		{
   213  			description: "One - Append One",
   214  			givenA:      []string{"a1"},
   215  			givenB:      []string{"b1"},
   216  			expected:    []string{"a1", "b1"},
   217  		},
   218  		{
   219  			description: "One - Append Many",
   220  			givenA:      []string{"a1"},
   221  			givenB:      []string{"b1", "b2"},
   222  			expected:    []string{"a1", "b2", "b1"},
   223  		},
   224  		{
   225  			description: "Many - Append Nil",
   226  			givenA:      []string{"a1", "a2"},
   227  			givenB:      nil,
   228  			expected:    []string{"a1", "a2"},
   229  		},
   230  		{
   231  			description: "Many - Append Empty",
   232  			givenA:      []string{"a1", "a2"},
   233  			givenB:      []string{},
   234  			expected:    []string{"a1", "a2"},
   235  		},
   236  		{
   237  			description: "Many - Append One",
   238  			givenA:      []string{"a1", "a2"},
   239  			givenB:      []string{"b"},
   240  			expected:    []string{"a1", "a2", "b"},
   241  		},
   242  		{
   243  			description: "Many - Append Many",
   244  			givenA:      []string{"a1", "a2"},
   245  			givenB:      []string{"b1", "b2"},
   246  			expected:    []string{"a1", "a2", "b2", "b1"},
   247  		},
   248  	}
   249  
   250  	for _, test := range testCases {
   251  		givenBCopy := copySlice(test.givenB)
   252  
   253  		chooser := standardBidderChooser{shuffler: shuffler}
   254  		result := chooser.shuffledAppend(test.givenA, test.givenB)
   255  
   256  		assert.Equal(t, givenBCopy, test.givenB, test.description+":input")
   257  		assert.Equal(t, test.expected, result, test.description+":result")
   258  	}
   259  }
   260  
   261  // copySlice returns a cloned a slice or nil.
   262  func copySlice(a []string) []string {
   263  	var aCopy []string
   264  	if a != nil {
   265  		aCopy = make([]string, len(a))
   266  		copy(aCopy, a)
   267  	}
   268  	return aCopy
   269  }
   270  
   271  type reverseShuffler struct{}
   272  
   273  func (reverseShuffler) shuffle(a []string) {
   274  	for i, j := 0, len(a)-1; i < j; i, j = i+1, j-1 {
   275  		a[i], a[j] = a[j], a[i]
   276  	}
   277  }