@@ -2,7 +2,6 @@ package view
22
33import (
44 "bytes"
5- "fmt"
65 "io"
76 "net/http"
87 "testing"
@@ -137,11 +136,14 @@ func TestIssueView_web(t *testing.T) {
137136
138137func TestIssueView_nontty_Preview (t * testing.T ) {
139138 tests := map [string ]struct {
140- fixture string
139+ httpStubs func ( * httpmock. Registry )
141140 expectedOutputs []string
142141 }{
143142 "Open issue without metadata" : {
144- fixture : "./fixtures/issueView_preview.json" ,
143+ httpStubs : func (r * httpmock.Registry ) {
144+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_preview.json" ))
145+ mockEmptyV2ProjectItems (t , r )
146+ },
145147 expectedOutputs : []string {
146148 `title:\tix of coins` ,
147149 `state:\tOPEN` ,
@@ -153,22 +155,28 @@ func TestIssueView_nontty_Preview(t *testing.T) {
153155 },
154156 },
155157 "Open issue with metadata" : {
156- fixture : "./fixtures/issueView_previewWithMetadata.json" ,
158+ httpStubs : func (r * httpmock.Registry ) {
159+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewWithMetadata.json" ))
160+ mockV2ProjectItems (t , r )
161+ },
157162 expectedOutputs : []string {
158163 `title:\tix of coins` ,
159164 `assignees:\tmarseilles, monaco` ,
160165 `author:\tmarseilles` ,
161166 `state:\tOPEN` ,
162167 `comments:\t9` ,
163168 `labels:\tClosed: Duplicate, Closed: Won't Fix, help wanted, Status: In Progress, Type: Bug` ,
164- `projects:\tProject 1 \(column A\), Project 2 \(column B\), Project 3 \(column C\), Project 4 \(Awaiting triage\)\n` ,
169+ `projects:\tv2 Project 1 \(No Status\), v2 Project 2 \(Done\), Project 1 \(column A\), Project 2 \(column B\), Project 3 \(column C\), Project 4 \(Awaiting triage\)\n` ,
165170 `milestone:\tuluru\n` ,
166171 `number:\t123\n` ,
167172 `\*\*bold story\*\*` ,
168173 },
169174 },
170175 "Open issue with empty body" : {
171- fixture : "./fixtures/issueView_previewWithEmptyBody.json" ,
176+ httpStubs : func (r * httpmock.Registry ) {
177+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewWithEmptyBody.json" ))
178+ mockEmptyV2ProjectItems (t , r )
179+ },
172180 expectedOutputs : []string {
173181 `title:\tix of coins` ,
174182 `state:\tOPEN` ,
@@ -178,7 +186,10 @@ func TestIssueView_nontty_Preview(t *testing.T) {
178186 },
179187 },
180188 "Closed issue" : {
181- fixture : "./fixtures/issueView_previewClosedState.json" ,
189+ httpStubs : func (r * httpmock.Registry ) {
190+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewClosedState.json" ))
191+ mockEmptyV2ProjectItems (t , r )
192+ },
182193 expectedOutputs : []string {
183194 `title:\tix of coins` ,
184195 `state:\tCLOSED` ,
@@ -194,8 +205,9 @@ func TestIssueView_nontty_Preview(t *testing.T) {
194205 t .Run (name , func (t * testing.T ) {
195206 http := & httpmock.Registry {}
196207 defer http .Verify (t )
197-
198- http .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse (tc .fixture ))
208+ if tc .httpStubs != nil {
209+ tc .httpStubs (http )
210+ }
199211
200212 output , err := runCommand (http , false , "123" )
201213 if err != nil {
@@ -212,11 +224,14 @@ func TestIssueView_nontty_Preview(t *testing.T) {
212224
213225func TestIssueView_tty_Preview (t * testing.T ) {
214226 tests := map [string ]struct {
215- fixture string
227+ httpStubs func ( * httpmock. Registry )
216228 expectedOutputs []string
217229 }{
218230 "Open issue without metadata" : {
219- fixture : "./fixtures/issueView_preview.json" ,
231+ httpStubs : func (r * httpmock.Registry ) {
232+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_preview.json" ))
233+ mockEmptyV2ProjectItems (t , r )
234+ },
220235 expectedOutputs : []string {
221236 `ix of coins OWNER/REPO#123` ,
222237 `Open.*marseilles opened about 9 years ago.*9 comments` ,
@@ -225,21 +240,27 @@ func TestIssueView_tty_Preview(t *testing.T) {
225240 },
226241 },
227242 "Open issue with metadata" : {
228- fixture : "./fixtures/issueView_previewWithMetadata.json" ,
243+ httpStubs : func (r * httpmock.Registry ) {
244+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewWithMetadata.json" ))
245+ mockV2ProjectItems (t , r )
246+ },
229247 expectedOutputs : []string {
230248 `ix of coins OWNER/REPO#123` ,
231249 `Open.*marseilles opened about 9 years ago.*9 comments` ,
232250 `8 \x{1f615} • 7 \x{1f440} • 6 \x{2764}\x{fe0f} • 5 \x{1f389} • 4 \x{1f604} • 3 \x{1f680} • 2 \x{1f44e} • 1 \x{1f44d}` ,
233251 `Assignees:.*marseilles, monaco\n` ,
234252 `Labels:.*Closed: Duplicate, Closed: Won't Fix, help wanted, Status: In Progress, Type: Bug\n` ,
235- `Projects:.*Project 1 \(column A\), Project 2 \(column B\), Project 3 \(column C\), Project 4 \(Awaiting triage\)\n` ,
253+ `Projects:.*v2 Project 1 \(No Status\), v2 Project 2 \(Done\), Project 1 \(column A\), Project 2 \(column B\), Project 3 \(column C\), Project 4 \(Awaiting triage\)\n` ,
236254 `Milestone:.*uluru\n` ,
237255 `bold story` ,
238256 `View this issue on GitHub: https://github.com/OWNER/REPO/issues/123` ,
239257 },
240258 },
241259 "Open issue with empty body" : {
242- fixture : "./fixtures/issueView_previewWithEmptyBody.json" ,
260+ httpStubs : func (r * httpmock.Registry ) {
261+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewWithEmptyBody.json" ))
262+ mockEmptyV2ProjectItems (t , r )
263+ },
243264 expectedOutputs : []string {
244265 `ix of coins OWNER/REPO#123` ,
245266 `Open.*marseilles opened about 9 years ago.*9 comments` ,
@@ -248,7 +269,10 @@ func TestIssueView_tty_Preview(t *testing.T) {
248269 },
249270 },
250271 "Closed issue" : {
251- fixture : "./fixtures/issueView_previewClosedState.json" ,
272+ httpStubs : func (r * httpmock.Registry ) {
273+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewClosedState.json" ))
274+ mockEmptyV2ProjectItems (t , r )
275+ },
252276 expectedOutputs : []string {
253277 `ix of coins OWNER/REPO#123` ,
254278 `Closed.*marseilles opened about 9 years ago.*9 comments` ,
@@ -266,8 +290,9 @@ func TestIssueView_tty_Preview(t *testing.T) {
266290
267291 httpReg := & httpmock.Registry {}
268292 defer httpReg .Verify (t )
269-
270- httpReg .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse (tc .fixture ))
293+ if tc .httpStubs != nil {
294+ tc .httpStubs (httpReg )
295+ }
271296
272297 opts := ViewOptions {
273298 IO : ios ,
@@ -354,14 +379,15 @@ func TestIssueView_disabledIssues(t *testing.T) {
354379func TestIssueView_tty_Comments (t * testing.T ) {
355380 tests := map [string ]struct {
356381 cli string
357- fixtures map [ string ] string
382+ httpStubs func ( * httpmock. Registry )
358383 expectedOutputs []string
359384 wantsErr bool
360385 }{
361386 "without comments flag" : {
362387 cli : "123" ,
363- fixtures : map [string ]string {
364- "IssueByNumber" : "./fixtures/issueView_previewSingleComment.json" ,
388+ httpStubs : func (r * httpmock.Registry ) {
389+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewSingleComment.json" ))
390+ mockEmptyV2ProjectItems (t , r )
365391 },
366392 expectedOutputs : []string {
367393 `some title OWNER/REPO#123` ,
@@ -375,9 +401,10 @@ func TestIssueView_tty_Comments(t *testing.T) {
375401 },
376402 "with comments flag" : {
377403 cli : "123 --comments" ,
378- fixtures : map [string ]string {
379- "IssueByNumber" : "./fixtures/issueView_previewSingleComment.json" ,
380- "CommentsForIssue" : "./fixtures/issueView_previewFullComments.json" ,
404+ httpStubs : func (r * httpmock.Registry ) {
405+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewSingleComment.json" ))
406+ r .Register (httpmock .GraphQL (`query CommentsForIssue\b` ), httpmock .FileResponse ("./fixtures/issueView_previewFullComments.json" ))
407+ mockEmptyV2ProjectItems (t , r )
381408 },
382409 expectedOutputs : []string {
383410 `some title OWNER/REPO#123` ,
@@ -406,9 +433,8 @@ func TestIssueView_tty_Comments(t *testing.T) {
406433 t .Run (name , func (t * testing.T ) {
407434 http := & httpmock.Registry {}
408435 defer http .Verify (t )
409- for name , file := range tc .fixtures {
410- name := fmt .Sprintf (`query %s\b` , name )
411- http .Register (httpmock .GraphQL (name ), httpmock .FileResponse (file ))
436+ if tc .httpStubs != nil {
437+ tc .httpStubs (http )
412438 }
413439 output , err := runCommand (http , true , tc .cli )
414440 if tc .wantsErr {
@@ -426,14 +452,15 @@ func TestIssueView_tty_Comments(t *testing.T) {
426452func TestIssueView_nontty_Comments (t * testing.T ) {
427453 tests := map [string ]struct {
428454 cli string
429- fixtures map [ string ] string
455+ httpStubs func ( * httpmock. Registry )
430456 expectedOutputs []string
431457 wantsErr bool
432458 }{
433459 "without comments flag" : {
434460 cli : "123" ,
435- fixtures : map [string ]string {
436- "IssueByNumber" : "./fixtures/issueView_previewSingleComment.json" ,
461+ httpStubs : func (r * httpmock.Registry ) {
462+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewSingleComment.json" ))
463+ mockEmptyV2ProjectItems (t , r )
437464 },
438465 expectedOutputs : []string {
439466 `title:\tsome title` ,
@@ -446,9 +473,10 @@ func TestIssueView_nontty_Comments(t *testing.T) {
446473 },
447474 "with comments flag" : {
448475 cli : "123 --comments" ,
449- fixtures : map [string ]string {
450- "IssueByNumber" : "./fixtures/issueView_previewSingleComment.json" ,
451- "CommentsForIssue" : "./fixtures/issueView_previewFullComments.json" ,
476+ httpStubs : func (r * httpmock.Registry ) {
477+ r .Register (httpmock .GraphQL (`query IssueByNumber\b` ), httpmock .FileResponse ("./fixtures/issueView_previewSingleComment.json" ))
478+ r .Register (httpmock .GraphQL (`query CommentsForIssue\b` ), httpmock .FileResponse ("./fixtures/issueView_previewFullComments.json" ))
479+ mockEmptyV2ProjectItems (t , r )
452480 },
453481 expectedOutputs : []string {
454482 `author:\tmonalisa` ,
@@ -482,9 +510,8 @@ func TestIssueView_nontty_Comments(t *testing.T) {
482510 t .Run (name , func (t * testing.T ) {
483511 http := & httpmock.Registry {}
484512 defer http .Verify (t )
485- for name , file := range tc .fixtures {
486- name := fmt .Sprintf (`query %s\b` , name )
487- http .Register (httpmock .GraphQL (name ), httpmock .FileResponse (file ))
513+ if tc .httpStubs != nil {
514+ tc .httpStubs (http )
488515 }
489516 output , err := runCommand (http , false , tc .cli )
490517 if tc .wantsErr {
@@ -561,3 +588,50 @@ func TestProjectsV1Deprecation(t *testing.T) {
561588 reg .Verify (t )
562589 })
563590}
591+
592+ // mockEmptyV2ProjectItems registers GraphQL queries to report an issue is not contained on any v2 projects.
593+ func mockEmptyV2ProjectItems (t * testing.T , r * httpmock.Registry ) {
594+ r .Register (httpmock .GraphQL (`query IssueProjectItems\b` ), httpmock .StringResponse (`
595+ { "data": { "repository": { "issue": {
596+ "projectItems": {
597+ "totalCount": 0,
598+ "nodes": []
599+ } } } } }
600+ ` ))
601+ }
602+
603+ // mockV2ProjectItems registers GraphQL queries to report an issue on multiple v2 projects in various states
604+ // - `NO_STATUS_ITEM`: emulates this issue is on a project but is not given a status
605+ // - `DONE_STATUS_ITEM`: emulates this issue is on a project and considered done
606+ func mockV2ProjectItems (t * testing.T , r * httpmock.Registry ) {
607+ r .Register (httpmock .GraphQL (`query IssueProjectItems\b` ), httpmock .StringResponse (`
608+ { "data": { "repository": { "issue": {
609+ "projectItems": {
610+ "totalCount": 2,
611+ "nodes": [
612+ {
613+ "id": "NO_STATUS_ITEM",
614+ "project": {
615+ "id": "PROJECT1",
616+ "title": "v2 Project 1"
617+ },
618+ "status": {
619+ "optionId": "",
620+ "name": ""
621+ }
622+ },
623+ {
624+ "id": "DONE_STATUS_ITEM",
625+ "project": {
626+ "id": "PROJECT2",
627+ "title": "v2 Project 2"
628+ },
629+ "status": {
630+ "optionId": "PROJECTITEMFIELD1",
631+ "name": "Done"
632+ }
633+ }
634+ ]
635+ } } } } }
636+ ` ))
637+ }
0 commit comments