github.com/prebid/prebid-server/v2@v2.18.0/floors/enforce_test.go (about)

     1  package floors
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"reflect"
     7  	"testing"
     8  
     9  	"github.com/prebid/openrtb/v20/openrtb2"
    10  	"github.com/prebid/prebid-server/v2/config"
    11  	"github.com/prebid/prebid-server/v2/currency"
    12  	"github.com/prebid/prebid-server/v2/exchange/entities"
    13  	"github.com/prebid/prebid-server/v2/openrtb_ext"
    14  	"github.com/prebid/prebid-server/v2/util/ptrutil"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  type convert struct {
    19  }
    20  
    21  func (c convert) GetRate(from string, to string) (float64, error) {
    22  	if from == to {
    23  		return 1, nil
    24  	}
    25  
    26  	if from == "USD" && to == "INR" {
    27  		return 77.59, nil
    28  	} else if from == "INR" && to == "USD" {
    29  		return 0.013, nil
    30  	}
    31  	return 0, errors.New("currency conversion not supported")
    32  }
    33  
    34  func (c convert) GetRates() *map[string]map[string]float64 {
    35  	return &map[string]map[string]float64{}
    36  }
    37  
    38  func TestIsValidImpBidfloorPresentInRequest(t *testing.T) {
    39  
    40  	tests := []struct {
    41  		name string
    42  		imp  []openrtb2.Imp
    43  		want bool
    44  	}{
    45  		{
    46  			imp:  []openrtb2.Imp{{ID: "1234"}},
    47  			want: false,
    48  		},
    49  		{
    50  			imp:  []openrtb2.Imp{{ID: "1234", BidFloor: 10, BidFloorCur: "USD"}},
    51  			want: true,
    52  		},
    53  	}
    54  
    55  	for _, tt := range tests {
    56  		got := isValidImpBidFloorPresent(tt.imp)
    57  		assert.Equal(t, tt.want, got, tt.name)
    58  	}
    59  }
    60  
    61  func TestEnforceFloorToBids(t *testing.T) {
    62  	type args struct {
    63  		bidRequestWrapper *openrtb_ext.RequestWrapper
    64  		seatBids          map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid
    65  		conversions       currency.Conversions
    66  		enforceDealFloors bool
    67  	}
    68  	tests := []struct {
    69  		name            string
    70  		args            args
    71  		expEligibleBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid
    72  		expErrs         []error
    73  		expRejectedBids []*entities.PbsOrtbSeatBid
    74  	}{
    75  		{
    76  			name: "Floors enforcement disabled using enforcepbs = false",
    77  			args: args{
    78  				bidRequestWrapper: func() *openrtb_ext.RequestWrapper {
    79  					bw := openrtb_ext.RequestWrapper{
    80  						BidRequest: &openrtb2.BidRequest{
    81  							ID: "some-request-id",
    82  							Imp: []openrtb2.Imp{
    83  								{ID: "some-impression-id-1", BidFloor: 1.01, BidFloorCur: "USD"},
    84  								{ID: "some-impression-id-2", BidFloor: 2.01, BidFloorCur: "USD"},
    85  							},
    86  							Ext: json.RawMessage(`{"prebid":{"floors":{"enforcement":{"enforcepbs":false}}}}`),
    87  						},
    88  					}
    89  					bw.RebuildRequest()
    90  					return &bw
    91  				}(),
    92  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
    93  					"pubmatic": {
    94  						Bids: []*entities.PbsOrtbBid{
    95  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
    96  							{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
    97  						},
    98  						Seat:     "pubmatic",
    99  						Currency: "USD",
   100  					},
   101  					"appnexus": {
   102  						Bids: []*entities.PbsOrtbBid{
   103  							{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, ImpID: "some-impression-id-1"}},
   104  							{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   105  						},
   106  						Seat:     "appnexus",
   107  						Currency: "USD",
   108  					},
   109  				},
   110  				conversions:       currency.Conversions(convert{}),
   111  				enforceDealFloors: false,
   112  			},
   113  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   114  				"pubmatic": {
   115  					Bids: []*entities.PbsOrtbBid{
   116  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   117  						{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
   118  					},
   119  					Seat:     "pubmatic",
   120  					Currency: "USD",
   121  				},
   122  				"appnexus": {
   123  					Bids: []*entities.PbsOrtbBid{
   124  						{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, ImpID: "some-impression-id-1"}},
   125  						{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   126  					},
   127  					Seat:     "appnexus",
   128  					Currency: "USD",
   129  				},
   130  			},
   131  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   132  			expErrs:         []error{},
   133  		},
   134  		{
   135  			name: "Bids with price less than bidfloor",
   136  			args: args{
   137  				bidRequestWrapper: func() *openrtb_ext.RequestWrapper {
   138  					bw := openrtb_ext.RequestWrapper{
   139  						BidRequest: &openrtb2.BidRequest{
   140  							ID: "some-request-id",
   141  							Imp: []openrtb2.Imp{
   142  								{ID: "some-impression-id-1", BidFloor: 1.01, BidFloorCur: "USD"},
   143  								{ID: "some-impression-id-2", BidFloor: 2.01, BidFloorCur: "USD"},
   144  							},
   145  						},
   146  					}
   147  					bw.RebuildRequest()
   148  					return &bw
   149  				}(),
   150  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   151  					"pubmatic": {
   152  						Bids: []*entities.PbsOrtbBid{
   153  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   154  							{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
   155  						},
   156  						Seat:     "pubmatic",
   157  						Currency: "USD",
   158  					},
   159  					"appnexus": {
   160  						Bids: []*entities.PbsOrtbBid{
   161  							{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, ImpID: "some-impression-id-1"}},
   162  							{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   163  						},
   164  						Seat:     "appnexus",
   165  						Currency: "USD",
   166  					},
   167  				},
   168  				conversions:       currency.Conversions(convert{}),
   169  				enforceDealFloors: false,
   170  			},
   171  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   172  				"pubmatic": {
   173  					Bids: []*entities.PbsOrtbBid{
   174  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   175  						{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
   176  					},
   177  					Seat:     "pubmatic",
   178  					Currency: "USD",
   179  				},
   180  				"appnexus": {
   181  					Bids: []*entities.PbsOrtbBid{
   182  						{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   183  					},
   184  					Seat:     "appnexus",
   185  					Currency: "USD",
   186  				},
   187  			},
   188  			expRejectedBids: []*entities.PbsOrtbSeatBid{
   189  				{
   190  					Seat:     "appnexus",
   191  					Currency: "USD",
   192  					Bids: []*entities.PbsOrtbBid{
   193  						{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, ImpID: "some-impression-id-1"}},
   194  					},
   195  				},
   196  			},
   197  			expErrs: []error{},
   198  		},
   199  		{
   200  			name: "Bids with price less than bidfloor with floorsPrecision",
   201  			args: args{
   202  				bidRequestWrapper: func() *openrtb_ext.RequestWrapper {
   203  					bw := openrtb_ext.RequestWrapper{
   204  						BidRequest: &openrtb2.BidRequest{
   205  							ID: "some-request-id",
   206  							Imp: []openrtb2.Imp{
   207  								{ID: "some-impression-id-1", BidFloor: 1, BidFloorCur: "USD"},
   208  								{ID: "some-impression-id-2", BidFloor: 2, BidFloorCur: "USD"},
   209  							},
   210  						},
   211  					}
   212  					bw.RebuildRequest()
   213  					return &bw
   214  				}(),
   215  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   216  					"pubmatic": {
   217  						Bids: []*entities.PbsOrtbBid{
   218  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 0.998, ImpID: "some-impression-id-1"}},
   219  							{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
   220  						},
   221  						Seat:     "pubmatic",
   222  						Currency: "USD",
   223  					},
   224  					"appnexus": {
   225  						Bids: []*entities.PbsOrtbBid{
   226  							{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.8, ImpID: "some-impression-id-1"}},
   227  							{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   228  						},
   229  						Seat:     "appnexus",
   230  						Currency: "USD",
   231  					},
   232  				},
   233  				conversions:       currency.Conversions(convert{}),
   234  				enforceDealFloors: false,
   235  			},
   236  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   237  				"pubmatic": {
   238  					Bids: []*entities.PbsOrtbBid{
   239  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 0.998, ImpID: "some-impression-id-1"}},
   240  						{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
   241  					},
   242  					Seat:     "pubmatic",
   243  					Currency: "USD",
   244  				},
   245  				"appnexus": {
   246  					Bids: []*entities.PbsOrtbBid{
   247  						{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   248  					},
   249  					Seat:     "appnexus",
   250  					Currency: "USD",
   251  				},
   252  			},
   253  			expRejectedBids: []*entities.PbsOrtbSeatBid{
   254  				{
   255  					Seat:     "appnexus",
   256  					Currency: "USD",
   257  					Bids: []*entities.PbsOrtbBid{
   258  						{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.8, ImpID: "some-impression-id-1"}},
   259  					},
   260  				},
   261  			},
   262  			expErrs: []error{},
   263  		},
   264  		{
   265  			name: "Bids with different currency with enforceDealFloor true",
   266  			args: args{
   267  				bidRequestWrapper: func() *openrtb_ext.RequestWrapper {
   268  					bw := openrtb_ext.RequestWrapper{
   269  						BidRequest: &openrtb2.BidRequest{
   270  							ID: "some-request-id",
   271  							Imp: []openrtb2.Imp{
   272  								{ID: "some-impression-id-1", BidFloor: 60, BidFloorCur: "INR"},
   273  								{ID: "some-impression-id-2", BidFloor: 100, BidFloorCur: "INR"},
   274  							},
   275  						},
   276  					}
   277  					bw.RebuildRequest()
   278  					return &bw
   279  				}(),
   280  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   281  					"pubmatic": {
   282  						Bids: []*entities.PbsOrtbBid{
   283  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   284  							{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
   285  						},
   286  						Seat:     "pubmatic",
   287  						Currency: "USD",
   288  					},
   289  					"appnexus": {
   290  						Bids: []*entities.PbsOrtbBid{
   291  							{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, ImpID: "some-impression-id-1"}},
   292  							{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   293  						},
   294  						Seat:     "appnexus",
   295  						Currency: "USD",
   296  					},
   297  				},
   298  				conversions:       currency.Conversions(convert{}),
   299  				enforceDealFloors: true,
   300  			},
   301  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   302  				"pubmatic": {
   303  					Bids: []*entities.PbsOrtbBid{
   304  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   305  						{Bid: &openrtb2.Bid{ID: "some-bid-2", Price: 1.5, DealID: "deal_Id", ImpID: "some-impression-id-2"}},
   306  					},
   307  					Seat:     "pubmatic",
   308  					Currency: "USD",
   309  				},
   310  				"appnexus": {
   311  					Bids: []*entities.PbsOrtbBid{
   312  						{Bid: &openrtb2.Bid{ID: "some-bid-12", Price: 2.2, ImpID: "some-impression-id-2"}},
   313  					},
   314  					Seat:     "appnexus",
   315  					Currency: "USD",
   316  				},
   317  			},
   318  			expRejectedBids: []*entities.PbsOrtbSeatBid{
   319  				{
   320  					Seat:     "appnexus",
   321  					Currency: "USD",
   322  					Bids: []*entities.PbsOrtbBid{
   323  						{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, ImpID: "some-impression-id-1"}},
   324  					},
   325  				},
   326  			},
   327  			expErrs: []error{},
   328  		},
   329  		{
   330  			name: "Error in currency conversion",
   331  			args: args{
   332  				bidRequestWrapper: func() *openrtb_ext.RequestWrapper {
   333  					bw := openrtb_ext.RequestWrapper{
   334  						BidRequest: &openrtb2.BidRequest{
   335  							ID:  "some-request-id",
   336  							Cur: []string{"USD"},
   337  							Imp: []openrtb2.Imp{{ID: "some-impression-id-1", BidFloor: 1.01}},
   338  						},
   339  					}
   340  					bw.RebuildRequest()
   341  					return &bw
   342  				}(),
   343  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   344  					"pubmatic": {
   345  						Bids: []*entities.PbsOrtbBid{
   346  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   347  						},
   348  						Currency: "EUR",
   349  					},
   350  				},
   351  				conversions:       convert{},
   352  				enforceDealFloors: true,
   353  			},
   354  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   355  				"pubmatic": {
   356  					Bids:     []*entities.PbsOrtbBid{},
   357  					Currency: "EUR",
   358  				},
   359  			},
   360  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   361  			expErrs:         []error{errors.New("error in rate conversion from = EUR to  with bidder pubmatic for impression id some-impression-id-1 and bid id some-bid-1 error = currency conversion not supported")},
   362  		},
   363  		{
   364  			name: "Bids with invalid impression ID",
   365  			args: args{
   366  				bidRequestWrapper: func() *openrtb_ext.RequestWrapper {
   367  					bw := openrtb_ext.RequestWrapper{
   368  						BidRequest: &openrtb2.BidRequest{
   369  							ID: "some-request-id",
   370  							Imp: []openrtb2.Imp{
   371  								{ID: "some-impression-id-2", BidFloor: 2.01, BidFloorCur: "USD"},
   372  							},
   373  						},
   374  					}
   375  					bw.RebuildRequest()
   376  					return &bw
   377  				}(),
   378  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   379  					"pubmatic": {
   380  						Bids: []*entities.PbsOrtbBid{
   381  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-123"}},
   382  						},
   383  						Seat:     "pubmatic",
   384  						Currency: "USD",
   385  					},
   386  				},
   387  				conversions:       currency.Conversions(convert{}),
   388  				enforceDealFloors: false,
   389  			},
   390  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   391  				"pubmatic": {
   392  					Bids:     []*entities.PbsOrtbBid{},
   393  					Seat:     "pubmatic",
   394  					Currency: "USD",
   395  				},
   396  			},
   397  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   398  			expErrs:         []error{},
   399  		},
   400  	}
   401  	for _, tt := range tests {
   402  		seatbids, errs, rejBids := enforceFloorToBids(tt.args.bidRequestWrapper, tt.args.seatBids, tt.args.conversions, tt.args.enforceDealFloors)
   403  		assert.Equal(t, tt.expEligibleBids, seatbids, tt.name)
   404  		assert.Equal(t, tt.expErrs, errs, tt.name)
   405  		assert.Equal(t, tt.expRejectedBids, rejBids, tt.name)
   406  	}
   407  }
   408  
   409  func TestEnforce(t *testing.T) {
   410  	type args struct {
   411  		bidRequestWrapper *openrtb_ext.RequestWrapper
   412  		bidRequest        *openrtb2.BidRequest
   413  		seatBids          map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid
   414  		priceFloorsCfg    config.AccountPriceFloors
   415  		conversions       currency.Conversions
   416  	}
   417  	tests := []struct {
   418  		name            string
   419  		args            args
   420  		expEligibleBids map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid
   421  		expErrs         []error
   422  		expRejectedBids []*entities.PbsOrtbSeatBid
   423  	}{
   424  		{
   425  			name: "Error in getting request extension",
   426  			args: args{
   427  				bidRequestWrapper: &openrtb_ext.RequestWrapper{
   428  					BidRequest: &openrtb2.BidRequest{
   429  						ID: "some-request-id",
   430  						Imp: []openrtb2.Imp{{
   431  							ID:          "some-impression-id-1",
   432  							Banner:      &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}},
   433  							BidFloor:    5.01,
   434  							BidFloorCur: "USD",
   435  						}},
   436  						Ext: json.RawMessage(`{"prebid":{"floors":{"floormin":1,"data":{"currency":"USD","skiprate":100,"modelgroups":[{"modelversion":"version1","skiprate":10,"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"},"values":{"*|*|*":20.01,"*|*|www.website1.com":16.01},"default":21}]},"enforcement":{"enforcepbs":true,"floordeals":false},"enabled":false,"skipped":false}}`),
   437  					},
   438  				},
   439  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   440  					"pubmatic": {
   441  						Bids: []*entities.PbsOrtbBid{
   442  							{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 4.5, ImpID: "some-impression-id-1"}},
   443  						},
   444  						Seat:     "pubmatic",
   445  						Currency: "USD",
   446  					},
   447  				},
   448  				conversions:    convert{},
   449  				priceFloorsCfg: config.AccountPriceFloors{Enabled: false, EnforceFloorsRate: 100, EnforceDealFloors: true},
   450  			},
   451  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   452  				"pubmatic": {
   453  					Bids: []*entities.PbsOrtbBid{
   454  						{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 4.5, ImpID: "some-impression-id-1"}},
   455  					},
   456  					Seat:     "pubmatic",
   457  					Currency: "USD",
   458  				},
   459  			},
   460  			expErrs:         []error{errors.New("Error in getting request extension")},
   461  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   462  		},
   463  		{
   464  			name: "Should not enforce floors when req.ext.prebid.floors.enabled = false",
   465  			args: args{
   466  				bidRequestWrapper: &openrtb_ext.RequestWrapper{
   467  					BidRequest: &openrtb2.BidRequest{
   468  						ID: "some-request-id",
   469  						Imp: []openrtb2.Imp{{
   470  							ID:          "some-impression-id-1",
   471  							Banner:      &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}},
   472  							BidFloor:    5.01,
   473  							BidFloorCur: "USD",
   474  						}},
   475  						Ext: json.RawMessage(`{"prebid":{"floors":{"floormin":1,"data":{"currency":"USD","skiprate":100,"modelgroups":[{"modelversion":"version1","skiprate":10,"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"},"values":{"*|*|*":20.01,"*|*|www.website1.com":16.01},"default":21}]},"enforcement":{"enforcepbs":true,"floordeals":false},"enabled":false}}}`),
   476  					},
   477  				},
   478  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   479  					"pubmatic": {
   480  						Bids: []*entities.PbsOrtbBid{
   481  							{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 4.5, ImpID: "some-impression-id-1"}},
   482  						},
   483  						Seat:     "pubmatic",
   484  						Currency: "USD",
   485  					},
   486  				},
   487  				conversions:    convert{},
   488  				priceFloorsCfg: config.AccountPriceFloors{Enabled: true, EnforceFloorsRate: 100, EnforceDealFloors: true},
   489  			},
   490  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   491  				"pubmatic": {
   492  					Bids: []*entities.PbsOrtbBid{
   493  						{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 4.5, ImpID: "some-impression-id-1"}},
   494  					},
   495  					Seat:     "pubmatic",
   496  					Currency: "USD",
   497  				},
   498  			},
   499  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   500  		},
   501  		{
   502  			name: "Should not enforce floors is disabled in account config",
   503  			args: args{
   504  				bidRequestWrapper: &openrtb_ext.RequestWrapper{
   505  					BidRequest: &openrtb2.BidRequest{
   506  						ID: "some-request-id",
   507  						Imp: []openrtb2.Imp{{
   508  							ID:          "some-impression-id-1",
   509  							Banner:      &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}, {W: 300, H: 600}}},
   510  							BidFloor:    5.01,
   511  							BidFloorCur: "USD",
   512  						}},
   513  						Ext: json.RawMessage(`{"prebid":{"floors":{"floormin":1,"data":{"currency":"USD","skiprate":100,"modelgroups":[{"modelversion":"version1","skiprate":10,"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"},"values":{"*|*|*":20.01,"*|*|www.website1.com":16.01},"default":21}]},"enforcement":{"enforcepbs":true,"floordeals":false},"enabled":true}}}`),
   514  					},
   515  				},
   516  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   517  					"pubmatic": {
   518  						Bids: []*entities.PbsOrtbBid{
   519  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   520  						},
   521  						Seat:     "pubmatic",
   522  						Currency: "USD",
   523  					},
   524  				},
   525  				conversions:    convert{},
   526  				priceFloorsCfg: config.AccountPriceFloors{Enabled: false, EnforceFloorsRate: 100, EnforceDealFloors: true},
   527  			},
   528  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   529  				"pubmatic": {
   530  					Bids: []*entities.PbsOrtbBid{
   531  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   532  					},
   533  					Seat:     "pubmatic",
   534  					Currency: "USD",
   535  				},
   536  			},
   537  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   538  		},
   539  		{
   540  			name: "Should not enforce floors when req.ext.prebid.floors.enforcement.enforcepbs = false",
   541  			args: args{
   542  				bidRequestWrapper: &openrtb_ext.RequestWrapper{
   543  					BidRequest: &openrtb2.BidRequest{
   544  						ID: "some-request-id",
   545  						Imp: []openrtb2.Imp{{
   546  							ID:          "some-impression-id-1",
   547  							Banner:      &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}, {W: 300, H: 600}}},
   548  							BidFloor:    5.01,
   549  							BidFloorCur: "USD",
   550  						}},
   551  						Ext: json.RawMessage(`{"prebid":{"floors":{"floormin":1,"data":{"currency":"USD","skiprate":100,"modelgroups":[{"modelversion":"version1","skiprate":10,"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"},"values":{"*|*|*":20.01,"*|*|www.website1.com":16.01},"default":21}]},"enforcement":{"enforcepbs":false,"floordeals":false},"enabled":true,"skipped":false}}}`),
   552  					},
   553  				},
   554  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   555  					"pubmatic": {
   556  						Bids: []*entities.PbsOrtbBid{
   557  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   558  						},
   559  						Seat:     "pubmatic",
   560  						Currency: "USD",
   561  					},
   562  				},
   563  				conversions:    convert{},
   564  				priceFloorsCfg: config.AccountPriceFloors{Enabled: true, EnforceFloorsRate: 100, EnforceDealFloors: true},
   565  			},
   566  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   567  				"pubmatic": {
   568  					Bids: []*entities.PbsOrtbBid{
   569  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}, BidFloors: &openrtb_ext.ExtBidPrebidFloors{FloorValue: 5.01, FloorCurrency: "USD"}},
   570  					},
   571  					Seat:     "pubmatic",
   572  					Currency: "USD",
   573  				},
   574  			},
   575  			expErrs:         []error{},
   576  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   577  		},
   578  		{
   579  			name: "Should not enforce floors when req.ext.prebid.floors.skipped = true",
   580  			args: args{
   581  				bidRequestWrapper: &openrtb_ext.RequestWrapper{
   582  					BidRequest: &openrtb2.BidRequest{
   583  						ID: "some-request-id",
   584  						Imp: []openrtb2.Imp{{
   585  							ID:          "some-impression-id-1",
   586  							Banner:      &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}, {W: 300, H: 600}}},
   587  							BidFloor:    5.01,
   588  							BidFloorCur: "USD",
   589  						}},
   590  						Ext: json.RawMessage(`{"prebid":{"floors":{"floormin":1,"data":{"currency":"USD","skiprate":100,"modelgroups":[{"modelversion":"version1","skiprate":10,"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"},"values":{"*|*|*":20.01,"*|*|www.website1.com":16.01},"default":21}]},"enforcement":{"enforcepbs":true,"floordeals":false},"enabled":true,"skipped":true}}}`),
   591  					},
   592  				},
   593  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   594  					"pubmatic": {
   595  						Bids: []*entities.PbsOrtbBid{
   596  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   597  						},
   598  						Seat:     "pubmatic",
   599  						Currency: "USD",
   600  					},
   601  				},
   602  				conversions:    convert{},
   603  				priceFloorsCfg: config.AccountPriceFloors{Enabled: true, EnforceFloorsRate: 100, EnforceDealFloors: true},
   604  			},
   605  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   606  				"pubmatic": {
   607  					Bids: []*entities.PbsOrtbBid{
   608  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, ImpID: "some-impression-id-1"}},
   609  					},
   610  					Seat:     "pubmatic",
   611  					Currency: "USD",
   612  				},
   613  			},
   614  			expRejectedBids: []*entities.PbsOrtbSeatBid{},
   615  		},
   616  		{
   617  			name: "Should enforce floors for deals, ext.prebid.floors.enforcement.floorDeals = true and floors enabled = true",
   618  			args: args{
   619  				bidRequestWrapper: &openrtb_ext.RequestWrapper{
   620  					BidRequest: &openrtb2.BidRequest{
   621  						ID: "some-request-id",
   622  						Imp: []openrtb2.Imp{{
   623  							ID: "some-impression-id-1", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}, BidFloor: 20.01, BidFloorCur: "USD",
   624  						}},
   625  						Ext: json.RawMessage(`{"prebid":{"floors":{"floormin":1,"data":{"currency":"USD","skiprate":100,"modelgroups":[{"modelversion":"version1","skiprate":10,"schema":{"fields":["mediaType","size","domain"],"delimiter":"|"},"values":{"*|*|*":20.01,"*|*|www.website1.com":16.01},"default":21}]},"enforcement":{"enforcepbs":true,"floordeals":true},"enabled":true}}}`),
   626  					},
   627  				},
   628  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   629  					"pubmatic": {
   630  						Bids:     []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, DealID: "deal_Id_1", ImpID: "some-impression-id-1"}}},
   631  						Seat:     "pubmatic",
   632  						Currency: "USD",
   633  					},
   634  					"appnexus": {
   635  						Bids:     []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, DealID: "deal_Id_3", ImpID: "some-impression-id-1"}}},
   636  						Seat:     "appnexus",
   637  						Currency: "USD",
   638  					},
   639  				},
   640  				conversions:    convert{},
   641  				priceFloorsCfg: config.AccountPriceFloors{Enabled: true, EnforceFloorsRate: 0, EnforceDealFloors: true},
   642  			},
   643  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   644  				"pubmatic": {
   645  					Bids:     []*entities.PbsOrtbBid{},
   646  					Seat:     "pubmatic",
   647  					Currency: "USD",
   648  				},
   649  				"appnexus": {
   650  					Bids:     []*entities.PbsOrtbBid{},
   651  					Seat:     "appnexus",
   652  					Currency: "USD",
   653  				},
   654  			},
   655  			expRejectedBids: []*entities.PbsOrtbSeatBid{
   656  				{
   657  					Seat:     "pubmatic",
   658  					Currency: "USD",
   659  					Bids:     []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, DealID: "deal_Id_1", ImpID: "some-impression-id-1"}, BidFloors: &openrtb_ext.ExtBidPrebidFloors{FloorCurrency: "USD", FloorValue: 20.01}}},
   660  				},
   661  				{
   662  					Seat:     "appnexus",
   663  					Currency: "USD",
   664  					Bids:     []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 0.5, DealID: "deal_Id_3", ImpID: "some-impression-id-1"}, BidFloors: &openrtb_ext.ExtBidPrebidFloors{FloorCurrency: "USD", FloorValue: 20.01}}},
   665  				},
   666  			},
   667  			expErrs: []error{},
   668  		},
   669  		{
   670  			name: "Should enforce floors when imp.bidfloor provided and enforcepbs not provided",
   671  			args: args{
   672  				bidRequestWrapper: &openrtb_ext.RequestWrapper{
   673  					BidRequest: &openrtb2.BidRequest{
   674  						ID: "some-request-id",
   675  						Imp: []openrtb2.Imp{{
   676  							ID: "some-impression-id-1", Banner: &openrtb2.Banner{Format: []openrtb2.Format{{W: 300, H: 250}}}, BidFloor: 5.01, BidFloorCur: "USD",
   677  						}},
   678  						Ext: json.RawMessage(`{"prebid":{"floors":{"floormin":1}}}`),
   679  					},
   680  				},
   681  				seatBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   682  					"pubmatic": {
   683  						Bids: []*entities.PbsOrtbBid{
   684  							{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, DealID: "deal_Id_1", ImpID: "some-impression-id-1"}},
   685  						},
   686  						Seat:     "pubmatic",
   687  						Currency: "USD",
   688  					},
   689  					"appnexus": {
   690  						Bids: []*entities.PbsOrtbBid{
   691  							{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 4.5, ImpID: "some-impression-id-1"}},
   692  						},
   693  						Seat:     "appnexus",
   694  						Currency: "USD",
   695  					},
   696  				},
   697  				conversions:    convert{},
   698  				priceFloorsCfg: config.AccountPriceFloors{Enabled: true, EnforceFloorsRate: 0, EnforceDealFloors: false},
   699  			},
   700  			expEligibleBids: map[openrtb_ext.BidderName]*entities.PbsOrtbSeatBid{
   701  				"pubmatic": {
   702  					Bids: []*entities.PbsOrtbBid{
   703  						{Bid: &openrtb2.Bid{ID: "some-bid-1", Price: 1.2, DealID: "deal_Id_1", ImpID: "some-impression-id-1"}, BidFloors: &openrtb_ext.ExtBidPrebidFloors{FloorValue: 5.01, FloorCurrency: "USD"}},
   704  					},
   705  					Seat:     "pubmatic",
   706  					Currency: "USD",
   707  				},
   708  				"appnexus": {
   709  					Bids:     []*entities.PbsOrtbBid{},
   710  					Seat:     "appnexus",
   711  					Currency: "USD",
   712  				},
   713  			},
   714  			expRejectedBids: []*entities.PbsOrtbSeatBid{
   715  				{
   716  					Seat:     "appnexus",
   717  					Currency: "USD",
   718  					Bids:     []*entities.PbsOrtbBid{{Bid: &openrtb2.Bid{ID: "some-bid-11", Price: 4.5, ImpID: "some-impression-id-1"}, BidFloors: &openrtb_ext.ExtBidPrebidFloors{FloorValue: 5.01, FloorCurrency: "USD"}}},
   719  				},
   720  			},
   721  			expErrs: []error{},
   722  		},
   723  	}
   724  	for _, tt := range tests {
   725  		actEligibleBids, actErrs, actRejecteBids := Enforce(tt.args.bidRequestWrapper, tt.args.seatBids, config.Account{PriceFloors: tt.args.priceFloorsCfg}, tt.args.conversions)
   726  		assert.Equal(t, tt.expErrs, actErrs, tt.name)
   727  		assert.ElementsMatch(t, tt.expRejectedBids, actRejecteBids, tt.name)
   728  
   729  		if !reflect.DeepEqual(tt.expEligibleBids, actEligibleBids) {
   730  			assert.Failf(t, "eligible bids don't match", "Expected: %v, Got: %v", tt.expEligibleBids, actEligibleBids)
   731  		}
   732  	}
   733  }
   734  
   735  func TestUpdateBidExtWithFloors(t *testing.T) {
   736  	type args struct {
   737  		reqImp        *openrtb_ext.ImpWrapper
   738  		bid           *entities.PbsOrtbBid
   739  		floorCurrency string
   740  	}
   741  	tests := []struct {
   742  		name        string
   743  		expBidFloor *openrtb_ext.ExtBidPrebidFloors
   744  		args        args
   745  	}{
   746  		{
   747  			name: "Empty prebid extension in imp.ext",
   748  			args: args{
   749  				reqImp: &openrtb_ext.ImpWrapper{
   750  					Imp: &openrtb2.Imp{BidFloor: 10, BidFloorCur: "USD"},
   751  				},
   752  				bid: &entities.PbsOrtbBid{
   753  					Bid: &openrtb2.Bid{
   754  						Price: 10.10,
   755  						AdM:   "Adm",
   756  					},
   757  				},
   758  				floorCurrency: "USD",
   759  			},
   760  			expBidFloor: &openrtb_ext.ExtBidPrebidFloors{
   761  				FloorValue:    10,
   762  				FloorCurrency: "USD",
   763  			},
   764  		},
   765  		{
   766  			name: "Valid prebid extension in imp.ext",
   767  			args: args{
   768  				reqImp: &openrtb_ext.ImpWrapper{Imp: &openrtb2.Imp{ID: "1234", Video: &openrtb2.Video{W: ptrutil.ToPtr[int64](300), H: ptrutil.ToPtr[int64](250)}, Ext: []byte(`{"prebid":{"floors":{"floorrule":"test|123|xyz","floorrulevalue":5.5,"floorvalue":5.5}}}`)}},
   769  				bid: &entities.PbsOrtbBid{
   770  					Bid: &openrtb2.Bid{
   771  						Price: 10.10,
   772  						AdM:   "Adm",
   773  					},
   774  				},
   775  				floorCurrency: "USD",
   776  			},
   777  			expBidFloor: &openrtb_ext.ExtBidPrebidFloors{
   778  				FloorRule:      "test|123|xyz",
   779  				FloorRuleValue: 5.5,
   780  				FloorValue:     5.5,
   781  				FloorCurrency:  "USD",
   782  			},
   783  		},
   784  	}
   785  	for _, tt := range tests {
   786  		updateBidExtWithFloors(tt.args.reqImp, tt.args.bid, tt.args.floorCurrency)
   787  		assert.Equal(t, tt.expBidFloor, tt.args.bid.BidFloors, tt.name)
   788  	}
   789  }
   790  
   791  func TestIsEnforcementEnabledForRequest(t *testing.T) {
   792  	tests := []struct {
   793  		name   string
   794  		reqExt *openrtb_ext.RequestExt
   795  		want   bool
   796  	}{
   797  		{
   798  			name: "Req.ext not provided",
   799  			reqExt: func() *openrtb_ext.RequestExt {
   800  				return &openrtb_ext.RequestExt{}
   801  			}(),
   802  			want: true,
   803  		},
   804  		{
   805  			name: "Req.ext provided EnforcePBS = false",
   806  			reqExt: func() *openrtb_ext.RequestExt {
   807  				reqExt := openrtb_ext.RequestExt{}
   808  				prebidExt := openrtb_ext.ExtRequestPrebid{
   809  					Floors: &openrtb_ext.PriceFloorRules{
   810  						Enforcement: &openrtb_ext.PriceFloorEnforcement{
   811  							EnforcePBS: ptrutil.ToPtr(false),
   812  						},
   813  					},
   814  				}
   815  				reqExt.SetPrebid(&prebidExt)
   816  				return &reqExt
   817  			}(),
   818  			want: false,
   819  		},
   820  		{
   821  			name: "Req.ext provided EnforcePBS = true",
   822  			reqExt: func() *openrtb_ext.RequestExt {
   823  				reqExt := openrtb_ext.RequestExt{}
   824  				prebidExt := openrtb_ext.ExtRequestPrebid{
   825  					Floors: &openrtb_ext.PriceFloorRules{
   826  						Enforcement: &openrtb_ext.PriceFloorEnforcement{
   827  							EnforcePBS: ptrutil.ToPtr(true),
   828  						},
   829  					},
   830  				}
   831  				reqExt.SetPrebid(&prebidExt)
   832  				return &reqExt
   833  			}(),
   834  			want: true,
   835  		},
   836  	}
   837  	for _, tt := range tests {
   838  		got := isEnforcementEnabled(tt.reqExt)
   839  		assert.Equal(t, tt.want, got, tt.name)
   840  	}
   841  }
   842  
   843  func TestIsSignalingSkipped(t *testing.T) {
   844  	tests := []struct {
   845  		name   string
   846  		reqExt *openrtb_ext.RequestExt
   847  		want   bool
   848  	}{
   849  		{
   850  			name: "Req.ext nil",
   851  			reqExt: func() *openrtb_ext.RequestExt {
   852  				return nil
   853  			}(),
   854  			want: false,
   855  		},
   856  		{
   857  			name: "Req.ext provided without prebid ext",
   858  			reqExt: func() *openrtb_ext.RequestExt {
   859  				return &openrtb_ext.RequestExt{}
   860  			}(),
   861  			want: false,
   862  		},
   863  		{
   864  			name: "Req.ext provided without Floors in prebid ext",
   865  			reqExt: func() *openrtb_ext.RequestExt {
   866  				reqExt := openrtb_ext.RequestExt{}
   867  				prebidExt := openrtb_ext.ExtRequestPrebid{}
   868  				reqExt.SetPrebid(&prebidExt)
   869  				return &reqExt
   870  			}(),
   871  			want: false,
   872  		},
   873  		{
   874  			name: "Req.ext provided Skipped = true",
   875  			reqExt: func() *openrtb_ext.RequestExt {
   876  				reqExt := openrtb_ext.RequestExt{}
   877  				prebidExt := openrtb_ext.ExtRequestPrebid{
   878  					Floors: &openrtb_ext.PriceFloorRules{
   879  						Skipped: ptrutil.ToPtr(true),
   880  					},
   881  				}
   882  				reqExt.SetPrebid(&prebidExt)
   883  				return &reqExt
   884  			}(),
   885  			want: true,
   886  		},
   887  		{
   888  			name: "Req.ext provided Skipped = false",
   889  			reqExt: func() *openrtb_ext.RequestExt {
   890  				reqExt := openrtb_ext.RequestExt{}
   891  				prebidExt := openrtb_ext.ExtRequestPrebid{
   892  					Floors: &openrtb_ext.PriceFloorRules{
   893  						Skipped: ptrutil.ToPtr(false),
   894  					},
   895  				}
   896  				reqExt.SetPrebid(&prebidExt)
   897  				return &reqExt
   898  			}(),
   899  			want: false,
   900  		},
   901  	}
   902  	for _, tt := range tests {
   903  		got := isSignalingSkipped(tt.reqExt)
   904  		assert.Equal(t, tt.want, got, tt.name)
   905  	}
   906  }
   907  
   908  func TestGetEnforceRateRequest(t *testing.T) {
   909  	tests := []struct {
   910  		name   string
   911  		reqExt *openrtb_ext.RequestExt
   912  		want   int
   913  	}{
   914  		{
   915  			name: "Req.ext not provided",
   916  			reqExt: func() *openrtb_ext.RequestExt {
   917  				return &openrtb_ext.RequestExt{}
   918  			}(),
   919  			want: 0,
   920  		},
   921  		{
   922  			name: "Req.ext.prebid.floors provided with EnforceRate = 0",
   923  			reqExt: func() *openrtb_ext.RequestExt {
   924  				reqExt := openrtb_ext.RequestExt{}
   925  				prebidExt := openrtb_ext.ExtRequestPrebid{
   926  					Floors: &openrtb_ext.PriceFloorRules{
   927  						Enforcement: &openrtb_ext.PriceFloorEnforcement{
   928  							EnforceRate: 0,
   929  						},
   930  					},
   931  				}
   932  				reqExt.SetPrebid(&prebidExt)
   933  				return &reqExt
   934  			}(),
   935  			want: 0,
   936  		},
   937  		{
   938  			name: "Req.ext.prebid.floors provided with EnforceRate = 50",
   939  			reqExt: func() *openrtb_ext.RequestExt {
   940  				reqExt := openrtb_ext.RequestExt{}
   941  				prebidExt := openrtb_ext.ExtRequestPrebid{
   942  					Floors: &openrtb_ext.PriceFloorRules{
   943  						Enforcement: &openrtb_ext.PriceFloorEnforcement{
   944  							EnforceRate: 50,
   945  						},
   946  					},
   947  				}
   948  				reqExt.SetPrebid(&prebidExt)
   949  				return &reqExt
   950  			}(),
   951  			want: 50,
   952  		},
   953  		{
   954  			name: "Req.ext.prebid.floors provided with EnforceRate = 100",
   955  			reqExt: func() *openrtb_ext.RequestExt {
   956  				reqExt := openrtb_ext.RequestExt{}
   957  				prebidExt := openrtb_ext.ExtRequestPrebid{
   958  					Floors: &openrtb_ext.PriceFloorRules{
   959  						Enforcement: &openrtb_ext.PriceFloorEnforcement{
   960  							EnforceRate: 100,
   961  						},
   962  					},
   963  				}
   964  				reqExt.SetPrebid(&prebidExt)
   965  				return &reqExt
   966  			}(),
   967  			want: 100,
   968  		},
   969  	}
   970  	for _, tt := range tests {
   971  		got := getEnforceRateRequest(tt.reqExt)
   972  		assert.Equal(t, tt.want, got, tt.name)
   973  	}
   974  }
   975  
   976  func TestGetEnforceDealsFlag(t *testing.T) {
   977  	tests := []struct {
   978  		name   string
   979  		reqExt *openrtb_ext.RequestExt
   980  		want   bool
   981  	}{
   982  		{
   983  			name: "Req.ext not provided",
   984  			reqExt: func() *openrtb_ext.RequestExt {
   985  				return &openrtb_ext.RequestExt{}
   986  			}(),
   987  			want: false,
   988  		},
   989  		{
   990  			name: "Req.ext.prebid.floors provided, enforceDeals not provided",
   991  			reqExt: func() *openrtb_ext.RequestExt {
   992  				reqExt := openrtb_ext.RequestExt{}
   993  				prebidExt := openrtb_ext.ExtRequestPrebid{
   994  					Floors: &openrtb_ext.PriceFloorRules{
   995  						Enforcement: &openrtb_ext.PriceFloorEnforcement{},
   996  					},
   997  				}
   998  				reqExt.SetPrebid(&prebidExt)
   999  				return &reqExt
  1000  			}(),
  1001  			want: false,
  1002  		},
  1003  		{
  1004  			name: "Req.ext.prebid.floors provided with enforceDeals = false",
  1005  			reqExt: func() *openrtb_ext.RequestExt {
  1006  				reqExt := openrtb_ext.RequestExt{}
  1007  				prebidExt := openrtb_ext.ExtRequestPrebid{
  1008  					Floors: &openrtb_ext.PriceFloorRules{
  1009  						Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1010  							FloorDeals: ptrutil.ToPtr(false),
  1011  						},
  1012  					},
  1013  				}
  1014  				reqExt.SetPrebid(&prebidExt)
  1015  				return &reqExt
  1016  			}(),
  1017  			want: false,
  1018  		},
  1019  		{
  1020  			name: "Req.ext.prebid.floors provided with enforceDeals = true",
  1021  			reqExt: func() *openrtb_ext.RequestExt {
  1022  				reqExt := openrtb_ext.RequestExt{}
  1023  				prebidExt := openrtb_ext.ExtRequestPrebid{
  1024  					Floors: &openrtb_ext.PriceFloorRules{
  1025  						Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1026  							FloorDeals: ptrutil.ToPtr(true),
  1027  						},
  1028  					},
  1029  				}
  1030  				reqExt.SetPrebid(&prebidExt)
  1031  				return &reqExt
  1032  			}(),
  1033  			want: true,
  1034  		},
  1035  	}
  1036  	for _, tt := range tests {
  1037  		got := getEnforceDealsFlag(tt.reqExt)
  1038  		assert.Equal(t, tt.want, got, tt.name)
  1039  	}
  1040  }
  1041  
  1042  func TestIsSatisfiedByEnforceRate(t *testing.T) {
  1043  	type args struct {
  1044  		reqExt            *openrtb_ext.RequestExt
  1045  		configEnforceRate int
  1046  		f                 func(int) int
  1047  	}
  1048  	tests := []struct {
  1049  		name string
  1050  		args args
  1051  		want bool
  1052  	}{
  1053  		{
  1054  			name: "With EnforceRate = 50",
  1055  			args: args{
  1056  				reqExt: func() *openrtb_ext.RequestExt {
  1057  					reqExt := openrtb_ext.RequestExt{}
  1058  					prebidExt := openrtb_ext.ExtRequestPrebid{
  1059  						Floors: &openrtb_ext.PriceFloorRules{
  1060  							Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1061  								EnforceRate: 50,
  1062  								EnforcePBS:  ptrutil.ToPtr(true),
  1063  							},
  1064  						},
  1065  					}
  1066  					reqExt.SetPrebid(&prebidExt)
  1067  					return &reqExt
  1068  				}(),
  1069  				configEnforceRate: 100,
  1070  				f: func(n int) int {
  1071  					return n
  1072  				},
  1073  			},
  1074  			want: false,
  1075  		},
  1076  		{
  1077  			name: "With EnforceRate = 100",
  1078  			args: args{
  1079  				reqExt: func() *openrtb_ext.RequestExt {
  1080  					reqExt := openrtb_ext.RequestExt{}
  1081  					prebidExt := openrtb_ext.ExtRequestPrebid{
  1082  						Floors: &openrtb_ext.PriceFloorRules{
  1083  							Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1084  								EnforceRate: 100,
  1085  								EnforcePBS:  ptrutil.ToPtr(true),
  1086  							},
  1087  						},
  1088  					}
  1089  					reqExt.SetPrebid(&prebidExt)
  1090  					return &reqExt
  1091  				}(),
  1092  				configEnforceRate: 100,
  1093  				f: func(n int) int {
  1094  					return n - 1
  1095  				},
  1096  			},
  1097  			want: true,
  1098  		},
  1099  		{
  1100  			name: "With configEnforceRate = 0",
  1101  			args: args{
  1102  				reqExt: func() *openrtb_ext.RequestExt {
  1103  					reqExt := openrtb_ext.RequestExt{}
  1104  					prebidExt := openrtb_ext.ExtRequestPrebid{
  1105  						Floors: &openrtb_ext.PriceFloorRules{
  1106  							Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1107  								EnforceRate: 0,
  1108  								EnforcePBS:  ptrutil.ToPtr(true),
  1109  							},
  1110  						},
  1111  					}
  1112  					reqExt.SetPrebid(&prebidExt)
  1113  					return &reqExt
  1114  				}(),
  1115  				configEnforceRate: 0,
  1116  				f: func(n int) int {
  1117  					return n - 1
  1118  				},
  1119  			},
  1120  			want: true,
  1121  		},
  1122  	}
  1123  	for _, tt := range tests {
  1124  		got := isSatisfiedByEnforceRate(tt.args.reqExt, tt.args.configEnforceRate, tt.args.f)
  1125  		assert.Equal(t, tt.want, got, tt.name)
  1126  	}
  1127  }
  1128  
  1129  func TestUpdateEnforcePBS(t *testing.T) {
  1130  	type args struct {
  1131  		enforceFloors bool
  1132  		reqExt        *openrtb_ext.RequestExt
  1133  	}
  1134  	tests := []struct {
  1135  		name string
  1136  		args args
  1137  		want bool
  1138  	}{
  1139  		{
  1140  			name: "Enforce PBS is true in request and to be updated = true",
  1141  			args: args{
  1142  				enforceFloors: true,
  1143  				reqExt: func() *openrtb_ext.RequestExt {
  1144  					reqExt := openrtb_ext.RequestExt{}
  1145  					prebidExt := openrtb_ext.ExtRequestPrebid{
  1146  						Floors: &openrtb_ext.PriceFloorRules{
  1147  							Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1148  								EnforcePBS: ptrutil.ToPtr(true),
  1149  							},
  1150  						},
  1151  					}
  1152  					reqExt.SetPrebid(&prebidExt)
  1153  					return &reqExt
  1154  				}(),
  1155  			},
  1156  			want: false,
  1157  		},
  1158  		{
  1159  			name: "Enforce PBS is false in request and to be updated = true",
  1160  			args: args{
  1161  				enforceFloors: true,
  1162  				reqExt: func() *openrtb_ext.RequestExt {
  1163  					reqExt := openrtb_ext.RequestExt{}
  1164  					prebidExt := openrtb_ext.ExtRequestPrebid{
  1165  						Floors: &openrtb_ext.PriceFloorRules{
  1166  							Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1167  								EnforcePBS: ptrutil.ToPtr(false),
  1168  							},
  1169  						},
  1170  					}
  1171  					reqExt.SetPrebid(&prebidExt)
  1172  					return &reqExt
  1173  				}(),
  1174  			},
  1175  			want: false,
  1176  		},
  1177  		{
  1178  			name: "Enforce PBS is true in request and to be updated = false",
  1179  			args: args{
  1180  				enforceFloors: false,
  1181  				reqExt: func() *openrtb_ext.RequestExt {
  1182  					reqExt := openrtb_ext.RequestExt{}
  1183  					prebidExt := openrtb_ext.ExtRequestPrebid{
  1184  						Floors: &openrtb_ext.PriceFloorRules{
  1185  							Enforcement: &openrtb_ext.PriceFloorEnforcement{
  1186  								EnforcePBS: ptrutil.ToPtr(true),
  1187  							},
  1188  						},
  1189  					}
  1190  					reqExt.SetPrebid(&prebidExt)
  1191  					return &reqExt
  1192  				}(),
  1193  			},
  1194  			want: true,
  1195  		},
  1196  		{
  1197  			name: "empty prebid ext and to be updated = false",
  1198  			args: args{enforceFloors: false,
  1199  				reqExt: func() *openrtb_ext.RequestExt {
  1200  					return &openrtb_ext.RequestExt{}
  1201  				}(),
  1202  			},
  1203  			want: true,
  1204  		},
  1205  		{
  1206  			name: "empty prebid ext and to be updated = true",
  1207  			args: args{enforceFloors: true,
  1208  				reqExt: func() *openrtb_ext.RequestExt {
  1209  					reqExt := openrtb_ext.RequestExt{}
  1210  					prebidExt := openrtb_ext.ExtRequestPrebid{}
  1211  					reqExt.SetPrebid(&prebidExt)
  1212  					return &reqExt
  1213  				}(),
  1214  			},
  1215  			want: true,
  1216  		},
  1217  	}
  1218  	for _, tt := range tests {
  1219  		t.Run(tt.name, func(t *testing.T) {
  1220  			got := updateEnforcePBS(tt.args.enforceFloors, tt.args.reqExt)
  1221  			assert.Equal(t, tt.want, got, tt.name)
  1222  		})
  1223  	}
  1224  }