github.com/prebid/prebid-server@v0.275.0/floors/rule_test.go (about)

     1  package floors
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"testing"
     7  
     8  	"github.com/prebid/openrtb/v19/openrtb2"
     9  	"github.com/prebid/prebid-server/currency"
    10  	"github.com/prebid/prebid-server/openrtb_ext"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func TestPrepareRuleCombinations(t *testing.T) {
    15  	testCases := []struct {
    16  		name string
    17  		in   []string
    18  		del  string
    19  		exp  []string
    20  	}{
    21  		{
    22  			name: "Schema items, n = 1",
    23  			in:   []string{"A"},
    24  			del:  "|",
    25  			exp: []string{
    26  				"a",
    27  				"*",
    28  			},
    29  		},
    30  		{
    31  			name: "Schema items, n = 2",
    32  			in:   []string{"A", "B"},
    33  			del:  "|",
    34  			exp: []string{
    35  				"a|b",
    36  				"a|*",
    37  				"*|b",
    38  				"*|*",
    39  			},
    40  		},
    41  		{
    42  			name: "Schema items, n = 3",
    43  			in:   []string{"A", "B", "C"},
    44  			del:  "|",
    45  			exp: []string{
    46  				"a|b|c",
    47  				"a|b|*",
    48  				"a|*|c",
    49  				"*|b|c",
    50  				"a|*|*",
    51  				"*|b|*",
    52  				"*|*|c",
    53  				"*|*|*",
    54  			},
    55  		},
    56  		{
    57  			name: "Schema items, n = 4",
    58  			in:   []string{"A", "B", "C", "D"},
    59  			del:  "|",
    60  			exp: []string{
    61  				"a|b|c|d",
    62  				"a|b|c|*",
    63  				"a|b|*|d",
    64  				"a|*|c|d",
    65  				"*|b|c|d",
    66  				"a|b|*|*",
    67  				"a|*|c|*",
    68  				"a|*|*|d",
    69  				"*|b|c|*",
    70  				"*|b|*|d",
    71  				"*|*|c|d",
    72  				"a|*|*|*",
    73  				"*|b|*|*",
    74  				"*|*|c|*",
    75  				"*|*|*|d",
    76  				"*|*|*|*",
    77  			},
    78  		},
    79  		{
    80  			name: "Schema items, n = 1 with wildcards",
    81  			in:   []string{"*"},
    82  			del:  "|",
    83  			exp: []string{
    84  				"*",
    85  			},
    86  		},
    87  		{
    88  			name: "Schema items, n = 2 with wildcard at index = 0",
    89  			in:   []string{"*", "B"},
    90  			del:  "|",
    91  			exp: []string{
    92  				"*|b",
    93  				"*|*",
    94  			},
    95  		},
    96  		{
    97  			name: "Schema items, n = 2 with wildcards at index = 1",
    98  			in:   []string{"A", "*"},
    99  			del:  "|",
   100  			exp: []string{
   101  				"a|*",
   102  				"*|*",
   103  			},
   104  		},
   105  
   106  		{
   107  			name: "Schema items, n = 2 wildcards at index = 0,1",
   108  			in:   []string{"*", "*"},
   109  			del:  "|",
   110  			exp: []string{
   111  				"*|*",
   112  			},
   113  		},
   114  
   115  		{
   116  			name: "Schema items, n = 3 wildcard at index = 0",
   117  			in:   []string{"*", "B", "C"},
   118  			del:  "|",
   119  			exp: []string{
   120  				"*|b|c",
   121  				"*|b|*",
   122  				"*|*|c",
   123  				"*|*|*",
   124  			},
   125  		},
   126  		{
   127  			name: "Schema items, n = 3 wildcard at index = 1",
   128  			in:   []string{"A", "*", "C"},
   129  			del:  "|",
   130  			exp: []string{
   131  				"a|*|c",
   132  				"a|*|*",
   133  				"*|*|c",
   134  				"*|*|*",
   135  			},
   136  		},
   137  		{
   138  			name: "Schema items, n = 3 with wildcard at index = 2",
   139  			in:   []string{"A", "B", "*"},
   140  			del:  "|",
   141  			exp: []string{
   142  				"a|b|*",
   143  				"a|*|*",
   144  				"*|b|*",
   145  				"*|*|*",
   146  			},
   147  		},
   148  		{
   149  			name: "Schema items, n = 3 with wildcard at index = 0,2",
   150  			in:   []string{"*", "B", "*"},
   151  			del:  "|",
   152  			exp: []string{
   153  				"*|b|*",
   154  				"*|*|*",
   155  			},
   156  		},
   157  		{
   158  			name: "Schema items, n = 3 with wildcard at index = 0,1",
   159  			in:   []string{"*", "*", "C"},
   160  			del:  "|",
   161  			exp: []string{
   162  				"*|*|c",
   163  				"*|*|*",
   164  			},
   165  		},
   166  		{
   167  			name: "Schema items, n = 3 with wildcard at index = 1,2",
   168  			in:   []string{"A", "*", "*"},
   169  			del:  "|",
   170  			exp: []string{
   171  				"a|*|*",
   172  				"*|*|*",
   173  			},
   174  		},
   175  	}
   176  	for _, tc := range testCases {
   177  		t.Run(tc.name, func(t *testing.T) {
   178  			act := prepareRuleCombinations(tc.in, tc.del)
   179  			assert.Equal(t, tc.exp, act, tc.name)
   180  		})
   181  	}
   182  }
   183  
   184  func TestUpdateImpExtWithFloorDetails(t *testing.T) {
   185  	testCases := []struct {
   186  		name         string
   187  		matchedRule  string
   188  		floorRuleVal float64
   189  		floorVal     float64
   190  		imp          *openrtb_ext.ImpWrapper
   191  		expected     json.RawMessage
   192  	}{
   193  		{
   194  			name:         "Nil ImpExt",
   195  			matchedRule:  "test|123|xyz",
   196  			floorRuleVal: 5.5,
   197  			floorVal:     5.5,
   198  			imp:          &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{ID: "1234", Video: &openrtb2.Video{W: 300, H: 250}}},
   199  			expected:     []byte(`{"prebid":{"floors":{"floorrule":"test|123|xyz","floorrulevalue":5.5,"floorvalue":5.5}}}`),
   200  		},
   201  		{
   202  			name:         "Empty ImpExt",
   203  			matchedRule:  "test|123|xyz",
   204  			floorRuleVal: 5.5,
   205  			floorVal:     5.5,
   206  			imp:          &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{ID: "1234", Video: &openrtb2.Video{W: 300, H: 250}, Ext: json.RawMessage{}}},
   207  			expected:     []byte(`{"prebid":{"floors":{"floorrule":"test|123|xyz","floorrulevalue":5.5,"floorvalue":5.5}}}`),
   208  		},
   209  		{
   210  			name:         "With prebid Ext",
   211  			matchedRule:  "banner|www.test.com|*",
   212  			floorRuleVal: 5.5,
   213  			floorVal:     15.5,
   214  			imp:          &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{ID: "1234", Video: &openrtb2.Video{W: 300, H: 250}, Ext: []byte(`{"prebid": {"test": true}}`)}},
   215  			expected:     []byte(`{"prebid":{"floors":{"floorrule":"banner|www.test.com|*","floorrulevalue":5.5,"floorvalue":15.5}}}`),
   216  		},
   217  	}
   218  	for _, tc := range testCases {
   219  		t.Run(tc.name, func(t *testing.T) {
   220  			updateImpExtWithFloorDetails(tc.imp, tc.matchedRule, tc.floorRuleVal, tc.floorVal)
   221  			_ = tc.imp.RebuildImp()
   222  			if tc.imp.Ext != nil {
   223  				assert.Equal(t, tc.imp.Ext, tc.expected, tc.name)
   224  			}
   225  		})
   226  	}
   227  }
   228  
   229  func TestCreateRuleKeys(t *testing.T) {
   230  	testCases := []struct {
   231  		name        string
   232  		floorSchema openrtb_ext.PriceFloorSchema
   233  		request     *openrtb2.BidRequest
   234  		out         []string
   235  	}{
   236  		{
   237  			name: "CreateRule with banner mediatype, size and domain",
   238  			request: &openrtb2.BidRequest{
   239  				Site: &openrtb2.Site{
   240  					Domain: "www.test.com",
   241  				},
   242  				Imp: []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}}},
   243  				Ext: json.RawMessage(`{"prebid": { "floors": {"data": {"currency": "USD","skipRate": 0,"schema": {"fields": [ "mediaType", "size", "domain" ] },"values": {  "banner|300x250|www.website.com": 1.01, "banner|300x250|*": 2.01, "banner|300x600|www.website.com": 3.01,  "banner|300x600|*": 4.01, "banner|728x90|www.website.com": 5.01, "banner|728x90|*": 6.01, "banner|*|www.website.com": 7.01, "banner|*|*": 8.01, "*|300x250|www.website.com": 9.01, "*|300x250|*": 10.01, "*|300x600|www.website.com": 11.01,  "*|300x600|*": 12.01,  "*|728x90|www.website.com": 13.01, "*|728x90|*": 14.01,  "*|*|www.website.com": 15.01, "*|*|*": 16.01  }, "default": 1}}}}`),
   244  			},
   245  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "size", "domain"}},
   246  			out:         []string{"banner", "300x250", "www.test.com"},
   247  		},
   248  		{
   249  			name: "CreateRule with video mediatype, size and domain",
   250  			request: &openrtb2.BidRequest{
   251  				Site: &openrtb2.Site{
   252  					Domain: "www.test.com",
   253  				},
   254  				Imp: []openrtb2.Imp{{ID: "1234", Video: &openrtb2.Video{W: 640, H: 480, Placement: 1}}},
   255  			},
   256  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "size", "domain"}},
   257  			out:         []string{"video", "640x480", "www.test.com"},
   258  		},
   259  		{
   260  			name: "CreateRule with video mediatype, size and domain",
   261  			request: &openrtb2.BidRequest{
   262  				Site: &openrtb2.Site{
   263  					Domain: "www.test.com",
   264  				},
   265  				Imp: []openrtb2.Imp{{ID: "1234", Video: &openrtb2.Video{W: 300, H: 250, Placement: 2}}},
   266  			},
   267  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "size", "domain"}},
   268  			out:         []string{"video-outstream", "300x250", "www.test.com"},
   269  		},
   270  		{
   271  			name: "CreateRule with audio mediatype, adUnitCode and domain",
   272  			request: &openrtb2.BidRequest{
   273  				Site: &openrtb2.Site{
   274  					Domain: "www.test.com",
   275  				},
   276  				Imp: []openrtb2.Imp{{ID: "1234", TagID: "tag123", Audio: &openrtb2.Audio{MaxDuration: 300}}},
   277  			},
   278  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "adUnitCode", "siteDomain"}},
   279  			out:         []string{"audio", "tag123", "www.test.com"},
   280  		},
   281  		{
   282  			name: "CreateRule with audio mediatype, adUnitCode=* and domain",
   283  			request: &openrtb2.BidRequest{
   284  				Site: &openrtb2.Site{
   285  					Domain: "www.test.com",
   286  				},
   287  				Imp: []openrtb2.Imp{{ID: "1234", Audio: &openrtb2.Audio{MaxDuration: 300}}},
   288  			},
   289  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "adUnitCode", "siteDomain"}},
   290  			out:         []string{"audio", "*", "www.test.com"},
   291  		},
   292  		{
   293  			name: "CreateRule with native mediatype, bundle and domain",
   294  			request: &openrtb2.BidRequest{
   295  				App: &openrtb2.App{
   296  					Domain: "www.test.com",
   297  					Bundle: "bundle123",
   298  				},
   299  				Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}},
   300  			},
   301  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "bundle", "siteDomain"}},
   302  			out:         []string{"native", "bundle123", "www.test.com"},
   303  		},
   304  		{
   305  			name: "CreateRule with native, banner mediatype, bundle and domain",
   306  			request: &openrtb2.BidRequest{
   307  				App: &openrtb2.App{
   308  					Domain: "www.test.com",
   309  					Bundle: "bundle123",
   310  				},
   311  				Imp: []openrtb2.Imp{{ID: "1234", Audio: &openrtb2.Audio{MaxDuration: 300}, Native: &openrtb2.Native{Request: "Test"}}},
   312  			},
   313  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"mediaType", "bundle", "siteDomain"}},
   314  			out:         []string{"*", "bundle123", "www.test.com"},
   315  		},
   316  		{
   317  			name: "CreateRule with channel, country, deviceType",
   318  			request: &openrtb2.BidRequest{
   319  				App: &openrtb2.App{
   320  					Publisher: &openrtb2.Publisher{
   321  						Domain: "www.test.com",
   322  					},
   323  					Bundle: "bundle123",
   324  				},
   325  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "tablet"},
   326  				Imp:    []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}},
   327  				Ext:    json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`),
   328  			},
   329  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}},
   330  			out:         []string{"chName", "USA", "tablet"},
   331  		},
   332  		{
   333  			name: "CreateRule with channel, country, deviceType=tablet",
   334  			request: &openrtb2.BidRequest{
   335  				App: &openrtb2.App{
   336  					Publisher: &openrtb2.Publisher{
   337  						Domain: "www.test.com",
   338  					},
   339  					Bundle: "bundle123",
   340  				},
   341  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Windows NT touch"},
   342  				Imp:    []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}},
   343  				Ext:    json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`),
   344  			},
   345  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}},
   346  			out:         []string{"chName", "USA", "tablet"},
   347  		},
   348  		{
   349  			name: "CreateRule with channel, country, deviceType=desktop",
   350  			request: &openrtb2.BidRequest{
   351  				App: &openrtb2.App{
   352  					Publisher: &openrtb2.Publisher{
   353  						Domain: "www.test.com",
   354  					},
   355  					Bundle: "bundle123",
   356  				},
   357  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Windows NT"},
   358  				Imp:    []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}},
   359  				Ext:    json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`),
   360  			},
   361  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}},
   362  			out:         []string{"chName", "USA", "desktop"},
   363  		},
   364  		{
   365  			name: "CreateRule with channel, country, deviceType=desktop",
   366  			request: &openrtb2.BidRequest{
   367  				App: &openrtb2.App{
   368  					Publisher: &openrtb2.Publisher{
   369  						Domain: "www.test.com",
   370  					},
   371  					Bundle: "bundle123",
   372  				},
   373  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Windows NT"},
   374  				Imp:    []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}},
   375  				Ext:    json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`),
   376  			},
   377  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "country", "deviceType"}},
   378  			out:         []string{"chName", "USA", "desktop"},
   379  		},
   380  		{
   381  			name: "CreateRule with channel, size, deviceType=desktop",
   382  			request: &openrtb2.BidRequest{
   383  				App: &openrtb2.App{
   384  					Publisher: &openrtb2.Publisher{
   385  						Domain: "www.test.com",
   386  					},
   387  					Bundle: "bundle123",
   388  				},
   389  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "SomeDevice"},
   390  				Imp:    []openrtb2.Imp{{ID: "1234", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 100, H: 200}, {W: 200, H: 300}}}}},
   391  				Ext:    json.RawMessage(`{"prebid": {"test": "1}}`),
   392  			},
   393  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"channel", "size", "deviceType"}},
   394  			out:         []string{"*", "*", "desktop"},
   395  		},
   396  		{
   397  			name: "CreateRule with pubDomain, country, deviceType",
   398  			request: &openrtb2.BidRequest{
   399  				App: &openrtb2.App{
   400  					Publisher: &openrtb2.Publisher{
   401  						Domain: "www.test.com",
   402  					},
   403  					Bundle: "bundle123",
   404  				},
   405  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}, UA: "Phone"},
   406  				Imp:    []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"}}},
   407  				Ext:    json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`),
   408  			},
   409  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"pubDomain", "country", "deviceType"}},
   410  			out:         []string{"www.test.com", "USA", "phone"},
   411  		},
   412  		{
   413  			name: "CreateRule with pubDomain, gptSlot, deviceType",
   414  			request: &openrtb2.BidRequest{
   415  				Site: &openrtb2.Site{
   416  					Publisher: &openrtb2.Publisher{
   417  						Domain: "www.test.com",
   418  					},
   419  				},
   420  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}},
   421  				Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"},
   422  					Ext: json.RawMessage(`{"data": {"adserver": {"name": "gam","adslot": "adslot123"}, "pbadslot": "pbadslot123"}}`),
   423  				}},
   424  				Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`),
   425  			},
   426  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"pubDomain", "gptSlot", "deviceType"}},
   427  			out:         []string{"www.test.com", "adslot123", "*"},
   428  		},
   429  		{
   430  			name: "CreateRule with pubDomain, gptSlot, deviceType",
   431  			request: &openrtb2.BidRequest{
   432  				Site: &openrtb2.Site{
   433  					Publisher: &openrtb2.Publisher{
   434  						Domain: "www.test.com",
   435  					},
   436  				},
   437  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}},
   438  				Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"},
   439  					Ext: json.RawMessage(`{"data": {"adserver": {"name": "test","adslot": "adslot123"}, "pbadslot": "pbadslot123"}}`),
   440  				}},
   441  				Ext: json.RawMessage(`{"prebid": {"channel": {"name": "chName","version": "ver1"}}}`),
   442  			},
   443  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"pubDomain", "gptSlot", "deviceType"}},
   444  			out:         []string{"www.test.com", "pbadslot123", "*"},
   445  		},
   446  		{
   447  			name: "CreateRule with domain, adUnitCode, channel",
   448  			request: &openrtb2.BidRequest{
   449  				App: &openrtb2.App{
   450  					Publisher: &openrtb2.Publisher{
   451  						Domain: "www.test.com",
   452  					},
   453  				},
   454  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}},
   455  				Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"},
   456  					Ext: json.RawMessage(`{"data": {"adserver": {"name": "test","adslot": "adslot123"}, "pbadslot": "pbadslot123"}}`),
   457  				}},
   458  			},
   459  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}},
   460  			out:         []string{"www.test.com", "pbadslot123", "*"},
   461  		},
   462  		{
   463  			name: "CreateRule with domain, adUnitCode, channel",
   464  			request: &openrtb2.BidRequest{
   465  				App: &openrtb2.App{
   466  					Publisher: &openrtb2.Publisher{
   467  						Domain: "www.test.com",
   468  					},
   469  				},
   470  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}},
   471  				Imp: []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{Request: "Test"},
   472  					Ext: json.RawMessage(`{"gpid":  "gpid_134"}`),
   473  				}},
   474  			},
   475  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}},
   476  			out:         []string{"www.test.com", "gpid_134", "*"},
   477  		},
   478  		{
   479  			name: "CreateRule with domain, adUnitCode, channel",
   480  			request: &openrtb2.BidRequest{
   481  				App: &openrtb2.App{
   482  					Publisher: &openrtb2.Publisher{
   483  						Domain: "www.test.com",
   484  					},
   485  				},
   486  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}},
   487  				Imp:    []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{}, Ext: json.RawMessage(`{"prebid": {"storedrequest": {"id": "storedid_123"}}}`)}},
   488  			},
   489  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}},
   490  			out:         []string{"www.test.com", "storedid_123", "*"},
   491  		},
   492  		{
   493  			name: "CreateRule with domain, adUnitCode, channel",
   494  			request: &openrtb2.BidRequest{
   495  				App: &openrtb2.App{
   496  					Publisher: &openrtb2.Publisher{
   497  						Domain: "www.test.com",
   498  					},
   499  				},
   500  				Device: &openrtb2.Device{Geo: &openrtb2.Geo{Country: "USA"}},
   501  				Imp:    []openrtb2.Imp{{ID: "1234", Native: &openrtb2.Native{}, Ext: json.RawMessage(`{"prebid": {"storedrequest": {"id": "storedid_123"}}}`)}},
   502  			},
   503  			floorSchema: openrtb_ext.PriceFloorSchema{Delimiter: "|", Fields: []string{"domain", "adUnitCode", "channel"}},
   504  			out:         []string{"www.test.com", "storedid_123", "*"},
   505  		},
   506  	}
   507  	for _, tc := range testCases {
   508  		t.Run(tc.name, func(t *testing.T) {
   509  			out := createRuleKey(tc.floorSchema, &openrtb_ext.RequestWrapper{BidRequest: tc.request}, &openrtb_ext.ImpWrapper{Imp: &tc.request.Imp[0]})
   510  			assert.Equal(t, out, tc.out, tc.name)
   511  		})
   512  	}
   513  }
   514  
   515  func TestShouldSkipFloors(t *testing.T) {
   516  
   517  	testCases := []struct {
   518  		name                string
   519  		ModelGroupsSkipRate int
   520  		DataSkipRate        int
   521  		RootSkipRate        int
   522  		out                 bool
   523  		randomGen           func(int) int
   524  	}{
   525  		{
   526  			name:                "ModelGroupsSkipRate=10 with skip = true",
   527  			ModelGroupsSkipRate: 10,
   528  			DataSkipRate:        0,
   529  			RootSkipRate:        0,
   530  			randomGen:           func(i int) int { return 5 },
   531  			out:                 true,
   532  		},
   533  		{
   534  			name:                "ModelGroupsSkipRate=100 with skip = true",
   535  			ModelGroupsSkipRate: 100,
   536  			DataSkipRate:        0,
   537  			RootSkipRate:        0,
   538  			randomGen:           func(i int) int { return 5 },
   539  			out:                 true,
   540  		},
   541  		{
   542  			name:                "ModelGroupsSkipRate=0 with skip = false",
   543  			ModelGroupsSkipRate: 0,
   544  			DataSkipRate:        0,
   545  			RootSkipRate:        0,
   546  			randomGen:           func(i int) int { return 0 },
   547  			out:                 false,
   548  		},
   549  		{
   550  			name:                "DataSkipRate=50  with with skip = true",
   551  			ModelGroupsSkipRate: 0,
   552  			DataSkipRate:        50,
   553  			RootSkipRate:        0,
   554  			randomGen:           func(i int) int { return 40 },
   555  			out:                 true,
   556  		},
   557  		{
   558  			name:                "RootSkipRate=50  with with skip = true",
   559  			ModelGroupsSkipRate: 0,
   560  			DataSkipRate:        0,
   561  			RootSkipRate:        60,
   562  			randomGen:           func(i int) int { return 40 },
   563  			out:                 true,
   564  		},
   565  		{
   566  			name:                "RootSkipRate=50  with with skip = false",
   567  			ModelGroupsSkipRate: 0,
   568  			DataSkipRate:        0,
   569  			RootSkipRate:        60,
   570  			randomGen:           func(i int) int { return 70 },
   571  			out:                 false,
   572  		},
   573  		{
   574  			name:                "RootSkipRate=100  with with skip = true",
   575  			ModelGroupsSkipRate: 0,
   576  			DataSkipRate:        0,
   577  			RootSkipRate:        100,
   578  			randomGen:           func(i int) int { return 100 },
   579  			out:                 true,
   580  		},
   581  	}
   582  	for _, tc := range testCases {
   583  		t.Run(tc.name, func(t *testing.T) {
   584  			out := shouldSkipFloors(tc.ModelGroupsSkipRate, tc.DataSkipRate, tc.RootSkipRate, tc.randomGen)
   585  			assert.Equal(t, out, tc.out, tc.name)
   586  		})
   587  	}
   588  
   589  }
   590  
   591  func TestSelectFloorModelGroup(t *testing.T) {
   592  	weightNilModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: nil}
   593  	weight01ModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: getIntPtr(1)}
   594  	weight25ModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: getIntPtr(25)}
   595  	weight50ModelGroup := openrtb_ext.PriceFloorModelGroup{ModelWeight: getIntPtr(50)}
   596  
   597  	testCases := []struct {
   598  		name               string
   599  		ModelGroup         []openrtb_ext.PriceFloorModelGroup
   600  		fn                 func(int) int
   601  		expectedModelGroup []openrtb_ext.PriceFloorModelGroup
   602  	}{
   603  		{
   604  			name: "ModelGroup with default weight selection",
   605  			ModelGroup: []openrtb_ext.PriceFloorModelGroup{
   606  				weightNilModelGroup,
   607  			},
   608  			fn: func(i int) int { return 0 },
   609  			expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{
   610  				weight01ModelGroup,
   611  			},
   612  		},
   613  		{
   614  			name: "ModelGroup with weight = 25 selection",
   615  			ModelGroup: []openrtb_ext.PriceFloorModelGroup{
   616  				weight25ModelGroup,
   617  				weight50ModelGroup,
   618  			},
   619  			fn: func(i int) int { return 5 },
   620  			expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{
   621  				weight25ModelGroup,
   622  			},
   623  		},
   624  		{
   625  			name: "ModelGroup with weight = 50 selection",
   626  			ModelGroup: []openrtb_ext.PriceFloorModelGroup{
   627  				weight50ModelGroup,
   628  			},
   629  			fn: func(i int) int { return 55 },
   630  			expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{
   631  				weight50ModelGroup,
   632  			},
   633  		},
   634  		{
   635  			name: "ModelGroup with weight = 25 selection",
   636  			ModelGroup: []openrtb_ext.PriceFloorModelGroup{
   637  				weight25ModelGroup,
   638  				weight50ModelGroup,
   639  			},
   640  			fn: func(i int) int { return 80 },
   641  			expectedModelGroup: []openrtb_ext.PriceFloorModelGroup{
   642  				weight25ModelGroup,
   643  			},
   644  		},
   645  	}
   646  
   647  	for _, tc := range testCases {
   648  		t.Run(tc.name, func(t *testing.T) {
   649  			resp := selectFloorModelGroup(tc.ModelGroup, tc.fn)
   650  			assert.Equal(t, resp, tc.expectedModelGroup)
   651  		})
   652  	}
   653  }
   654  
   655  func TestGetMinFloorValue(t *testing.T) {
   656  	rates := map[string]map[string]float64{
   657  		"USD": {
   658  			"INR": 81.17,
   659  		},
   660  	}
   661  
   662  	type args struct {
   663  		floorExt    *openrtb_ext.PriceFloorRules
   664  		imp         openrtb2.Imp
   665  		conversions currency.Conversions
   666  	}
   667  	testCases := []struct {
   668  		name    string
   669  		args    args
   670  		want    float64
   671  		want1   string
   672  		wantErr error
   673  	}{
   674  		{
   675  			name: "Floor min is available in imp and floor ext",
   676  			args: args{
   677  				floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 2.0, FloorMinCur: "INR", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}},
   678  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "INR","floorMin":1.0}}}`)},
   679  			},
   680  			want:  1,
   681  			want1: "INR",
   682  		},
   683  		{
   684  			name: "Floor min and floor min currency is available in imp ext only",
   685  			args: args{
   686  				floorExt: &openrtb_ext.PriceFloorRules{},
   687  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "INR", "floorMin": 1.0}}}`)},
   688  			},
   689  			want:  0.0123,
   690  			want1: "USD",
   691  		},
   692  		{
   693  			name: "Floor min is available in floor ext only",
   694  			args: args{
   695  				floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 1.0, FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{Currency: "EUR"}},
   696  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{}}}`)},
   697  			},
   698  			want:  1.0,
   699  			want1: "EUR",
   700  		},
   701  		{
   702  			name: "Floor min is available in floorExt and currency is available in imp",
   703  			args: args{
   704  				floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 2.0, Data: &openrtb_ext.PriceFloorData{Currency: "INR"}},
   705  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "INR"}}}`)},
   706  			},
   707  			want:  2,
   708  			want1: "INR",
   709  		},
   710  		{
   711  			name: "Floor min is available in ImpExt and currency is available in floorExt",
   712  			args: args{
   713  				floorExt: &openrtb_ext.PriceFloorRules{FloorMinCur: "USD", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}},
   714  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"FloorMin": 2.0}}}`)},
   715  			},
   716  			want:  162.34,
   717  			want1: "INR",
   718  		},
   719  		{
   720  			name: "Floor Min and floor Currency are in Imp and only floor currency is available in floor ext",
   721  			args: args{
   722  				floorExt: &openrtb_ext.PriceFloorRules{FloorMinCur: "USD"},
   723  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "USD","floorMin":1.0}}}`)},
   724  			},
   725  			want:  1,
   726  			want1: "USD",
   727  		},
   728  		{
   729  			name: "Currency are different in floor ext and imp",
   730  			args: args{
   731  				floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 0.0, FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}},
   732  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "USD","floorMin":1.0}}}`)},
   733  			},
   734  			want:  81.17,
   735  			want1: "INR",
   736  		},
   737  		{
   738  			name: "Floor min is 0 in imp ",
   739  			args: args{
   740  				floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 2.0, FloorMinCur: "JPY", Data: &openrtb_ext.PriceFloorData{Currency: "INR"}},
   741  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "USD","floorMin":0.0}}}`)},
   742  			},
   743  			want:  162.34,
   744  			want1: "INR",
   745  		},
   746  		{
   747  			name: "Floor Currency is empty in imp",
   748  			args: args{
   749  				floorExt: &openrtb_ext.PriceFloorRules{FloorMin: 1.0, FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{Currency: "EUR"}},
   750  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{"prebid":{"floors":{"floorMinCur": "","floorMin":-1.0}}}`)},
   751  			},
   752  			want:  1.0,
   753  			want1: "EUR",
   754  		},
   755  		{
   756  			name: "Invalid input",
   757  			args: args{
   758  				floorExt: &openrtb_ext.PriceFloorRules{FloorMinCur: "EUR", Data: &openrtb_ext.PriceFloorData{}},
   759  				imp:      openrtb2.Imp{Ext: json.RawMessage(`{`)},
   760  			},
   761  			want:    0.0,
   762  			want1:   "",
   763  			wantErr: errors.New("Error in getting FloorMin value : 'unexpected end of JSON input'"),
   764  		},
   765  	}
   766  	for _, tc := range testCases {
   767  		t.Run(tc.name, func(t *testing.T) {
   768  			got, got1, err := getMinFloorValue(tc.args.floorExt, &openrtb_ext.ImpWrapper{Imp: &tc.args.imp}, getCurrencyRates(rates))
   769  			assert.Equal(t, tc.wantErr, err, tc.name)
   770  			assert.Equal(t, tc.want, got, tc.name)
   771  			assert.Equal(t, tc.want1, got1, tc.name)
   772  		})
   773  	}
   774  }
   775  
   776  func TestSortCombinations(t *testing.T) {
   777  	type args struct {
   778  		comb            [][]int
   779  		numSchemaFields int
   780  	}
   781  	tests := []struct {
   782  		name    string
   783  		args    args
   784  		expComb [][]int
   785  	}{
   786  		{
   787  			name: "With schema fields = 3",
   788  			args: args{
   789  				comb:            [][]int{{0}, {1}, {2}},
   790  				numSchemaFields: 3,
   791  			},
   792  			expComb: [][]int{{2}, {1}, {0}},
   793  		},
   794  		{
   795  			name: "With schema fields = 3",
   796  			args: args{
   797  				comb:            [][]int{{0, 1}, {1, 2}, {0, 2}},
   798  				numSchemaFields: 3,
   799  			},
   800  			expComb: [][]int{{1, 2}, {0, 2}, {0, 1}},
   801  		},
   802  		{
   803  			name: "With schema fields = 4",
   804  			args: args{
   805  				comb:            [][]int{{0, 1, 2}, {1, 2, 3}, {0, 2, 3}, {0, 1, 3}},
   806  				numSchemaFields: 3,
   807  			},
   808  			expComb: [][]int{{1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2}},
   809  		},
   810  	}
   811  	for _, tt := range tests {
   812  		t.Run(tt.name, func(t *testing.T) {
   813  			sortCombinations(tt.args.comb, tt.args.numSchemaFields)
   814  			assert.Equal(t, tt.expComb, tt.args.comb)
   815  		})
   816  	}
   817  }
   818  
   819  func TestGenerateCombinations(t *testing.T) {
   820  
   821  	tests := []struct {
   822  		name            string
   823  		numSchemaFields int
   824  		numWildCard     int
   825  		expComb         [][]int
   826  	}{
   827  		{
   828  			name:            "With schema fields = 3, wildcard = 1",
   829  			numSchemaFields: 3,
   830  			numWildCard:     1,
   831  			expComb:         [][]int{{0}, {1}, {2}},
   832  		},
   833  		{
   834  			name:            "With schema fields = 3, wildcard = 2",
   835  			numSchemaFields: 3,
   836  			numWildCard:     2,
   837  			expComb:         [][]int{{0, 1}, {0, 2}, {1, 2}},
   838  		},
   839  		{
   840  			name:            "With schema fields = 3, wildcard = 3",
   841  			numSchemaFields: 3,
   842  			numWildCard:     3,
   843  			expComb:         [][]int{{0, 1, 2}},
   844  		},
   845  	}
   846  	for _, tt := range tests {
   847  		t.Run(tt.name, func(t *testing.T) {
   848  			gotComb := generateCombinations(tt.numSchemaFields, tt.numWildCard)
   849  			assert.Equal(t, tt.expComb, gotComb)
   850  		})
   851  	}
   852  }
   853  
   854  func TestGetDeviceType(t *testing.T) {
   855  	tests := []struct {
   856  		name    string
   857  		request *openrtb2.BidRequest
   858  		want    string
   859  	}{
   860  		{
   861  			name:    "user agent contains Phone",
   862  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Phone Samsung Mobile; Win64; x64)"}},
   863  			want:    "phone",
   864  		},
   865  		{
   866  			name:    "user agent contains iPhone",
   867  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Safari(iPhone Apple Mobile)"}},
   868  			want:    "phone",
   869  		},
   870  		{
   871  			name:    "user agent contains Mobile.*Android",
   872  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Mobile Android; Win64; x64)"}},
   873  			want:    "phone",
   874  		},
   875  		{
   876  			name:    "user agent contains Android.*Mobile",
   877  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Android Redmi Mobile; Win64; x64)"}},
   878  			want:    "phone",
   879  		},
   880  		{
   881  			name:    "user agent contains Mobile.*Android",
   882  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Mobile pixel Android; Win64; x64)"}},
   883  			want:    "phone",
   884  		},
   885  		{
   886  			name:    "user agent contains Windows NT touch",
   887  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Windows NT touch 10.0; Win64; x64)"}},
   888  			want:    "tablet",
   889  		},
   890  		{
   891  			name:    "user agent contains ipad",
   892  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (ipad 13.10; Win64; x64)"}},
   893  			want:    "tablet",
   894  		},
   895  		{
   896  			name:    "user agent contains Window NT.*touch",
   897  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Win64; x64; Trident/6.0; Touch)"}},
   898  			want:    "tablet",
   899  		},
   900  		{
   901  			name:    "user agent contains touch.* Window NT",
   902  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (touch realme Windows NT Win64; x64)"}},
   903  			want:    "tablet",
   904  		},
   905  		{
   906  			name:    "user agent contains Android",
   907  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Android; Win64; x64)"}},
   908  			want:    "tablet",
   909  		},
   910  		{
   911  			name:    "user agent not matching phone or tablet",
   912  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{UA: "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"}},
   913  			want:    "desktop",
   914  		},
   915  		{
   916  			name:    "empty user agent",
   917  			request: &openrtb2.BidRequest{Device: &openrtb2.Device{}},
   918  			want:    "*",
   919  		},
   920  	}
   921  	for _, tt := range tests {
   922  		t.Run(tt.name, func(t *testing.T) {
   923  			got := getDeviceType(&openrtb_ext.RequestWrapper{BidRequest: tt.request})
   924  			assert.Equal(t, tt.want, got)
   925  		})
   926  	}
   927  }
   928  
   929  func TestGetAdUnitCode(t *testing.T) {
   930  	tests := []struct {
   931  		name string
   932  		imp  *openrtb_ext.ImpWrapper
   933  		want string
   934  	}{
   935  		{
   936  			name: "imp.ext.gpid",
   937  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"gpid":"test_gpid"}`)}},
   938  			want: "test_gpid",
   939  		},
   940  		{
   941  			name: "imp.TagID",
   942  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{TagID: "tag_1"}},
   943  			want: "tag_1",
   944  		},
   945  		{
   946  			name: "imp.ext.data.pbadslot",
   947  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"data":{"pbadslot":"pbslot_1"}}`)}},
   948  			want: "pbslot_1",
   949  		},
   950  		{
   951  			name: "imp.ext.prebid.storedrequest.id",
   952  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"prebid": {"storedrequest":{"id":"123"}}}`)}},
   953  			want: "123",
   954  		},
   955  		{
   956  			name: "empty adUnitCode",
   957  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{}},
   958  			want: "*",
   959  		},
   960  	}
   961  
   962  	for _, tt := range tests {
   963  		t.Run(tt.name, func(t *testing.T) {
   964  			got := getAdUnitCode(tt.imp)
   965  			assert.Equal(t, tt.want, got)
   966  		})
   967  	}
   968  }
   969  
   970  func TestGetGptSlot(t *testing.T) {
   971  	tests := []struct {
   972  		name string
   973  		imp  *openrtb_ext.ImpWrapper
   974  		want string
   975  	}{
   976  		{
   977  			name: "imp.ext.data.adserver.adslot",
   978  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"data":{"adserver": {"name": "gam", "adslot": "slot_1"}}}`)}},
   979  			want: "slot_1",
   980  		},
   981  		{
   982  			name: "gptSlot = imp.ext.data.pbadslot",
   983  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{Ext: json.RawMessage(`{"data":{"pbadslot":"pbslot_1"}}`)}},
   984  			want: "pbslot_1",
   985  		},
   986  		{
   987  			name: "empty gptSlot",
   988  			imp:  &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{}},
   989  			want: "*",
   990  		},
   991  	}
   992  	for _, tt := range tests {
   993  		t.Run(tt.name, func(t *testing.T) {
   994  			got := getGptSlot(tt.imp)
   995  			assert.Equal(t, tt.want, got)
   996  		})
   997  	}
   998  }
   999  
  1000  func TestGetSizeValue(t *testing.T) {
  1001  	tests := []struct {
  1002  		name string
  1003  		imp  *openrtb2.Imp
  1004  		want string
  1005  	}{
  1006  		{
  1007  			name: "banner: only one size exists in imp.banner.format",
  1008  			imp:  &openrtb2.Imp{Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}},
  1009  			want: "300x250",
  1010  		},
  1011  		{
  1012  			name: "banner: no imp.banner.format",
  1013  			imp:  &openrtb2.Imp{Banner: &openrtb2.Banner{W: getInt64Ptr(320), H: getInt64Ptr(240)}},
  1014  			want: "320x240",
  1015  		},
  1016  		{
  1017  			name: "video:  imp.video.w and  imp.video.h present",
  1018  			imp:  &openrtb2.Imp{Video: &openrtb2.Video{W: 120, H: 240}},
  1019  			want: "120x240",
  1020  		},
  1021  		{
  1022  			name: "banner: more than one size exists in imp.banner.format",
  1023  			imp:  &openrtb2.Imp{Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}, {W: 200, H: 300}}}},
  1024  			want: "*",
  1025  		},
  1026  		{
  1027  			name: "Audo creative",
  1028  			imp:  &openrtb2.Imp{Audio: &openrtb2.Audio{}},
  1029  			want: "*",
  1030  		},
  1031  	}
  1032  	for _, tt := range tests {
  1033  		t.Run(tt.name, func(t *testing.T) {
  1034  			got := getSizeValue(tt.imp)
  1035  			assert.Equal(t, tt.want, got)
  1036  		})
  1037  	}
  1038  }
  1039  
  1040  func TestGetMediaType(t *testing.T) {
  1041  	tests := []struct {
  1042  		name string
  1043  		imp  *openrtb2.Imp
  1044  		want string
  1045  	}{
  1046  		{
  1047  			name: "more than one of these: imp.banner, imp.video, imp.native, imp.audio present",
  1048  			imp:  &openrtb2.Imp{Video: &openrtb2.Video{W: 120, H: 240}, Banner: &openrtb2.Banner{W: getInt64Ptr(320), H: getInt64Ptr(240)}},
  1049  			want: "*",
  1050  		},
  1051  		{
  1052  			name: "only banner present",
  1053  			imp:  &openrtb2.Imp{Banner: &openrtb2.Banner{W: getInt64Ptr(320), H: getInt64Ptr(240)}},
  1054  			want: "banner",
  1055  		},
  1056  		{
  1057  			name: "video-outstream present",
  1058  			imp:  &openrtb2.Imp{Video: &openrtb2.Video{W: 120, H: 240, Placement: 2}},
  1059  			want: "video-outstream",
  1060  		},
  1061  		{
  1062  			name: "video-instream present",
  1063  			imp:  &openrtb2.Imp{Video: &openrtb2.Video{W: 120, H: 240, Placement: 1}},
  1064  			want: "video",
  1065  		},
  1066  		{
  1067  			name: "only audio",
  1068  			imp:  &openrtb2.Imp{Audio: &openrtb2.Audio{MinDuration: 10}},
  1069  			want: "audio",
  1070  		},
  1071  		{
  1072  			name: "only native",
  1073  			imp:  &openrtb2.Imp{Native: &openrtb2.Native{Request: "test_req"}},
  1074  			want: "native",
  1075  		},
  1076  	}
  1077  
  1078  	for _, tt := range tests {
  1079  		t.Run(tt.name, func(t *testing.T) {
  1080  			got := getMediaType(tt.imp)
  1081  			assert.Equal(t, tt.want, got)
  1082  		})
  1083  	}
  1084  }
  1085  
  1086  func TestGetSiteDomain(t *testing.T) {
  1087  	type args struct {
  1088  		request *openrtb_ext.RequestWrapper
  1089  	}
  1090  	tests := []struct {
  1091  		name    string
  1092  		request *openrtb_ext.RequestWrapper
  1093  		want    string
  1094  	}{
  1095  		{
  1096  			name:    "Site Domain present",
  1097  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Domain: "abc.xyz.com"}}},
  1098  			want:    "abc.xyz.com",
  1099  		},
  1100  		{
  1101  			name:    "Site Domain not present",
  1102  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{}}},
  1103  			want:    "*",
  1104  		},
  1105  		{
  1106  			name:    "App Domain present",
  1107  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Domain: "cde.rtu.com"}}},
  1108  			want:    "cde.rtu.com",
  1109  		},
  1110  		{
  1111  			name:    "App Domain not present",
  1112  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}}},
  1113  			want:    "*",
  1114  		},
  1115  	}
  1116  	for _, tt := range tests {
  1117  		t.Run(tt.name, func(t *testing.T) {
  1118  			got := getSiteDomain(tt.request)
  1119  			assert.Equal(t, tt.want, got)
  1120  		})
  1121  	}
  1122  }
  1123  
  1124  func TestGetPublisherDomain(t *testing.T) {
  1125  	type args struct {
  1126  	}
  1127  	tests := []struct {
  1128  		name    string
  1129  		request *openrtb_ext.RequestWrapper
  1130  		want    string
  1131  	}{
  1132  		{
  1133  			name:    "Site publisher domain present",
  1134  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{Domain: "qwe.xyz.com"}}}},
  1135  			want:    "qwe.xyz.com",
  1136  		},
  1137  		{
  1138  			name:    "Site publisher domain not present",
  1139  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{}}}},
  1140  			want:    "*",
  1141  		},
  1142  		{
  1143  			name:    "App publisher domain present",
  1144  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Publisher: &openrtb2.Publisher{Domain: "xyz.com"}}}},
  1145  			want:    "xyz.com",
  1146  		},
  1147  		{
  1148  			name:    "App publisher domain not present",
  1149  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}}},
  1150  			want:    "*",
  1151  		},
  1152  	}
  1153  	for _, tt := range tests {
  1154  		t.Run(tt.name, func(t *testing.T) {
  1155  			got := getPublisherDomain(tt.request)
  1156  			assert.Equal(t, tt.want, got)
  1157  		})
  1158  	}
  1159  }
  1160  
  1161  func TestGetDomain(t *testing.T) {
  1162  	type args struct {
  1163  	}
  1164  	tests := []struct {
  1165  		name    string
  1166  		request *openrtb_ext.RequestWrapper
  1167  		want    string
  1168  	}{
  1169  		{
  1170  			name:    "Site domain present",
  1171  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Domain: "qwe.xyz.com", Publisher: &openrtb2.Publisher{Domain: "abc.xyz.com"}}}},
  1172  			want:    "qwe.xyz.com",
  1173  		},
  1174  		{
  1175  			name:    "Site publisher domain present",
  1176  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{Domain: "abc.xyz.com"}}}},
  1177  			want:    "abc.xyz.com",
  1178  		},
  1179  		{
  1180  			name:    "Site domain not present",
  1181  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{Site: &openrtb2.Site{Publisher: &openrtb2.Publisher{}}}},
  1182  			want:    "*",
  1183  		},
  1184  		{
  1185  			name:    "App publisher domain present",
  1186  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Domain: "abc.com", Publisher: &openrtb2.Publisher{Domain: "xyz.com"}}}},
  1187  			want:    "abc.com",
  1188  		},
  1189  		{
  1190  			name:    "App domain present",
  1191  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{Publisher: &openrtb2.Publisher{Domain: "xyz.com"}}}},
  1192  			want:    "xyz.com",
  1193  		},
  1194  		{
  1195  			name:    "App domain not present",
  1196  			request: &openrtb_ext.RequestWrapper{BidRequest: &openrtb2.BidRequest{App: &openrtb2.App{}}},
  1197  			want:    "*",
  1198  		},
  1199  	}
  1200  	for _, tt := range tests {
  1201  		t.Run(tt.name, func(t *testing.T) {
  1202  			got := getDomain(tt.request)
  1203  			assert.Equal(t, tt.want, got)
  1204  		})
  1205  	}
  1206  }
  1207  
  1208  func getIntPtr(v int) *int {
  1209  	return &v
  1210  }
  1211  
  1212  func getInt64Ptr(v int64) *int64 {
  1213  	return &v
  1214  }