github.com/prebid/prebid-server/v2@v2.18.0/stored_requests/backends/file_fetcher/fetcher_test.go (about) 1 package file_fetcher 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 "testing" 8 9 "github.com/prebid/prebid-server/v2/stored_requests" 10 "github.com/prebid/prebid-server/v2/util/jsonutil" 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestFileFetcher(t *testing.T) { 15 // Load the test input files for testing 16 fetcher, err := NewFileFetcher("./test") 17 if err != nil { 18 t.Errorf("Failed to create a Fetcher: %v", err) 19 } 20 21 // Test stored request and stored imps 22 storedReqs, storedImps, errs := fetcher.FetchRequests(context.Background(), []string{"1", "2"}, []string{"some-imp"}) 23 assertErrorCount(t, 0, errs) 24 25 validateStoredReqOne(t, storedReqs) 26 validateStoredReqTwo(t, storedReqs) 27 validateImp(t, storedImps) 28 } 29 30 func TestStoredResponseFileFetcher(t *testing.T) { 31 // grab the fetcher that do not have /test/stored_responses/stored_responses FS directory 32 directoryNotExistfetcher, err := NewFileFetcher("./test/stored_responses") 33 if err != nil { 34 t.Errorf("Failed to create a Fetcher: %v", err) 35 } 36 37 // we should receive 1 error since we do not have "stored_responses" directory in ./test/stored_responses 38 _, errs := directoryNotExistfetcher.FetchResponses(context.Background(), []string{}) 39 assertErrorCount(t, 1, errs) 40 41 // grab the fetcher that has /test/stored_responses FS directory 42 fetcher, err := NewFileFetcher("./test") 43 if err != nil { 44 t.Errorf("Failed to create a Fetcher: %v", err) 45 } 46 47 // Test stored responses, we have 3 stored responses in ./test/stored_responses 48 storedResps, errs := fetcher.FetchResponses(context.Background(), []string{"bar", "escaped", "does_not_exist"}) 49 // expect 1 error since we do not have "does_not_exist" stored response file from ./test 50 assertErrorCount(t, 1, errs) 51 52 validateStoredResponse[map[string]string](t, storedResps, "bar", func(val map[string]string) error { 53 if len(val) != 1 { 54 return fmt.Errorf("Unexpected value length. Expected %d, Got %d", 1, len(val)) 55 } 56 57 data, hadKey := val["test"] 58 if !hadKey { 59 return fmt.Errorf(`missing key "test" in the value`) 60 } 61 62 expectedVal := "bar" 63 if data != expectedVal { 64 return fmt.Errorf(`Bad value for key "test". Expected "%s", Got "%s"`, expectedVal, data) 65 } 66 return nil 67 }) 68 69 validateStoredResponse[string](t, storedResps, "escaped", func(val string) error { 70 expectedVal := `esca"ped` 71 if val != expectedVal { 72 return fmt.Errorf(`Bad data. Expected "%v", Got "%s"`, expectedVal, val) 73 } 74 return nil 75 }) 76 } 77 78 func TestAccountFetcher(t *testing.T) { 79 fetcher, err := NewFileFetcher("./test") 80 assert.NoError(t, err, "Failed to create test fetcher") 81 82 account, errs := fetcher.FetchAccount(context.Background(), json.RawMessage(`{"events_enabled":true}`), "valid") 83 assertErrorCount(t, 0, errs) 84 assert.JSONEq(t, `{"disabled":false, "events_enabled":true, "id":"valid" }`, string(account)) 85 86 _, errs = fetcher.FetchAccount(context.Background(), json.RawMessage(`{"events_enabled":true}`), "nonexistent") 87 assertErrorCount(t, 1, errs) 88 assert.Error(t, errs[0]) 89 assert.Equal(t, stored_requests.NotFoundError{ID: "nonexistent", DataType: "Account"}, errs[0]) 90 91 _, errs = fetcher.FetchAccount(context.Background(), json.RawMessage(`{"events_enabled"}`), "valid") 92 assertErrorCount(t, 1, errs) 93 assert.Error(t, errs[0]) 94 assert.Equal(t, fmt.Errorf("Invalid JSON Document"), errs[0]) 95 96 } 97 98 func TestInvalidDirectory(t *testing.T) { 99 _, err := NewFileFetcher("./nonexistant-directory") 100 if err == nil { 101 t.Errorf("There should be an error if we use a directory which doesn't exist.") 102 } 103 } 104 105 func validateStoredReqOne(t *testing.T, storedRequests map[string]json.RawMessage) { 106 value, hasID := storedRequests["1"] 107 if !hasID { 108 t.Fatalf("Expected stored request data to have id: %d", 1) 109 } 110 111 var req1Val map[string]string 112 if err := jsonutil.UnmarshalValid(value, &req1Val); err != nil { 113 t.Errorf("Failed to unmarshal 1: %v", err) 114 } 115 if len(req1Val) != 1 { 116 t.Errorf("Unexpected req1Val length. Expected %d, Got %d", 1, len(req1Val)) 117 } 118 data, hadKey := req1Val["test"] 119 if !hadKey { 120 t.Errorf("req1Val should have had a \"test\" key, but it didn't.") 121 } 122 if data != "foo" { 123 t.Errorf(`Bad data in "test" of stored request "1". Expected %s, Got %s`, "foo", data) 124 } 125 } 126 127 func validateStoredReqTwo(t *testing.T, storedRequests map[string]json.RawMessage) { 128 value, hasId := storedRequests["2"] 129 if !hasId { 130 t.Fatalf("Expected stored request map to have id: %d", 2) 131 } 132 133 var req2Val string 134 if err := jsonutil.UnmarshalValid(value, &req2Val); err != nil { 135 t.Errorf("Failed to unmarshal %d: %v", 2, err) 136 } 137 if req2Val != `esca"ped` { 138 t.Errorf(`Bad data in stored request "2". Expected %v, Got %s`, `esca"ped`, req2Val) 139 } 140 } 141 142 func validateImp(t *testing.T, storedImps map[string]json.RawMessage) { 143 value, hasId := storedImps["some-imp"] 144 if !hasId { 145 t.Fatal("Expected Stored Imp map to have id: some-imp") 146 } 147 148 var impVal map[string]bool 149 if err := jsonutil.UnmarshalValid(value, &impVal); err != nil { 150 t.Errorf("Failed to unmarshal some-imp: %v", err) 151 } 152 if len(impVal) != 1 { 153 t.Errorf("Unexpected impVal length. Expected %d, Got %d", 1, len(impVal)) 154 } 155 data, hadKey := impVal["imp"] 156 if !hadKey { 157 t.Errorf("some-imp should have had a \"imp\" key, but it didn't.") 158 } 159 if !data { 160 t.Errorf(`Bad data in "imp" of stored request "some-imp". Expected true, Got %t`, data) 161 } 162 } 163 164 func assertErrorCount(t *testing.T, num int, errs []error) { 165 t.Helper() 166 if len(errs) != num { 167 t.Errorf("Wrong number of errors. Expected %d. Got %d. Errors are %v", num, len(errs), errs) 168 } 169 } 170 171 func newCategoryFetcher(directory string) (stored_requests.CategoryFetcher, error) { 172 fetcher, err := NewFileFetcher(directory) 173 if err != nil { 174 return nil, err 175 } 176 catfetcher, ok := fetcher.(stored_requests.CategoryFetcher) 177 if !ok { 178 return nil, fmt.Errorf("Failed to type cast fetcher to CategoryFetcher") 179 } 180 return catfetcher, nil 181 } 182 183 func TestCategoriesFetcherWithPublisher(t *testing.T) { 184 fetcher, err := newCategoryFetcher("./test/category-mapping") 185 if err != nil { 186 t.Errorf("Failed to create a category Fetcher: %v", err) 187 } 188 category, err := fetcher.FetchCategories(nil, "test", "categories", "IAB1-1") 189 assert.Equal(t, nil, err, "Categories were loaded incorrectly") 190 assert.Equal(t, "Beverages", category, "Categories were loaded incorrectly") 191 } 192 193 func TestCategoriesFetcherWithoutPublisher(t *testing.T) { 194 fetcher, err := newCategoryFetcher("./test/category-mapping") 195 if err != nil { 196 t.Errorf("Failed to create a category Fetcher: %v", err) 197 } 198 category, err := fetcher.FetchCategories(nil, "test", "", "IAB1-1") 199 assert.Equal(t, nil, err, "Categories were loaded incorrectly") 200 assert.Equal(t, "VideoGames", category, "Categories were loaded incorrectly") 201 } 202 203 func TestCategoriesFetcherNoCategory(t *testing.T) { 204 fetcher, err := newCategoryFetcher("./test/category-mapping") 205 if err != nil { 206 t.Errorf("Failed to create a category Fetcher: %v", err) 207 } 208 _, fetchingErr := fetcher.FetchCategories(nil, "test", "", "IAB1-100") 209 assert.Equal(t, fmt.Errorf("Unable to find category for adserver 'test', publisherId: '', iab category: 'IAB1-100'"), 210 fetchingErr, "Categories were loaded incorrectly") 211 } 212 213 func TestCategoriesFetcherBrokenJson(t *testing.T) { 214 fetcher, err := newCategoryFetcher("./test/category-mapping") 215 if err != nil { 216 t.Errorf("Failed to create a category Fetcher: %v", err) 217 } 218 _, fetchingErr := fetcher.FetchCategories(nil, "test", "broken", "IAB1-100") 219 assert.Equal(t, fmt.Errorf("Unable to unmarshal categories for adserver: 'test', publisherId: 'broken'"), 220 fetchingErr, "Categories were loaded incorrectly") 221 } 222 223 func TestCategoriesFetcherNoCategoriesFile(t *testing.T) { 224 fetcher, err := newCategoryFetcher("./test/category-mapping") 225 if err != nil { 226 t.Errorf("Failed to create a category Fetcher: %v", err) 227 } 228 _, fetchingErr := fetcher.FetchCategories(nil, "test", "not_exists", "IAB1-100") 229 assert.Equal(t, fmt.Errorf("Unable to find mapping file for adserver: 'test', publisherId: 'not_exists'"), 230 fetchingErr, "Categories were loaded incorrectly") 231 } 232 233 // validateStoredResponse - reusable function in the stored response test to verify the actual data read from the fetcher 234 func validateStoredResponse[T any](t *testing.T, storedInfo map[string]json.RawMessage, id string, verifyFunc func(outputVal T) error) { 235 storedValue, hasID := storedInfo[id] 236 if !hasID { 237 t.Fatalf(`Expected stored response data to have id: "%s"`, id) 238 } 239 240 var unmarshalledValue T 241 if err := jsonutil.UnmarshalValid(storedValue, &unmarshalledValue); err != nil { 242 t.Errorf(`Failed to unmarshal stored response data of id "%s": %v`, id, err) 243 } 244 245 if err := verifyFunc(unmarshalledValue); err != nil { 246 t.Errorf(`Bad data in stored response of id: "%s": %v`, id, err) 247 } 248 }