github.com/google/go-github/v49@v49.1.0/github/actions_workflow_jobs_test.go (about) 1 // Copyright 2020 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 "errors" 11 "fmt" 12 "net/http" 13 "net/url" 14 "testing" 15 "time" 16 17 "github.com/google/go-cmp/cmp" 18 ) 19 20 func TestActionsService_ListWorkflowJobs(t *testing.T) { 21 client, mux, _, teardown := setup() 22 defer teardown() 23 24 mux.HandleFunc("/repos/o/r/actions/runs/29679449/jobs", func(w http.ResponseWriter, r *http.Request) { 25 testMethod(t, r, "GET") 26 testFormValues(t, r, values{"per_page": "2", "page": "2"}) 27 fmt.Fprint(w, `{"total_count":4,"jobs":[{"id":399444496,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"},{"id":399444497,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}]}`) 28 }) 29 30 opts := &ListWorkflowJobsOptions{ListOptions: ListOptions{Page: 2, PerPage: 2}} 31 ctx := context.Background() 32 jobs, _, err := client.Actions.ListWorkflowJobs(ctx, "o", "r", 29679449, opts) 33 if err != nil { 34 t.Errorf("Actions.ListWorkflowJobs returned error: %v", err) 35 } 36 37 want := &Jobs{ 38 TotalCount: Int(4), 39 Jobs: []*WorkflowJob{ 40 {ID: Int64(399444496), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, 41 {ID: Int64(399444497), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, 42 }, 43 } 44 if !cmp.Equal(jobs, want) { 45 t.Errorf("Actions.ListWorkflowJobs returned %+v, want %+v", jobs, want) 46 } 47 48 const methodName = "ListWorkflowJobs" 49 testBadOptions(t, methodName, func() (err error) { 50 _, _, err = client.Actions.ListWorkflowJobs(ctx, "\n", "\n", 29679449, opts) 51 return err 52 }) 53 54 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 55 got, resp, err := client.Actions.ListWorkflowJobs(ctx, "o", "r", 29679449, opts) 56 if got != nil { 57 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 58 } 59 return resp, err 60 }) 61 } 62 63 func TestActionsService_ListWorkflowJobs_Filter(t *testing.T) { 64 client, mux, _, teardown := setup() 65 defer teardown() 66 67 mux.HandleFunc("/repos/o/r/actions/runs/29679449/jobs", func(w http.ResponseWriter, r *http.Request) { 68 testMethod(t, r, "GET") 69 testFormValues(t, r, values{"filter": "all", "per_page": "2", "page": "2"}) 70 fmt.Fprint(w, `{"total_count":4,"jobs":[{"id":399444496,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"},{"id":399444497,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}]}`) 71 }) 72 73 opts := &ListWorkflowJobsOptions{Filter: "all", ListOptions: ListOptions{Page: 2, PerPage: 2}} 74 ctx := context.Background() 75 jobs, _, err := client.Actions.ListWorkflowJobs(ctx, "o", "r", 29679449, opts) 76 if err != nil { 77 t.Errorf("Actions.ListWorkflowJobs returned error: %v", err) 78 } 79 80 want := &Jobs{ 81 TotalCount: Int(4), 82 Jobs: []*WorkflowJob{ 83 {ID: Int64(399444496), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, 84 {ID: Int64(399444497), RunID: Int64(29679449), StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, 85 }, 86 } 87 if !cmp.Equal(jobs, want) { 88 t.Errorf("Actions.ListWorkflowJobs returned %+v, want %+v", jobs, want) 89 } 90 } 91 92 func TestActionsService_GetWorkflowJobByID(t *testing.T) { 93 client, mux, _, teardown := setup() 94 defer teardown() 95 96 mux.HandleFunc("/repos/o/r/actions/jobs/399444496", func(w http.ResponseWriter, r *http.Request) { 97 testMethod(t, r, "GET") 98 fmt.Fprint(w, `{"id":399444496,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}`) 99 }) 100 101 ctx := context.Background() 102 job, _, err := client.Actions.GetWorkflowJobByID(ctx, "o", "r", 399444496) 103 if err != nil { 104 t.Errorf("Actions.GetWorkflowJobByID returned error: %v", err) 105 } 106 107 want := &WorkflowJob{ 108 ID: Int64(399444496), 109 StartedAt: &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, 110 CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, 111 } 112 if !cmp.Equal(job, want) { 113 t.Errorf("Actions.GetWorkflowJobByID returned %+v, want %+v", job, want) 114 } 115 116 const methodName = "GetWorkflowJobByID" 117 testBadOptions(t, methodName, func() (err error) { 118 _, _, err = client.Actions.GetWorkflowJobByID(ctx, "\n", "\n", 399444496) 119 return err 120 }) 121 122 testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { 123 got, resp, err := client.Actions.GetWorkflowJobByID(ctx, "o", "r", 399444496) 124 if got != nil { 125 t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) 126 } 127 return resp, err 128 }) 129 } 130 131 func TestActionsService_GetWorkflowJobLogs(t *testing.T) { 132 client, mux, _, teardown := setup() 133 defer teardown() 134 135 mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { 136 testMethod(t, r, "GET") 137 http.Redirect(w, r, "http://github.com/a", http.StatusFound) 138 }) 139 140 ctx := context.Background() 141 url, resp, err := client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, true) 142 if err != nil { 143 t.Errorf("Actions.GetWorkflowJobLogs returned error: %v", err) 144 } 145 if resp.StatusCode != http.StatusFound { 146 t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound) 147 } 148 want := "http://github.com/a" 149 if url.String() != want { 150 t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want) 151 } 152 153 const methodName = "GetWorkflowJobLogs" 154 testBadOptions(t, methodName, func() (err error) { 155 _, _, err = client.Actions.GetWorkflowJobLogs(ctx, "\n", "\n", 399444496, true) 156 return err 157 }) 158 159 // Add custom round tripper 160 client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) { 161 return nil, errors.New("failed to get workflow logs") 162 }) 163 testBadOptions(t, methodName, func() (err error) { 164 _, _, err = client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, true) 165 return err 166 }) 167 } 168 169 func TestActionsService_GetWorkflowJobLogs_StatusMovedPermanently_dontFollowRedirects(t *testing.T) { 170 client, mux, _, teardown := setup() 171 defer teardown() 172 173 mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { 174 testMethod(t, r, "GET") 175 http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently) 176 }) 177 178 ctx := context.Background() 179 _, resp, _ := client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, false) 180 if resp.StatusCode != http.StatusMovedPermanently { 181 t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently) 182 } 183 } 184 185 func TestActionsService_GetWorkflowJobLogs_StatusMovedPermanently_followRedirects(t *testing.T) { 186 client, mux, serverURL, teardown := setup() 187 defer teardown() 188 189 // Mock a redirect link, which leads to an archive link 190 mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) { 191 testMethod(t, r, "GET") 192 redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect") 193 http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently) 194 }) 195 196 mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) { 197 testMethod(t, r, "GET") 198 http.Redirect(w, r, "http://github.com/a", http.StatusFound) 199 }) 200 201 ctx := context.Background() 202 url, resp, err := client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, true) 203 if err != nil { 204 t.Errorf("Actions.GetWorkflowJobLogs returned error: %v", err) 205 } 206 207 if resp.StatusCode != http.StatusFound { 208 t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound) 209 } 210 211 want := "http://github.com/a" 212 if url.String() != want { 213 t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want) 214 } 215 } 216 217 func TestTaskStep_Marshal(t *testing.T) { 218 testJSONMarshal(t, &TaskStep{}, "{}") 219 220 u := &TaskStep{ 221 Name: String("n"), 222 Status: String("s"), 223 Conclusion: String("c"), 224 Number: Int64(1), 225 StartedAt: &Timestamp{referenceTime}, 226 CompletedAt: &Timestamp{referenceTime}, 227 } 228 229 want := `{ 230 "name": "n", 231 "status": "s", 232 "conclusion": "c", 233 "number": 1, 234 "started_at": ` + referenceTimeStr + `, 235 "completed_at": ` + referenceTimeStr + ` 236 }` 237 238 testJSONMarshal(t, u, want) 239 } 240 241 func TestWorkflowJob_Marshal(t *testing.T) { 242 testJSONMarshal(t, &WorkflowJob{}, "{}") 243 244 u := &WorkflowJob{ 245 ID: Int64(1), 246 RunID: Int64(1), 247 RunURL: String("r"), 248 NodeID: String("n"), 249 HeadSHA: String("h"), 250 URL: String("u"), 251 HTMLURL: String("h"), 252 Status: String("s"), 253 Conclusion: String("c"), 254 StartedAt: &Timestamp{referenceTime}, 255 CompletedAt: &Timestamp{referenceTime}, 256 Name: String("n"), 257 Steps: []*TaskStep{ 258 { 259 Name: String("n"), 260 Status: String("s"), 261 Conclusion: String("c"), 262 Number: Int64(1), 263 StartedAt: &Timestamp{referenceTime}, 264 CompletedAt: &Timestamp{referenceTime}, 265 }, 266 }, 267 CheckRunURL: String("c"), 268 } 269 270 want := `{ 271 "id": 1, 272 "run_id": 1, 273 "run_url": "r", 274 "node_id": "n", 275 "head_sha": "h", 276 "url": "u", 277 "html_url": "h", 278 "status": "s", 279 "conclusion": "c", 280 "started_at": ` + referenceTimeStr + `, 281 "completed_at": ` + referenceTimeStr + `, 282 "name": "n", 283 "steps": [{ 284 "name": "n", 285 "status": "s", 286 "conclusion": "c", 287 "number": 1, 288 "started_at": ` + referenceTimeStr + `, 289 "completed_at": ` + referenceTimeStr + ` 290 }], 291 "check_run_url": "c" 292 }` 293 294 testJSONMarshal(t, u, want) 295 } 296 297 func TestJobs_Marshal(t *testing.T) { 298 testJSONMarshal(t, &Jobs{}, "{}") 299 300 u := &Jobs{ 301 TotalCount: Int(1), 302 Jobs: []*WorkflowJob{ 303 { 304 ID: Int64(1), 305 RunID: Int64(1), 306 RunURL: String("r"), 307 NodeID: String("n"), 308 HeadSHA: String("h"), 309 URL: String("u"), 310 HTMLURL: String("h"), 311 Status: String("s"), 312 Conclusion: String("c"), 313 StartedAt: &Timestamp{referenceTime}, 314 CompletedAt: &Timestamp{referenceTime}, 315 Name: String("n"), 316 Steps: []*TaskStep{ 317 { 318 Name: String("n"), 319 Status: String("s"), 320 Conclusion: String("c"), 321 Number: Int64(1), 322 StartedAt: &Timestamp{referenceTime}, 323 CompletedAt: &Timestamp{referenceTime}, 324 }, 325 }, 326 CheckRunURL: String("c"), 327 RunAttempt: Int64(2), 328 }, 329 }, 330 } 331 332 want := `{ 333 "total_count": 1, 334 "jobs": [{ 335 "id": 1, 336 "run_id": 1, 337 "run_url": "r", 338 "node_id": "n", 339 "head_sha": "h", 340 "url": "u", 341 "html_url": "h", 342 "status": "s", 343 "conclusion": "c", 344 "started_at": ` + referenceTimeStr + `, 345 "completed_at": ` + referenceTimeStr + `, 346 "name": "n", 347 "steps": [{ 348 "name": "n", 349 "status": "s", 350 "conclusion": "c", 351 "number": 1, 352 "started_at": ` + referenceTimeStr + `, 353 "completed_at": ` + referenceTimeStr + ` 354 }], 355 "check_run_url": "c", 356 "run_attempt": 2 357 }] 358 }` 359 360 testJSONMarshal(t, u, want) 361 }