github.com/google/go-github/v65@v65.0.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_ListWorkflowJobsAttempt(t *testing.T) {
    93  	client, mux, _, teardown := setup()
    94  	defer teardown()
    95  
    96  	mux.HandleFunc("/repos/o/r/actions/runs/29679449/attempts/1/jobs", func(w http.ResponseWriter, r *http.Request) {
    97  		testMethod(t, r, "GET")
    98  		testFormValues(t, r, values{"per_page": "2", "page": "2"})
    99  		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","run_attempt":2},{"id":399444497,"run_id":29679449,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z","run_attempt":2}]}`)
   100  	})
   101  	opts := &ListOptions{Page: 2, PerPage: 2}
   102  	ctx := context.Background()
   103  	jobs, _, err := client.Actions.ListWorkflowJobsAttempt(ctx, "o", "r", 29679449, 1, opts)
   104  	if err != nil {
   105  		t.Errorf("Actions.ListWorkflowJobsAttempt returned error: %v", err)
   106  	}
   107  
   108  	want := &Jobs{
   109  		TotalCount: Int(4),
   110  		Jobs: []*WorkflowJob{
   111  			{
   112  				ID:          Int64(399444496),
   113  				RunID:       Int64(29679449),
   114  				StartedAt:   &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)},
   115  				CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)},
   116  				RunAttempt:  Int64(2),
   117  			},
   118  			{
   119  				ID:          Int64(399444497),
   120  				RunID:       Int64(29679449),
   121  				StartedAt:   &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)},
   122  				CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)},
   123  				RunAttempt:  Int64(2),
   124  			},
   125  		},
   126  	}
   127  	if !cmp.Equal(jobs, want) {
   128  		t.Errorf("Actions.ListWorkflowJobsAttempt returned %+v, want %+v", jobs, want)
   129  	}
   130  
   131  	const methodName = "ListWorkflowJobsAttempt"
   132  	testBadOptions(t, methodName, func() (err error) {
   133  		_, _, err = client.Actions.ListWorkflowJobsAttempt(ctx, "\n", "\n", 29679449, 1, opts)
   134  		return err
   135  	})
   136  
   137  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   138  		got, resp, err := client.Actions.ListWorkflowJobsAttempt(ctx, "o", "r", 29679449, 1, opts)
   139  		if got != nil {
   140  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   141  		}
   142  		return resp, err
   143  	})
   144  }
   145  
   146  func TestActionsService_GetWorkflowJobByID(t *testing.T) {
   147  	client, mux, _, teardown := setup()
   148  	defer teardown()
   149  
   150  	mux.HandleFunc("/repos/o/r/actions/jobs/399444496", func(w http.ResponseWriter, r *http.Request) {
   151  		testMethod(t, r, "GET")
   152  		fmt.Fprint(w, `{"id":399444496,"started_at":"2019-01-02T15:04:05Z","completed_at":"2020-01-02T15:04:05Z"}`)
   153  	})
   154  
   155  	ctx := context.Background()
   156  	job, _, err := client.Actions.GetWorkflowJobByID(ctx, "o", "r", 399444496)
   157  	if err != nil {
   158  		t.Errorf("Actions.GetWorkflowJobByID returned error: %v", err)
   159  	}
   160  
   161  	want := &WorkflowJob{
   162  		ID:          Int64(399444496),
   163  		StartedAt:   &Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)},
   164  		CompletedAt: &Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)},
   165  	}
   166  	if !cmp.Equal(job, want) {
   167  		t.Errorf("Actions.GetWorkflowJobByID returned %+v, want %+v", job, want)
   168  	}
   169  
   170  	const methodName = "GetWorkflowJobByID"
   171  	testBadOptions(t, methodName, func() (err error) {
   172  		_, _, err = client.Actions.GetWorkflowJobByID(ctx, "\n", "\n", 399444496)
   173  		return err
   174  	})
   175  
   176  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   177  		got, resp, err := client.Actions.GetWorkflowJobByID(ctx, "o", "r", 399444496)
   178  		if got != nil {
   179  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   180  		}
   181  		return resp, err
   182  	})
   183  }
   184  
   185  func TestActionsService_GetWorkflowJobLogs(t *testing.T) {
   186  	client, mux, _, teardown := setup()
   187  	defer teardown()
   188  
   189  	mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) {
   190  		testMethod(t, r, "GET")
   191  		http.Redirect(w, r, "http://github.com/a", http.StatusFound)
   192  	})
   193  
   194  	ctx := context.Background()
   195  	url, resp, err := client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, 1)
   196  	if err != nil {
   197  		t.Errorf("Actions.GetWorkflowJobLogs returned error: %v", err)
   198  	}
   199  	if resp.StatusCode != http.StatusFound {
   200  		t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound)
   201  	}
   202  	want := "http://github.com/a"
   203  	if url.String() != want {
   204  		t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want)
   205  	}
   206  
   207  	const methodName = "GetWorkflowJobLogs"
   208  	testBadOptions(t, methodName, func() (err error) {
   209  		_, _, err = client.Actions.GetWorkflowJobLogs(ctx, "\n", "\n", 399444496, 1)
   210  		return err
   211  	})
   212  
   213  	// Add custom round tripper
   214  	client.client.Transport = roundTripperFunc(func(r *http.Request) (*http.Response, error) {
   215  		return nil, errors.New("failed to get workflow logs")
   216  	})
   217  	testBadOptions(t, methodName, func() (err error) {
   218  		_, _, err = client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, 1)
   219  		return err
   220  	})
   221  }
   222  
   223  func TestActionsService_GetWorkflowJobLogs_StatusMovedPermanently_dontFollowRedirects(t *testing.T) {
   224  	client, mux, _, teardown := setup()
   225  	defer teardown()
   226  
   227  	mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) {
   228  		testMethod(t, r, "GET")
   229  		http.Redirect(w, r, "http://github.com/a", http.StatusMovedPermanently)
   230  	})
   231  
   232  	ctx := context.Background()
   233  	_, resp, _ := client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, 0)
   234  	if resp.StatusCode != http.StatusMovedPermanently {
   235  		t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusMovedPermanently)
   236  	}
   237  }
   238  
   239  func TestActionsService_GetWorkflowJobLogs_StatusMovedPermanently_followRedirects(t *testing.T) {
   240  	client, mux, serverURL, teardown := setup()
   241  	defer teardown()
   242  
   243  	// Mock a redirect link, which leads to an archive link
   244  	mux.HandleFunc("/repos/o/r/actions/jobs/399444496/logs", func(w http.ResponseWriter, r *http.Request) {
   245  		testMethod(t, r, "GET")
   246  		redirectURL, _ := url.Parse(serverURL + baseURLPath + "/redirect")
   247  		http.Redirect(w, r, redirectURL.String(), http.StatusMovedPermanently)
   248  	})
   249  
   250  	mux.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
   251  		testMethod(t, r, "GET")
   252  		http.Redirect(w, r, "http://github.com/a", http.StatusFound)
   253  	})
   254  
   255  	ctx := context.Background()
   256  	url, resp, err := client.Actions.GetWorkflowJobLogs(ctx, "o", "r", 399444496, 1)
   257  	if err != nil {
   258  		t.Errorf("Actions.GetWorkflowJobLogs returned error: %v", err)
   259  	}
   260  
   261  	if resp.StatusCode != http.StatusFound {
   262  		t.Errorf("Actions.GetWorkflowJobLogs returned status: %d, want %d", resp.StatusCode, http.StatusFound)
   263  	}
   264  
   265  	want := "http://github.com/a"
   266  	if url.String() != want {
   267  		t.Errorf("Actions.GetWorkflowJobLogs returned %+v, want %+v", url.String(), want)
   268  	}
   269  }
   270  
   271  func TestTaskStep_Marshal(t *testing.T) {
   272  	testJSONMarshal(t, &TaskStep{}, "{}")
   273  
   274  	u := &TaskStep{
   275  		Name:        String("n"),
   276  		Status:      String("s"),
   277  		Conclusion:  String("c"),
   278  		Number:      Int64(1),
   279  		StartedAt:   &Timestamp{referenceTime},
   280  		CompletedAt: &Timestamp{referenceTime},
   281  	}
   282  
   283  	want := `{
   284  		"name": "n",
   285  		"status": "s",
   286  		"conclusion": "c",
   287  		"number": 1,
   288  		"started_at": ` + referenceTimeStr + `,
   289  		"completed_at": ` + referenceTimeStr + `
   290  	}`
   291  
   292  	testJSONMarshal(t, u, want)
   293  }
   294  
   295  func TestWorkflowJob_Marshal(t *testing.T) {
   296  	testJSONMarshal(t, &WorkflowJob{}, "{}")
   297  
   298  	u := &WorkflowJob{
   299  		ID:          Int64(1),
   300  		RunID:       Int64(1),
   301  		RunURL:      String("r"),
   302  		NodeID:      String("n"),
   303  		HeadBranch:  String("b"),
   304  		HeadSHA:     String("h"),
   305  		URL:         String("u"),
   306  		HTMLURL:     String("h"),
   307  		Status:      String("s"),
   308  		Conclusion:  String("c"),
   309  		CreatedAt:   &Timestamp{referenceTime},
   310  		StartedAt:   &Timestamp{referenceTime},
   311  		CompletedAt: &Timestamp{referenceTime},
   312  		Name:        String("n"),
   313  		Steps: []*TaskStep{
   314  			{
   315  				Name:        String("n"),
   316  				Status:      String("s"),
   317  				Conclusion:  String("c"),
   318  				Number:      Int64(1),
   319  				StartedAt:   &Timestamp{referenceTime},
   320  				CompletedAt: &Timestamp{referenceTime},
   321  			},
   322  		},
   323  		CheckRunURL:  String("c"),
   324  		WorkflowName: String("w"),
   325  	}
   326  
   327  	want := `{
   328  		"id": 1,
   329  		"run_id": 1,
   330  		"run_url": "r",
   331  		"node_id": "n",
   332  		"head_branch": "b",
   333  		"head_sha": "h",
   334  		"url": "u",
   335  		"html_url": "h",
   336  		"status": "s",
   337  		"conclusion": "c",
   338  		"created_at": ` + referenceTimeStr + `,
   339  		"started_at": ` + referenceTimeStr + `,
   340  		"completed_at": ` + referenceTimeStr + `,
   341  		"name": "n",
   342  		"steps": [{
   343  			"name": "n",
   344  			"status": "s",
   345  			"conclusion": "c",
   346  			"number": 1,
   347  			"started_at": ` + referenceTimeStr + `,
   348  			"completed_at": ` + referenceTimeStr + `
   349  		}],
   350  		"check_run_url": "c",
   351  		"workflow_name": "w"
   352  	}`
   353  
   354  	testJSONMarshal(t, u, want)
   355  }
   356  
   357  func TestJobs_Marshal(t *testing.T) {
   358  	testJSONMarshal(t, &Jobs{}, "{}")
   359  
   360  	u := &Jobs{
   361  		TotalCount: Int(1),
   362  		Jobs: []*WorkflowJob{
   363  			{
   364  				ID:          Int64(1),
   365  				RunID:       Int64(1),
   366  				RunURL:      String("r"),
   367  				NodeID:      String("n"),
   368  				HeadBranch:  String("b"),
   369  				HeadSHA:     String("h"),
   370  				URL:         String("u"),
   371  				HTMLURL:     String("h"),
   372  				Status:      String("s"),
   373  				Conclusion:  String("c"),
   374  				CreatedAt:   &Timestamp{referenceTime},
   375  				StartedAt:   &Timestamp{referenceTime},
   376  				CompletedAt: &Timestamp{referenceTime},
   377  				Name:        String("n"),
   378  				Steps: []*TaskStep{
   379  					{
   380  						Name:        String("n"),
   381  						Status:      String("s"),
   382  						Conclusion:  String("c"),
   383  						Number:      Int64(1),
   384  						StartedAt:   &Timestamp{referenceTime},
   385  						CompletedAt: &Timestamp{referenceTime},
   386  					},
   387  				},
   388  				CheckRunURL:  String("c"),
   389  				RunAttempt:   Int64(2),
   390  				WorkflowName: String("w"),
   391  			},
   392  		},
   393  	}
   394  
   395  	want := `{
   396  		"total_count": 1,
   397  		"jobs": [{
   398  			"id": 1,
   399  			"run_id": 1,
   400  			"run_url": "r",
   401  			"node_id": "n",
   402  			"head_branch": "b",
   403  			"head_sha": "h",
   404  			"url": "u",
   405  			"html_url": "h",
   406  			"status": "s",
   407  			"conclusion": "c",
   408  			"created_at": ` + referenceTimeStr + `,
   409  			"started_at": ` + referenceTimeStr + `,
   410  			"completed_at": ` + referenceTimeStr + `,
   411  			"name": "n",
   412  			"steps": [{
   413  				"name": "n",
   414  				"status": "s",
   415  				"conclusion": "c",
   416  				"number": 1,
   417  				"started_at": ` + referenceTimeStr + `,
   418  				"completed_at": ` + referenceTimeStr + `
   419  			}],
   420  			"check_run_url": "c",
   421  			"run_attempt": 2,
   422  			"workflow_name": "w"
   423  		}]
   424  	}`
   425  
   426  	testJSONMarshal(t, u, want)
   427  }