Address PR comments

This commit is contained in:
Sam Coe 2020-12-07 15:02:43 -05:00
parent bad5a59427
commit bec5e0cd77
No known key found for this signature in database
GPG key ID: 8E322C20F811D086
9 changed files with 253 additions and 501 deletions

65
api/queries_comments.go Normal file
View file

@ -0,0 +1,65 @@
package api
import (
"context"
"time"
"github.com/cli/cli/internal/ghrepo"
"github.com/shurcooL/githubv4"
)
type Comments struct {
Nodes []Comment
TotalCount int
PageInfo PageInfo
}
type Comment struct {
Author Author
AuthorAssociation string
Body string
CreatedAt time.Time
IncludesCreatedEdit bool
ReactionGroups ReactionGroups
}
type PageInfo struct {
HasNextPage bool
EndCursor string
}
func CommentsForIssue(client *Client, repo ghrepo.Interface, issue *Issue) (*Comments, error) {
type response struct {
Repository struct {
Issue struct {
Comments Comments `graphql:"comments(first: 100, after: $endCursor)"`
} `graphql:"issue(number: $number)"`
} `graphql:"repository(owner: $owner, name: $repo)"`
}
variables := map[string]interface{}{
"owner": githubv4.String(repo.RepoOwner()),
"repo": githubv4.String(repo.RepoName()),
"number": githubv4.Int(issue.Number),
"endCursor": (*githubv4.String)(nil),
}
gql := graphQLClient(client.http, repo.RepoHost())
var comments []Comment
for {
var query response
err := gql.QueryNamed(context.Background(), "CommentsForIssue", &query, variables)
if err != nil {
return nil, err
}
comments = append(comments, query.Repository.Issue.Comments.Nodes...)
if !query.Repository.Issue.Comments.PageInfo.HasNextPage {
break
}
variables["endCursor"] = githubv4.String(query.Repository.Issue.Comments.PageInfo.EndCursor)
}
return &Comments{Nodes: comments, TotalCount: len(comments)}, nil
}

View file

@ -33,7 +33,7 @@ type Issue struct {
Body string
CreatedAt time.Time
UpdatedAt time.Time
Comments IssueComments
Comments Comments
Author Author
Assignees struct {
Nodes []struct {
@ -68,20 +68,6 @@ type IssuesDisabledError struct {
error
}
type IssueComments struct {
Nodes []IssueComment
TotalCount int
}
type IssueComment struct {
Author Author
AuthorAssociation string
Body string
CreatedAt time.Time
IncludesCreatedEdit bool
ReactionGroups ReactionGroups
}
type Author struct {
Login string
}
@ -335,7 +321,7 @@ loop:
return &res, nil
}
func IssueByNumber(client *Client, repo ghrepo.Interface, number, comments int) (*Issue, error) {
func IssueByNumber(client *Client, repo ghrepo.Interface, number int) (*Issue, error) {
type response struct {
Repository struct {
Issue Issue
@ -344,7 +330,7 @@ func IssueByNumber(client *Client, repo ghrepo.Interface, number, comments int)
}
query := `
query IssueByNumber($owner: String!, $repo: String!, $issue_number: Int!, $comments: Int!) {
query IssueByNumber($owner: String!, $repo: String!, $issue_number: Int!) {
repository(owner: $owner, name: $repo) {
hasIssuesEnabled
issue(number: $issue_number) {
@ -356,7 +342,7 @@ func IssueByNumber(client *Client, repo ghrepo.Interface, number, comments int)
author {
login
}
comments(last: $comments) {
comments(last: 1) {
nodes {
author {
login
@ -417,7 +403,6 @@ func IssueByNumber(client *Client, repo ghrepo.Interface, number, comments int)
"owner": repo.RepoOwner(),
"repo": repo.RepoName(),
"issue_number": number,
"comments": comments,
}
var resp response

View file

@ -1,10 +1,5 @@
package api
import (
"fmt"
"strings"
)
type ReactionGroups []ReactionGroup
type ReactionGroup struct {
@ -16,28 +11,12 @@ type ReactionGroupUsers struct {
TotalCount int
}
func (rg ReactionGroup) String() string {
c := rg.Users.TotalCount
if c == 0 {
return ""
}
e := reactionEmoji[rg.Content]
if e == "" {
return ""
}
return fmt.Sprintf("%v %s", c, e)
func (rg ReactionGroup) Count() int {
return rg.Users.TotalCount
}
func (rgs ReactionGroups) String() string {
var rs []string
for _, rg := range rgs {
if r := rg.String(); r != "" {
rs = append(rs, r)
}
}
return strings.Join(rs, " • ")
func (rg ReactionGroup) Emoji() string {
return reactionEmoji[rg.Content]
}
var reactionEmoji = map[string]string{

View file

@ -8,48 +8,93 @@ import (
func Test_String(t *testing.T) {
tests := map[string]struct {
rgs ReactionGroups
output string
rg ReactionGroup
emoji string
count int
}{
"empty reaction groups": {
rgs: []ReactionGroup{},
output: `^$`,
"empty reaction group": {
rg: ReactionGroup{},
emoji: "",
count: 0,
},
"non-empty reaction groups": {
rgs: []ReactionGroup{
{
Content: "LAUGH",
Users: ReactionGroupUsers{TotalCount: 0},
},
{
Content: "HOORAY",
Users: ReactionGroupUsers{TotalCount: 1},
},
{
Content: "CONFUSED",
Users: ReactionGroupUsers{TotalCount: 0},
},
{
Content: "HEART",
Users: ReactionGroupUsers{TotalCount: 2},
},
"unknown reaction group": {
rg: ReactionGroup{
Content: "UNKNOWN",
Users: ReactionGroupUsers{TotalCount: 1},
},
output: `^1 \x{1f389} • 2 \x{2764}\x{fe0f}$`,
emoji: "",
count: 1,
},
"reaction groups with unmapped emoji": {
rgs: []ReactionGroup{
{
Content: "UNKNOWN",
Users: ReactionGroupUsers{TotalCount: 1},
},
"thumbs up reaction group": {
rg: ReactionGroup{
Content: "THUMBS_UP",
Users: ReactionGroupUsers{TotalCount: 2},
},
output: `^$`,
emoji: "\U0001f44d",
count: 2,
},
"thumbs down reaction group": {
rg: ReactionGroup{
Content: "THUMBS_DOWN",
Users: ReactionGroupUsers{TotalCount: 3},
},
emoji: "\U0001f44e",
count: 3,
},
"laugh reaction group": {
rg: ReactionGroup{
Content: "LAUGH",
Users: ReactionGroupUsers{TotalCount: 4},
},
emoji: "\U0001f604",
count: 4,
},
"hooray reaction group": {
rg: ReactionGroup{
Content: "HOORAY",
Users: ReactionGroupUsers{TotalCount: 5},
},
emoji: "\U0001f389",
count: 5,
},
"confused reaction group": {
rg: ReactionGroup{
Content: "CONFUSED",
Users: ReactionGroupUsers{TotalCount: 6},
},
emoji: "\U0001f615",
count: 6,
},
"heart reaction group": {
rg: ReactionGroup{
Content: "HEART",
Users: ReactionGroupUsers{TotalCount: 7},
},
emoji: "\u2764\ufe0f",
count: 7,
},
"rocket reaction group": {
rg: ReactionGroup{
Content: "ROCKET",
Users: ReactionGroupUsers{TotalCount: 8},
},
emoji: "\U0001f680",
count: 8,
},
"eyes reaction group": {
rg: ReactionGroup{
Content: "EYES",
Users: ReactionGroupUsers{TotalCount: 9},
},
emoji: "\U0001f440",
count: 9,
},
}
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
assert.Regexp(t, tt.output, tt.rgs.String())
assert.Equal(t, tt.emoji, tt.rg.Emoji())
assert.Equal(t, tt.count, tt.rg.Count())
})
}
}

View file

@ -11,7 +11,7 @@ import (
"github.com/cli/cli/internal/ghrepo"
)
func IssueWithCommentsFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.Interface, error), arg string, comments int) (*api.Issue, ghrepo.Interface, error) {
func IssueFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.Interface, error), arg string) (*api.Issue, ghrepo.Interface, error) {
issueNumber, baseRepo := issueMetadataFromURL(arg)
if baseRepo == nil {
@ -30,14 +30,10 @@ func IssueWithCommentsFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.I
}
}
issue, err := issueFromNumber(apiClient, baseRepo, issueNumber, comments)
issue, err := issueFromNumber(apiClient, baseRepo, issueNumber)
return issue, baseRepo, err
}
func IssueFromArg(apiClient *api.Client, baseRepoFn func() (ghrepo.Interface, error), arg string) (*api.Issue, ghrepo.Interface, error) {
return IssueWithCommentsFromArg(apiClient, baseRepoFn, arg, 0)
}
var issueURLRE = regexp.MustCompile(`^/([^/]+)/([^/]+)/issues/(\d+)`)
func issueMetadataFromURL(s string) (int, ghrepo.Interface) {
@ -60,6 +56,6 @@ func issueMetadataFromURL(s string) (int, ghrepo.Interface) {
return issueNumber, repo
}
func issueFromNumber(apiClient *api.Client, repo ghrepo.Interface, issueNumber, comments int) (*api.Issue, error) {
return api.IssueByNumber(apiClient, repo, issueNumber, comments)
func issueFromNumber(apiClient *api.Client, repo ghrepo.Interface, issueNumber int) (*api.Issue, error) {
return api.IssueByNumber(apiClient, repo, issueNumber)
}

View file

@ -1,81 +1,7 @@
{
"data": {
"repository": {
"hasIssuesEnabled": true,
"issue": {
"number": 123,
"body": "some body",
"title": "some title",
"state": "OPEN",
"createdAt": "2020-01-01T12:00:00Z",
"author": {
"login": "marseilles"
},
"assignees": {
"nodes": [],
"totalCount": 0
},
"labels": {
"nodes": [],
"totalCount": 0
},
"projectcards": {
"nodes": [],
"totalCount": 0
},
"milestone": {
"title": ""
},
"reactionGroups": [
{
"content": "CONFUSED",
"users": {
"totalCount": 0
}
},
{
"content": "EYES",
"users": {
"totalCount": 0
}
},
{
"content": "HEART",
"users": {
"totalCount": 0
}
},
{
"content": "HOORAY",
"users": {
"totalCount": 0
}
},
{
"content": "LAUGH",
"users": {
"totalCount": 0
}
},
{
"content": "ROCKET",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_DOWN",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_UP",
"users": {
"totalCount": 0
}
}
],
"comments": {
"nodes": [
{
@ -375,8 +301,7 @@
}
],
"totalCount": 5
},
"url": "https://github.com/OWNER/REPO/issues/123"
}
}
}
}

View file

@ -1,265 +0,0 @@
{
"data": {
"repository": {
"hasIssuesEnabled": true,
"issue": {
"number": 123,
"body": "some body",
"title": "some title",
"state": "OPEN",
"createdAt": "2020-01-01T12:00:00Z",
"author": {
"login": "marseilles"
},
"assignees": {
"nodes": [],
"totalCount": 0
},
"labels": {
"nodes": [],
"totalCount": 0
},
"projectcards": {
"nodes": [],
"totalCount": 0
},
"milestone": {
"title": ""
},
"reactionGroups": [
{
"content": "CONFUSED",
"users": {
"totalCount": 0
}
},
{
"content": "EYES",
"users": {
"totalCount": 0
}
},
{
"content": "HEART",
"users": {
"totalCount": 0
}
},
{
"content": "HOORAY",
"users": {
"totalCount": 0
}
},
{
"content": "LAUGH",
"users": {
"totalCount": 0
}
},
{
"content": "ROCKET",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_DOWN",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_UP",
"users": {
"totalCount": 0
}
}
],
"comments": {
"nodes": [
{
"author": {
"login": "elvisp"
},
"authorAssociation": "MEMBER",
"body": "Comment 3",
"createdAt": "2020-01-01T12:00:00Z",
"includesCreatedEdit": false,
"reactionGroups": [
{
"content": "CONFUSED",
"users": {
"totalCount": 0
}
},
{
"content": "EYES",
"users": {
"totalCount": 0
}
},
{
"content": "HEART",
"users": {
"totalCount": 0
}
},
{
"content": "HOORAY",
"users": {
"totalCount": 0
}
},
{
"content": "LAUGH",
"users": {
"totalCount": 0
}
},
{
"content": "ROCKET",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_DOWN",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_UP",
"users": {
"totalCount": 0
}
}
]
},
{
"author": {
"login": "loislane"
},
"authorAssociation": "OWNER",
"body": "Comment 4",
"createdAt": "2020-01-01T12:00:00Z",
"includesCreatedEdit": false,
"reactionGroups": [
{
"content": "CONFUSED",
"users": {
"totalCount": 0
}
},
{
"content": "EYES",
"users": {
"totalCount": 0
}
},
{
"content": "HEART",
"users": {
"totalCount": 0
}
},
{
"content": "HOORAY",
"users": {
"totalCount": 0
}
},
{
"content": "LAUGH",
"users": {
"totalCount": 0
}
},
{
"content": "ROCKET",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_DOWN",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_UP",
"users": {
"totalCount": 0
}
}
]
},
{
"author": {
"login": "marseilles"
},
"authorAssociation": "COLLABORATOR",
"body": "Comment 5",
"createdAt": "2020-01-01T12:00:00Z",
"includesCreatedEdit": false,
"reactionGroups": [
{
"content": "CONFUSED",
"users": {
"totalCount": 0
}
},
{
"content": "EYES",
"users": {
"totalCount": 0
}
},
{
"content": "HEART",
"users": {
"totalCount": 0
}
},
{
"content": "HOORAY",
"users": {
"totalCount": 0
}
},
{
"content": "LAUGH",
"users": {
"totalCount": 0
}
},
{
"content": "ROCKET",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_DOWN",
"users": {
"totalCount": 0
}
},
{
"content": "THUMBS_UP",
"users": {
"totalCount": 0
}
}
]
}
],
"totalCount": 5
},
"url": "https://github.com/OWNER/REPO/issues/123"
}
}
}
}

View file

@ -8,6 +8,7 @@ import (
"time"
"github.com/MakeNowJust/heredoc"
"github.com/briandowns/spinner"
"github.com/cli/cli/api"
"github.com/cli/cli/internal/config"
"github.com/cli/cli/internal/ghrepo"
@ -27,10 +28,9 @@ type ViewOptions struct {
IO *iostreams.IOStreams
BaseRepo func() (ghrepo.Interface, error)
SelectorArg string
WebMode bool
Comments int
CommentsProvided bool
SelectorArg string
WebMode bool
Comments bool
}
func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Command {
@ -55,8 +55,6 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
// support `-R, --repo` override
opts.BaseRepo = f.BaseRepo
opts.CommentsProvided = cmd.Flags().Changed("comments")
if len(args) > 0 {
opts.SelectorArg = args[0]
}
@ -69,8 +67,7 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
}
cmd.Flags().BoolVarP(&opts.WebMode, "web", "w", false, "Open an issue in the browser")
cmd.Flags().IntVarP(&opts.Comments, "comments", "c", 1, "View issue comments sorted by most recent")
cmd.Flags().Lookup("comments").NoOptDefVal = "30"
cmd.Flags().BoolVarP(&opts.Comments, "comments", "c", false, "View issue comments")
return cmd
}
@ -82,20 +79,37 @@ func viewRun(opts *ViewOptions) error {
}
apiClient := api.NewClientFromHTTP(httpClient)
issue, _, err := issueShared.IssueWithCommentsFromArg(apiClient, opts.BaseRepo, opts.SelectorArg, opts.Comments)
issue, repo, err := issueShared.IssueFromArg(apiClient, opts.BaseRepo, opts.SelectorArg)
if err != nil {
return err
}
openURL := issue.URL
if opts.WebMode {
openURL := issue.URL
if opts.IO.IsStdoutTTY() {
fmt.Fprintf(opts.IO.ErrOut, "Opening %s in your browser.\n", utils.DisplayURL(openURL))
}
return utils.OpenInBrowser(openURL)
}
if opts.Comments {
var s *spinner.Spinner
if opts.IO.IsStdoutTTY() {
s = utils.Spinner(opts.IO.ErrOut)
utils.StartSpinner(s)
}
comments, err := api.CommentsForIssue(apiClient, repo, issue)
if err != nil {
return err
}
issue.Comments = *comments
if opts.IO.IsStdoutTTY() {
utils.StopSpinner(s)
}
}
opts.IO.DetectTerminalTheme()
err = opts.IO.StartPager()
@ -108,7 +122,7 @@ func viewRun(opts *ViewOptions) error {
return printHumanIssuePreview(opts.IO, issue)
}
if opts.CommentsProvided {
if opts.Comments {
return printRawIssueComments(opts.IO.Out, issue)
}
@ -144,7 +158,7 @@ func printRawIssueComments(out io.Writer, issue *api.Issue) error {
return nil
}
func rawIssueComment(comment api.IssueComment) string {
func rawIssueComment(comment api.Comment) string {
var b strings.Builder
fmt.Fprintf(&b, "author:\t%s\n", comment.Author.Login)
fmt.Fprintf(&b, "association:\t%s\n", strings.ToLower(comment.AuthorAssociation))
@ -172,7 +186,7 @@ func printHumanIssuePreview(io *iostreams.IOStreams, issue *api.Issue) error {
)
// Reactions
if reactions := issue.ReactionGroups.String(); reactions != "" {
if reactions := reactionGroupList(issue.ReactionGroups); reactions != "" {
fmt.Fprint(out, reactions)
fmt.Fprintln(out)
}
@ -210,7 +224,7 @@ func printHumanIssuePreview(io *iostreams.IOStreams, issue *api.Issue) error {
// Comments
if issue.Comments.TotalCount > 0 {
comments, err := issueComments(io, issue.Comments)
comments, err := issueCommentList(io, issue.Comments)
if err != nil {
return err
}
@ -223,20 +237,20 @@ func printHumanIssuePreview(io *iostreams.IOStreams, issue *api.Issue) error {
return nil
}
func issueComments(io *iostreams.IOStreams, comments api.IssueComments) (string, error) {
func issueCommentList(io *iostreams.IOStreams, comments api.Comments) (string, error) {
var b strings.Builder
cs := io.ColorScheme()
retrievedCount := len(comments.Nodes)
hiddenCount := comments.TotalCount - retrievedCount
if hiddenCount > 0 {
fmt.Fprint(&b, cs.Gray(fmt.Sprintf("———————— Hiding %v comments ————————", hiddenCount)))
fmt.Fprint(&b, cs.Gray(fmt.Sprintf("———————— Not showing %s ————————", utils.Pluralize(hiddenCount, "comment"))))
fmt.Fprintf(&b, "\n\n\n")
}
for i, comment := range comments.Nodes {
last := i+1 == retrievedCount
cmt, err := issueComment(io, comment, last)
cmt, err := formatIssueComment(io, comment, last)
if err != nil {
return "", err
}
@ -254,7 +268,7 @@ func issueComments(io *iostreams.IOStreams, comments api.IssueComments) (string,
return b.String(), nil
}
func issueComment(io *iostreams.IOStreams, comment api.IssueComment, newest bool) (string, error) {
func formatIssueComment(io *iostreams.IOStreams, comment api.Comment, newest bool) (string, error) {
var b strings.Builder
cs := io.ColorScheme()
@ -274,7 +288,7 @@ func issueComment(io *iostreams.IOStreams, comment api.IssueComment, newest bool
fmt.Fprintln(&b)
// Reactions
if reactions := comment.ReactionGroups.String(); reactions != "" {
if reactions := reactionGroupList(comment.ReactionGroups); reactions != "" {
fmt.Fprint(&b, reactions)
fmt.Fprintln(&b)
}
@ -334,3 +348,27 @@ func issueProjectList(issue api.Issue) string {
}
return list
}
func reactionGroupList(rgs api.ReactionGroups) string {
var rs []string
for _, rg := range rgs {
if r := formatReactionGroup(rg); r != "" {
rs = append(rs, r)
}
}
return strings.Join(rs, " • ")
}
func formatReactionGroup(rg api.ReactionGroup) string {
c := rg.Count()
if c == 0 {
return ""
}
e := rg.Emoji()
if e == "" {
return ""
}
return fmt.Sprintf("%v %s", c, e)
}

View file

@ -2,11 +2,13 @@ package view
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"os/exec"
"testing"
"github.com/briandowns/spinner"
"github.com/cli/cli/internal/config"
"github.com/cli/cli/internal/ghrepo"
"github.com/cli/cli/internal/run"
@ -14,6 +16,7 @@ import (
"github.com/cli/cli/pkg/httpmock"
"github.com/cli/cli/pkg/iostreams"
"github.com/cli/cli/test"
"github.com/cli/cli/utils"
"github.com/google/shlex"
"github.com/stretchr/testify/assert"
)
@ -337,26 +340,31 @@ func TestIssueView_web_urlArg(t *testing.T) {
func TestIssueView_tty_Comments(t *testing.T) {
tests := map[string]struct {
cli string
fixture string
fixtures map[string]string
expectedOutputs []string
wantsErr bool
}{
"without comments flag": {
cli: "123",
fixture: "./fixtures/issueView_previewSingleComment.json",
cli: "123",
fixtures: map[string]string{
"IssueByNumber": "./fixtures/issueView_previewSingleComment.json",
},
expectedOutputs: []string{
`some title`,
`some body`,
`———————— Hiding 4 comments ————————`,
`———————— Not showing 4 comments ————————`,
`marseilles \(collaborator\) • Jan 1, 2020 • Newest comment`,
`Comment 5`,
`Use --comments to view the full conversation`,
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
},
},
"with default comments flag": {
cli: "123 --comments",
fixture: "./fixtures/issueView_previewFullComments.json",
"with comments flag": {
cli: "123 --comments",
fixtures: map[string]string{
"IssueByNumber": "./fixtures/issueView_previewSingleComment.json",
"CommentsForIssue": "./fixtures/issueView_previewFullComments.json",
},
expectedOutputs: []string{
`some title`,
`some body`,
@ -374,35 +382,19 @@ func TestIssueView_tty_Comments(t *testing.T) {
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
},
},
"with specified comments flag": {
cli: "123 --comments=3",
fixture: "./fixtures/issueView_previewThreeComments.json",
expectedOutputs: []string{
`some title`,
`some body`,
`———————— Hiding 2 comments ————————`,
`elvisp \(member\) • Jan 1, 2020`,
`Comment 3`,
`loislane \(owner\) • Jan 1, 2020`,
`Comment 4`,
`marseilles \(collaborator\) • Jan 1, 2020 • Newest comment`,
`Comment 5`,
`Use --comments to view the full conversation`,
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
},
},
"with incorrect comments flag": {
"with invalid comments flag": {
cli: "123 --comments 3",
fixture: "",
wantsErr: true,
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
stubSpinner()
http := &httpmock.Registry{}
defer http.Verify(t)
if tc.fixture != "" {
http.Register(httpmock.GraphQL(`query IssueByNumber\b`), httpmock.FileResponse(tc.fixture))
for name, file := range tc.fixtures {
name := fmt.Sprintf(`query %s\b`, name)
http.Register(httpmock.GraphQL(name), httpmock.FileResponse(file))
}
output, err := runCommand(http, true, tc.cli)
if tc.wantsErr {
@ -419,13 +411,15 @@ func TestIssueView_tty_Comments(t *testing.T) {
func TestIssueView_nontty_Comments(t *testing.T) {
tests := map[string]struct {
cli string
fixture string
fixtures map[string]string
expectedOutputs []string
wantsErr bool
}{
"without comments flag": {
cli: "123",
fixture: "./fixtures/issueView_previewSingleComment.json",
cli: "123",
fixtures: map[string]string{
"IssueByNumber": "./fixtures/issueView_previewSingleComment.json",
},
expectedOutputs: []string{
`title:\tsome title`,
`state:\tOPEN`,
@ -434,9 +428,12 @@ func TestIssueView_nontty_Comments(t *testing.T) {
`some body`,
},
},
"with default comments flag": {
cli: "123 --comments",
fixture: "./fixtures/issueView_previewFullComments.json",
"with comments flag": {
cli: "123 --comments",
fixtures: map[string]string{
"IssueByNumber": "./fixtures/issueView_previewSingleComment.json",
"CommentsForIssue": "./fixtures/issueView_previewFullComments.json",
},
expectedOutputs: []string{
`author:\tmonalisa`,
`association:\t`,
@ -460,27 +457,8 @@ func TestIssueView_nontty_Comments(t *testing.T) {
`Comment 5`,
},
},
"with specified comments flag": {
cli: "123 --comments=3",
fixture: "./fixtures/issueView_previewThreeComments.json",
expectedOutputs: []string{
`author:\telvisp`,
`association:\tmember`,
`edited:\tfalse`,
`Comment 3`,
`author:\tloislane`,
`association:\towner`,
`edited:\tfalse`,
`Comment 4`,
`author:\tmarseilles`,
`association:\tcollaborator`,
`edited:\tfalse`,
`Comment 5`,
},
},
"with incorrect comments flag": {
"with invalid comments flag": {
cli: "123 --comments 3",
fixture: "",
wantsErr: true,
},
}
@ -488,8 +466,9 @@ func TestIssueView_nontty_Comments(t *testing.T) {
t.Run(name, func(t *testing.T) {
http := &httpmock.Registry{}
defer http.Verify(t)
if tc.fixture != "" {
http.Register(httpmock.GraphQL(`query IssueByNumber\b`), httpmock.FileResponse(tc.fixture))
for name, file := range tc.fixtures {
name := fmt.Sprintf(`query %s\b`, name)
http.Register(httpmock.GraphQL(name), httpmock.FileResponse(file))
}
output, err := runCommand(http, false, tc.cli)
if tc.wantsErr {
@ -502,3 +481,8 @@ func TestIssueView_nontty_Comments(t *testing.T) {
})
}
}
func stubSpinner() {
utils.StartSpinner = func(_ *spinner.Spinner) {}
utils.StopSpinner = func(_ *spinner.Spinner) {}
}