github.com/ungtb10d/cli/v2@v2.0.0-20221110210412-98537dd9d6a1/pkg/cmd/issue/shared/lookup_test.go (about)

     1  package shared
     2  
     3  import (
     4  	"net/http"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/ungtb10d/cli/v2/internal/ghrepo"
     9  	"github.com/ungtb10d/cli/v2/pkg/httpmock"
    10  )
    11  
    12  func TestIssueFromArgWithFields(t *testing.T) {
    13  	type args struct {
    14  		baseRepoFn func() (ghrepo.Interface, error)
    15  		selector   string
    16  	}
    17  	tests := []struct {
    18  		name         string
    19  		args         args
    20  		httpStub     func(*httpmock.Registry)
    21  		wantIssue    int
    22  		wantRepo     string
    23  		wantProjects string
    24  		wantErr      bool
    25  	}{
    26  		{
    27  			name: "number argument",
    28  			args: args{
    29  				selector: "13",
    30  				baseRepoFn: func() (ghrepo.Interface, error) {
    31  					return ghrepo.FromFullName("OWNER/REPO")
    32  				},
    33  			},
    34  			httpStub: func(r *httpmock.Registry) {
    35  				r.Register(
    36  					httpmock.GraphQL(`query IssueByNumber\b`),
    37  					httpmock.StringResponse(`{"data":{"repository":{
    38  						"hasIssuesEnabled": true,
    39  						"issue":{"number":13}
    40  					}}}`))
    41  			},
    42  			wantIssue: 13,
    43  			wantRepo:  "https://github.com/OWNER/REPO",
    44  		},
    45  		{
    46  			name: "number with hash argument",
    47  			args: args{
    48  				selector: "#13",
    49  				baseRepoFn: func() (ghrepo.Interface, error) {
    50  					return ghrepo.FromFullName("OWNER/REPO")
    51  				},
    52  			},
    53  			httpStub: func(r *httpmock.Registry) {
    54  				r.Register(
    55  					httpmock.GraphQL(`query IssueByNumber\b`),
    56  					httpmock.StringResponse(`{"data":{"repository":{
    57  						"hasIssuesEnabled": true,
    58  						"issue":{"number":13}
    59  					}}}`))
    60  			},
    61  			wantIssue: 13,
    62  			wantRepo:  "https://github.com/OWNER/REPO",
    63  		},
    64  		{
    65  			name: "URL argument",
    66  			args: args{
    67  				selector:   "https://example.org/OWNER/REPO/issues/13#comment-123",
    68  				baseRepoFn: nil,
    69  			},
    70  			httpStub: func(r *httpmock.Registry) {
    71  				r.Register(
    72  					httpmock.GraphQL(`query IssueByNumber\b`),
    73  					httpmock.StringResponse(`{"data":{"repository":{
    74  						"hasIssuesEnabled": true,
    75  						"issue":{"number":13}
    76  					}}}`))
    77  			},
    78  			wantIssue: 13,
    79  			wantRepo:  "https://example.org/OWNER/REPO",
    80  		},
    81  		{
    82  			name: "project cards permission issue",
    83  			args: args{
    84  				selector:   "https://example.org/OWNER/REPO/issues/13",
    85  				baseRepoFn: nil,
    86  			},
    87  			httpStub: func(r *httpmock.Registry) {
    88  				r.Register(
    89  					httpmock.GraphQL(`query IssueByNumber\b`),
    90  					httpmock.StringResponse(`
    91  					{
    92  						"data": {
    93  							"repository": {
    94  								"hasIssuesEnabled": true,
    95  								"issue": {
    96  									"number": 13,
    97  									"projectCards": {
    98  										"nodes": [
    99  											null,
   100  											{
   101  												"project": {"name": "myproject"},
   102  												"column": {"name": "To Do"}
   103  											},
   104  											null,
   105  											{
   106  												"project": {"name": "other project"},
   107  												"column": null
   108  											}
   109  										]
   110  									}
   111  								}
   112  							}
   113  						},
   114  						"errors": [
   115  							{
   116  								"type": "FORBIDDEN",
   117  								"message": "Resource not accessible by integration",
   118  								"path": ["repository", "issue", "projectCards", "nodes", 0]
   119  							},
   120  							{
   121  								"type": "FORBIDDEN",
   122  								"message": "Resource not accessible by integration",
   123  								"path": ["repository", "issue", "projectCards", "nodes", 2]
   124  							}
   125  						]
   126  					}`))
   127  			},
   128  			wantErr:      true,
   129  			wantIssue:    13,
   130  			wantProjects: "myproject, other project",
   131  			wantRepo:     "https://example.org/OWNER/REPO",
   132  		},
   133  		{
   134  			name: "projects permission issue",
   135  			args: args{
   136  				selector:   "https://example.org/OWNER/REPO/issues/13",
   137  				baseRepoFn: nil,
   138  			},
   139  			httpStub: func(r *httpmock.Registry) {
   140  				r.Register(
   141  					httpmock.GraphQL(`query IssueByNumber\b`),
   142  					httpmock.StringResponse(`
   143  					{
   144  						"data": {
   145  							"repository": {
   146  								"hasIssuesEnabled": true,
   147  								"issue": {
   148  									"number": 13,
   149  									"projectCards": {
   150  										"nodes": null,
   151  										"totalCount": 0
   152  									}
   153  								}
   154  							}
   155  						},
   156  						"errors": [
   157  							{
   158  								"type": "FORBIDDEN",
   159  								"message": "Resource not accessible by integration",
   160  								"path": ["repository", "issue", "projectCards", "nodes"]
   161  							}
   162  						]
   163  					}`))
   164  			},
   165  			wantErr:      true,
   166  			wantIssue:    13,
   167  			wantProjects: "",
   168  			wantRepo:     "https://example.org/OWNER/REPO",
   169  		},
   170  	}
   171  	for _, tt := range tests {
   172  		t.Run(tt.name, func(t *testing.T) {
   173  			reg := &httpmock.Registry{}
   174  			if tt.httpStub != nil {
   175  				tt.httpStub(reg)
   176  			}
   177  			httpClient := &http.Client{Transport: reg}
   178  			issue, repo, err := IssueFromArgWithFields(httpClient, tt.args.baseRepoFn, tt.args.selector, []string{"number"})
   179  			if (err != nil) != tt.wantErr {
   180  				t.Errorf("IssueFromArgWithFields() error = %v, wantErr %v", err, tt.wantErr)
   181  				if issue == nil {
   182  					return
   183  				}
   184  			}
   185  			if issue.Number != tt.wantIssue {
   186  				t.Errorf("want issue #%d, got #%d", tt.wantIssue, issue.Number)
   187  			}
   188  			if gotProjects := strings.Join(issue.ProjectCards.ProjectNames(), ", "); gotProjects != tt.wantProjects {
   189  				t.Errorf("want projects %q, got %q", tt.wantProjects, gotProjects)
   190  			}
   191  			repoURL := ghrepo.GenerateRepoURL(repo, "")
   192  			if repoURL != tt.wantRepo {
   193  				t.Errorf("want repo %s, got %s", tt.wantRepo, repoURL)
   194  			}
   195  		})
   196  	}
   197  }