github.com/google/go-github/v64@v64.0.0/github/actions_secrets_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  	"encoding/json"
    11  	"fmt"
    12  	"net/http"
    13  	"testing"
    14  	"time"
    15  
    16  	"github.com/google/go-cmp/cmp"
    17  )
    18  
    19  func TestPublicKey_UnmarshalJSON(t *testing.T) {
    20  	var testCases = map[string]struct {
    21  		data          []byte
    22  		wantPublicKey PublicKey
    23  		wantErr       bool
    24  	}{
    25  		"Empty": {
    26  			data:          []byte("{}"),
    27  			wantPublicKey: PublicKey{},
    28  			wantErr:       false,
    29  		},
    30  		"Invalid JSON": {
    31  			data:          []byte("{"),
    32  			wantPublicKey: PublicKey{},
    33  			wantErr:       true,
    34  		},
    35  		"Numeric KeyID": {
    36  			data:          []byte(`{"key_id":1234,"key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`),
    37  			wantPublicKey: PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")},
    38  			wantErr:       false,
    39  		},
    40  		"String KeyID": {
    41  			data:          []byte(`{"key_id":"1234","key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`),
    42  			wantPublicKey: PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")},
    43  			wantErr:       false,
    44  		},
    45  		"Invalid KeyID": {
    46  			data:          []byte(`{"key_id":["1234"],"key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`),
    47  			wantPublicKey: PublicKey{KeyID: nil, Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")},
    48  			wantErr:       true,
    49  		},
    50  		"Invalid Key": {
    51  			data:          []byte(`{"key":123}`),
    52  			wantPublicKey: PublicKey{KeyID: nil, Key: nil},
    53  			wantErr:       true,
    54  		},
    55  		"Nil": {
    56  			data:          nil,
    57  			wantPublicKey: PublicKey{KeyID: nil, Key: nil},
    58  			wantErr:       true,
    59  		},
    60  		"Empty String": {
    61  			data:          []byte(""),
    62  			wantPublicKey: PublicKey{KeyID: nil, Key: nil},
    63  			wantErr:       true,
    64  		},
    65  		"Missing Key": {
    66  			data:          []byte(`{"key_id":"1234"}`),
    67  			wantPublicKey: PublicKey{KeyID: String("1234")},
    68  			wantErr:       false,
    69  		},
    70  		"Missing KeyID": {
    71  			data:          []byte(`{"key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`),
    72  			wantPublicKey: PublicKey{Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")},
    73  			wantErr:       false,
    74  		},
    75  	}
    76  
    77  	for name, tt := range testCases {
    78  		tt := tt
    79  		t.Run(name, func(t *testing.T) {
    80  			pk := PublicKey{}
    81  			err := json.Unmarshal(tt.data, &pk)
    82  			if err == nil && tt.wantErr {
    83  				t.Errorf("PublicKey.UnmarshalJSON returned nil instead of an error")
    84  			}
    85  			if err != nil && !tt.wantErr {
    86  				t.Errorf("PublicKey.UnmarshalJSON returned an unexpected error: %+v", err)
    87  			}
    88  			if !cmp.Equal(tt.wantPublicKey, pk) {
    89  				t.Errorf("PublicKey.UnmarshalJSON expected public key %+v, got %+v", tt.wantPublicKey, pk)
    90  			}
    91  		})
    92  	}
    93  }
    94  
    95  func TestActionsService_GetRepoPublicKey(t *testing.T) {
    96  	client, mux, _, teardown := setup()
    97  	defer teardown()
    98  
    99  	mux.HandleFunc("/repos/o/r/actions/secrets/public-key", func(w http.ResponseWriter, r *http.Request) {
   100  		testMethod(t, r, "GET")
   101  		fmt.Fprint(w, `{"key_id":"1234","key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`)
   102  	})
   103  
   104  	ctx := context.Background()
   105  	key, _, err := client.Actions.GetRepoPublicKey(ctx, "o", "r")
   106  	if err != nil {
   107  		t.Errorf("Actions.GetRepoPublicKey returned error: %v", err)
   108  	}
   109  
   110  	want := &PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")}
   111  	if !cmp.Equal(key, want) {
   112  		t.Errorf("Actions.GetRepoPublicKey returned %+v, want %+v", key, want)
   113  	}
   114  
   115  	const methodName = "GetRepoPublicKey"
   116  	testBadOptions(t, methodName, func() (err error) {
   117  		_, _, err = client.Actions.GetRepoPublicKey(ctx, "\n", "\n")
   118  		return err
   119  	})
   120  
   121  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   122  		got, resp, err := client.Actions.GetRepoPublicKey(ctx, "o", "r")
   123  		if got != nil {
   124  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   125  		}
   126  		return resp, err
   127  	})
   128  }
   129  
   130  func TestActionsService_GetRepoPublicKeyNumeric(t *testing.T) {
   131  	client, mux, _, teardown := setup()
   132  	defer teardown()
   133  
   134  	mux.HandleFunc("/repos/o/r/actions/secrets/public-key", func(w http.ResponseWriter, r *http.Request) {
   135  		testMethod(t, r, "GET")
   136  		fmt.Fprint(w, `{"key_id":1234,"key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`)
   137  	})
   138  
   139  	ctx := context.Background()
   140  	key, _, err := client.Actions.GetRepoPublicKey(ctx, "o", "r")
   141  	if err != nil {
   142  		t.Errorf("Actions.GetRepoPublicKey returned error: %v", err)
   143  	}
   144  
   145  	want := &PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")}
   146  	if !cmp.Equal(key, want) {
   147  		t.Errorf("Actions.GetRepoPublicKey returned %+v, want %+v", key, want)
   148  	}
   149  
   150  	const methodName = "GetRepoPublicKey"
   151  	testBadOptions(t, methodName, func() (err error) {
   152  		_, _, err = client.Actions.GetRepoPublicKey(ctx, "\n", "\n")
   153  		return err
   154  	})
   155  
   156  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   157  		got, resp, err := client.Actions.GetRepoPublicKey(ctx, "o", "r")
   158  		if got != nil {
   159  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   160  		}
   161  		return resp, err
   162  	})
   163  }
   164  
   165  func TestActionsService_ListRepoSecrets(t *testing.T) {
   166  	client, mux, _, teardown := setup()
   167  	defer teardown()
   168  
   169  	mux.HandleFunc("/repos/o/r/actions/secrets", func(w http.ResponseWriter, r *http.Request) {
   170  		testMethod(t, r, "GET")
   171  		testFormValues(t, r, values{"per_page": "2", "page": "2"})
   172  		fmt.Fprint(w, `{"total_count":4,"secrets":[{"name":"A","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`)
   173  	})
   174  
   175  	opts := &ListOptions{Page: 2, PerPage: 2}
   176  	ctx := context.Background()
   177  	secrets, _, err := client.Actions.ListRepoSecrets(ctx, "o", "r", opts)
   178  	if err != nil {
   179  		t.Errorf("Actions.ListRepoSecrets returned error: %v", err)
   180  	}
   181  
   182  	want := &Secrets{
   183  		TotalCount: 4,
   184  		Secrets: []*Secret{
   185  			{Name: "A", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
   186  			{Name: "B", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
   187  		},
   188  	}
   189  	if !cmp.Equal(secrets, want) {
   190  		t.Errorf("Actions.ListRepoSecrets returned %+v, want %+v", secrets, want)
   191  	}
   192  
   193  	const methodName = "ListRepoSecrets"
   194  	testBadOptions(t, methodName, func() (err error) {
   195  		_, _, err = client.Actions.ListRepoSecrets(ctx, "\n", "\n", opts)
   196  		return err
   197  	})
   198  
   199  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   200  		got, resp, err := client.Actions.ListRepoSecrets(ctx, "o", "r", opts)
   201  		if got != nil {
   202  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   203  		}
   204  		return resp, err
   205  	})
   206  }
   207  
   208  func TestActionsService_ListRepoOrgSecrets(t *testing.T) {
   209  	client, mux, _, teardown := setup()
   210  	defer teardown()
   211  
   212  	mux.HandleFunc("/repos/o/r/actions/organization-secrets", func(w http.ResponseWriter, r *http.Request) {
   213  		testMethod(t, r, "GET")
   214  		testFormValues(t, r, values{"per_page": "2", "page": "2"})
   215  		fmt.Fprint(w, `{"total_count":4,"secrets":[{"name":"A","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`)
   216  	})
   217  
   218  	opts := &ListOptions{Page: 2, PerPage: 2}
   219  	ctx := context.Background()
   220  	secrets, _, err := client.Actions.ListRepoOrgSecrets(ctx, "o", "r", opts)
   221  	if err != nil {
   222  		t.Errorf("Actions.ListRepoOrgSecrets returned error: %v", err)
   223  	}
   224  
   225  	want := &Secrets{
   226  		TotalCount: 4,
   227  		Secrets: []*Secret{
   228  			{Name: "A", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
   229  			{Name: "B", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
   230  		},
   231  	}
   232  	if !cmp.Equal(secrets, want) {
   233  		t.Errorf("Actions.ListRepoOrgSecrets returned %+v, want %+v", secrets, want)
   234  	}
   235  
   236  	const methodName = "ListRepoOrgSecrets"
   237  	testBadOptions(t, methodName, func() (err error) {
   238  		_, _, err = client.Actions.ListRepoOrgSecrets(ctx, "\n", "\n", opts)
   239  		return err
   240  	})
   241  
   242  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   243  		got, resp, err := client.Actions.ListRepoOrgSecrets(ctx, "o", "r", opts)
   244  		if got != nil {
   245  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   246  		}
   247  		return resp, err
   248  	})
   249  }
   250  
   251  func TestActionsService_GetRepoSecret(t *testing.T) {
   252  	client, mux, _, teardown := setup()
   253  	defer teardown()
   254  
   255  	mux.HandleFunc("/repos/o/r/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) {
   256  		testMethod(t, r, "GET")
   257  		fmt.Fprint(w, `{"name":"NAME","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`)
   258  	})
   259  
   260  	ctx := context.Background()
   261  	secret, _, err := client.Actions.GetRepoSecret(ctx, "o", "r", "NAME")
   262  	if err != nil {
   263  		t.Errorf("Actions.GetRepoSecret returned error: %v", err)
   264  	}
   265  
   266  	want := &Secret{
   267  		Name:      "NAME",
   268  		CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)},
   269  		UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)},
   270  	}
   271  	if !cmp.Equal(secret, want) {
   272  		t.Errorf("Actions.GetRepoSecret returned %+v, want %+v", secret, want)
   273  	}
   274  
   275  	const methodName = "GetRepoSecret"
   276  	testBadOptions(t, methodName, func() (err error) {
   277  		_, _, err = client.Actions.GetRepoSecret(ctx, "\n", "\n", "\n")
   278  		return err
   279  	})
   280  
   281  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   282  		got, resp, err := client.Actions.GetRepoSecret(ctx, "o", "r", "NAME")
   283  		if got != nil {
   284  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   285  		}
   286  		return resp, err
   287  	})
   288  }
   289  
   290  func TestActionsService_CreateOrUpdateRepoSecret(t *testing.T) {
   291  	client, mux, _, teardown := setup()
   292  	defer teardown()
   293  
   294  	mux.HandleFunc("/repos/o/r/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) {
   295  		testMethod(t, r, "PUT")
   296  		testHeader(t, r, "Content-Type", "application/json")
   297  		testBody(t, r, `{"key_id":"1234","encrypted_value":"QIv="}`+"\n")
   298  		w.WriteHeader(http.StatusCreated)
   299  	})
   300  
   301  	input := &EncryptedSecret{
   302  		Name:           "NAME",
   303  		EncryptedValue: "QIv=",
   304  		KeyID:          "1234",
   305  	}
   306  	ctx := context.Background()
   307  	_, err := client.Actions.CreateOrUpdateRepoSecret(ctx, "o", "r", input)
   308  	if err != nil {
   309  		t.Errorf("Actions.CreateOrUpdateRepoSecret returned error: %v", err)
   310  	}
   311  
   312  	const methodName = "CreateOrUpdateRepoSecret"
   313  	testBadOptions(t, methodName, func() (err error) {
   314  		_, err = client.Actions.CreateOrUpdateRepoSecret(ctx, "\n", "\n", input)
   315  		return err
   316  	})
   317  
   318  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   319  		return client.Actions.CreateOrUpdateRepoSecret(ctx, "o", "r", input)
   320  	})
   321  }
   322  
   323  func TestActionsService_DeleteRepoSecret(t *testing.T) {
   324  	client, mux, _, teardown := setup()
   325  	defer teardown()
   326  
   327  	mux.HandleFunc("/repos/o/r/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) {
   328  		testMethod(t, r, "DELETE")
   329  	})
   330  
   331  	ctx := context.Background()
   332  	_, err := client.Actions.DeleteRepoSecret(ctx, "o", "r", "NAME")
   333  	if err != nil {
   334  		t.Errorf("Actions.DeleteRepoSecret returned error: %v", err)
   335  	}
   336  
   337  	const methodName = "DeleteRepoSecret"
   338  	testBadOptions(t, methodName, func() (err error) {
   339  		_, err = client.Actions.DeleteRepoSecret(ctx, "\n", "\n", "\n")
   340  		return err
   341  	})
   342  
   343  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   344  		return client.Actions.DeleteRepoSecret(ctx, "o", "r", "NAME")
   345  	})
   346  }
   347  
   348  func TestActionsService_GetOrgPublicKey(t *testing.T) {
   349  	client, mux, _, teardown := setup()
   350  	defer teardown()
   351  
   352  	mux.HandleFunc("/orgs/o/actions/secrets/public-key", func(w http.ResponseWriter, r *http.Request) {
   353  		testMethod(t, r, "GET")
   354  		fmt.Fprint(w, `{"key_id":"012345678","key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`)
   355  	})
   356  
   357  	ctx := context.Background()
   358  	key, _, err := client.Actions.GetOrgPublicKey(ctx, "o")
   359  	if err != nil {
   360  		t.Errorf("Actions.GetOrgPublicKey returned error: %v", err)
   361  	}
   362  
   363  	want := &PublicKey{KeyID: String("012345678"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")}
   364  	if !cmp.Equal(key, want) {
   365  		t.Errorf("Actions.GetOrgPublicKey returned %+v, want %+v", key, want)
   366  	}
   367  
   368  	const methodName = "GetOrgPublicKey"
   369  	testBadOptions(t, methodName, func() (err error) {
   370  		_, _, err = client.Actions.GetOrgPublicKey(ctx, "\n")
   371  		return err
   372  	})
   373  
   374  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   375  		got, resp, err := client.Actions.GetOrgPublicKey(ctx, "o")
   376  		if got != nil {
   377  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   378  		}
   379  		return resp, err
   380  	})
   381  }
   382  
   383  func TestActionsService_ListOrgSecrets(t *testing.T) {
   384  	client, mux, _, teardown := setup()
   385  	defer teardown()
   386  
   387  	mux.HandleFunc("/orgs/o/actions/secrets", func(w http.ResponseWriter, r *http.Request) {
   388  		testMethod(t, r, "GET")
   389  		testFormValues(t, r, values{"per_page": "2", "page": "2"})
   390  		fmt.Fprint(w, `{"total_count":3,"secrets":[{"name":"GIST_ID","created_at":"2019-08-10T14:59:22Z","updated_at":"2020-01-10T14:59:22Z","visibility":"private"},{"name":"DEPLOY_TOKEN","created_at":"2019-08-10T14:59:22Z","updated_at":"2020-01-10T14:59:22Z","visibility":"all"},{"name":"GH_TOKEN","created_at":"2019-08-10T14:59:22Z","updated_at":"2020-01-10T14:59:22Z","visibility":"selected","selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories"}]}`)
   391  	})
   392  
   393  	opts := &ListOptions{Page: 2, PerPage: 2}
   394  	ctx := context.Background()
   395  	secrets, _, err := client.Actions.ListOrgSecrets(ctx, "o", opts)
   396  	if err != nil {
   397  		t.Errorf("Actions.ListOrgSecrets returned error: %v", err)
   398  	}
   399  
   400  	want := &Secrets{
   401  		TotalCount: 3,
   402  		Secrets: []*Secret{
   403  			{Name: "GIST_ID", CreatedAt: Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 10, 14, 59, 22, 0, time.UTC)}, Visibility: "private"},
   404  			{Name: "DEPLOY_TOKEN", CreatedAt: Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 10, 14, 59, 22, 0, time.UTC)}, Visibility: "all"},
   405  			{Name: "GH_TOKEN", CreatedAt: Timestamp{time.Date(2019, time.August, 10, 14, 59, 22, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 10, 14, 59, 22, 0, time.UTC)}, Visibility: "selected", SelectedRepositoriesURL: "https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories"},
   406  		},
   407  	}
   408  	if !cmp.Equal(secrets, want) {
   409  		t.Errorf("Actions.ListOrgSecrets returned %+v, want %+v", secrets, want)
   410  	}
   411  
   412  	const methodName = "ListOrgSecrets"
   413  	testBadOptions(t, methodName, func() (err error) {
   414  		_, _, err = client.Actions.ListOrgSecrets(ctx, "\n", opts)
   415  		return err
   416  	})
   417  
   418  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   419  		got, resp, err := client.Actions.ListOrgSecrets(ctx, "o", opts)
   420  		if got != nil {
   421  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   422  		}
   423  		return resp, err
   424  	})
   425  }
   426  
   427  func TestActionsService_GetOrgSecret(t *testing.T) {
   428  	client, mux, _, teardown := setup()
   429  	defer teardown()
   430  
   431  	mux.HandleFunc("/orgs/o/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) {
   432  		testMethod(t, r, "GET")
   433  		fmt.Fprint(w, `{"name":"NAME","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z","visibility":"selected","selected_repositories_url":"https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories"}`)
   434  	})
   435  
   436  	ctx := context.Background()
   437  	secret, _, err := client.Actions.GetOrgSecret(ctx, "o", "NAME")
   438  	if err != nil {
   439  		t.Errorf("Actions.GetOrgSecret returned error: %v", err)
   440  	}
   441  
   442  	want := &Secret{
   443  		Name:                    "NAME",
   444  		CreatedAt:               Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)},
   445  		UpdatedAt:               Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)},
   446  		Visibility:              "selected",
   447  		SelectedRepositoriesURL: "https://api.github.com/orgs/octo-org/actions/secrets/SUPER_SECRET/repositories",
   448  	}
   449  	if !cmp.Equal(secret, want) {
   450  		t.Errorf("Actions.GetOrgSecret returned %+v, want %+v", secret, want)
   451  	}
   452  
   453  	const methodName = "GetOrgSecret"
   454  	testBadOptions(t, methodName, func() (err error) {
   455  		_, _, err = client.Actions.GetOrgSecret(ctx, "\n", "\n")
   456  		return err
   457  	})
   458  
   459  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   460  		got, resp, err := client.Actions.GetOrgSecret(ctx, "o", "NAME")
   461  		if got != nil {
   462  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   463  		}
   464  		return resp, err
   465  	})
   466  }
   467  
   468  func TestActionsService_CreateOrUpdateOrgSecret(t *testing.T) {
   469  	client, mux, _, teardown := setup()
   470  	defer teardown()
   471  
   472  	mux.HandleFunc("/orgs/o/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) {
   473  		testMethod(t, r, "PUT")
   474  		testHeader(t, r, "Content-Type", "application/json")
   475  		testBody(t, r, `{"key_id":"1234","encrypted_value":"QIv=","visibility":"selected","selected_repository_ids":[1296269,1269280]}`+"\n")
   476  		w.WriteHeader(http.StatusCreated)
   477  	})
   478  
   479  	input := &EncryptedSecret{
   480  		Name:                  "NAME",
   481  		EncryptedValue:        "QIv=",
   482  		KeyID:                 "1234",
   483  		Visibility:            "selected",
   484  		SelectedRepositoryIDs: SelectedRepoIDs{1296269, 1269280},
   485  	}
   486  	ctx := context.Background()
   487  	_, err := client.Actions.CreateOrUpdateOrgSecret(ctx, "o", input)
   488  	if err != nil {
   489  		t.Errorf("Actions.CreateOrUpdateOrgSecret returned error: %v", err)
   490  	}
   491  
   492  	const methodName = "CreateOrUpdateOrgSecret"
   493  	testBadOptions(t, methodName, func() (err error) {
   494  		_, err = client.Actions.CreateOrUpdateOrgSecret(ctx, "\n", input)
   495  		return err
   496  	})
   497  
   498  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   499  		return client.Actions.CreateOrUpdateOrgSecret(ctx, "o", input)
   500  	})
   501  }
   502  
   503  func TestActionsService_ListSelectedReposForOrgSecret(t *testing.T) {
   504  	client, mux, _, teardown := setup()
   505  	defer teardown()
   506  
   507  	mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories", func(w http.ResponseWriter, r *http.Request) {
   508  		testMethod(t, r, "GET")
   509  		fmt.Fprintf(w, `{"total_count":1,"repositories":[{"id":1}]}`)
   510  	})
   511  
   512  	opts := &ListOptions{Page: 2, PerPage: 2}
   513  	ctx := context.Background()
   514  	repos, _, err := client.Actions.ListSelectedReposForOrgSecret(ctx, "o", "NAME", opts)
   515  	if err != nil {
   516  		t.Errorf("Actions.ListSelectedReposForOrgSecret returned error: %v", err)
   517  	}
   518  
   519  	want := &SelectedReposList{
   520  		TotalCount: Int(1),
   521  		Repositories: []*Repository{
   522  			{ID: Int64(1)},
   523  		},
   524  	}
   525  	if !cmp.Equal(repos, want) {
   526  		t.Errorf("Actions.ListSelectedReposForOrgSecret returned %+v, want %+v", repos, want)
   527  	}
   528  
   529  	const methodName = "ListSelectedReposForOrgSecret"
   530  	testBadOptions(t, methodName, func() (err error) {
   531  		_, _, err = client.Actions.ListSelectedReposForOrgSecret(ctx, "\n", "\n", opts)
   532  		return err
   533  	})
   534  
   535  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   536  		got, resp, err := client.Actions.ListSelectedReposForOrgSecret(ctx, "o", "NAME", opts)
   537  		if got != nil {
   538  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   539  		}
   540  		return resp, err
   541  	})
   542  }
   543  
   544  func TestActionsService_SetSelectedReposForOrgSecret(t *testing.T) {
   545  	client, mux, _, teardown := setup()
   546  	defer teardown()
   547  
   548  	mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories", func(w http.ResponseWriter, r *http.Request) {
   549  		testMethod(t, r, "PUT")
   550  		testHeader(t, r, "Content-Type", "application/json")
   551  		testBody(t, r, `{"selected_repository_ids":[64780797]}`+"\n")
   552  	})
   553  
   554  	ctx := context.Background()
   555  	_, err := client.Actions.SetSelectedReposForOrgSecret(ctx, "o", "NAME", SelectedRepoIDs{64780797})
   556  	if err != nil {
   557  		t.Errorf("Actions.SetSelectedReposForOrgSecret returned error: %v", err)
   558  	}
   559  
   560  	const methodName = "SetSelectedReposForOrgSecret"
   561  	testBadOptions(t, methodName, func() (err error) {
   562  		_, err = client.Actions.SetSelectedReposForOrgSecret(ctx, "\n", "\n", SelectedRepoIDs{64780797})
   563  		return err
   564  	})
   565  
   566  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   567  		return client.Actions.SetSelectedReposForOrgSecret(ctx, "o", "NAME", SelectedRepoIDs{64780797})
   568  	})
   569  }
   570  
   571  func TestActionsService_AddSelectedRepoToOrgSecret(t *testing.T) {
   572  	client, mux, _, teardown := setup()
   573  	defer teardown()
   574  
   575  	mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories/1234", func(w http.ResponseWriter, r *http.Request) {
   576  		testMethod(t, r, "PUT")
   577  	})
   578  
   579  	repo := &Repository{ID: Int64(1234)}
   580  	ctx := context.Background()
   581  	_, err := client.Actions.AddSelectedRepoToOrgSecret(ctx, "o", "NAME", repo)
   582  	if err != nil {
   583  		t.Errorf("Actions.AddSelectedRepoToOrgSecret returned error: %v", err)
   584  	}
   585  
   586  	const methodName = "AddSelectedRepoToOrgSecret"
   587  	testBadOptions(t, methodName, func() (err error) {
   588  		_, err = client.Actions.AddSelectedRepoToOrgSecret(ctx, "\n", "\n", repo)
   589  		return err
   590  	})
   591  
   592  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   593  		return client.Actions.AddSelectedRepoToOrgSecret(ctx, "o", "NAME", repo)
   594  	})
   595  }
   596  
   597  func TestActionsService_RemoveSelectedRepoFromOrgSecret(t *testing.T) {
   598  	client, mux, _, teardown := setup()
   599  	defer teardown()
   600  
   601  	mux.HandleFunc("/orgs/o/actions/secrets/NAME/repositories/1234", func(w http.ResponseWriter, r *http.Request) {
   602  		testMethod(t, r, "DELETE")
   603  	})
   604  
   605  	repo := &Repository{ID: Int64(1234)}
   606  	ctx := context.Background()
   607  	_, err := client.Actions.RemoveSelectedRepoFromOrgSecret(ctx, "o", "NAME", repo)
   608  	if err != nil {
   609  		t.Errorf("Actions.RemoveSelectedRepoFromOrgSecret returned error: %v", err)
   610  	}
   611  
   612  	const methodName = "RemoveSelectedRepoFromOrgSecret"
   613  	testBadOptions(t, methodName, func() (err error) {
   614  		_, err = client.Actions.RemoveSelectedRepoFromOrgSecret(ctx, "\n", "\n", repo)
   615  		return err
   616  	})
   617  
   618  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   619  		return client.Actions.RemoveSelectedRepoFromOrgSecret(ctx, "o", "NAME", repo)
   620  	})
   621  }
   622  
   623  func TestActionsService_DeleteOrgSecret(t *testing.T) {
   624  	client, mux, _, teardown := setup()
   625  	defer teardown()
   626  
   627  	mux.HandleFunc("/orgs/o/actions/secrets/NAME", func(w http.ResponseWriter, r *http.Request) {
   628  		testMethod(t, r, "DELETE")
   629  	})
   630  
   631  	ctx := context.Background()
   632  	_, err := client.Actions.DeleteOrgSecret(ctx, "o", "NAME")
   633  	if err != nil {
   634  		t.Errorf("Actions.DeleteOrgSecret returned error: %v", err)
   635  	}
   636  
   637  	const methodName = "DeleteOrgSecret"
   638  	testBadOptions(t, methodName, func() (err error) {
   639  		_, err = client.Actions.DeleteOrgSecret(ctx, "\n", "\n")
   640  		return err
   641  	})
   642  
   643  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   644  		return client.Actions.DeleteOrgSecret(ctx, "o", "NAME")
   645  	})
   646  }
   647  
   648  func TestActionsService_GetEnvPublicKey(t *testing.T) {
   649  	client, mux, _, teardown := setup()
   650  	defer teardown()
   651  	mux.HandleFunc("/repositories/1/environments/e/secrets/public-key", func(w http.ResponseWriter, r *http.Request) {
   652  		testMethod(t, r, "GET")
   653  		fmt.Fprint(w, `{"key_id":"1234","key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`)
   654  	})
   655  
   656  	ctx := context.Background()
   657  	key, _, err := client.Actions.GetEnvPublicKey(ctx, 1, "e")
   658  	if err != nil {
   659  		t.Errorf("Actions.GetEnvPublicKey returned error: %v", err)
   660  	}
   661  
   662  	want := &PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")}
   663  	if !cmp.Equal(key, want) {
   664  		t.Errorf("Actions.GetEnvPublicKey returned %+v, want %+v", key, want)
   665  	}
   666  
   667  	const methodName = "GetEnvPublicKey"
   668  	testBadOptions(t, methodName, func() (err error) {
   669  		_, _, err = client.Actions.GetEnvPublicKey(ctx, 0.0, "\n")
   670  		return err
   671  	})
   672  
   673  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   674  		got, resp, err := client.Actions.GetEnvPublicKey(ctx, 1, "e")
   675  		if got != nil {
   676  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   677  		}
   678  		return resp, err
   679  	})
   680  }
   681  
   682  func TestActionsService_GetEnvPublicKeyNumeric(t *testing.T) {
   683  	client, mux, _, teardown := setup()
   684  	defer teardown()
   685  
   686  	mux.HandleFunc("/repositories/1/environments/e/secrets/public-key", func(w http.ResponseWriter, r *http.Request) {
   687  		testMethod(t, r, "GET")
   688  		fmt.Fprint(w, `{"key_id":1234,"key":"2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234"}`)
   689  	})
   690  
   691  	ctx := context.Background()
   692  	key, _, err := client.Actions.GetEnvPublicKey(ctx, 1, "e")
   693  	if err != nil {
   694  		t.Errorf("Actions.GetEnvPublicKey returned error: %v", err)
   695  	}
   696  
   697  	want := &PublicKey{KeyID: String("1234"), Key: String("2Sg8iYjAxxmI2LvUXpJjkYrMxURPc8r+dB7TJyvv1234")}
   698  	if !cmp.Equal(key, want) {
   699  		t.Errorf("Actions.GetEnvPublicKey returned %+v, want %+v", key, want)
   700  	}
   701  
   702  	const methodName = "GetEnvPublicKey"
   703  	testBadOptions(t, methodName, func() (err error) {
   704  		_, _, err = client.Actions.GetEnvPublicKey(ctx, 0.0, "\n")
   705  		return err
   706  	})
   707  
   708  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   709  		got, resp, err := client.Actions.GetEnvPublicKey(ctx, 1, "e")
   710  		if got != nil {
   711  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   712  		}
   713  		return resp, err
   714  	})
   715  }
   716  
   717  func TestActionsService_ListEnvSecrets(t *testing.T) {
   718  	client, mux, _, teardown := setup()
   719  	defer teardown()
   720  
   721  	mux.HandleFunc("/repositories/1/environments/e/secrets", func(w http.ResponseWriter, r *http.Request) {
   722  		testMethod(t, r, "GET")
   723  		testFormValues(t, r, values{"per_page": "2", "page": "2"})
   724  		fmt.Fprint(w, `{"total_count":4,"secrets":[{"name":"A","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`)
   725  	})
   726  
   727  	opts := &ListOptions{Page: 2, PerPage: 2}
   728  	ctx := context.Background()
   729  	secrets, _, err := client.Actions.ListEnvSecrets(ctx, 1, "e", opts)
   730  	if err != nil {
   731  		t.Errorf("Actions.ListEnvSecrets returned error: %v", err)
   732  	}
   733  
   734  	want := &Secrets{
   735  		TotalCount: 4,
   736  		Secrets: []*Secret{
   737  			{Name: "A", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
   738  			{Name: "B", CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}},
   739  		},
   740  	}
   741  	if !cmp.Equal(secrets, want) {
   742  		t.Errorf("Actions.ListEnvSecrets returned %+v, want %+v", secrets, want)
   743  	}
   744  
   745  	const methodName = "ListEnvSecrets"
   746  	testBadOptions(t, methodName, func() (err error) {
   747  		_, _, err = client.Actions.ListEnvSecrets(ctx, 0.0, "\n", opts)
   748  		return err
   749  	})
   750  
   751  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   752  		got, resp, err := client.Actions.ListEnvSecrets(ctx, 1, "e", opts)
   753  		if got != nil {
   754  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   755  		}
   756  		return resp, err
   757  	})
   758  }
   759  
   760  func TestActionsService_GetEnvSecret(t *testing.T) {
   761  	client, mux, _, teardown := setup()
   762  	defer teardown()
   763  
   764  	mux.HandleFunc("/repositories/1/environments/e/secrets/secret", func(w http.ResponseWriter, r *http.Request) {
   765  		testMethod(t, r, "GET")
   766  		fmt.Fprint(w, `{"name":"secret","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`)
   767  	})
   768  
   769  	ctx := context.Background()
   770  	secret, _, err := client.Actions.GetEnvSecret(ctx, 1, "e", "secret")
   771  	if err != nil {
   772  		t.Errorf("Actions.GetEnvSecret returned error: %v", err)
   773  	}
   774  
   775  	want := &Secret{
   776  		Name:      "secret",
   777  		CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)},
   778  		UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)},
   779  	}
   780  	if !cmp.Equal(secret, want) {
   781  		t.Errorf("Actions.GetEnvSecret returned %+v, want %+v", secret, want)
   782  	}
   783  
   784  	const methodName = "GetEnvSecret"
   785  	testBadOptions(t, methodName, func() (err error) {
   786  		_, _, err = client.Actions.GetEnvSecret(ctx, 0.0, "\n", "\n")
   787  		return err
   788  	})
   789  
   790  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   791  		got, resp, err := client.Actions.GetEnvSecret(ctx, 1, "e", "secret")
   792  		if got != nil {
   793  			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
   794  		}
   795  		return resp, err
   796  	})
   797  }
   798  
   799  func TestActionsService_CreateOrUpdateEnvSecret(t *testing.T) {
   800  	client, mux, _, teardown := setup()
   801  	defer teardown()
   802  
   803  	mux.HandleFunc("/repositories/1/environments/e/secrets/secret", func(w http.ResponseWriter, r *http.Request) {
   804  		testMethod(t, r, "PUT")
   805  		testHeader(t, r, "Content-Type", "application/json")
   806  		testBody(t, r, `{"key_id":"1234","encrypted_value":"QIv="}`+"\n")
   807  		w.WriteHeader(http.StatusCreated)
   808  	})
   809  
   810  	input := &EncryptedSecret{
   811  		Name:           "secret",
   812  		EncryptedValue: "QIv=",
   813  		KeyID:          "1234",
   814  	}
   815  	ctx := context.Background()
   816  	_, err := client.Actions.CreateOrUpdateEnvSecret(ctx, 1, "e", input)
   817  	if err != nil {
   818  		t.Errorf("Actions.CreateOrUpdateEnvSecret returned error: %v", err)
   819  	}
   820  
   821  	const methodName = "CreateOrUpdateEnvSecret"
   822  	testBadOptions(t, methodName, func() (err error) {
   823  		_, err = client.Actions.CreateOrUpdateEnvSecret(ctx, 0.0, "\n", input)
   824  		return err
   825  	})
   826  
   827  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   828  		return client.Actions.CreateOrUpdateEnvSecret(ctx, 1, "e", input)
   829  	})
   830  }
   831  
   832  func TestActionsService_DeleteEnvSecret(t *testing.T) {
   833  	client, mux, _, teardown := setup()
   834  	defer teardown()
   835  
   836  	mux.HandleFunc("/repositories/1/environments/e/secrets/secret", func(w http.ResponseWriter, r *http.Request) {
   837  		testMethod(t, r, "DELETE")
   838  	})
   839  
   840  	ctx := context.Background()
   841  	_, err := client.Actions.DeleteEnvSecret(ctx, 1, "e", "secret")
   842  	if err != nil {
   843  		t.Errorf("Actions.DeleteEnvSecret returned error: %v", err)
   844  	}
   845  
   846  	const methodName = "DeleteEnvSecret"
   847  	testBadOptions(t, methodName, func() (err error) {
   848  		_, err = client.Actions.DeleteEnvSecret(ctx, 0.0, "\n", "\n")
   849  		return err
   850  	})
   851  
   852  	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
   853  		return client.Actions.DeleteEnvSecret(ctx, 1, "r", "secret")
   854  	})
   855  }
   856  
   857  func TestPublicKey_Marshal(t *testing.T) {
   858  	testJSONMarshal(t, &PublicKey{}, "{}")
   859  
   860  	u := &PublicKey{
   861  		KeyID: String("kid"),
   862  		Key:   String("k"),
   863  	}
   864  
   865  	want := `{
   866  		"key_id": "kid",
   867  		"key": "k"
   868  	}`
   869  
   870  	testJSONMarshal(t, u, want)
   871  }
   872  
   873  func TestSecret_Marshal(t *testing.T) {
   874  	testJSONMarshal(t, &Secret{}, "{}")
   875  
   876  	u := &Secret{
   877  		Name:                    "n",
   878  		CreatedAt:               Timestamp{referenceTime},
   879  		UpdatedAt:               Timestamp{referenceTime},
   880  		Visibility:              "v",
   881  		SelectedRepositoriesURL: "s",
   882  	}
   883  
   884  	want := `{
   885  		"name": "n",
   886  		"created_at": ` + referenceTimeStr + `,
   887  		"updated_at": ` + referenceTimeStr + `,
   888  		"visibility": "v",
   889  		"selected_repositories_url": "s"
   890  	}`
   891  
   892  	testJSONMarshal(t, u, want)
   893  }
   894  
   895  func TestSecrets_Marshal(t *testing.T) {
   896  	testJSONMarshal(t, &Secrets{}, "{}")
   897  
   898  	u := &Secrets{
   899  		TotalCount: 1,
   900  		Secrets: []*Secret{
   901  			{
   902  				Name:                    "n",
   903  				CreatedAt:               Timestamp{referenceTime},
   904  				UpdatedAt:               Timestamp{referenceTime},
   905  				Visibility:              "v",
   906  				SelectedRepositoriesURL: "s"},
   907  		},
   908  	}
   909  
   910  	want := `{
   911  		"total_count": 1,
   912  		"secrets": [
   913  			{
   914  				"name": "n",
   915  				"created_at": ` + referenceTimeStr + `,
   916  				"updated_at": ` + referenceTimeStr + `,
   917  				"visibility": "v",
   918  				"selected_repositories_url": "s"
   919  			}
   920  		]
   921  	}`
   922  
   923  	testJSONMarshal(t, u, want)
   924  }
   925  
   926  func TestEncryptedSecret_Marshal(t *testing.T) {
   927  	testJSONMarshal(t, &EncryptedSecret{}, "{}")
   928  
   929  	u := &EncryptedSecret{
   930  		Name:                  "n",
   931  		KeyID:                 "kid",
   932  		EncryptedValue:        "e",
   933  		Visibility:            "v",
   934  		SelectedRepositoryIDs: []int64{1},
   935  	}
   936  
   937  	want := `{
   938  		"key_id": "kid",
   939  		"encrypted_value": "e",
   940  		"visibility": "v",
   941  		"selected_repository_ids": [1]
   942  	}`
   943  
   944  	testJSONMarshal(t, u, want)
   945  }
   946  
   947  func TestSelectedReposList_Marshal(t *testing.T) {
   948  	testJSONMarshal(t, &SelectedReposList{}, "{}")
   949  
   950  	u := &SelectedReposList{
   951  		TotalCount: Int(1),
   952  		Repositories: []*Repository{
   953  			{
   954  				ID:   Int64(1),
   955  				URL:  String("u"),
   956  				Name: String("n"),
   957  			},
   958  		},
   959  	}
   960  
   961  	want := `{
   962  		"total_count": 1,
   963  		"repositories": [
   964  			{
   965  				"id": 1,
   966  				"url": "u",
   967  				"name": "n"
   968  			}
   969  		]
   970  	}`
   971  
   972  	testJSONMarshal(t, u, want)
   973  }