github.com/prebid/prebid-server/v2@v2.18.0/privacy/lmt/ios_test.go (about)

     1  package lmt
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  
     7  	"github.com/prebid/openrtb/v20/openrtb2"
     8  	"github.com/prebid/prebid-server/v2/util/iosutil"
     9  	"github.com/stretchr/testify/assert"
    10  )
    11  
    12  // TestModifyForIOS is a simple spot check end-to-end test for the integration of all functional components.
    13  func TestModifyForIOS(t *testing.T) {
    14  	testCases := []struct {
    15  		description  string
    16  		givenRequest *openrtb2.BidRequest
    17  		expectedLMT  *int8
    18  	}{
    19  		{
    20  			description: "13.0",
    21  			givenRequest: &openrtb2.BidRequest{
    22  				App:    &openrtb2.App{},
    23  				Device: &openrtb2.Device{OS: "iOS", OSV: "13.0", IFA: "", Lmt: nil},
    24  			},
    25  			expectedLMT: nil,
    26  		},
    27  		{
    28  			description: "14.0",
    29  			givenRequest: &openrtb2.BidRequest{
    30  				App:    &openrtb2.App{},
    31  				Device: &openrtb2.Device{OS: "iOS", OSV: "14.0", IFA: "", Lmt: nil},
    32  			},
    33  			expectedLMT: openrtb2.Int8Ptr(1),
    34  		},
    35  		{
    36  			description: "14.1",
    37  			givenRequest: &openrtb2.BidRequest{
    38  				App:    &openrtb2.App{},
    39  				Device: &openrtb2.Device{OS: "iOS", OSV: "14.1", IFA: "", Lmt: nil},
    40  			},
    41  			expectedLMT: openrtb2.Int8Ptr(1),
    42  		},
    43  		{
    44  			description: "14.1.3",
    45  			givenRequest: &openrtb2.BidRequest{
    46  				App:    &openrtb2.App{},
    47  				Device: &openrtb2.Device{OS: "iOS", OSV: "14.1.3", IFA: "", Lmt: nil},
    48  			},
    49  			expectedLMT: openrtb2.Int8Ptr(1),
    50  		},
    51  		{
    52  			description: "14.2",
    53  			givenRequest: &openrtb2.BidRequest{
    54  				App:    &openrtb2.App{},
    55  				Device: &openrtb2.Device{Ext: json.RawMessage(`{"atts":0}`), OS: "iOS", OSV: "14.2", IFA: "", Lmt: nil},
    56  			},
    57  			expectedLMT: openrtb2.Int8Ptr(1),
    58  		},
    59  		{
    60  			description: "14.2",
    61  			givenRequest: &openrtb2.BidRequest{
    62  				App:    &openrtb2.App{},
    63  				Device: &openrtb2.Device{Ext: json.RawMessage(`{"atts":2}`), OS: "iOS", OSV: "14.2", IFA: "", Lmt: openrtb2.Int8Ptr(0)},
    64  			},
    65  			expectedLMT: openrtb2.Int8Ptr(1),
    66  		},
    67  		{
    68  			description: "14.2.7",
    69  			givenRequest: &openrtb2.BidRequest{
    70  				App:    &openrtb2.App{},
    71  				Device: &openrtb2.Device{Ext: json.RawMessage(`{"atts":1}`), OS: "iOS", OSV: "14.2.7", IFA: "", Lmt: nil},
    72  			},
    73  			expectedLMT: openrtb2.Int8Ptr(1),
    74  		},
    75  		{
    76  			description: "14.2.7",
    77  			givenRequest: &openrtb2.BidRequest{
    78  				App:    &openrtb2.App{},
    79  				Device: &openrtb2.Device{Ext: json.RawMessage(`{"atts":3}`), OS: "iOS", OSV: "14.2.7", IFA: "", Lmt: openrtb2.Int8Ptr(1)},
    80  			},
    81  			expectedLMT: openrtb2.Int8Ptr(0),
    82  		},
    83  	}
    84  
    85  	for _, test := range testCases {
    86  		ModifyForIOS(test.givenRequest)
    87  		assert.Equal(t, test.expectedLMT, test.givenRequest.Device.Lmt, test.description)
    88  	}
    89  }
    90  
    91  func TestModifyForIOSHelper(t *testing.T) {
    92  	testCases := []struct {
    93  		description               string
    94  		givenRequest              *openrtb2.BidRequest
    95  		expectedModifier140Called bool
    96  		expectedModifier142Called bool
    97  	}{
    98  		{
    99  			description: "Valid 14.0",
   100  			givenRequest: &openrtb2.BidRequest{
   101  				App:    &openrtb2.App{},
   102  				Device: &openrtb2.Device{OS: "iOS", OSV: "14.0"},
   103  			},
   104  			expectedModifier140Called: true,
   105  			expectedModifier142Called: false,
   106  		},
   107  		{
   108  			description: "Valid 14.2 Or Greater",
   109  			givenRequest: &openrtb2.BidRequest{
   110  				App:    &openrtb2.App{},
   111  				Device: &openrtb2.Device{OS: "iOS", OSV: "14.2"},
   112  			},
   113  			expectedModifier140Called: false,
   114  			expectedModifier142Called: true,
   115  		},
   116  		{
   117  			description: "Invalid Version",
   118  			givenRequest: &openrtb2.BidRequest{
   119  				App:    &openrtb2.App{},
   120  				Device: &openrtb2.Device{OS: "iOS", OSV: "invalid"},
   121  			},
   122  			expectedModifier140Called: false,
   123  			expectedModifier142Called: false,
   124  		},
   125  		{
   126  			description: "Invalid OS",
   127  			givenRequest: &openrtb2.BidRequest{
   128  				App:    &openrtb2.App{},
   129  				Device: &openrtb2.Device{OS: "invalid", OSV: "14.0"},
   130  			},
   131  			expectedModifier140Called: false,
   132  			expectedModifier142Called: false,
   133  		},
   134  		{
   135  			description: "Invalid Nil Device",
   136  			givenRequest: &openrtb2.BidRequest{
   137  				App:    &openrtb2.App{},
   138  				Device: nil,
   139  			},
   140  			expectedModifier140Called: false,
   141  			expectedModifier142Called: false,
   142  		},
   143  	}
   144  
   145  	for _, test := range testCases {
   146  		modifierIOS140Called := false
   147  		modifierIOS140 := func(req *openrtb2.BidRequest) { modifierIOS140Called = true }
   148  
   149  		modifierIOS142Called := false
   150  		modifierIOS142 := func(req *openrtb2.BidRequest) { modifierIOS142Called = true }
   151  
   152  		modifiers := map[iosutil.VersionClassification]modifier{
   153  			iosutil.Version140:          modifierIOS140,
   154  			iosutil.Version142OrGreater: modifierIOS142,
   155  		}
   156  
   157  		modifyForIOS(test.givenRequest, modifiers)
   158  
   159  		assert.Equal(t, test.expectedModifier140Called, modifierIOS140Called, test.description)
   160  		assert.Equal(t, test.expectedModifier142Called, modifierIOS142Called, test.description)
   161  	}
   162  }
   163  
   164  func TestIsRequestForIOS(t *testing.T) {
   165  	testCases := []struct {
   166  		description  string
   167  		givenRequest *openrtb2.BidRequest
   168  		expected     bool
   169  	}{
   170  		{
   171  			description: "Valid",
   172  			givenRequest: &openrtb2.BidRequest{
   173  				App:    &openrtb2.App{},
   174  				Device: &openrtb2.Device{OS: "iOS"},
   175  			},
   176  			expected: true,
   177  		},
   178  		{
   179  			description: "Valid - OS Case Insensitive",
   180  			givenRequest: &openrtb2.BidRequest{
   181  				App:    &openrtb2.App{},
   182  				Device: &openrtb2.Device{OS: "IOS"},
   183  			},
   184  			expected: true,
   185  		},
   186  		{
   187  			description:  "Invalid - Nil Request",
   188  			givenRequest: nil,
   189  			expected:     false,
   190  		},
   191  		{
   192  			description: "Invalid - Nil App",
   193  			givenRequest: &openrtb2.BidRequest{
   194  				App:    nil,
   195  				Device: &openrtb2.Device{OS: "iOS"},
   196  			},
   197  			expected: false,
   198  		},
   199  		{
   200  			description: "Invalid - Nil Device",
   201  			givenRequest: &openrtb2.BidRequest{
   202  				App:    &openrtb2.App{},
   203  				Device: nil,
   204  			},
   205  			expected: false,
   206  		},
   207  		{
   208  			description: "Invalid - Empty OS",
   209  			givenRequest: &openrtb2.BidRequest{
   210  				App:    &openrtb2.App{},
   211  				Device: &openrtb2.Device{OS: ""},
   212  			},
   213  			expected: false,
   214  		},
   215  		{
   216  			description: "Invalid - Wrong OS",
   217  			givenRequest: &openrtb2.BidRequest{
   218  				App:    &openrtb2.App{},
   219  				Device: &openrtb2.Device{OS: "Android"},
   220  			},
   221  			expected: false,
   222  		},
   223  	}
   224  
   225  	for _, test := range testCases {
   226  		result := isRequestForIOS(test.givenRequest)
   227  		assert.Equal(t, test.expected, result, test.description)
   228  	}
   229  }
   230  
   231  func TestModifyForIOS14X(t *testing.T) {
   232  	testCases := []struct {
   233  		description string
   234  		givenDevice openrtb2.Device
   235  		expectedLMT *int8
   236  	}{
   237  		{
   238  			description: "IFA Empty",
   239  			givenDevice: openrtb2.Device{IFA: "", Lmt: nil},
   240  			expectedLMT: openrtb2.Int8Ptr(1),
   241  		},
   242  		{
   243  			description: "IFA Zero UUID",
   244  			givenDevice: openrtb2.Device{IFA: "00000000-0000-0000-0000-000000000000", Lmt: nil},
   245  			expectedLMT: openrtb2.Int8Ptr(1),
   246  		},
   247  		{
   248  			description: "IFA Populated",
   249  			givenDevice: openrtb2.Device{IFA: "any-real-value", Lmt: nil},
   250  			expectedLMT: openrtb2.Int8Ptr(0),
   251  		},
   252  		{
   253  			description: "Overwrites Existing",
   254  			givenDevice: openrtb2.Device{IFA: "", Lmt: openrtb2.Int8Ptr(0)},
   255  			expectedLMT: openrtb2.Int8Ptr(1),
   256  		},
   257  	}
   258  
   259  	for _, test := range testCases {
   260  		request := &openrtb2.BidRequest{Device: &test.givenDevice}
   261  		modifyForIOS14X(request)
   262  		assert.Equal(t, test.expectedLMT, request.Device.Lmt, test.description)
   263  	}
   264  }
   265  
   266  func TestModifyForIOS142OrGreater(t *testing.T) {
   267  	testCases := []struct {
   268  		description string
   269  		givenDevice openrtb2.Device
   270  		expectedLMT *int8
   271  	}{
   272  		{
   273  			description: "Not Determined",
   274  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":0}`), Lmt: nil},
   275  			expectedLMT: openrtb2.Int8Ptr(1),
   276  		},
   277  		{
   278  			description: "Restricted",
   279  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":1}`), Lmt: nil},
   280  			expectedLMT: openrtb2.Int8Ptr(1),
   281  		},
   282  		{
   283  			description: "Denied",
   284  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":2}`), Lmt: nil},
   285  			expectedLMT: openrtb2.Int8Ptr(1),
   286  		},
   287  		{
   288  			description: "Authorized",
   289  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":3}`), Lmt: nil},
   290  			expectedLMT: openrtb2.Int8Ptr(0),
   291  		},
   292  		{
   293  			description: "Overwrites Existing",
   294  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":3}`), Lmt: openrtb2.Int8Ptr(1)},
   295  			expectedLMT: openrtb2.Int8Ptr(0),
   296  		},
   297  		{
   298  			description: "Invalid Value - Unknown",
   299  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":4}`), Lmt: nil},
   300  			expectedLMT: nil,
   301  		},
   302  		{
   303  			description: "Invalid Value - Unknown - Does Not Overwrite Existing",
   304  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":4}`), Lmt: openrtb2.Int8Ptr(1)},
   305  			expectedLMT: openrtb2.Int8Ptr(1),
   306  		},
   307  		{
   308  			description: "Invalid Value - Missing",
   309  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{}`), Lmt: nil},
   310  			expectedLMT: nil,
   311  		},
   312  		{
   313  			description: "Invalid Value - Wrong Type",
   314  			givenDevice: openrtb2.Device{Ext: json.RawMessage(`{"atts":"wrong type"}`), Lmt: nil},
   315  			expectedLMT: nil,
   316  		},
   317  	}
   318  
   319  	for _, test := range testCases {
   320  		request := &openrtb2.BidRequest{Device: &test.givenDevice}
   321  		modifyForIOS142OrGreater(request)
   322  		assert.Equal(t, test.expectedLMT, request.Device.Lmt, test.description)
   323  	}
   324  }