From 3870a803d29759644d295bfe52cf0005d9d1fb8b Mon Sep 17 00:00:00 2001 From: Chris Novakovic Date: Fri, 23 Feb 2024 12:28:23 +0000 Subject: [PATCH] Allow API endpoints to determine default boolean option values (#12) On Jira API endpoints that accept boolean parameters, the value of the parameter may default to either true or false if it isn't supplied in the request, depending on the endpoint. In options structs that have them, change the type of fields representing these parameters from `bool` to `*bool`, so that their value isn't explicitly set to false in the request if a value isn't given in the struct - in order words, let the API endpoint decide what the value should be, not go-jira. --- filter.go | 2 +- issue.go | 14 +++++++------- jira_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/filter.go b/filter.go index f40f3a58..7844c288 100644 --- a/filter.go +++ b/filter.go @@ -38,7 +38,7 @@ type Filter struct { // GetMyFiltersQueryOptions specifies the optional parameters for the Get My Filters method type GetMyFiltersQueryOptions struct { - IncludeFavourites bool `url:"includeFavourites,omitempty"` + IncludeFavourites *bool `url:"includeFavourites,omitempty"` Expand string `url:"expand,omitempty"` } diff --git a/issue.go b/issue.go index 0aa03b70..b20ff4d4 100644 --- a/issue.go +++ b/issue.go @@ -34,9 +34,9 @@ type IssueService struct { // UpdateQueryOptions specifies the optional parameters to the Edit issue type UpdateQueryOptions struct { - NotifyUsers bool `url:"notifyUsers,omitempty"` - OverrideScreenSecurity bool `url:"overrideScreenSecurity,omitempty"` - OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"` + NotifyUsers *bool `url:"notifyUsers,omitempty"` + OverrideScreenSecurity *bool `url:"overrideScreenSecurity,omitempty"` + OverrideEditableFlag *bool `url:"overrideEditableFlag,omitempty"` } // Issue represents a Jira issue. @@ -544,8 +544,8 @@ type GetQueryOptions struct { // Properties is the list of properties to return for the issue. By default no properties are returned. Properties string `url:"properties,omitempty"` // FieldsByKeys if true then fields in issues will be referenced by keys instead of ids - FieldsByKeys bool `url:"fieldsByKeys,omitempty"` - UpdateHistory bool `url:"updateHistory,omitempty"` + FieldsByKeys *bool `url:"fieldsByKeys,omitempty"` + UpdateHistory *bool `url:"updateHistory,omitempty"` ProjectKeys string `url:"projectKeys,omitempty"` } @@ -558,12 +558,12 @@ type GetWorklogsQueryOptions struct { } type AddWorklogQueryOptions struct { - NotifyUsers bool `url:"notifyUsers,omitempty"` + NotifyUsers *bool `url:"notifyUsers,omitempty"` AdjustEstimate string `url:"adjustEstimate,omitempty"` NewEstimate string `url:"newEstimate,omitempty"` ReduceBy string `url:"reduceBy,omitempty"` Expand string `url:"expand,omitempty"` - OverrideEditableFlag bool `url:"overrideEditableFlag,omitempty"` + OverrideEditableFlag *bool `url:"overrideEditableFlag,omitempty"` } // CustomFields represents custom fields of Jira diff --git a/jira_test.go b/jira_test.go index 73dd64dd..d8c99dc4 100644 --- a/jira_test.go +++ b/jira_test.go @@ -293,6 +293,51 @@ func TestClient_NewRequest_EmptyBody(t *testing.T) { } } +// Tests that addOptions correctly serialises *bools, which are used to convey the desired value of +// options that default to true on the API endpoint if a value is not specified in the request: +// +// | Option value | Expected outcome | +// | ------------ | ------------------------------ | +// | *true | opt=true in request | +// | *false | opt=false in request | +// | nil | Determined by the API endpoint | +func Test_addOptions_Bool_Pointer(t *testing.T) { + apiEndpoint := "rest/api/2/issue/123" + + for _, test := range []struct { + Description string + Opts *UpdateQueryOptions + Expected string + }{ + { + Description: "*bool implicitly nil", + Opts: &UpdateQueryOptions{}, + Expected: "", + }, + { + Description: "*bool explicitly nil", + Opts: &UpdateQueryOptions{NotifyUsers: nil}, + Expected: "", + }, + { + Description: "*bool explicitly true", + Opts: &UpdateQueryOptions{NotifyUsers: Bool(true)}, + Expected: "?notifyUsers=true", + }, + { + Description: "*bool explicitly false", + Opts: &UpdateQueryOptions{NotifyUsers: Bool(false)}, + Expected: "?notifyUsers=false", + }, + } { + t.Run(test.Description, func(t *testing.T) { + actual, err := addOptions(apiEndpoint, test.Opts) + assert.NoError(t, err) + assert.Equal(t, apiEndpoint + test.Expected, actual) + }) + } +} + func TestClient_NewMultiPartRequest(t *testing.T) { c, err := NewClient(nil, testJiraInstanceURL) if err != nil {