Loading workitems.go +28 −28 Changes for workitems.go: 28 added lines, 28 removed lines. Original line number Diff line number Diff line Loading @@ -44,32 +44,32 @@ var _ WorkItemsServiceInterface = (*WorkItemsService)(nil) // // Experimental: The Work Items API is a work in progress and may introduce breaking changes even between minor versions. type WorkItem struct { ID int64 IID int64 Type string State string Status *string Title string Description string CreatedAt *time.Time UpdatedAt *time.Time ClosedAt *time.Time WebURL string Author *BasicUser Assignees []*BasicUser ID int64 `json:"id"` IID int64 `json:"iid"` Type string `json:"type"` State string `json:"state"` Status *string `json:"status,omitempty"` Title string `json:"title"` Description string `json:"description"` CreatedAt *time.Time `json:"created_at"` UpdatedAt *time.Time `json:"updated_at"` ClosedAt *time.Time `json:"closed_at"` WebURL string `json:"web_url"` Author *BasicUser `json:"author"` Assignees []*BasicUser `json:"assignees"` Color *string Confidential bool DueDate *ISOTime HealthStatus *string IterationID *int64 Labels []LabelDetails LinkedItems []LinkedWorkItem MilestoneID *int64 Parent *WorkItemIID Children []WorkItemIID StartDate *ISOTime Weight *int64 Color *string `json:"color,omitempty"` Confidential bool `json:"confidential"` DueDate *ISOTime `json:"due_date"` HealthStatus *string `json:"health_status,omitempty"` IterationID *int64 `json:"iteration_id,omitempty"` Labels []LabelDetails `json:"labels"` LinkedItems []LinkedWorkItem `json:"linked_items"` MilestoneID *int64 `json:"milestone_id"` Parent *WorkItemIID `json:"parent"` Children []WorkItemIID `json:"children"` StartDate *ISOTime `json:"start_date"` Weight *int64 `json:"weight,omitempty"` } func (wi WorkItem) GID() string { Loading @@ -83,8 +83,8 @@ func (wi WorkItem) GID() string { // // Experimental: The Work Items API is a work in progress and may introduce breaking changes even between minor versions. type WorkItemIID struct { NamespacePath string IID int64 NamespacePath string `json:"namespace_path"` IID int64 `json:"iid"` } type workItemIIDGQL struct { Loading Loading @@ -118,7 +118,7 @@ type LinkedWorkItem struct { // LinkType is the type of relationship between the work items. // Possible values: blocks, is_blocked_by, relates_to LinkType string LinkType string `json:"link_type"` } // WorkItemStateEvent represents a state change event for a work item. Loading workitems_test.go +80 −0 Changes for workitems_test.go: 80 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -1896,3 +1896,83 @@ func TestWorkItemCEAndEEFieldsAreDisjoint(t *testing.T) { assert.False(t, isEE, "%q appears in both workItemCEFields and workItemEEFields", f.Name) } } func TestWorkItem_MarshalJSON_SnakeCaseKeys(t *testing.T) { t.Parallel() createdAt := time.Date(2026, time.January, 1, 10, 0, 0, 0, time.UTC) dueDate := ISOTime(time.Date(2026, time.January, 2, 0, 0, 0, 0, time.UTC)) wi := WorkItem{ ID: 1, IID: 2, Type: "Issue", State: "OPEN", Status: new("To do"), Title: "Title", Description: "Description", CreatedAt: &createdAt, UpdatedAt: &createdAt, WebURL: "https://gitlab.example.com/group/project/-/work_items/2", Author: &BasicUser{ID: 3, Username: "author"}, Assignees: []*BasicUser{{ID: 4, Username: "assignee"}}, Color: new("#1068bf"), Confidential: true, DueDate: &dueDate, HealthStatus: new("onTrack"), IterationID: new(int64(5)), Labels: []LabelDetails{{ID: 6, Name: "bug"}}, LinkedItems: []LinkedWorkItem{{ WorkItemIID: WorkItemIID{NamespacePath: "group/project", IID: 7}, LinkType: "blocks", }}, MilestoneID: new(int64(8)), Parent: &WorkItemIID{NamespacePath: "group", IID: 9}, Children: []WorkItemIID{{NamespacePath: "group/project", IID: 10}}, StartDate: &dueDate, Weight: new(int64(3)), } data, err := json.Marshal(wi) require.NoError(t, err) var raw map[string]any require.NoError(t, json.Unmarshal(data, &raw)) keys := make([]string, 0, len(raw)) for k := range raw { keys = append(keys, k) } assert.ElementsMatch(t, []string{ "id", "iid", "type", "state", "status", "title", "description", "created_at", "updated_at", "closed_at", "web_url", "author", "assignees", "color", "confidential", "due_date", "health_status", "iteration_id", "labels", "linked_items", "milestone_id", "parent", "children", "start_date", "weight", }, keys) assert.Equal(t, "2026-01-02", raw["due_date"]) assert.Equal(t, map[string]any{"namespace_path": "group", "iid": float64(9)}, raw["parent"]) assert.Equal(t, []any{ map[string]any{"namespace_path": "group/project", "iid": float64(10)}, }, raw["children"]) assert.Equal(t, []any{ map[string]any{"namespace_path": "group/project", "iid": float64(7), "link_type": "blocks"}, }, raw["linked_items"]) } func TestWorkItem_MarshalJSON_OmitsUnsetEEFields(t *testing.T) { t.Parallel() data, err := json.Marshal(WorkItem{ID: 1, IID: 2, Title: "CE only"}) require.NoError(t, err) var raw map[string]any require.NoError(t, json.Unmarshal(data, &raw)) for _, key := range []string{"color", "health_status", "iteration_id", "status", "weight"} { assert.NotContains(t, raw, key) } assert.Contains(t, raw, "closed_at") assert.Nil(t, raw["closed_at"]) } Loading
workitems.go +28 −28 Changes for workitems.go: 28 added lines, 28 removed lines. Original line number Diff line number Diff line Loading @@ -44,32 +44,32 @@ var _ WorkItemsServiceInterface = (*WorkItemsService)(nil) // // Experimental: The Work Items API is a work in progress and may introduce breaking changes even between minor versions. type WorkItem struct { ID int64 IID int64 Type string State string Status *string Title string Description string CreatedAt *time.Time UpdatedAt *time.Time ClosedAt *time.Time WebURL string Author *BasicUser Assignees []*BasicUser ID int64 `json:"id"` IID int64 `json:"iid"` Type string `json:"type"` State string `json:"state"` Status *string `json:"status,omitempty"` Title string `json:"title"` Description string `json:"description"` CreatedAt *time.Time `json:"created_at"` UpdatedAt *time.Time `json:"updated_at"` ClosedAt *time.Time `json:"closed_at"` WebURL string `json:"web_url"` Author *BasicUser `json:"author"` Assignees []*BasicUser `json:"assignees"` Color *string Confidential bool DueDate *ISOTime HealthStatus *string IterationID *int64 Labels []LabelDetails LinkedItems []LinkedWorkItem MilestoneID *int64 Parent *WorkItemIID Children []WorkItemIID StartDate *ISOTime Weight *int64 Color *string `json:"color,omitempty"` Confidential bool `json:"confidential"` DueDate *ISOTime `json:"due_date"` HealthStatus *string `json:"health_status,omitempty"` IterationID *int64 `json:"iteration_id,omitempty"` Labels []LabelDetails `json:"labels"` LinkedItems []LinkedWorkItem `json:"linked_items"` MilestoneID *int64 `json:"milestone_id"` Parent *WorkItemIID `json:"parent"` Children []WorkItemIID `json:"children"` StartDate *ISOTime `json:"start_date"` Weight *int64 `json:"weight,omitempty"` } func (wi WorkItem) GID() string { Loading @@ -83,8 +83,8 @@ func (wi WorkItem) GID() string { // // Experimental: The Work Items API is a work in progress and may introduce breaking changes even between minor versions. type WorkItemIID struct { NamespacePath string IID int64 NamespacePath string `json:"namespace_path"` IID int64 `json:"iid"` } type workItemIIDGQL struct { Loading Loading @@ -118,7 +118,7 @@ type LinkedWorkItem struct { // LinkType is the type of relationship between the work items. // Possible values: blocks, is_blocked_by, relates_to LinkType string LinkType string `json:"link_type"` } // WorkItemStateEvent represents a state change event for a work item. Loading
workitems_test.go +80 −0 Changes for workitems_test.go: 80 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -1896,3 +1896,83 @@ func TestWorkItemCEAndEEFieldsAreDisjoint(t *testing.T) { assert.False(t, isEE, "%q appears in both workItemCEFields and workItemEEFields", f.Name) } } func TestWorkItem_MarshalJSON_SnakeCaseKeys(t *testing.T) { t.Parallel() createdAt := time.Date(2026, time.January, 1, 10, 0, 0, 0, time.UTC) dueDate := ISOTime(time.Date(2026, time.January, 2, 0, 0, 0, 0, time.UTC)) wi := WorkItem{ ID: 1, IID: 2, Type: "Issue", State: "OPEN", Status: new("To do"), Title: "Title", Description: "Description", CreatedAt: &createdAt, UpdatedAt: &createdAt, WebURL: "https://gitlab.example.com/group/project/-/work_items/2", Author: &BasicUser{ID: 3, Username: "author"}, Assignees: []*BasicUser{{ID: 4, Username: "assignee"}}, Color: new("#1068bf"), Confidential: true, DueDate: &dueDate, HealthStatus: new("onTrack"), IterationID: new(int64(5)), Labels: []LabelDetails{{ID: 6, Name: "bug"}}, LinkedItems: []LinkedWorkItem{{ WorkItemIID: WorkItemIID{NamespacePath: "group/project", IID: 7}, LinkType: "blocks", }}, MilestoneID: new(int64(8)), Parent: &WorkItemIID{NamespacePath: "group", IID: 9}, Children: []WorkItemIID{{NamespacePath: "group/project", IID: 10}}, StartDate: &dueDate, Weight: new(int64(3)), } data, err := json.Marshal(wi) require.NoError(t, err) var raw map[string]any require.NoError(t, json.Unmarshal(data, &raw)) keys := make([]string, 0, len(raw)) for k := range raw { keys = append(keys, k) } assert.ElementsMatch(t, []string{ "id", "iid", "type", "state", "status", "title", "description", "created_at", "updated_at", "closed_at", "web_url", "author", "assignees", "color", "confidential", "due_date", "health_status", "iteration_id", "labels", "linked_items", "milestone_id", "parent", "children", "start_date", "weight", }, keys) assert.Equal(t, "2026-01-02", raw["due_date"]) assert.Equal(t, map[string]any{"namespace_path": "group", "iid": float64(9)}, raw["parent"]) assert.Equal(t, []any{ map[string]any{"namespace_path": "group/project", "iid": float64(10)}, }, raw["children"]) assert.Equal(t, []any{ map[string]any{"namespace_path": "group/project", "iid": float64(7), "link_type": "blocks"}, }, raw["linked_items"]) } func TestWorkItem_MarshalJSON_OmitsUnsetEEFields(t *testing.T) { t.Parallel() data, err := json.Marshal(WorkItem{ID: 1, IID: 2, Title: "CE only"}) require.NoError(t, err) var raw map[string]any require.NoError(t, json.Unmarshal(data, &raw)) for _, key := range []string{"color", "health_status", "iteration_id", "status", "weight"} { assert.NotContains(t, raw, key) } assert.Contains(t, raw, "closed_at") assert.Nil(t, raw["closed_at"]) }