cli/api/export_pr_test.go
Simon Taranto 34c3b3c809 Add databaseId to assignees GraphQL fragment
The assignees query fragment only requested id, login, and name but the
GitHubUser struct includes a DatabaseID field. Since the field was never
requested from the API, it always defaulted to Go's zero value (0) in
JSON output. This adds databaseId to the fragment so the actual value is
returned.

Also adds ExportData test cases for assignees on both Issue and
PullRequest to verify databaseId round-trips correctly through JSON
serialization.
2026-02-25 10:26:46 -05:00

458 lines
9.3 KiB
Go

package api
import (
"bytes"
"encoding/json"
"strings"
"testing"
"github.com/MakeNowJust/heredoc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIssue_ExportData(t *testing.T) {
tests := []struct {
name string
fields []string
inputJSON string
outputJSON string
}{
{
name: "simple",
fields: []string{"number", "title"},
inputJSON: heredoc.Doc(`
{ "title": "Bugs hugs", "number": 2345 }
`),
outputJSON: heredoc.Doc(`
{
"number": 2345,
"title": "Bugs hugs"
}
`),
},
{
name: "milestone",
fields: []string{"number", "milestone"},
inputJSON: heredoc.Doc(`
{ "number": 2345, "milestone": {"title": "The next big thing"} }
`),
outputJSON: heredoc.Doc(`
{
"milestone": {
"number": 0,
"title": "The next big thing",
"description": "",
"dueOn": null
},
"number": 2345
}
`),
},
{
name: "project cards",
fields: []string{"projectCards"},
inputJSON: heredoc.Doc(`
{ "projectCards": { "nodes": [
{
"project": { "name": "Rewrite" },
"column": { "name": "TO DO" }
}
] } }
`),
outputJSON: heredoc.Doc(`
{
"projectCards": [
{
"project": {
"name": "Rewrite"
},
"column": {
"name": "TO DO"
}
}
]
}
`),
},
{
name: "project items",
fields: []string{"projectItems"},
inputJSON: heredoc.Doc(`
{ "projectItems": { "nodes": [
{
"id": "PVTI_id",
"project": {
"id": "PVT_id",
"title": "Some Project"
},
"status": {
"name": "Todo",
"optionId": "abc123"
}
}
] } }
`),
outputJSON: heredoc.Doc(`
{
"projectItems": [
{
"status": {
"optionId": "abc123",
"name": "Todo"
},
"title": "Some Project"
}
]
}
`),
},
{
name: "assignees",
fields: []string{"assignees"},
inputJSON: heredoc.Doc(`
{ "assignees": { "nodes": [
{
"id": "MDQ6VXNlcjE=",
"login": "monalisa",
"name": "Mona Lisa",
"databaseId": 1234
}
] } }
`),
outputJSON: heredoc.Doc(`
{
"assignees": [
{
"id": "MDQ6VXNlcjE=",
"login": "monalisa",
"name": "Mona Lisa",
"databaseId": 1234
}
]
}
`),
},
{
name: "linked pull requests",
fields: []string{"closedByPullRequestsReferences"},
inputJSON: heredoc.Doc(`
{ "closedByPullRequestsReferences": { "nodes": [
{
"id": "I_123",
"number": 123,
"url": "https://github.com/cli/cli/pull/123",
"repository": {
"id": "R_123",
"name": "cli",
"owner": {
"id": "O_123",
"login": "cli"
}
}
},
{
"id": "I_456",
"number": 456,
"url": "https://github.com/cli/cli/pull/456",
"repository": {
"id": "R_456",
"name": "cli",
"owner": {
"id": "O_456",
"login": "cli"
}
}
}
] } }
`),
outputJSON: heredoc.Doc(`
{ "closedByPullRequestsReferences": [
{
"id": "I_123",
"number": 123,
"repository": {
"id": "R_123",
"name": "cli",
"owner": {
"id": "O_123",
"login": "cli"
}
},
"url": "https://github.com/cli/cli/pull/123"
},
{
"id": "I_456",
"number": 456,
"repository": {
"id": "R_456",
"name": "cli",
"owner": {
"id": "O_456",
"login": "cli"
}
},
"url": "https://github.com/cli/cli/pull/456"
}
] }
`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var issue Issue
dec := json.NewDecoder(strings.NewReader(tt.inputJSON))
require.NoError(t, dec.Decode(&issue))
exported := issue.ExportData(tt.fields)
buf := bytes.Buffer{}
enc := json.NewEncoder(&buf)
enc.SetIndent("", "\t")
require.NoError(t, enc.Encode(exported))
var gotData interface{}
dec = json.NewDecoder(&buf)
require.NoError(t, dec.Decode(&gotData))
var expectData interface{}
require.NoError(t, json.Unmarshal([]byte(tt.outputJSON), &expectData))
assert.Equal(t, expectData, gotData)
})
}
}
func TestPullRequest_ExportData(t *testing.T) {
tests := []struct {
name string
fields []string
inputJSON string
outputJSON string
}{
{
name: "simple",
fields: []string{"number", "title"},
inputJSON: heredoc.Doc(`
{ "title": "Bugs hugs", "number": 2345 }
`),
outputJSON: heredoc.Doc(`
{
"number": 2345,
"title": "Bugs hugs"
}
`),
},
{
name: "milestone",
fields: []string{"number", "milestone"},
inputJSON: heredoc.Doc(`
{ "number": 2345, "milestone": {"title": "The next big thing"} }
`),
outputJSON: heredoc.Doc(`
{
"milestone": {
"number": 0,
"title": "The next big thing",
"description": "",
"dueOn": null
},
"number": 2345
}
`),
},
{
name: "status checks",
fields: []string{"statusCheckRollup"},
inputJSON: heredoc.Doc(`
{ "statusCheckRollup": { "nodes": [
{ "commit": { "statusCheckRollup": { "contexts": { "nodes": [
{
"__typename": "CheckRun",
"name": "mycheck",
"checkSuite": {"workflowRun": {"workflow": {"name": "myworkflow"}}},
"status": "COMPLETED",
"conclusion": "SUCCESS",
"startedAt": "2020-08-31T15:44:24+02:00",
"completedAt": "2020-08-31T15:45:24+02:00",
"detailsUrl": "http://example.com/details"
},
{
"__typename": "StatusContext",
"context": "mycontext",
"state": "SUCCESS",
"createdAt": "2020-08-31T15:44:24+02:00",
"targetUrl": "http://example.com/details"
}
] } } } }
] } }
`),
outputJSON: heredoc.Doc(`
{
"statusCheckRollup": [
{
"__typename": "CheckRun",
"name": "mycheck",
"workflowName": "myworkflow",
"status": "COMPLETED",
"conclusion": "SUCCESS",
"startedAt": "2020-08-31T15:44:24+02:00",
"completedAt": "2020-08-31T15:45:24+02:00",
"detailsUrl": "http://example.com/details"
},
{
"__typename": "StatusContext",
"context": "mycontext",
"state": "SUCCESS",
"startedAt": "2020-08-31T15:44:24+02:00",
"targetUrl": "http://example.com/details"
}
]
}
`),
},
{
name: "project items",
fields: []string{"projectItems"},
inputJSON: heredoc.Doc(`
{ "projectItems": { "nodes": [
{
"id": "PVTPR_id",
"project": {
"id": "PVT_id",
"title": "Some Project"
},
"status": {
"name": "Todo",
"optionId": "abc123"
}
}
] } }
`),
outputJSON: heredoc.Doc(`
{
"projectItems": [
{
"status": {
"optionId": "abc123",
"name": "Todo"
},
"title": "Some Project"
}
]
}
`),
},
{
name: "assignees",
fields: []string{"assignees"},
inputJSON: heredoc.Doc(`
{ "assignees": { "nodes": [
{
"id": "MDQ6VXNlcjE=",
"login": "monalisa",
"name": "Mona Lisa",
"databaseId": 1234
}
] } }
`),
outputJSON: heredoc.Doc(`
{
"assignees": [
{
"id": "MDQ6VXNlcjE=",
"login": "monalisa",
"name": "Mona Lisa",
"databaseId": 1234
}
]
}
`),
},
{
name: "linked issues",
fields: []string{"closingIssuesReferences"},
inputJSON: heredoc.Doc(`
{ "closingIssuesReferences": { "nodes": [
{
"id": "I_123",
"number": 123,
"url": "https://github.com/cli/cli/issues/123",
"repository": {
"id": "R_123",
"name": "cli",
"owner": {
"id": "O_123",
"login": "cli"
}
}
},
{
"id": "I_456",
"number": 456,
"url": "https://github.com/cli/cli/issues/456",
"repository": {
"id": "R_456",
"name": "cli",
"owner": {
"id": "O_456",
"login": "cli"
}
}
}
] } }
`),
outputJSON: heredoc.Doc(`
{ "closingIssuesReferences": [
{
"id": "I_123",
"number": 123,
"repository": {
"id": "R_123",
"name": "cli",
"owner": {
"id": "O_123",
"login": "cli"
}
},
"url": "https://github.com/cli/cli/issues/123"
},
{
"id": "I_456",
"number": 456,
"repository": {
"id": "R_456",
"name": "cli",
"owner": {
"id": "O_456",
"login": "cli"
}
},
"url": "https://github.com/cli/cli/issues/456"
}
] }
`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var pr PullRequest
dec := json.NewDecoder(strings.NewReader(tt.inputJSON))
require.NoError(t, dec.Decode(&pr))
exported := pr.ExportData(tt.fields)
buf := bytes.Buffer{}
enc := json.NewEncoder(&buf)
enc.SetIndent("", "\t")
require.NoError(t, enc.Encode(exported))
var gotData interface{}
dec = json.NewDecoder(&buf)
require.NoError(t, dec.Decode(&gotData))
var expectData interface{}
require.NoError(t, json.Unmarshal([]byte(tt.outputJSON), &expectData))
assert.Equal(t, expectData, gotData)
})
}
}