diff --git a/pkg/cmd/repo/view/view.go b/pkg/cmd/repo/view/view.go index adcf384a4ff..7896d1d71a7 100644 --- a/pkg/cmd/repo/view/view.go +++ b/pkg/cmd/repo/view/view.go @@ -2,9 +2,9 @@ package view import ( "fmt" - "html/template" "net/http" "strings" + "text/template" "github.com/MakeNowJust/heredoc" "github.com/cli/cli/api" diff --git a/pkg/cmd/repo/view/view_test.go b/pkg/cmd/repo/view/view_test.go index 7dba0f6dfca..626ff62ed3a 100644 --- a/pkg/cmd/repo/view/view_test.go +++ b/pkg/cmd/repo/view/view_test.go @@ -515,3 +515,86 @@ func Test_ViewRun_WithoutUsername(t *testing.T) { assert.Equal(t, "", stderr.String()) reg.Verify(t) } + +func Test_ViewRun_HandlesSpecialCharacters(t *testing.T) { + tests := []struct { + name string + opts *ViewOptions + repoName string + stdoutTTY bool + wantOut string + wantStderr string + wantErr bool + }{ + { + name: "nontty", + wantOut: heredoc.Doc(` + name: OWNER/REPO + description: Some basic special characters " & / < > ' + -- + # < is always > than & ' and " + `), + }, + { + name: "no args", + stdoutTTY: true, + wantOut: heredoc.Doc(` + OWNER/REPO + Some basic special characters " & / < > ' + + + # < is always > than & ' and " + + + + View this repository on GitHub: https://github.com/OWNER/REPO + `), + }, + } + for _, tt := range tests { + if tt.opts == nil { + tt.opts = &ViewOptions{} + } + + if tt.repoName == "" { + tt.repoName = "OWNER/REPO" + } + + tt.opts.BaseRepo = func() (ghrepo.Interface, error) { + repo, _ := ghrepo.FromFullName(tt.repoName) + return repo, nil + } + + reg := &httpmock.Registry{} + reg.Register( + httpmock.GraphQL(`query RepositoryInfo\b`), + httpmock.StringResponse(` + { "data": { + "repository": { + "description": "Some basic special characters \" & / < > '" + } } }`)) + reg.Register( + httpmock.REST("GET", fmt.Sprintf("repos/%s/readme", tt.repoName)), + httpmock.StringResponse(` + { "name": "readme.md", + "content": "IyA8IGlzIGFsd2F5cyA+IHRoYW4gJiAnIGFuZCAi"}`)) + + tt.opts.HttpClient = func() (*http.Client, error) { + return &http.Client{Transport: reg}, nil + } + + io, _, stdout, stderr := iostreams.Test() + tt.opts.IO = io + + t.Run(tt.name, func(t *testing.T) { + io.SetStdoutTTY(tt.stdoutTTY) + + if err := viewRun(tt.opts); (err != nil) != tt.wantErr { + t.Errorf("viewRun() error = %v, wantErr %v", err, tt.wantErr) + } + assert.Equal(t, tt.wantStderr, stderr.String()) + assert.Equal(t, tt.wantOut, stdout.String()) + reg.Verify(t) + }) + } +}