github.com/google/go-github/v50@v50.2.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  		CreatedAt:   &Timestamp{referenceTime},
   255  		StartedAt:   &Timestamp{referenceTime},
   256  		CompletedAt: &Timestamp{referenceTime},
   257  		Name:        String("n"),
   258  		Steps: []*TaskStep{
   259  			{
   260  				Name:        String("n"),
   261  				Status:      String("s"),
   262  				Conclusion:  String("c"),
   263  				Number:      Int64(1),
   264  				StartedAt:   &Timestamp{referenceTime},
   265  				CompletedAt: &Timestamp{referenceTime},
   266  			},
   267  		},
   268  		CheckRunURL:  String("c"),
   269  		WorkflowName: String("w"),
   270  	}
   271  
   272  	want := `{
   273  		"id": 1,
   274  		"run_id": 1,
   275  		"run_url": "r",
   276  		"node_id": "n",
   277  		"head_sha": "h",
   278  		"url": "u",
   279  		"html_url": "h",
   280  		"status": "s",
   281  		"conclusion": "c",
   282  		"created_at": ` + referenceTimeStr + `,
   283  		"started_at": ` + referenceTimeStr + `,
   284  		"completed_at": ` + referenceTimeStr + `,
   285  		"name": "n",
   286  		"steps": [{
   287  			"name": "n",
   288  			"status": "s",
   289  			"conclusion": "c",
   290  			"number": 1,
   291  			"started_at": ` + referenceTimeStr + `,
   292  			"completed_at": ` + referenceTimeStr + `
   293  		}],
   294  		"check_run_url": "c",
   295  		"workflow_name": "w"
   296  	}`
   297  
   298  	testJSONMarshal(t, u, want)
   299  }
   300  
   301  func TestJobs_Marshal(t *testing.T) {
   302  	testJSONMarshal(t, &Jobs{}, "{}")
   303  
   304  	u := &Jobs{
   305  		TotalCount: Int(1),
   306  		Jobs: []*WorkflowJob{
   307  			{
   308  				ID:          Int64(1),
   309  				RunID:       Int64(1),
   310  				RunURL:      String("r"),
   311  				NodeID:      String("n"),
   312  				HeadSHA:     String("h"),
   313  				URL:         String("u"),
   314  				HTMLURL:     String("h"),
   315  				Status:      String("s"),
   316  				Conclusion:  String("c"),
   317  				CreatedAt:   &Timestamp{referenceTime},
   318  				StartedAt:   &Timestamp{referenceTime},
   319  				CompletedAt: &Timestamp{referenceTime},
   320  				Name:        String("n"),
   321  				Steps: []*TaskStep{
   322  					{
   323  						Name:        String("n"),
   324  						Status:      String("s"),
   325  						Conclusion:  String("c"),
   326  						Number:      Int64(1),
   327  						StartedAt:   &Timestamp{referenceTime},
   328  						CompletedAt: &Timestamp{referenceTime},
   329  					},
   330  				},
   331  				CheckRunURL:  String("c"),
   332  				RunAttempt:   Int64(2),
   333  				WorkflowName: String("w"),
   334  			},
   335  		},
   336  	}
   337  
   338  	want := `{
   339  		"total_count": 1,
   340  		"jobs": [{
   341  			"id": 1,
   342  			"run_id": 1,
   343  			"run_url": "r",
   344  			"node_id": "n",
   345  			"head_sha": "h",
   346  			"url": "u",
   347  			"html_url": "h",
   348  			"status": "s",
   349  			"conclusion": "c",
   350  			"created_at": ` + referenceTimeStr + `,
   351  			"started_at": ` + referenceTimeStr + `,
   352  			"completed_at": ` + referenceTimeStr + `,
   353  			"name": "n",
   354  			"steps": [{
   355  				"name": "n",
   356  				"status": "s",
   357  				"conclusion": "c",
   358  				"number": 1,
   359  				"started_at": ` + referenceTimeStr + `,
   360  				"completed_at": ` + referenceTimeStr + `
   361  			}],
   362  			"check_run_url": "c",
   363  			"run_attempt": 2,
   364  			"workflow_name": "w"
   365  		}]
   366  	}`
   367  
   368  	testJSONMarshal(t, u, want)
   369  }