github.com/cli/cli@v1.14.1-0.20210902173923-1af6a669e342/pkg/cmd/release/view/view_test.go (about)

     1  package view
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/MakeNowJust/heredoc"
    12  	"github.com/cli/cli/internal/ghrepo"
    13  	"github.com/cli/cli/pkg/cmdutil"
    14  	"github.com/cli/cli/pkg/httpmock"
    15  	"github.com/cli/cli/pkg/iostreams"
    16  	"github.com/google/shlex"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func Test_NewCmdView(t *testing.T) {
    22  	tests := []struct {
    23  		name    string
    24  		args    string
    25  		isTTY   bool
    26  		want    ViewOptions
    27  		wantErr string
    28  	}{
    29  		{
    30  			name:  "version argument",
    31  			args:  "v1.2.3",
    32  			isTTY: true,
    33  			want: ViewOptions{
    34  				TagName: "v1.2.3",
    35  				WebMode: false,
    36  			},
    37  		},
    38  		{
    39  			name:  "no arguments",
    40  			args:  "",
    41  			isTTY: true,
    42  			want: ViewOptions{
    43  				TagName: "",
    44  				WebMode: false,
    45  			},
    46  		},
    47  		{
    48  			name:  "web mode",
    49  			args:  "-w",
    50  			isTTY: true,
    51  			want: ViewOptions{
    52  				TagName: "",
    53  				WebMode: true,
    54  			},
    55  		},
    56  	}
    57  	for _, tt := range tests {
    58  		t.Run(tt.name, func(t *testing.T) {
    59  			io, _, _, _ := iostreams.Test()
    60  			io.SetStdoutTTY(tt.isTTY)
    61  			io.SetStdinTTY(tt.isTTY)
    62  			io.SetStderrTTY(tt.isTTY)
    63  
    64  			f := &cmdutil.Factory{
    65  				IOStreams: io,
    66  			}
    67  
    68  			var opts *ViewOptions
    69  			cmd := NewCmdView(f, func(o *ViewOptions) error {
    70  				opts = o
    71  				return nil
    72  			})
    73  			cmd.PersistentFlags().StringP("repo", "R", "", "")
    74  
    75  			argv, err := shlex.Split(tt.args)
    76  			require.NoError(t, err)
    77  			cmd.SetArgs(argv)
    78  
    79  			cmd.SetIn(&bytes.Buffer{})
    80  			cmd.SetOut(ioutil.Discard)
    81  			cmd.SetErr(ioutil.Discard)
    82  
    83  			_, err = cmd.ExecuteC()
    84  			if tt.wantErr != "" {
    85  				require.EqualError(t, err, tt.wantErr)
    86  				return
    87  			} else {
    88  				require.NoError(t, err)
    89  			}
    90  
    91  			assert.Equal(t, tt.want.TagName, opts.TagName)
    92  			assert.Equal(t, tt.want.WebMode, opts.WebMode)
    93  		})
    94  	}
    95  }
    96  
    97  func Test_viewRun(t *testing.T) {
    98  	oneHourAgo := time.Now().Add(time.Duration(-24) * time.Hour)
    99  	frozenTime, err := time.Parse(time.RFC3339, "2020-08-31T15:44:24+02:00")
   100  	require.NoError(t, err)
   101  
   102  	tests := []struct {
   103  		name       string
   104  		isTTY      bool
   105  		releasedAt time.Time
   106  		opts       ViewOptions
   107  		wantErr    string
   108  		wantStdout string
   109  		wantStderr string
   110  	}{
   111  		{
   112  			name:       "view specific release",
   113  			isTTY:      true,
   114  			releasedAt: oneHourAgo,
   115  			opts: ViewOptions{
   116  				TagName: "v1.2.3",
   117  			},
   118  			wantStdout: heredoc.Doc(`
   119  				v1.2.3
   120  				MonaLisa released this about 1 day ago
   121  				
   122  				                                                                              
   123  				  • Fixed bugs                                                                
   124  				
   125  				
   126  				Assets
   127  				windows.zip  12 B
   128  				linux.tgz    34 B
   129  				
   130  				View on GitHub: https://github.com/OWNER/REPO/releases/tags/v1.2.3
   131  			`),
   132  			wantStderr: ``,
   133  		},
   134  		{
   135  			name:       "view latest release",
   136  			isTTY:      true,
   137  			releasedAt: oneHourAgo,
   138  			opts: ViewOptions{
   139  				TagName: "",
   140  			},
   141  			wantStdout: heredoc.Doc(`
   142  				v1.2.3
   143  				MonaLisa released this about 1 day ago
   144  				
   145  				                                                                              
   146  				  • Fixed bugs                                                                
   147  				
   148  				
   149  				Assets
   150  				windows.zip  12 B
   151  				linux.tgz    34 B
   152  				
   153  				View on GitHub: https://github.com/OWNER/REPO/releases/tags/v1.2.3
   154  			`),
   155  			wantStderr: ``,
   156  		},
   157  		{
   158  			name:       "view machine-readable",
   159  			isTTY:      false,
   160  			releasedAt: frozenTime,
   161  			opts: ViewOptions{
   162  				TagName: "v1.2.3",
   163  			},
   164  			wantStdout: heredoc.Doc(`
   165  				title:	
   166  				tag:	v1.2.3
   167  				draft:	false
   168  				prerelease:	false
   169  				author:	MonaLisa
   170  				created:	2020-08-31T15:44:24+02:00
   171  				published:	2020-08-31T15:44:24+02:00
   172  				url:	https://github.com/OWNER/REPO/releases/tags/v1.2.3
   173  				asset:	windows.zip
   174  				asset:	linux.tgz
   175  				--
   176  				* Fixed bugs
   177  			`),
   178  			wantStderr: ``,
   179  		},
   180  	}
   181  	for _, tt := range tests {
   182  		t.Run(tt.name, func(t *testing.T) {
   183  			io, _, stdout, stderr := iostreams.Test()
   184  			io.SetStdoutTTY(tt.isTTY)
   185  			io.SetStdinTTY(tt.isTTY)
   186  			io.SetStderrTTY(tt.isTTY)
   187  
   188  			path := "repos/OWNER/REPO/releases/tags/v1.2.3"
   189  			if tt.opts.TagName == "" {
   190  				path = "repos/OWNER/REPO/releases/latest"
   191  			}
   192  
   193  			fakeHTTP := &httpmock.Registry{}
   194  			fakeHTTP.Register(httpmock.REST("GET", path), httpmock.StringResponse(fmt.Sprintf(`{
   195  				"tag_name": "v1.2.3",
   196  				"draft": false,
   197  				"author": { "login": "MonaLisa" },
   198  				"body": "* Fixed bugs\n",
   199  				"created_at": "%[1]s",
   200  				"published_at": "%[1]s",
   201  				"html_url": "https://github.com/OWNER/REPO/releases/tags/v1.2.3",
   202  				"assets": [
   203  					{ "name": "windows.zip", "size": 12 },
   204  					{ "name": "linux.tgz", "size": 34 }
   205  				]
   206  			}`, tt.releasedAt.Format(time.RFC3339))))
   207  
   208  			tt.opts.IO = io
   209  			tt.opts.HttpClient = func() (*http.Client, error) {
   210  				return &http.Client{Transport: fakeHTTP}, nil
   211  			}
   212  			tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
   213  				return ghrepo.FromFullName("OWNER/REPO")
   214  			}
   215  
   216  			err := viewRun(&tt.opts)
   217  			if tt.wantErr != "" {
   218  				require.EqualError(t, err, tt.wantErr)
   219  				return
   220  			} else {
   221  				require.NoError(t, err)
   222  			}
   223  
   224  			assert.Equal(t, tt.wantStdout, stdout.String())
   225  			assert.Equal(t, tt.wantStderr, stderr.String())
   226  		})
   227  	}
   228  }
   229  
   230  func Test_humanFileSize(t *testing.T) {
   231  	tests := []struct {
   232  		name string
   233  		size int64
   234  		want string
   235  	}{
   236  		{
   237  			name: "min bytes",
   238  			size: 1,
   239  			want: "1 B",
   240  		},
   241  		{
   242  			name: "max bytes",
   243  			size: 1023,
   244  			want: "1023 B",
   245  		},
   246  		{
   247  			name: "min kibibytes",
   248  			size: 1024,
   249  			want: "1.00 KiB",
   250  		},
   251  		{
   252  			name: "max kibibytes",
   253  			size: 1024*1024 - 1,
   254  			want: "1023.99 KiB",
   255  		},
   256  		{
   257  			name: "min mibibytes",
   258  			size: 1024 * 1024,
   259  			want: "1.00 MiB",
   260  		},
   261  		{
   262  			name: "fractional mibibytes",
   263  			size: 1024*1024*12 + 1024*350,
   264  			want: "12.34 MiB",
   265  		},
   266  		{
   267  			name: "max mibibytes",
   268  			size: 1024*1024*1024 - 1,
   269  			want: "1023.99 MiB",
   270  		},
   271  		{
   272  			name: "min gibibytes",
   273  			size: 1024 * 1024 * 1024,
   274  			want: "1.00 GiB",
   275  		},
   276  		{
   277  			name: "fractional gibibytes",
   278  			size: 1024 * 1024 * 1024 * 1.5,
   279  			want: "1.50 GiB",
   280  		},
   281  	}
   282  	for _, tt := range tests {
   283  		t.Run(tt.name, func(t *testing.T) {
   284  			if got := humanFileSize(tt.size); got != tt.want {
   285  				t.Errorf("humanFileSize() = %v, want %v", got, tt.want)
   286  			}
   287  		})
   288  	}
   289  }