github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/prow/prstatus/prstatus_test.go (about) 1 /* 2 Copyright 2018 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package prstatus 18 19 import ( 20 "context" 21 "encoding/gob" 22 "golang.org/x/oauth2" 23 "io/ioutil" 24 "net/http" 25 "net/http/httptest" 26 "reflect" 27 "testing" 28 "time" 29 30 "github.com/ghodss/yaml" 31 gogithub "github.com/google/go-github/github" 32 "github.com/gorilla/sessions" 33 "github.com/sirupsen/logrus" 34 35 "k8s.io/test-infra/ghclient" 36 "k8s.io/test-infra/prow/config" 37 "k8s.io/test-infra/prow/github" 38 ) 39 40 type MockQueryHandler struct { 41 prs []PullRequest 42 contextMap map[int][]Context 43 } 44 45 func (mh *MockQueryHandler) QueryPullRequests(ctx context.Context, ghc githubClient, query string) ([]PullRequest, error) { 46 return mh.prs, nil 47 } 48 49 func (mh *MockQueryHandler) HeadContexts(ghc githubClient, pr PullRequest) ([]Context, error) { 50 return mh.contextMap[int(pr.Number)], nil 51 } 52 53 func (mh *MockQueryHandler) GetUser(*ghclient.Client) (*gogithub.User, error) { 54 login := "random_user" 55 return &gogithub.User{ 56 Login: &login, 57 }, nil 58 } 59 60 type fgc struct { 61 combinedStatus *github.CombinedStatus 62 } 63 64 func (c *fgc) Query(context.Context, interface{}, map[string]interface{}) error { 65 return nil 66 } 67 68 func (c *fgc) GetCombinedStatus(org, repo, ref string) (*github.CombinedStatus, error) { 69 return c.combinedStatus, nil 70 } 71 72 func newMockQueryHandler(prs []PullRequest, contextMap map[int][]Context) *MockQueryHandler { 73 return &MockQueryHandler{ 74 prs: prs, 75 contextMap: contextMap, 76 } 77 } 78 79 func createMockAgent(repos []string, config *config.GithubOAuthConfig) *DashboardAgent { 80 return &DashboardAgent{ 81 repos: repos, 82 goac: config, 83 log: logrus.WithField("unit-test", "dashboard-agent"), 84 } 85 } 86 87 func TestHandlePrStatusWithoutLogin(t *testing.T) { 88 repos := []string{"mock/repo", "kubernetes/test-infra", "foo/bar"} 89 mockCookieStore := sessions.NewCookieStore([]byte("secret-key")) 90 mockConfig := &config.GithubOAuthConfig{ 91 CookieStore: mockCookieStore, 92 } 93 mockAgent := createMockAgent(repos, mockConfig) 94 mockData := UserData{ 95 Login: false, 96 } 97 98 rr := httptest.NewRecorder() 99 request := httptest.NewRequest(http.MethodGet, "/pr-data.js", nil) 100 101 mockQueryHandler := newMockQueryHandler(nil, nil) 102 prHandler := mockAgent.HandlePrStatus(mockQueryHandler) 103 prHandler.ServeHTTP(rr, request) 104 if rr.Code != http.StatusOK { 105 t.Fatalf("Bad status code: %d", rr.Code) 106 } 107 response := rr.Result() 108 defer response.Body.Close() 109 body, err := ioutil.ReadAll(response.Body) 110 if err != nil { 111 t.Fatalf("Error with reading response body: %v", err) 112 } 113 var dataReturned UserData 114 if err := yaml.Unmarshal(body, &dataReturned); err != nil { 115 t.Errorf("Error with unmarshaling response: %v", err) 116 } 117 if !reflect.DeepEqual(dataReturned, mockData) { 118 t.Errorf("Invalid user data. Got %v, expected %v", dataReturned, mockData) 119 } 120 } 121 122 func TestHandlePrStatusWithLogin(t *testing.T) { 123 repos := []string{"mock/repo", "kubernetes/test-infra", "foo/bar"} 124 mockCookieStore := sessions.NewCookieStore([]byte("secret-key")) 125 mockConfig := &config.GithubOAuthConfig{ 126 CookieStore: mockCookieStore, 127 } 128 mockAgent := createMockAgent(repos, mockConfig) 129 130 testCases := []struct { 131 prs []PullRequest 132 contextMap map[int][]Context 133 expectedData UserData 134 }{ 135 { 136 prs: []PullRequest{}, 137 contextMap: map[int][]Context{}, 138 expectedData: UserData{ 139 Login: true, 140 }, 141 }, 142 { 143 prs: []PullRequest{ 144 { 145 Number: 0, 146 Title: "random pull request", 147 }, 148 { 149 Number: 1, 150 Title: "This is a test", 151 }, 152 { 153 Number: 2, 154 Title: "test pull request", 155 }, 156 }, 157 contextMap: map[int][]Context{ 158 0: { 159 { 160 Context: "gofmt-job", 161 Description: "job succeed", 162 State: "SUCCESS", 163 }, 164 }, 165 1: { 166 { 167 Context: "verify-bazel-job", 168 Description: "job failed", 169 State: "FAILURE", 170 }, 171 }, 172 2: { 173 { 174 Context: "gofmt-job", 175 Description: "job succeed", 176 State: "SUCCESS", 177 }, 178 { 179 Context: "verify-bazel-job", 180 Description: "job failed", 181 State: "FAILURE", 182 }, 183 }, 184 }, 185 expectedData: UserData{ 186 Login: true, 187 PullRequestsWithContexts: []PullRequestWithContext{ 188 { 189 PullRequest: PullRequest{ 190 Number: 0, 191 Title: "random pull request", 192 }, 193 Contexts: []Context{ 194 { 195 Context: "gofmt-job", 196 Description: "job succeed", 197 State: "SUCCESS", 198 }, 199 }, 200 }, 201 { 202 PullRequest: PullRequest{ 203 Number: 1, 204 Title: "This is a test", 205 }, 206 Contexts: []Context{ 207 { 208 Context: "verify-bazel-job", 209 Description: "job failed", 210 State: "FAILURE", 211 }, 212 }, 213 }, 214 { 215 PullRequest: PullRequest{ 216 Number: 2, 217 Title: "test pull request", 218 }, 219 Contexts: []Context{ 220 { 221 Context: "gofmt-job", 222 Description: "job succeed", 223 State: "SUCCESS", 224 }, 225 { 226 Context: "verify-bazel-job", 227 Description: "job failed", 228 State: "FAILURE", 229 }, 230 }, 231 }, 232 }, 233 }, 234 }, 235 } 236 for id, testcase := range testCases { 237 t.Logf("Test %d:", id) 238 rr := httptest.NewRecorder() 239 request := httptest.NewRequest(http.MethodGet, "/pr-data.js", nil) 240 mockSession, err := sessions.GetRegistry(request).Get(mockCookieStore, tokenSession) 241 if err != nil { 242 t.Errorf("Error with creating mock session: %v", err) 243 } 244 gob.Register(oauth2.Token{}) 245 token := &oauth2.Token{AccessToken: "secret-token", Expiry: time.Now().Add(time.Duration(24*365) * time.Hour)} 246 mockSession.Values[tokenKey] = token 247 mockSession.Values[loginKey] = "random_user" 248 mockQueryHandler := newMockQueryHandler(testcase.prs, testcase.contextMap) 249 prHandler := mockAgent.HandlePrStatus(mockQueryHandler) 250 prHandler.ServeHTTP(rr, request) 251 if rr.Code != http.StatusOK { 252 t.Fatalf("Bad status code: %d", rr.Code) 253 } 254 response := rr.Result() 255 body, err := ioutil.ReadAll(response.Body) 256 if err != nil { 257 t.Fatalf("Error with reading response body: %v", err) 258 } 259 var dataReturned UserData 260 if err := yaml.Unmarshal(body, &dataReturned); err != nil { 261 t.Errorf("Error with unmarshaling response: %v", err) 262 } 263 if !reflect.DeepEqual(dataReturned, testcase.expectedData) { 264 t.Fatalf("Invalid user data. Got %v, expected %v.", dataReturned, testcase.expectedData) 265 } 266 t.Logf("Passed") 267 response.Body.Close() 268 } 269 } 270 271 func TestHeadContexts(t *testing.T) { 272 repos := []string{"mock/repo", "kubernetes/test-infra", "foo/bar"} 273 mockCookieStore := sessions.NewCookieStore([]byte("secret-key")) 274 mockConfig := &config.GithubOAuthConfig{ 275 CookieStore: mockCookieStore, 276 } 277 mockAgent := createMockAgent(repos, mockConfig) 278 testCases := []struct { 279 combinedStatus *github.CombinedStatus 280 pr PullRequest 281 expectedContexts []Context 282 }{ 283 { 284 combinedStatus: &github.CombinedStatus{}, 285 pr: PullRequest{}, 286 expectedContexts: []Context{}, 287 }, 288 { 289 combinedStatus: &github.CombinedStatus{ 290 Statuses: []github.Status{ 291 { 292 State: "FAILURE", 293 Description: "job failed", 294 Context: "gofmt-job", 295 }, 296 { 297 State: "SUCCESS", 298 Description: "job succeed", 299 Context: "k8s-job", 300 }, 301 { 302 State: "PENDING", 303 Description: "triggered", 304 Context: "test-job", 305 }, 306 }, 307 }, 308 pr: PullRequest{}, 309 expectedContexts: []Context{ 310 { 311 Context: "gofmt-job", 312 Description: "job failed", 313 State: "FAILURE", 314 }, 315 { 316 State: "SUCCESS", 317 Description: "job succeed", 318 Context: "k8s-job", 319 }, 320 { 321 State: "PENDING", 322 Description: "triggered", 323 Context: "test-job", 324 }, 325 }, 326 }, 327 } 328 for id, testcase := range testCases { 329 t.Logf("Test %d:", id) 330 contexts, err := mockAgent.HeadContexts(&fgc{ 331 combinedStatus: testcase.combinedStatus, 332 }, testcase.pr) 333 if err != nil { 334 t.Fatalf("Error with getting head contexts") 335 } 336 if !reflect.DeepEqual(contexts, testcase.expectedContexts) { 337 t.Fatalf("Invalid user data. Got %v, expected %v.", contexts, testcase.expectedContexts) 338 } 339 t.Logf("Passed") 340 } 341 } 342 343 func TestConstructSearchQuery(t *testing.T) { 344 repos := []string{"mock/repo", "kubernetes/test-infra", "foo/bar"} 345 mockCookieStore := sessions.NewCookieStore([]byte("secret-key")) 346 mockConfig := &config.GithubOAuthConfig{ 347 CookieStore: mockCookieStore, 348 } 349 mockAgent := createMockAgent(repos, mockConfig) 350 query := mockAgent.ConstructSearchQuery("random_username") 351 mockQuery := "is:pr state:open author:random_username repo:\"mock/repo\" repo:\"kubernetes/test-infra\" repo:\"foo/bar\"" 352 if query != mockQuery { 353 t.Errorf("Invalid query. Got: %v, expected %v", query, mockQuery) 354 } 355 }