github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/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/ungtb10d/cli/v2/internal/config"
    10  	"github.com/ungtb10d/cli/v2/internal/prompter"
    11  	"github.com/ungtb10d/cli/v2/pkg/cmdutil"
    12  	"github.com/ungtb10d/cli/v2/pkg/httpmock"
    13  	"github.com/ungtb10d/cli/v2/pkg/iostreams"
    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:     "nontty no arguments",
    28  			cli:      "",
    29  			wantsErr: true,
    30  		},
    31  		{
    32  			name: "tty no arguments",
    33  			tty:  true,
    34  			cli:  "",
    35  			wants: LogoutOptions{
    36  				Hostname: "",
    37  			},
    38  		},
    39  		{
    40  			name: "tty with hostname",
    41  			tty:  true,
    42  			cli:  "--hostname harry.mason",
    43  			wants: LogoutOptions{
    44  				Hostname: "harry.mason",
    45  			},
    46  		},
    47  		{
    48  			name: "nontty with hostname",
    49  			cli:  "--hostname harry.mason",
    50  			wants: LogoutOptions{
    51  				Hostname: "harry.mason",
    52  			},
    53  		},
    54  	}
    55  	for _, tt := range tests {
    56  		t.Run(tt.name, func(t *testing.T) {
    57  			ios, _, _, _ := iostreams.Test()
    58  			f := &cmdutil.Factory{
    59  				IOStreams: ios,
    60  			}
    61  			ios.SetStdinTTY(tt.tty)
    62  			ios.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  		prompterStubs func(*prompter.PrompterMock)
    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  			prompterStubs: func(pm *prompter.PrompterMock) {
   109  				pm.SelectFunc = func(_, _ string, opts []string) (int, error) {
   110  					return prompter.IndexFor(opts, "github.com")
   111  				}
   112  			},
   113  			wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`),
   114  		},
   115  		{
   116  			name:       "no arguments, one host",
   117  			opts:       &LogoutOptions{},
   118  			cfgHosts:   []string{"github.com"},
   119  			wantHosts:  "{}\n",
   120  			wantErrOut: regexp.MustCompile(`Logged out of github.com account 'cybilb'`),
   121  		},
   122  		{
   123  			name:    "no arguments, no hosts",
   124  			opts:    &LogoutOptions{},
   125  			wantErr: `not logged in to any hosts`,
   126  		},
   127  		{
   128  			name: "hostname",
   129  			opts: &LogoutOptions{
   130  				Hostname: "cheryl.mason",
   131  			},
   132  			cfgHosts:   []string{"cheryl.mason", "github.com"},
   133  			wantHosts:  "github.com:\n    oauth_token: abc123\n",
   134  			wantErrOut: regexp.MustCompile(`Logged out of cheryl.mason account 'cybilb'`),
   135  		},
   136  	}
   137  
   138  	for _, tt := range tests {
   139  		t.Run(tt.name, func(t *testing.T) {
   140  			readConfigs := config.StubWriteConfig(t)
   141  			cfg := config.NewFromString("")
   142  			for _, hostname := range tt.cfgHosts {
   143  				cfg.Set(hostname, "oauth_token", "abc123")
   144  			}
   145  			tt.opts.Config = func() (config.Config, error) {
   146  				return cfg, nil
   147  			}
   148  
   149  			ios, _, _, stderr := iostreams.Test()
   150  			ios.SetStdinTTY(true)
   151  			ios.SetStdoutTTY(true)
   152  			tt.opts.IO = ios
   153  
   154  			reg := &httpmock.Registry{}
   155  			reg.Register(
   156  				httpmock.GraphQL(`query UserCurrent\b`),
   157  				httpmock.StringResponse(`{"data":{"viewer":{"login":"cybilb"}}}`),
   158  			)
   159  			tt.opts.HttpClient = func() (*http.Client, error) {
   160  				return &http.Client{Transport: reg}, nil
   161  			}
   162  
   163  			pm := &prompter.PrompterMock{}
   164  			if tt.prompterStubs != nil {
   165  				tt.prompterStubs(pm)
   166  			}
   167  			tt.opts.Prompter = pm
   168  
   169  			err := logoutRun(tt.opts)
   170  			if tt.wantErr != "" {
   171  				assert.EqualError(t, err, tt.wantErr)
   172  				return
   173  			} else {
   174  				assert.NoError(t, err)
   175  			}
   176  
   177  			if tt.wantErrOut == nil {
   178  				assert.Equal(t, "", stderr.String())
   179  			} else {
   180  				assert.True(t, tt.wantErrOut.MatchString(stderr.String()))
   181  			}
   182  
   183  			mainBuf := bytes.Buffer{}
   184  			hostsBuf := bytes.Buffer{}
   185  			readConfigs(&mainBuf, &hostsBuf)
   186  
   187  			assert.Equal(t, tt.wantHosts, hostsBuf.String())
   188  			reg.Verify(t)
   189  		})
   190  	}
   191  }
   192  
   193  func Test_logoutRun_nontty(t *testing.T) {
   194  	tests := []struct {
   195  		name      string
   196  		opts      *LogoutOptions
   197  		cfgHosts  []string
   198  		wantHosts string
   199  		wantErr   string
   200  		ghtoken   string
   201  	}{
   202  		{
   203  			name: "hostname, one host",
   204  			opts: &LogoutOptions{
   205  				Hostname: "harry.mason",
   206  			},
   207  			cfgHosts:  []string{"harry.mason"},
   208  			wantHosts: "{}\n",
   209  		},
   210  		{
   211  			name: "hostname, multiple hosts",
   212  			opts: &LogoutOptions{
   213  				Hostname: "harry.mason",
   214  			},
   215  			cfgHosts:  []string{"harry.mason", "cheryl.mason"},
   216  			wantHosts: "cheryl.mason:\n    oauth_token: abc123\n",
   217  		},
   218  		{
   219  			name: "hostname, no hosts",
   220  			opts: &LogoutOptions{
   221  				Hostname: "harry.mason",
   222  			},
   223  			wantErr: `not logged in to any hosts`,
   224  		},
   225  	}
   226  
   227  	for _, tt := range tests {
   228  		t.Run(tt.name, func(t *testing.T) {
   229  			readConfigs := config.StubWriteConfig(t)
   230  			cfg := config.NewFromString("")
   231  			for _, hostname := range tt.cfgHosts {
   232  				cfg.Set(hostname, "oauth_token", "abc123")
   233  			}
   234  			tt.opts.Config = func() (config.Config, error) {
   235  				return cfg, nil
   236  			}
   237  
   238  			ios, _, _, stderr := iostreams.Test()
   239  			ios.SetStdinTTY(false)
   240  			ios.SetStdoutTTY(false)
   241  			tt.opts.IO = ios
   242  
   243  			reg := &httpmock.Registry{}
   244  			tt.opts.HttpClient = func() (*http.Client, error) {
   245  				return &http.Client{Transport: reg}, nil
   246  			}
   247  
   248  			err := logoutRun(tt.opts)
   249  			if tt.wantErr != "" {
   250  				assert.EqualError(t, err, tt.wantErr)
   251  			} else {
   252  				assert.NoError(t, err)
   253  			}
   254  
   255  			assert.Equal(t, "", stderr.String())
   256  
   257  			mainBuf := bytes.Buffer{}
   258  			hostsBuf := bytes.Buffer{}
   259  			readConfigs(&mainBuf, &hostsBuf)
   260  
   261  			assert.Equal(t, tt.wantHosts, hostsBuf.String())
   262  			reg.Verify(t)
   263  		})
   264  	}
   265  }