github.com/google/go-github/v33@v33.0.0/github/search_test.go (about) 1 // Copyright 2013 The go-github AUTHORS. All rights reserved. 2 // 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package github 7 8 import ( 9 "context" 10 "fmt" 11 "net/http" 12 "reflect" 13 "testing" 14 ) 15 16 func TestSearchService_Repositories(t *testing.T) { 17 client, mux, _, teardown := setup() 18 defer teardown() 19 20 mux.HandleFunc("/search/repositories", func(w http.ResponseWriter, r *http.Request) { 21 testMethod(t, r, "GET") 22 testFormValues(t, r, values{ 23 "q": "blah", 24 "sort": "forks", 25 "order": "desc", 26 "page": "2", 27 "per_page": "2", 28 }) 29 30 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"id":1},{"id":2}]}`) 31 }) 32 33 opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}} 34 result, _, err := client.Search.Repositories(context.Background(), "blah", opts) 35 if err != nil { 36 t.Errorf("Search.Repositories returned error: %v", err) 37 } 38 39 want := &RepositoriesSearchResult{ 40 Total: Int(4), 41 IncompleteResults: Bool(false), 42 Repositories: []*Repository{{ID: Int64(1)}, {ID: Int64(2)}}, 43 } 44 if !reflect.DeepEqual(result, want) { 45 t.Errorf("Search.Repositories returned %+v, want %+v", result, want) 46 } 47 } 48 49 func TestSearchService_Topics(t *testing.T) { 50 client, mux, _, teardown := setup() 51 defer teardown() 52 53 mux.HandleFunc("/search/topics", func(w http.ResponseWriter, r *http.Request) { 54 testMethod(t, r, "GET") 55 testFormValues(t, r, values{ 56 "q": "blah", 57 "page": "2", 58 "per_page": "2", 59 }) 60 61 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"name":"blah"},{"name":"blahblah"}]}`) 62 }) 63 64 opts := &SearchOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}} 65 result, _, err := client.Search.Topics(context.Background(), "blah", opts) 66 if err != nil { 67 t.Errorf("Search.Topics returned error: %v", err) 68 } 69 70 want := &TopicsSearchResult{ 71 Total: Int(4), 72 IncompleteResults: Bool(false), 73 Topics: []*TopicResult{{Name: String("blah")}, {Name: String("blahblah")}}, 74 } 75 if !reflect.DeepEqual(result, want) { 76 t.Errorf("Search.Topics returned %+v, want %+v", result, want) 77 } 78 } 79 80 func TestSearchService_Commits(t *testing.T) { 81 client, mux, _, teardown := setup() 82 defer teardown() 83 84 mux.HandleFunc("/search/commits", func(w http.ResponseWriter, r *http.Request) { 85 testMethod(t, r, "GET") 86 testFormValues(t, r, values{ 87 "q": "blah", 88 "sort": "author-date", 89 "order": "desc", 90 }) 91 92 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"sha":"random_hash1"},{"sha":"random_hash2"}]}`) 93 }) 94 95 opts := &SearchOptions{Sort: "author-date", Order: "desc"} 96 result, _, err := client.Search.Commits(context.Background(), "blah", opts) 97 if err != nil { 98 t.Errorf("Search.Commits returned error: %v", err) 99 } 100 101 want := &CommitsSearchResult{ 102 Total: Int(4), 103 IncompleteResults: Bool(false), 104 Commits: []*CommitResult{{SHA: String("random_hash1")}, {SHA: String("random_hash2")}}, 105 } 106 if !reflect.DeepEqual(result, want) { 107 t.Errorf("Search.Commits returned %+v, want %+v", result, want) 108 } 109 } 110 111 func TestSearchService_Issues(t *testing.T) { 112 client, mux, _, teardown := setup() 113 defer teardown() 114 115 mux.HandleFunc("/search/issues", func(w http.ResponseWriter, r *http.Request) { 116 testMethod(t, r, "GET") 117 testFormValues(t, r, values{ 118 "q": "blah", 119 "sort": "forks", 120 "order": "desc", 121 "page": "2", 122 "per_page": "2", 123 }) 124 125 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": true, "items": [{"number":1},{"number":2}]}`) 126 }) 127 128 opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}} 129 result, _, err := client.Search.Issues(context.Background(), "blah", opts) 130 if err != nil { 131 t.Errorf("Search.Issues returned error: %v", err) 132 } 133 134 want := &IssuesSearchResult{ 135 Total: Int(4), 136 IncompleteResults: Bool(true), 137 Issues: []*Issue{{Number: Int(1)}, {Number: Int(2)}}, 138 } 139 if !reflect.DeepEqual(result, want) { 140 t.Errorf("Search.Issues returned %+v, want %+v", result, want) 141 } 142 } 143 144 func TestSearchService_Issues_withQualifiersNoOpts(t *testing.T) { 145 client, mux, _, teardown := setup() 146 defer teardown() 147 148 const q = "gopher is:issue label:bug language:c++ pushed:>=2018-01-01 stars:>=200" 149 150 var requestURI string 151 mux.HandleFunc("/search/issues", func(w http.ResponseWriter, r *http.Request) { 152 testMethod(t, r, "GET") 153 testFormValues(t, r, values{ 154 "q": q, 155 }) 156 requestURI = r.RequestURI 157 158 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": true, "items": [{"number":1},{"number":2}]}`) 159 }) 160 161 opts := &SearchOptions{} 162 result, _, err := client.Search.Issues(context.Background(), q, opts) 163 if err != nil { 164 t.Errorf("Search.Issues returned error: %v", err) 165 } 166 167 if want := "/api-v3/search/issues?q=gopher+is%3Aissue+label%3Abug+language%3Ac%2B%2B+pushed%3A%3E%3D2018-01-01+stars%3A%3E%3D200"; requestURI != want { 168 t.Fatalf("URI encoding failed: got %v, want %v", requestURI, want) 169 } 170 171 want := &IssuesSearchResult{ 172 Total: Int(4), 173 IncompleteResults: Bool(true), 174 Issues: []*Issue{{Number: Int(1)}, {Number: Int(2)}}, 175 } 176 if !reflect.DeepEqual(result, want) { 177 t.Errorf("Search.Issues returned %+v, want %+v", result, want) 178 } 179 } 180 181 func TestSearchService_Issues_withQualifiersAndOpts(t *testing.T) { 182 client, mux, _, teardown := setup() 183 defer teardown() 184 185 const q = "gopher is:issue label:bug language:c++ pushed:>=2018-01-01 stars:>=200" 186 187 var requestURI string 188 mux.HandleFunc("/search/issues", func(w http.ResponseWriter, r *http.Request) { 189 testMethod(t, r, "GET") 190 testFormValues(t, r, values{ 191 "q": q, 192 "sort": "forks", 193 }) 194 requestURI = r.RequestURI 195 196 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": true, "items": [{"number":1},{"number":2}]}`) 197 }) 198 199 opts := &SearchOptions{Sort: "forks"} 200 result, _, err := client.Search.Issues(context.Background(), q, opts) 201 if err != nil { 202 t.Errorf("Search.Issues returned error: %v", err) 203 } 204 205 if want := "/api-v3/search/issues?q=gopher+is%3Aissue+label%3Abug+language%3Ac%2B%2B+pushed%3A%3E%3D2018-01-01+stars%3A%3E%3D200&sort=forks"; requestURI != want { 206 t.Fatalf("URI encoding failed: got %v, want %v", requestURI, want) 207 } 208 209 want := &IssuesSearchResult{ 210 Total: Int(4), 211 IncompleteResults: Bool(true), 212 Issues: []*Issue{{Number: Int(1)}, {Number: Int(2)}}, 213 } 214 if !reflect.DeepEqual(result, want) { 215 t.Errorf("Search.Issues returned %+v, want %+v", result, want) 216 } 217 } 218 219 func TestSearchService_Users(t *testing.T) { 220 client, mux, _, teardown := setup() 221 defer teardown() 222 223 mux.HandleFunc("/search/users", func(w http.ResponseWriter, r *http.Request) { 224 testMethod(t, r, "GET") 225 testFormValues(t, r, values{ 226 "q": "blah", 227 "sort": "forks", 228 "order": "desc", 229 "page": "2", 230 "per_page": "2", 231 }) 232 233 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"id":1},{"id":2}]}`) 234 }) 235 236 opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}} 237 result, _, err := client.Search.Users(context.Background(), "blah", opts) 238 if err != nil { 239 t.Errorf("Search.Issues returned error: %v", err) 240 } 241 242 want := &UsersSearchResult{ 243 Total: Int(4), 244 IncompleteResults: Bool(false), 245 Users: []*User{{ID: Int64(1)}, {ID: Int64(2)}}, 246 } 247 if !reflect.DeepEqual(result, want) { 248 t.Errorf("Search.Users returned %+v, want %+v", result, want) 249 } 250 } 251 252 func TestSearchService_Code(t *testing.T) { 253 client, mux, _, teardown := setup() 254 defer teardown() 255 256 mux.HandleFunc("/search/code", func(w http.ResponseWriter, r *http.Request) { 257 testMethod(t, r, "GET") 258 testFormValues(t, r, values{ 259 "q": "blah", 260 "sort": "forks", 261 "order": "desc", 262 "page": "2", 263 "per_page": "2", 264 }) 265 266 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"name":"1"},{"name":"2"}]}`) 267 }) 268 269 opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}} 270 result, _, err := client.Search.Code(context.Background(), "blah", opts) 271 if err != nil { 272 t.Errorf("Search.Code returned error: %v", err) 273 } 274 275 want := &CodeSearchResult{ 276 Total: Int(4), 277 IncompleteResults: Bool(false), 278 CodeResults: []*CodeResult{{Name: String("1")}, {Name: String("2")}}, 279 } 280 if !reflect.DeepEqual(result, want) { 281 t.Errorf("Search.Code returned %+v, want %+v", result, want) 282 } 283 } 284 285 func TestSearchService_CodeTextMatch(t *testing.T) { 286 client, mux, _, teardown := setup() 287 defer teardown() 288 289 mux.HandleFunc("/search/code", func(w http.ResponseWriter, r *http.Request) { 290 testMethod(t, r, "GET") 291 292 textMatchResponse := ` 293 { 294 "total_count": 1, 295 "incomplete_results": false, 296 "items": [ 297 { 298 "name":"gopher1", 299 "text_matches": [ 300 { 301 "fragment": "I'm afraid my friend what you have found\nIs a gopher who lives to feed", 302 "matches": [ 303 { 304 "text": "gopher", 305 "indices": [ 306 14, 307 21 308 ] 309 } 310 ] 311 } 312 ] 313 } 314 ] 315 } 316 ` 317 318 fmt.Fprint(w, textMatchResponse) 319 }) 320 321 opts := &SearchOptions{Sort: "forks", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}, TextMatch: true} 322 result, _, err := client.Search.Code(context.Background(), "blah", opts) 323 if err != nil { 324 t.Errorf("Search.Code returned error: %v", err) 325 } 326 327 wantedCodeResult := &CodeResult{ 328 Name: String("gopher1"), 329 TextMatches: []*TextMatch{{ 330 Fragment: String("I'm afraid my friend what you have found\nIs a gopher who lives to feed"), 331 Matches: []*Match{{Text: String("gopher"), Indices: []int{14, 21}}}, 332 }, 333 }, 334 } 335 336 want := &CodeSearchResult{ 337 Total: Int(1), 338 IncompleteResults: Bool(false), 339 CodeResults: []*CodeResult{wantedCodeResult}, 340 } 341 if !reflect.DeepEqual(result, want) { 342 t.Errorf("Search.Code returned %+v, want %+v", result, want) 343 } 344 } 345 346 func TestSearchService_Labels(t *testing.T) { 347 client, mux, _, teardown := setup() 348 defer teardown() 349 350 mux.HandleFunc("/search/labels", func(w http.ResponseWriter, r *http.Request) { 351 testMethod(t, r, "GET") 352 testFormValues(t, r, values{ 353 "repository_id": "1234", 354 "q": "blah", 355 "sort": "updated", 356 "order": "desc", 357 "page": "2", 358 "per_page": "2", 359 }) 360 361 fmt.Fprint(w, `{"total_count": 4, "incomplete_results": false, "items": [{"id": 1234, "name":"bug", "description": "some text"},{"id": 4567, "name":"feature"}]}`) 362 }) 363 364 opts := &SearchOptions{Sort: "updated", Order: "desc", ListOptions: ListOptions{Page: 2, PerPage: 2}} 365 result, _, err := client.Search.Labels(context.Background(), 1234, "blah", opts) 366 if err != nil { 367 t.Errorf("Search.Code returned error: %v", err) 368 } 369 370 want := &LabelsSearchResult{ 371 Total: Int(4), 372 IncompleteResults: Bool(false), 373 Labels: []*LabelResult{ 374 {ID: Int64(1234), Name: String("bug"), Description: String("some text")}, 375 {ID: Int64(4567), Name: String("feature")}, 376 }, 377 } 378 if !reflect.DeepEqual(result, want) { 379 t.Errorf("Search.Labels returned %+v, want %+v", result, want) 380 } 381 }