github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/release/view/view_test.go (about)

     1  package view
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/MakeNowJust/heredoc"
    12  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
    13  	"github.com/ungtb10d/cli/v2/pkg/cmdutil"
    14  	"github.com/ungtb10d/cli/v2/pkg/httpmock"
    15  	"github.com/ungtb10d/cli/v2/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  			ios, _, _, _ := iostreams.Test()
    60  			ios.SetStdoutTTY(tt.isTTY)
    61  			ios.SetStdinTTY(tt.isTTY)
    62  			ios.SetStderrTTY(tt.isTTY)
    63  
    64  			f := &cmdutil.Factory{
    65  				IOStreams: ios,
    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(io.Discard)
    81  			cmd.SetErr(io.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  		releaseBody string
   106  		releasedAt  time.Time
   107  		opts        ViewOptions
   108  		wantErr     string
   109  		wantStdout  string
   110  		wantStderr  string
   111  	}{
   112  		{
   113  			name:        "view specific release",
   114  			isTTY:       true,
   115  			releaseBody: `* Fixed bugs\n`,
   116  			releasedAt:  oneHourAgo,
   117  			opts: ViewOptions{
   118  				TagName: "v1.2.3",
   119  			},
   120  			wantStdout: heredoc.Doc(`
   121  				v1.2.3
   122  				MonaLisa released this about 1 day ago
   123  				
   124  				                                                                              
   125  				  • Fixed bugs                                                                
   126  				
   127  				
   128  				Assets
   129  				windows.zip  12 B
   130  				linux.tgz    34 B
   131  				
   132  				View on GitHub: https://github.com/OWNER/REPO/releases/tags/v1.2.3
   133  			`),
   134  			wantStderr: ``,
   135  		},
   136  		{
   137  			name:        "view latest release",
   138  			isTTY:       true,
   139  			releaseBody: `* Fixed bugs\n`,
   140  			releasedAt:  oneHourAgo,
   141  			opts: ViewOptions{
   142  				TagName: "",
   143  			},
   144  			wantStdout: heredoc.Doc(`
   145  				v1.2.3
   146  				MonaLisa released this about 1 day ago
   147  				
   148  				                                                                              
   149  				  • Fixed bugs                                                                
   150  				
   151  				
   152  				Assets
   153  				windows.zip  12 B
   154  				linux.tgz    34 B
   155  				
   156  				View on GitHub: https://github.com/OWNER/REPO/releases/tags/v1.2.3
   157  			`),
   158  			wantStderr: ``,
   159  		},
   160  		{
   161  			name:        "view machine-readable",
   162  			isTTY:       false,
   163  			releaseBody: `* Fixed bugs\n`,
   164  			releasedAt:  frozenTime,
   165  			opts: ViewOptions{
   166  				TagName: "v1.2.3",
   167  			},
   168  			wantStdout: heredoc.Doc(`
   169  				title:	
   170  				tag:	v1.2.3
   171  				draft:	false
   172  				prerelease:	false
   173  				author:	MonaLisa
   174  				created:	2020-08-31T15:44:24+02:00
   175  				published:	2020-08-31T15:44:24+02:00
   176  				url:	https://github.com/OWNER/REPO/releases/tags/v1.2.3
   177  				asset:	windows.zip
   178  				asset:	linux.tgz
   179  				--
   180  				* Fixed bugs
   181  			`),
   182  			wantStderr: ``,
   183  		},
   184  		{
   185  			name:        "view machine-readable but body has no ending newline",
   186  			isTTY:       false,
   187  			releaseBody: `* Fixed bugs`,
   188  			releasedAt:  frozenTime,
   189  			opts: ViewOptions{
   190  				TagName: "v1.2.3",
   191  			},
   192  			wantStdout: heredoc.Doc(`
   193  				title:	
   194  				tag:	v1.2.3
   195  				draft:	false
   196  				prerelease:	false
   197  				author:	MonaLisa
   198  				created:	2020-08-31T15:44:24+02:00
   199  				published:	2020-08-31T15:44:24+02:00
   200  				url:	https://github.com/OWNER/REPO/releases/tags/v1.2.3
   201  				asset:	windows.zip
   202  				asset:	linux.tgz
   203  				--
   204  				* Fixed bugs
   205  			`),
   206  			wantStderr: ``,
   207  		},
   208  	}
   209  	for _, tt := range tests {
   210  		t.Run(tt.name, func(t *testing.T) {
   211  			ios, _, stdout, stderr := iostreams.Test()
   212  			ios.SetStdoutTTY(tt.isTTY)
   213  			ios.SetStdinTTY(tt.isTTY)
   214  			ios.SetStderrTTY(tt.isTTY)
   215  
   216  			path := "repos/OWNER/REPO/releases/tags/v1.2.3"
   217  			if tt.opts.TagName == "" {
   218  				path = "repos/OWNER/REPO/releases/latest"
   219  			}
   220  
   221  			fakeHTTP := &httpmock.Registry{}
   222  			fakeHTTP.Register(httpmock.REST("GET", path), httpmock.StringResponse(fmt.Sprintf(`{
   223  				"tag_name": "v1.2.3",
   224  				"draft": false,
   225  				"author": { "login": "MonaLisa" },
   226  				"body": "%[2]s",
   227  				"created_at": "%[1]s",
   228  				"published_at": "%[1]s",
   229  				"html_url": "https://github.com/OWNER/REPO/releases/tags/v1.2.3",
   230  				"assets": [
   231  					{ "name": "windows.zip", "size": 12 },
   232  					{ "name": "linux.tgz", "size": 34 }
   233  				]
   234  			}`, tt.releasedAt.Format(time.RFC3339), tt.releaseBody)))
   235  
   236  			tt.opts.IO = ios
   237  			tt.opts.HttpClient = func() (*http.Client, error) {
   238  				return &http.Client{Transport: fakeHTTP}, nil
   239  			}
   240  			tt.opts.BaseRepo = func() (ghrepo.Interface, error) {
   241  				return ghrepo.FromFullName("OWNER/REPO")
   242  			}
   243  
   244  			err := viewRun(&tt.opts)
   245  			if tt.wantErr != "" {
   246  				require.EqualError(t, err, tt.wantErr)
   247  				return
   248  			} else {
   249  				require.NoError(t, err)
   250  			}
   251  
   252  			assert.Equal(t, tt.wantStdout, stdout.String())
   253  			assert.Equal(t, tt.wantStderr, stderr.String())
   254  		})
   255  	}
   256  }
   257  
   258  func Test_humanFileSize(t *testing.T) {
   259  	tests := []struct {
   260  		name string
   261  		size int64
   262  		want string
   263  	}{
   264  		{
   265  			name: "min bytes",
   266  			size: 1,
   267  			want: "1 B",
   268  		},
   269  		{
   270  			name: "max bytes",
   271  			size: 1023,
   272  			want: "1023 B",
   273  		},
   274  		{
   275  			name: "min kibibytes",
   276  			size: 1024,
   277  			want: "1.00 KiB",
   278  		},
   279  		{
   280  			name: "max kibibytes",
   281  			size: 1024*1024 - 1,
   282  			want: "1023.99 KiB",
   283  		},
   284  		{
   285  			name: "min mibibytes",
   286  			size: 1024 * 1024,
   287  			want: "1.00 MiB",
   288  		},
   289  		{
   290  			name: "fractional mibibytes",
   291  			size: 1024*1024*12 + 1024*350,
   292  			want: "12.34 MiB",
   293  		},
   294  		{
   295  			name: "max mibibytes",
   296  			size: 1024*1024*1024 - 1,
   297  			want: "1023.99 MiB",
   298  		},
   299  		{
   300  			name: "min gibibytes",
   301  			size: 1024 * 1024 * 1024,
   302  			want: "1.00 GiB",
   303  		},
   304  		{
   305  			name: "fractional gibibytes",
   306  			size: 1024 * 1024 * 1024 * 1.5,
   307  			want: "1.50 GiB",
   308  		},
   309  	}
   310  	for _, tt := range tests {
   311  		t.Run(tt.name, func(t *testing.T) {
   312  			if got := humanFileSize(tt.size); got != tt.want {
   313  				t.Errorf("humanFileSize() = %v, want %v", got, tt.want)
   314  			}
   315  		})
   316  	}
   317  }