github.com/secman-team/gh-api@v1.8.2/pkg/cmd/auth/logout/logout_test.go (about)

     1  package logout
     2  
     3  import (
     4  	"bytes"
     5  	"net/http"
     6  	"regexp"
     7  	"testing"
     8  
     9  	"github.com/secman-team/gh-api/core/config"
    10  	"github.com/secman-team/gh-api/pkg/cmdutil"
    11  	"github.com/secman-team/gh-api/pkg/httpmock"
    12  	"github.com/secman-team/gh-api/pkg/iostreams"
    13  	"github.com/secman-team/gh-api/pkg/prompt"
    14  	"github.com/google/shlex"
    15  	"github.com/stretchr/testify/assert"
    16  )
    17  
    18  func Test_NewCmdLogout(t *testing.T) {
    19  	tests := []struct {
    20  		name     string
    21  		cli      string
    22  		wants    LogoutOptions
    23  		wantsErr bool
    24  		tty      bool
    25  	}{
    26  		{
    27  			name: "tty with hostname",
    28  			tty:  true,
    29  			cli:  "--hostname harry.mason",
    30  			wants: LogoutOptions{
    31  				Hostname: "harry.mason",
    32  			},
    33  		},
    34  		{
    35  			name: "tty no arguments",
    36  			tty:  true,
    37  			cli:  "",
    38  			wants: LogoutOptions{
    39  				Hostname: "",
    40  			},
    41  		},
    42  		{
    43  			name: "nontty with hostname",
    44  			cli:  "--hostname harry.mason",
    45  			wants: LogoutOptions{
    46  				Hostname: "harry.mason",
    47  			},
    48  		},
    49  		{
    50  			name:     "nontty no arguments",
    51  			cli:      "",
    52  			wantsErr: true,
    53  		},
    54  	}
    55  	for _, tt := range tests {
    56  		t.Run(tt.name, func(t *testing.T) {
    57  			io, _, _, _ := iostreams.Test()
    58  			f := &cmdutil.Factory{
    59  				IOStreams: io,
    60  			}
    61  			io.SetStdinTTY(tt.tty)
    62  			io.SetStdoutTTY(tt.tty)
    63  
    64  			argv, err := shlex.Split(tt.cli)
    65  			assert.NoError(t, err)
    66  
    67  			var gotOpts *LogoutOptions
    68  			cmd := NewCmdLogout(f, func(opts *LogoutOptions) error {
    69  				gotOpts = opts
    70  				return nil
    71  			})
    72  			// TODO cobra hack-around
    73  			cmd.Flags().BoolP("help", "x", false, "")
    74  
    75  			cmd.SetArgs(argv)
    76  			cmd.SetIn(&bytes.Buffer{})
    77  			cmd.SetOut(&bytes.Buffer{})
    78  			cmd.SetErr(&bytes.Buffer{})
    79  
    80  			_, err = cmd.ExecuteC()
    81  			if tt.wantsErr {
    82  				assert.Error(t, err)
    83  				return
    84  			}
    85  			assert.NoError(t, err)
    86  
    87  			assert.Equal(t, tt.wants.Hostname, gotOpts.Hostname)
    88  		})
    89  
    90  	}
    91  }
    92  
    93  func Test_logoutRun_tty(t *testing.T) {
    94  	tests := []struct {
    95  		name       string
    96  		opts       *LogoutOptions
    97  		askStubs   func(*prompt.AskStubber)
    98  		cfgHosts   []string
    99  		wantHosts  string
   100  		wantErrOut *regexp.Regexp
   101  		wantErr    string
   102  	}{
   103  		{
   104  			name:      "no arguments, multiple hosts",
   105  			opts:      &LogoutOptions{},
   106  			cfgHosts:  []string{"cheryl.mason", "github.com"},
   107  			wantHosts: "cheryl.mason:\n    oauth_token: abc123\n",
   108  			askStubs: func(as *prompt.AskStubber) {
   109  				as.StubOne("github.com")
   110  				as.StubOne(true)
   111  			},
   112  			wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`),
   113  		},
   114  		{
   115  			name:     "no arguments, one host",
   116  			opts:     &LogoutOptions{},
   117  			cfgHosts: []string{"github.com"},
   118  			askStubs: func(as *prompt.AskStubber) {
   119  				as.StubOne(true)
   120  			},
   121  			wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`),
   122  		},
   123  		{
   124  			name:    "no arguments, no hosts",
   125  			opts:    &LogoutOptions{},
   126  			wantErr: `not logged in to any hosts`,
   127  		},
   128  		{
   129  			name: "hostname",
   130  			opts: &LogoutOptions{
   131  				Hostname: "cheryl.mason",
   132  			},
   133  			cfgHosts:  []string{"cheryl.mason", "github.com"},
   134  			wantHosts: "github.com:\n    oauth_token: abc123\n",
   135  			askStubs: func(as *prompt.AskStubber) {
   136  				as.StubOne(true)
   137  			},
   138  			wantErrOut: regexp.MustCompile(`Logged out of cheryl.mason account 'cybilb'`),
   139  		},
   140  	}
   141  
   142  	for _, tt := range tests {
   143  		t.Run(tt.name, func(t *testing.T) {
   144  			io, _, _, stderr := iostreams.Test()
   145  
   146  			io.SetStdinTTY(true)
   147  			io.SetStdoutTTY(true)
   148  
   149  			tt.opts.IO = io
   150  			cfg := config.NewBlankConfig()
   151  			tt.opts.Config = func() (config.Config, error) {
   152  				return cfg, nil
   153  			}
   154  
   155  			for _, hostname := range tt.cfgHosts {
   156  				_ = cfg.Set(hostname, "oauth_token", "abc123")
   157  			}
   158  
   159  			reg := &httpmock.Registry{}
   160  			reg.Register(
   161  				httpmock.GraphQL(`query UserCurrent\b`),
   162  				httpmock.StringResponse(`{"data":{"viewer":{"login":"cybilb"}}}`))
   163  
   164  			tt.opts.HttpClient = func() (*http.Client, error) {
   165  				return &http.Client{Transport: reg}, nil
   166  			}
   167  
   168  			mainBuf := bytes.Buffer{}
   169  			hostsBuf := bytes.Buffer{}
   170  			defer config.StubWriteConfig(&mainBuf, &hostsBuf)()
   171  
   172  			as, teardown := prompt.InitAskStubber()
   173  			defer teardown()
   174  			if tt.askStubs != nil {
   175  				tt.askStubs(as)
   176  			}
   177  
   178  			err := logoutRun(tt.opts)
   179  			if tt.wantErr != "" {
   180  				assert.EqualError(t, err, tt.wantErr)
   181  				return
   182  			} else {
   183  				assert.NoError(t, err)
   184  			}
   185  
   186  			if tt.wantErrOut == nil {
   187  				assert.Equal(t, "", stderr.String())
   188  			} else {
   189  				assert.True(t, tt.wantErrOut.MatchString(stderr.String()))
   190  			}
   191  
   192  			assert.Equal(t, tt.wantHosts, hostsBuf.String())
   193  			reg.Verify(t)
   194  		})
   195  	}
   196  }
   197  
   198  func Test_logoutRun_nontty(t *testing.T) {
   199  	tests := []struct {
   200  		name      string
   201  		opts      *LogoutOptions
   202  		cfgHosts  []string
   203  		wantHosts string
   204  		wantErr   string
   205  		ghtoken   string
   206  	}{
   207  		{
   208  			name: "hostname, one host",
   209  			opts: &LogoutOptions{
   210  				Hostname: "harry.mason",
   211  			},
   212  			cfgHosts: []string{"harry.mason"},
   213  		},
   214  		{
   215  			name: "hostname, multiple hosts",
   216  			opts: &LogoutOptions{
   217  				Hostname: "harry.mason",
   218  			},
   219  			cfgHosts:  []string{"harry.mason", "cheryl.mason"},
   220  			wantHosts: "cheryl.mason:\n    oauth_token: abc123\n",
   221  		},
   222  		{
   223  			name: "hostname, no hosts",
   224  			opts: &LogoutOptions{
   225  				Hostname: "harry.mason",
   226  			},
   227  			wantErr: `not logged in to any hosts`,
   228  		},
   229  	}
   230  
   231  	for _, tt := range tests {
   232  		t.Run(tt.name, func(t *testing.T) {
   233  			io, _, _, stderr := iostreams.Test()
   234  
   235  			io.SetStdinTTY(false)
   236  			io.SetStdoutTTY(false)
   237  
   238  			tt.opts.IO = io
   239  			cfg := config.NewBlankConfig()
   240  			tt.opts.Config = func() (config.Config, error) {
   241  				return cfg, nil
   242  			}
   243  
   244  			for _, hostname := range tt.cfgHosts {
   245  				_ = cfg.Set(hostname, "oauth_token", "abc123")
   246  			}
   247  
   248  			reg := &httpmock.Registry{}
   249  			tt.opts.HttpClient = func() (*http.Client, error) {
   250  				return &http.Client{Transport: reg}, nil
   251  			}
   252  
   253  			mainBuf := bytes.Buffer{}
   254  			hostsBuf := bytes.Buffer{}
   255  			defer config.StubWriteConfig(&mainBuf, &hostsBuf)()
   256  
   257  			err := logoutRun(tt.opts)
   258  			if tt.wantErr != "" {
   259  				assert.EqualError(t, err, tt.wantErr)
   260  			} else {
   261  				assert.NoError(t, err)
   262  			}
   263  
   264  			assert.Equal(t, "", stderr.String())
   265  
   266  			assert.Equal(t, tt.wantHosts, hostsBuf.String())
   267  			reg.Verify(t)
   268  		})
   269  	}
   270  }