diff --git a/zendesk/mock/client.go b/zendesk/mock/client.go index b0fb252b..196c5e4e 100644 --- a/zendesk/mock/client.go +++ b/zendesk/mock/client.go @@ -284,6 +284,15 @@ func (m *Client) CreateUser(arg0 context.Context, arg1 zendesk.User) (zendesk.Us return ret0, ret1 } +// CreateOrUpdateUser mocks base method. +func (m *Client) CreateOrUpdateUser(arg0 context.Context, arg1 zendesk.User) (zendesk.User, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateOrUpdateUser", arg0, arg1) + ret0, _ := ret[0].(zendesk.User) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + // CreateUser indicates an expected call of CreateUser. func (mr *ClientMockRecorder) CreateUser(arg0, arg1 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() diff --git a/zendesk/user.go b/zendesk/user.go index 410eb987..e76e22c3 100644 --- a/zendesk/user.go +++ b/zendesk/user.go @@ -107,6 +107,7 @@ type UserAPI interface { GetUsers(ctx context.Context, opts *UserListOptions) ([]User, Page, error) GetUser(ctx context.Context, userID int64) (User, error) CreateUser(ctx context.Context, user User) (User, error) + CreateOrUpdateUser(ctx context.Context, user User) (User, error) UpdateUser(ctx context.Context, userID int64, user User) (User, error) GetUserRelated(ctx context.Context, userID int64) (UserRelated, error) } @@ -175,7 +176,7 @@ func (z *Client) GetManyUsers(ctx context.Context, opts *GetManyUsersOptions) ([ //TODO: GetUsersByGroupID, GetUsersByOrganizationID // CreateUser creates new user -// ref: https://developer.zendesk.com/rest_api/docs/core/triggers#create-trigger +// ref: https://developer.zendesk.com/api-reference/ticketing/users/users/#create-user func (z *Client) CreateUser(ctx context.Context, user User) (User, error) { var data, result struct { User User `json:"user"` @@ -194,6 +195,26 @@ func (z *Client) CreateUser(ctx context.Context, user User) (User, error) { return result.User, nil } +// CreateOrUpdateUser creates new user or updates a matching user +// ref: https://developer.zendesk.com/api-reference/ticketing/users/users/#create-or-update-user +func (z *Client) CreateOrUpdateUser(ctx context.Context, user User) (User, error) { + var data, result struct { + User User `json:"user"` + } + data.User = user + + body, err := z.post(ctx, "/users/create_or_update.json", data) + if err != nil { + return User{}, err + } + + err = json.Unmarshal(body, &result) + if err != nil { + return User{}, err + } + return result.User, nil +} + // TODO: CreateOrUpdateManyUsers(users []User) // GetUser get an existing user diff --git a/zendesk/user_test.go b/zendesk/user_test.go index b6944393..eb51c4a4 100644 --- a/zendesk/user_test.go +++ b/zendesk/user_test.go @@ -115,6 +115,52 @@ func TestCreateUser(t *testing.T) { } } +func TestCreateOrUpdateUserCreated(t *testing.T) { + mockAPI := newMockAPIWithStatus(http.MethodPost, "users.json", http.StatusCreated) + client := newTestClient(mockAPI) + defer mockAPI.Close() + + user, err := client.CreateOrUpdateUser(ctx, User{ + Email: "test@example.com", + Name: "testuser", + }) + if err != nil { + t.Fatalf("Failed to get valid response: %s", err) + } + if user.ID == 0 { + t.Fatal("Failed to create or update user") + } +} + +func TestCreateOrUpdateUserUpdated(t *testing.T) { + mockAPI := newMockAPIWithStatus(http.MethodPost, "users.json", http.StatusOK) + client := newTestClient(mockAPI) + defer mockAPI.Close() + + user, err := client.CreateOrUpdateUser(ctx, User{ + Email: "test@example.com", + Name: "testuser", + }) + if err != nil { + t.Fatalf("Failed to get valid response: %s", err) + } + if user.ID == 0 { + t.Fatal("Failed to create or update user") + } +} + +func TestCreateOrUpdateUserFailure(t *testing.T) { + mockAPI := newMockAPIWithStatus(http.MethodPost, "users.json", http.StatusInternalServerError) + + client := newTestClient(mockAPI) + defer mockAPI.Close() + + _, err := client.CreateOrUpdateUser(ctx, User{}) + if err == nil { + t.Fatal("Client did not return error when api failed") + } +} + func TestUpdateUser(t *testing.T) { mockAPI := newMockAPIWithStatus(http.MethodPut, "user.json", http.StatusOK) client := newTestClient(mockAPI) diff --git a/zendesk/zendesk.go b/zendesk/zendesk.go index f0b5d989..ba9bb66b 100644 --- a/zendesk/zendesk.go +++ b/zendesk/zendesk.go @@ -145,7 +145,7 @@ func (z *Client) post(ctx context.Context, path string, data interface{}) ([]byt return nil, err } - if resp.StatusCode != http.StatusCreated { + if !(resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusCreated) { return nil, Error{ body: body, resp: resp,