Skip to content

Commit bab5e6d

Browse files
committed
fix field types in project service
1 parent a94f37a commit bab5e6d

4 files changed

Lines changed: 58 additions & 92 deletions

File tree

github/github-accessors.go

Lines changed: 10 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/github-accessors_test.go

Lines changed: 12 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

github/projects.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package github
88
import (
99
"context"
1010
"fmt"
11+
"time"
1112
)
1213

1314
// ProjectsService handles communication with the project V2
@@ -79,28 +80,29 @@ type ListProjectsOptions struct {
7980
//
8081
// GitHub API docs: https://docs.github.com/rest/projects/fields
8182
type ProjectV2FieldOption struct {
82-
ID string `json:"id,omitempty"`
83+
ID string `json:"id"`
8384
// The display name of the option.
84-
Name string `json:"name,omitempty"`
85+
Name string `json:"name"`
8586
// The color associated with this option (e.g., "blue", "red").
86-
Color string `json:"color,omitempty"`
87+
Color string `json:"color"`
8788
// An optional description for this option.
88-
Description string `json:"description,omitempty"`
89+
Description string `json:"description"`
8990
}
9091

9192
// ProjectV2Field represents a field in a GitHub Projects V2 project.
9293
// Fields define the structure and data types for project items.
9394
//
9495
// GitHub API docs: https://docs.github.com/rest/projects/fields
9596
type ProjectV2Field struct {
96-
ID *int64 `json:"id,omitempty"`
97-
NodeID string `json:"node_id,omitempty"`
98-
Name string `json:"name,omitempty"`
99-
DataType string `json:"dataType,omitempty"`
100-
URL string `json:"url,omitempty"`
101-
Options []*any `json:"options,omitempty"`
102-
CreatedAt *Timestamp `json:"created_at,omitempty"`
103-
UpdatedAt *Timestamp `json:"updated_at,omitempty"`
97+
ID int64 `json:"id"`
98+
NodeID *string `json:"node_id,omitempty"`
99+
Name string `json:"name"`
100+
DataType string `json:"data_type"`
101+
URL *string `json:"url,omitempty"`
102+
ProjectURL string `json:"project_url"`
103+
Options []*ProjectV2FieldOption `json:"options,omitempty"`
104+
CreatedAt time.Time `json:"created_at"`
105+
UpdatedAt time.Time `json:"updated_at"`
104106
}
105107

106108
// ListProjectsForOrg lists Projects V2 for an organization.

github/projects_test.go

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@ func TestProjectsService_ListProjectFieldsForOrg(t *testing.T) {
278278
"id": 1,
279279
"node_id": "node_1",
280280
"name": "Status",
281-
"dataType": "single_select",
281+
"data_type": "single_select",
282+
"project_url": "https://api.github.com/projects/1",
282283
"url": "https://api.github.com/projects/1/fields/field1",
283284
"options": [
284285
{
@@ -300,7 +301,8 @@ func TestProjectsService_ListProjectFieldsForOrg(t *testing.T) {
300301
"id": 2,
301302
"node_id": "node_2",
302303
"name": "Priority",
303-
"dataType": "text",
304+
"data_type": "text",
305+
"project_url": "https://api.github.com/projects/1",
304306
"url": "https://api.github.com/projects/1/fields/field2",
305307
"created_at": "2011-01-02T15:04:05Z",
306308
"updated_at": "2012-01-02T15:04:05Z"
@@ -320,35 +322,21 @@ func TestProjectsService_ListProjectFieldsForOrg(t *testing.T) {
320322
}
321323

322324
field1 := fields[0]
323-
if field1.ID == nil || *field1.ID != 1 || field1.Name != "Status" || field1.DataType != "single_select" {
325+
if field1.ID != 1 || field1.Name != "Status" || field1.DataType != "single_select" {
324326
t.Errorf("First field: got ID=%v, Name=%v, DataType=%v; want 1, Status, single_select", field1.ID, field1.Name, field1.DataType)
325327
}
326328
if len(field1.Options) != 2 {
327329
t.Errorf("First field options: got %v, want 2", len(field1.Options))
328330
} else {
329-
getName := func(o *any) string {
330-
if o == nil || *o == nil {
331-
return ""
332-
}
333-
switch v := (*o).(type) {
334-
case map[string]any:
335-
if n, ok := v["name"].(string); ok {
336-
return n
337-
}
338-
default:
339-
// fall back to fmt for debug; reflection can be added if needed.
340-
}
341-
return ""
342-
}
343-
name0, name1 := getName(field1.Options[0]), getName(field1.Options[1])
344-
if name0 != "Todo" || name1 != "In Progress" {
331+
name0, name1 := field1.Options[0].Name, field1.Options[1].Name
332+
if field1.Options[0].Name != "Todo" || field1.Options[1].Name != "In Progress" {
345333
t.Errorf("First field option names: got %q, %q; want Todo, In Progress", name0, name1)
346334
}
347335
}
348336

349337
// Validate second field (without options)
350338
field2 := fields[1]
351-
if field2.ID == nil || *field2.ID != 2 || field2.Name != "Priority" || field2.DataType != "text" {
339+
if field2.ID != 2 || field2.Name != "Priority" || field2.DataType != "text" {
352340
t.Errorf("Second field: got ID=%v, Name=%v, DataType=%v; want 2, Priority, text", field2.ID, field2.Name, field2.DataType)
353341
}
354342
if len(field2.Options) != 0 {
@@ -406,7 +394,7 @@ func TestProjectsService_ListProjectFieldsForOrg_pagination(t *testing.T) {
406394
if err != nil {
407395
t.Fatalf("first page error: %v", err)
408396
}
409-
if len(first) != 1 || first[0].ID == nil || *first[0].ID != 1 {
397+
if len(first) != 1 || first[0].ID != 1 {
410398
t.Fatalf("unexpected first page %+v", first)
411399
}
412400
if resp.After != "cursor2" {
@@ -418,7 +406,7 @@ func TestProjectsService_ListProjectFieldsForOrg_pagination(t *testing.T) {
418406
if err != nil {
419407
t.Fatalf("second page error: %v", err)
420408
}
421-
if len(second) != 1 || second[0].ID == nil || *second[0].ID != 2 {
409+
if len(second) != 1 || second[0].ID != 2 {
422410
t.Fatalf("unexpected second page %+v", second)
423411
}
424412
if resp2.Before != "cursor2" {
@@ -456,32 +444,27 @@ func TestProjectV2Field_Marshal(t *testing.T) {
456444
testJSONMarshal(t, &ProjectV2Field{}, "{}") // empty struct
457445
testJSONMarshal(t, &ProjectV2FieldOption{}, "{}") // option struct still individually testable
458446

459-
type optStruct struct {
460-
Color string `json:"color,omitempty"`
461-
Description string `json:"description,omitempty"`
462-
ID string `json:"id,omitempty"`
463-
Name string `json:"name,omitempty"`
464-
}
465-
optVal := &optStruct{Color: "blue", Description: "Tasks to be done", ID: "option1", Name: "Todo"}
466-
var optAny any = optVal
447+
optVal := &ProjectV2FieldOption{Color: "blue", Description: "Tasks to be done", ID: "option1", Name: "Todo"}
467448

468449
field := &ProjectV2Field{
469-
ID: Ptr(int64(1)),
470-
NodeID: "node_1",
471-
Name: "Status",
472-
DataType: "single_select",
473-
URL: "https://api.github.com/projects/1/fields/field1",
474-
Options: []*any{&optAny},
475-
CreatedAt: &Timestamp{referenceTime},
476-
UpdatedAt: &Timestamp{referenceTime},
450+
ID: 1,
451+
NodeID: Ptr("node_1"),
452+
Name: "Status",
453+
DataType: "single_select",
454+
URL: Ptr("https://api.github.com/projects/1/fields/field1"),
455+
ProjectURL: "https://api.github.com/projects/1",
456+
Options: []*ProjectV2FieldOption{optVal},
457+
CreatedAt: referenceTime,
458+
UpdatedAt: referenceTime,
477459
}
478460

479461
want := `{
480462
"id": 1,
481463
"node_id": "node_1",
482464
"name": "Status",
483-
"dataType": "single_select",
465+
"data_type": "single_select",
484466
"url": "https://api.github.com/projects/1/fields/field1",
467+
"project_url": "https://api.github.com/projects/1",
485468
"options": [
486469
{
487470
"id": "option1",

0 commit comments

Comments
 (0)