github.com/andrewhsu/cli/v2@v2.0.1-0.20210910131313-d4b4061f5b89/pkg/cmd/secret/list/list_test.go (about)

     1  package list
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"strings"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/andrewhsu/cli/v2/internal/config"
    13  	"github.com/andrewhsu/cli/v2/internal/ghrepo"
    14  	"github.com/andrewhsu/cli/v2/pkg/cmd/secret/shared"
    15  	"github.com/andrewhsu/cli/v2/pkg/cmdutil"
    16  	"github.com/andrewhsu/cli/v2/pkg/httpmock"
    17  	"github.com/andrewhsu/cli/v2/pkg/iostreams"
    18  	"github.com/andrewhsu/cli/v2/test"
    19  	"github.com/google/shlex"
    20  	"github.com/stretchr/testify/assert"
    21  )
    22  
    23  func Test_NewCmdList(t *testing.T) {
    24  	tests := []struct {
    25  		name  string
    26  		cli   string
    27  		wants ListOptions
    28  	}{
    29  		{
    30  			name: "repo",
    31  			cli:  "",
    32  			wants: ListOptions{
    33  				OrgName: "",
    34  			},
    35  		},
    36  		{
    37  			name: "org",
    38  			cli:  "-oUmbrellaCorporation",
    39  			wants: ListOptions{
    40  				OrgName: "UmbrellaCorporation",
    41  			},
    42  		},
    43  		{
    44  			name: "env",
    45  			cli:  "-eDevelopment",
    46  			wants: ListOptions{
    47  				EnvName: "Development",
    48  			},
    49  		},
    50  	}
    51  
    52  	for _, tt := range tests {
    53  		t.Run(tt.name, func(t *testing.T) {
    54  			io, _, _, _ := iostreams.Test()
    55  			f := &cmdutil.Factory{
    56  				IOStreams: io,
    57  			}
    58  
    59  			argv, err := shlex.Split(tt.cli)
    60  			assert.NoError(t, err)
    61  
    62  			var gotOpts *ListOptions
    63  			cmd := NewCmdList(f, func(opts *ListOptions) error {
    64  				gotOpts = opts
    65  				return nil
    66  			})
    67  			cmd.SetArgs(argv)
    68  			cmd.SetIn(&bytes.Buffer{})
    69  			cmd.SetOut(&bytes.Buffer{})
    70  			cmd.SetErr(&bytes.Buffer{})
    71  
    72  			_, err = cmd.ExecuteC()
    73  			assert.NoError(t, err)
    74  
    75  			assert.Equal(t, tt.wants.OrgName, gotOpts.OrgName)
    76  			assert.Equal(t, tt.wants.EnvName, gotOpts.EnvName)
    77  		})
    78  	}
    79  }
    80  
    81  func Test_listRun(t *testing.T) {
    82  	tests := []struct {
    83  		name    string
    84  		tty     bool
    85  		opts    *ListOptions
    86  		wantOut []string
    87  	}{
    88  		{
    89  			name: "repo tty",
    90  			tty:  true,
    91  			opts: &ListOptions{},
    92  			wantOut: []string{
    93  				"SECRET_ONE.*Updated 1988-10-11",
    94  				"SECRET_TWO.*Updated 2020-12-04",
    95  				"SECRET_THREE.*Updated 1975-11-30",
    96  			},
    97  		},
    98  		{
    99  			name: "repo not tty",
   100  			tty:  false,
   101  			opts: &ListOptions{},
   102  			wantOut: []string{
   103  				"SECRET_ONE\t1988-10-11",
   104  				"SECRET_TWO\t2020-12-04",
   105  				"SECRET_THREE\t1975-11-30",
   106  			},
   107  		},
   108  		{
   109  			name: "org tty",
   110  			tty:  true,
   111  			opts: &ListOptions{
   112  				OrgName: "UmbrellaCorporation",
   113  			},
   114  			wantOut: []string{
   115  				"SECRET_ONE.*Updated 1988-10-11.*Visible to all repositories",
   116  				"SECRET_TWO.*Updated 2020-12-04.*Visible to private repositories",
   117  				"SECRET_THREE.*Updated 1975-11-30.*Visible to 2 selected repositories",
   118  			},
   119  		},
   120  		{
   121  			name: "org not tty",
   122  			tty:  false,
   123  			opts: &ListOptions{
   124  				OrgName: "UmbrellaCorporation",
   125  			},
   126  			wantOut: []string{
   127  				"SECRET_ONE\t1988-10-11\tALL",
   128  				"SECRET_TWO\t2020-12-04\tPRIVATE",
   129  				"SECRET_THREE\t1975-11-30\tSELECTED",
   130  			},
   131  		},
   132  		{
   133  			name: "env tty",
   134  			tty:  true,
   135  			opts: &ListOptions{
   136  				EnvName: "Development",
   137  			},
   138  			wantOut: []string{
   139  				"SECRET_ONE.*Updated 1988-10-11",
   140  				"SECRET_TWO.*Updated 2020-12-04",
   141  				"SECRET_THREE.*Updated 1975-11-30",
   142  			},
   143  		},
   144  		{
   145  			name: "env not tty",
   146  			tty:  false,
   147  			opts: &ListOptions{
   148  				EnvName: "Development",
   149  			},
   150  			wantOut: []string{
   151  				"SECRET_ONE\t1988-10-11",
   152  				"SECRET_TWO\t2020-12-04",
   153  				"SECRET_THREE\t1975-11-30",
   154  			},
   155  		},
   156  	}
   157  
   158  	for _, tt := range tests {
   159  		t.Run(tt.name, func(t *testing.T) {
   160  			reg := &httpmock.Registry{}
   161  
   162  			path := "repos/owner/repo/actions/secrets"
   163  			if tt.opts.EnvName != "" {
   164  				path = fmt.Sprintf("repos/owner/repo/environments/%s/secrets", tt.opts.EnvName)
   165  			}
   166  
   167  			t0, _ := time.Parse("2006-01-02", "1988-10-11")
   168  			t1, _ := time.Parse("2006-01-02", "2020-12-04")
   169  			t2, _ := time.Parse("2006-01-02", "1975-11-30")
   170  			payload := secretsPayload{}
   171  			payload.Secrets = []*Secret{
   172  				{
   173  					Name:      "SECRET_ONE",
   174  					UpdatedAt: t0,
   175  				},
   176  				{
   177  					Name:      "SECRET_TWO",
   178  					UpdatedAt: t1,
   179  				},
   180  				{
   181  					Name:      "SECRET_THREE",
   182  					UpdatedAt: t2,
   183  				},
   184  			}
   185  			if tt.opts.OrgName != "" {
   186  				payload.Secrets = []*Secret{
   187  					{
   188  						Name:       "SECRET_ONE",
   189  						UpdatedAt:  t0,
   190  						Visibility: shared.All,
   191  					},
   192  					{
   193  						Name:       "SECRET_TWO",
   194  						UpdatedAt:  t1,
   195  						Visibility: shared.Private,
   196  					},
   197  					{
   198  						Name:             "SECRET_THREE",
   199  						UpdatedAt:        t2,
   200  						Visibility:       shared.Selected,
   201  						SelectedReposURL: fmt.Sprintf("https://api.github.com/orgs/%s/actions/secrets/SECRET_THREE/repositories", tt.opts.OrgName),
   202  					},
   203  				}
   204  				path = fmt.Sprintf("orgs/%s/actions/secrets", tt.opts.OrgName)
   205  
   206  				reg.Register(
   207  					httpmock.REST("GET", fmt.Sprintf("orgs/%s/actions/secrets/SECRET_THREE/repositories", tt.opts.OrgName)),
   208  					httpmock.JSONResponse(struct {
   209  						TotalCount int `json:"total_count"`
   210  					}{2}))
   211  			}
   212  
   213  			reg.Register(httpmock.REST("GET", path), httpmock.JSONResponse(payload))
   214  
   215  			io, _, stdout, _ := iostreams.Test()
   216  
   217  			io.SetStdoutTTY(tt.tty)
   218  
   219  			tt.opts.IO = io
   220  			tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
   221  				return ghrepo.FromFullName("owner/repo")
   222  			}
   223  			tt.opts.HttpClient = func() (*http.Client, error) {
   224  				return &http.Client{Transport: reg}, nil
   225  			}
   226  			tt.opts.Config = func() (config.Config, error) {
   227  				return config.NewBlankConfig(), nil
   228  			}
   229  
   230  			err := listRun(tt.opts)
   231  			assert.NoError(t, err)
   232  
   233  			reg.Verify(t)
   234  
   235  			//nolint:staticcheck // prefer exact matchers over ExpectLines
   236  			test.ExpectLines(t, stdout.String(), tt.wantOut...)
   237  		})
   238  	}
   239  }
   240  
   241  func Test_getSecrets_pagination(t *testing.T) {
   242  	var requests []*http.Request
   243  	var client testClient = func(req *http.Request) (*http.Response, error) {
   244  		header := make(map[string][]string)
   245  		if len(requests) == 0 {
   246  			header["Link"] = []string{`<http://example.com/page/0>; rel="previous", <http://example.com/page/2>; rel="next"`}
   247  		}
   248  		requests = append(requests, req)
   249  		return &http.Response{
   250  			Request: req,
   251  			Body:    ioutil.NopCloser(strings.NewReader(`{"secrets":[{},{}]}`)),
   252  			Header:  header,
   253  		}, nil
   254  	}
   255  
   256  	secrets, err := getSecrets(client, "github.com", "path/to")
   257  	assert.NoError(t, err)
   258  	assert.Equal(t, 2, len(requests))
   259  	assert.Equal(t, 4, len(secrets))
   260  	assert.Equal(t, "https://api.github.com/path/to?per_page=100", requests[0].URL.String())
   261  	assert.Equal(t, "http://example.com/page/2", requests[1].URL.String())
   262  }
   263  
   264  type testClient func(*http.Request) (*http.Response, error)
   265  
   266  func (c testClient) Do(req *http.Request) (*http.Response, error) {
   267  	return c(req)
   268  }