github.com/prebid/prebid-server@v0.275.0/router/router_test.go (about) 1 package router 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "net/http/httptest" 7 "os" 8 "testing" 9 10 "github.com/prebid/prebid-server/config" 11 "github.com/prebid/prebid-server/openrtb_ext" 12 13 "github.com/stretchr/testify/assert" 14 ) 15 16 const adapterDirectory = "../adapters" 17 18 type testValidator struct{} 19 20 func (validator *testValidator) Validate(name openrtb_ext.BidderName, ext json.RawMessage) error { 21 return nil 22 } 23 24 func (validator *testValidator) Schema(name openrtb_ext.BidderName) string { 25 if name == openrtb_ext.BidderAppnexus { 26 return "{\"appnexus\":true}" 27 } else { 28 return "{\"appnexus\":false}" 29 } 30 } 31 32 func ensureHasKey(t *testing.T, data map[string]json.RawMessage, key string) { 33 t.Helper() 34 if _, ok := data[key]; !ok { 35 t.Errorf("Expected map to produce a schema for adapter: %s", key) 36 } 37 } 38 39 func TestNewJsonDirectoryServer(t *testing.T) { 40 defaultAlias := map[string]string{"aliastest": "appnexus"} 41 yamlAlias := map[openrtb_ext.BidderName]openrtb_ext.BidderName{openrtb_ext.BidderName("alias"): openrtb_ext.BidderName("parentAlias")} 42 handler := newJsonDirectoryServer("../static/bidder-params", &testValidator{}, defaultAlias, yamlAlias) 43 recorder := httptest.NewRecorder() 44 request, _ := http.NewRequest("GET", "/whatever", nil) 45 handler(recorder, request, nil) 46 47 var data map[string]json.RawMessage 48 json.Unmarshal(recorder.Body.Bytes(), &data) 49 50 // Make sure that every adapter has a json schema by the same name associated with it. 51 adapterFiles, err := os.ReadDir(adapterDirectory) 52 if err != nil { 53 t.Fatalf("Failed to open the adapters directory: %v", err) 54 } 55 56 for _, adapterFile := range adapterFiles { 57 if adapterFile.IsDir() && adapterFile.Name() != "adapterstest" { 58 ensureHasKey(t, data, adapterFile.Name()) 59 } 60 } 61 62 ensureHasKey(t, data, "aliastest") 63 ensureHasKey(t, data, "alias") 64 } 65 66 func TestCheckSupportedUserSyncEndpoints(t *testing.T) { 67 anyEndpoint := &config.SyncerEndpoint{URL: "anyURL"} 68 69 var testCases = []struct { 70 description string 71 givenBidderInfos config.BidderInfos 72 expectedError string 73 }{ 74 { 75 description: "None", 76 givenBidderInfos: config.BidderInfos{}, 77 expectedError: "", 78 }, 79 { 80 description: "One - No Syncer", 81 givenBidderInfos: config.BidderInfos{ 82 "a": config.BidderInfo{Syncer: nil}, 83 }, 84 expectedError: "", 85 }, 86 { 87 description: "One - Invalid Supported Endpoint", 88 givenBidderInfos: config.BidderInfos{ 89 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"invalid"}}}, 90 }, 91 expectedError: "failed to load bidder info for a, user sync supported endpoint 'invalid' is unrecognized", 92 }, 93 { 94 description: "One - IFrame Supported - Not Specified", 95 givenBidderInfos: config.BidderInfos{ 96 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"iframe"}, IFrame: nil}}, 97 }, 98 expectedError: "", 99 }, 100 { 101 description: "One - IFrame Supported - Specified", 102 givenBidderInfos: config.BidderInfos{ 103 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"iframe"}, IFrame: anyEndpoint}}, 104 }, 105 expectedError: "", 106 }, 107 { 108 description: "One - Redirect Supported - Not Specified", 109 givenBidderInfos: config.BidderInfos{ 110 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"redirect"}, Redirect: nil}}, 111 }, 112 expectedError: "", 113 }, 114 { 115 description: "One - IFrame Supported - Specified", 116 givenBidderInfos: config.BidderInfos{ 117 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"redirect"}, Redirect: anyEndpoint}}, 118 }, 119 expectedError: "", 120 }, 121 { 122 description: "One - IFrame + Redirect Supported - Not Specified", 123 givenBidderInfos: config.BidderInfos{ 124 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"iframe", "redirect"}, IFrame: nil, Redirect: nil}}, 125 }, 126 expectedError: "", 127 }, 128 { 129 description: "One - IFrame + Redirect Supported - Specified", 130 givenBidderInfos: config.BidderInfos{ 131 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"iframe", "redirect"}, IFrame: anyEndpoint, Redirect: anyEndpoint}}, 132 }, 133 expectedError: "", 134 }, 135 { 136 description: "Many - With Invalid Supported Endpoint", 137 givenBidderInfos: config.BidderInfos{ 138 "a": config.BidderInfo{}, 139 "b": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"invalid"}}}, 140 }, 141 expectedError: "failed to load bidder info for b, user sync supported endpoint 'invalid' is unrecognized", 142 }, 143 { 144 description: "Many - Specified + Not Specified", 145 givenBidderInfos: config.BidderInfos{ 146 "a": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"iframe"}, IFrame: anyEndpoint}}, 147 "b": config.BidderInfo{Syncer: &config.Syncer{Supports: []string{"redirect"}, Redirect: nil}}, 148 }, 149 expectedError: "", 150 }, 151 } 152 153 for _, test := range testCases { 154 resultErr := checkSupportedUserSyncEndpoints(test.givenBidderInfos) 155 if test.expectedError == "" { 156 assert.NoError(t, resultErr, test.description) 157 } else { 158 assert.EqualError(t, resultErr, test.expectedError, test.description) 159 } 160 } 161 } 162 163 // Prevents #648 164 func TestCORSSupport(t *testing.T) { 165 const origin = "https://publisher-domain.com" 166 handler := func(w http.ResponseWriter, r *http.Request) {} 167 cors := SupportCORS(http.HandlerFunc(handler)) 168 rr := httptest.NewRecorder() 169 req, err := http.NewRequest("OPTIONS", "http://some-domain.com/openrtb2/auction", nil) 170 req.Header.Set("Access-Control-Request-Method", "POST") 171 req.Header.Set("Access-Control-Request-Headers", "origin") 172 req.Header.Set("Origin", origin) 173 174 if !assert.NoError(t, err) { 175 return 176 } 177 cors.ServeHTTP(rr, req) 178 assert.Equal(t, origin, rr.Header().Get("Access-Control-Allow-Origin")) 179 } 180 181 func TestNoCache(t *testing.T) { 182 nc := NoCache{ 183 Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}), 184 } 185 rw := httptest.NewRecorder() 186 req, err := http.NewRequest("GET", "http://localhost/nocache", nil) 187 if err != nil { 188 t.Fatal(err) 189 } 190 req.Header.Set("ETag", "abcdef") 191 nc.ServeHTTP(rw, req) 192 h := rw.Header() 193 if expected := "no-cache, no-store, must-revalidate"; expected != h.Get("Cache-Control") { 194 t.Errorf("invalid cache-control header: expected: %s got: %s", expected, h.Get("Cache-Control")) 195 } 196 if expected := "no-cache"; expected != h.Get("Pragma") { 197 t.Errorf("invalid pragma header: expected: %s got: %s", expected, h.Get("Pragma")) 198 } 199 if expected := "0"; expected != h.Get("Expires") { 200 t.Errorf("invalid expires header: expected: %s got: %s", expected, h.Get("Expires")) 201 } 202 if expected := ""; expected != h.Get("ETag") { 203 t.Errorf("invalid etag header: expected: %s got: %s", expected, h.Get("ETag")) 204 } 205 } 206 207 var testDefReqConfig = config.DefReqConfig{ 208 Type: "file", 209 FileSystem: config.DefReqFiles{ 210 FileName: "test_aliases.json", 211 }, 212 AliasInfo: true, 213 } 214 215 func TestLoadDefaultAliases(t *testing.T) { 216 defAliases, aliasJSON := readDefaultRequest(testDefReqConfig) 217 expectedJSON := []byte(`{"ext":{"prebid":{"aliases": {"test1": "appnexus", "test2": "rubicon", "test3": "openx"}}}}`) 218 expectedAliases := map[string]string{ 219 "test1": "appnexus", 220 "test2": "rubicon", 221 "test3": "openx", 222 } 223 224 assert.JSONEq(t, string(expectedJSON), string(aliasJSON)) 225 assert.Equal(t, expectedAliases, defAliases) 226 } 227 228 func TestLoadDefaultAliasesNoInfo(t *testing.T) { 229 noInfoConfig := testDefReqConfig 230 noInfoConfig.AliasInfo = false 231 defAliases, aliasJSON := readDefaultRequest(noInfoConfig) 232 expectedJSON := []byte(`{"ext":{"prebid":{"aliases": {"test1": "appnexus", "test2": "rubicon", "test3": "openx"}}}}`) 233 expectedAliases := map[string]string{} 234 235 assert.JSONEq(t, string(expectedJSON), string(aliasJSON)) 236 assert.Equal(t, expectedAliases, defAliases) 237 } 238 239 func TestValidateDefaultAliases(t *testing.T) { 240 var testCases = []struct { 241 description string 242 givenAliases map[string]string 243 expectedError string 244 }{ 245 { 246 description: "None", 247 givenAliases: map[string]string{}, 248 expectedError: "", 249 }, 250 { 251 description: "Valid", 252 givenAliases: map[string]string{"aAlias": "a"}, 253 expectedError: "", 254 }, 255 { 256 description: "Invalid", 257 givenAliases: map[string]string{"all": "a"}, 258 expectedError: "default request alias errors (1 error):\n 1: alias all is a reserved bidder name and cannot be used\n", 259 }, 260 { 261 description: "Mixed", 262 givenAliases: map[string]string{"aAlias": "a", "all": "a"}, 263 expectedError: "default request alias errors (1 error):\n 1: alias all is a reserved bidder name and cannot be used\n", 264 }, 265 } 266 267 for _, test := range testCases { 268 err := validateDefaultAliases(test.givenAliases) 269 270 if test.expectedError == "" { 271 assert.NoError(t, err, test.description) 272 } else { 273 assert.EqualError(t, err, test.expectedError, test.description) 274 } 275 } 276 }