From 5d18e0799fb4137c948a96cc92691f70b6a8bf50 Mon Sep 17 00:00:00 2001 From: ko-da-k Date: Tue, 28 Jan 2020 16:46:45 +0900 Subject: [PATCH 1/7] add sample response JSON --- teams_test.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 teams_test.go diff --git a/teams_test.go b/teams_test.go new file mode 100644 index 0000000..861f11d --- /dev/null +++ b/teams_test.go @@ -0,0 +1,60 @@ +package gapi + +const ( + getTeamJSON = ` +{ + "id": 1, + "orgId": 1, + "name": "MyTestTeam", + "email": "", + "created": "2017-12-15T10:40:45+01:00", + "updated": "2017-12-15T10:40:45+01:00" +} +` + addTeamsJSON = ` +{ + "message":"Team created", + "teamId":2 +} +` + updateTeamJSON = `{ "message":"Team updated"}` + deleteTeamJSON = `{"message":"Team deleted"}` + getTeamMembersJSON = ` +[ + { + "orgId": 1, + "teamId": 1, + "userId": 3, + "email": "user1@email.com", + "login": "user1", + "avatarUrl": "\/avatar\/1b3c32f6386b0185c40d359cdc733a79" + }, + { + "orgId": 1, + "teamId": 1, + "userId": 2, + "email": "user2@email.com", + "login": "user2", + "avatarUrl": "\/avatar\/cad3c68da76e45d10269e8ef02f8e73e" + } +] +` + addTeamMemberJSON = ` +{ + "userId": 2 +} +` + removeMemberFromTeamJSON = `{"message":"Team Member removed"}` + getTeamPreferencesJSON = ` +{ + "theme": "", + "homeDashboardId": 0, + "timezone": "" +} +` + updateTeamPreferencesJSON = ` +{ + "message":"Preferences updated" +} +` +) From f2d0026cf98cc8cf2057b289632f1d1ddc179145 Mon Sep 17 00:00:00 2001 From: ko-da-k Date: Tue, 28 Jan 2020 18:19:10 +0900 Subject: [PATCH 2/7] add test --- teams_test.go | 77 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 2 deletions(-) diff --git a/teams_test.go b/teams_test.go index 861f11d..d75977b 100644 --- a/teams_test.go +++ b/teams_test.go @@ -1,5 +1,10 @@ package gapi +import ( + "github.com/gobs/pretty" + "testing" +) + const ( getTeamJSON = ` { @@ -7,8 +12,9 @@ const ( "orgId": 1, "name": "MyTestTeam", "email": "", - "created": "2017-12-15T10:40:45+01:00", - "updated": "2017-12-15T10:40:45+01:00" + "avatarUrl": "avatar/abcdef", + "memberCount": 1, + "permission": 0 } ` addTeamsJSON = ` @@ -58,3 +64,70 @@ const ( } ` ) + +func TestTeam(t *testing.T) { + server, client := gapiTestTools(200, getTeamJSON) + defer server.Close() + + id := int64(1) + resp, err := client.Team(id) + if err != nil { + t.Error(err) + } + + t.Log(pretty.PrettyFormat(resp)) + + expect := &Team{ + Id: 1, + OrgId: 1, + Name: "MyTestTeam", + Email: "", + AvatarUrl: "avatar/abcdef", + MemberCount: 1, + Permission: 0, + } + t.Run("check data", func(t *testing.T) { + if expect.Id != resp.Id || expect.Name != expect.Name { + t.Error("Not correctly data") + } + }) +} + +func TestAddTeam(t *testing.T) { + server, client := gapiTestTools(200, addTeamsJSON) + defer server.Close() + + name := "TestTeam" + email := "" + + err := client.AddTeam(name, email) + if err != nil { + t.Error(err) + } +} + +func TestUpdateTeam(t *testing.T) { + server, client := gapiTestTools(200, addTeamsJSON) + defer server.Close() + + id := int64(1) + name := "TestTeam" + email := "" + + err := client.UpdateTeam(id, name, email) + if err != nil { + t.Error(err) + } +} + +func TestDeleteTeam(t *testing.T) { + server, client := gapiTestTools(200, addTeamsJSON) + defer server.Close() + + id := int64(1) + + err := client.DeleteTeam(id) + if err != nil { + t.Error(err) + } +} From 8a8e053034b0fd047b6de4763e13ff0610689c26 Mon Sep 17 00:00:00 2001 From: ko-da-k Date: Tue, 28 Jan 2020 21:47:09 +0900 Subject: [PATCH 3/7] impl team member API and preferences API --- teams_test.go | 115 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 4 deletions(-) diff --git a/teams_test.go b/teams_test.go index d75977b..5adfa80 100644 --- a/teams_test.go +++ b/teams_test.go @@ -31,17 +31,23 @@ const ( "orgId": 1, "teamId": 1, "userId": 3, + "auth_module": "oauth_github", "email": "user1@email.com", "login": "user1", - "avatarUrl": "\/avatar\/1b3c32f6386b0185c40d359cdc733a79" + "avatarUrl": "\/avatar\/1b3c32f6386b0185c40d359cdc733a79", + "labels": [], + "permission": 0 }, { "orgId": 1, "teamId": 1, "userId": 2, + "auth_module": "oauth_github", "email": "user2@email.com", "login": "user2", - "avatarUrl": "\/avatar\/cad3c68da76e45d10269e8ef02f8e73e" + "avatarUrl": "\/avatar\/cad3c68da76e45d10269e8ef02f8e73e", + "labels": [], + "permission": 0 } ] ` @@ -107,7 +113,7 @@ func TestAddTeam(t *testing.T) { } func TestUpdateTeam(t *testing.T) { - server, client := gapiTestTools(200, addTeamsJSON) + server, client := gapiTestTools(200, updateTeamJSON) defer server.Close() id := int64(1) @@ -121,7 +127,7 @@ func TestUpdateTeam(t *testing.T) { } func TestDeleteTeam(t *testing.T) { - server, client := gapiTestTools(200, addTeamsJSON) + server, client := gapiTestTools(200, deleteTeamJSON) defer server.Close() id := int64(1) @@ -131,3 +137,104 @@ func TestDeleteTeam(t *testing.T) { t.Error(err) } } + +func TestTeamMembers(t *testing.T) { + server, client := gapiTestTools(200, getTeamMembersJSON) + defer server.Close() + + id := int64(1) + + resp, err := client.TeamMembers(id) + if err != nil { + t.Error(err) + } + expects := []TeamMember{ + { + OrgId: 1, + TeamId: 1, + UserId: 3, + Email: "user1@email.com", + Login: "user1", + AvatarUrl: "/avatar/1b3c32f6386b0185c40d359cdc733a79", + Permission: 0, + }, + { + OrgId: 1, + TeamId: 1, + UserId: 2, + Email: "user2@email.com", + Login: "user2", + AvatarUrl: "/avatar/cad3c68da76e45d10269e8ef02f8e73e", + Permission: 0, + }, + } + + for i, expect := range expects { + t.Run("check data", func(t *testing.T) { + if expect.Email != resp[i].Email || expect.AvatarUrl != resp[i].AvatarUrl { + t.Error("Not correctly data") + } + }) + } +} + +func TestAddTeamMember(t *testing.T) { + server, client := gapiTestTools(200, addTeamMemberJSON) + defer server.Close() + + id := int64(1) + userId := int64(2) + + if err := client.AddTeamMember(id, userId); err != nil { + t.Error(err) + } +} + +func TestRemoveMemberFromTeam(t *testing.T) { + server, client := gapiTestTools(200, removeMemberFromTeamJSON) + defer server.Close() + + id := int64(1) + userId := int64(2) + + if err := client.RemoveMemberFromTeam(id, userId); err != nil { + t.Error(err) + } +} + +func TestTeamPreferences(t *testing.T) { + server, client := gapiTestTools(200, getTeamPreferencesJSON) + defer server.Close() + + id := int64(1) + + resp, err := client.TeamPreferences(id) + if err != nil { + t.Error(err) + } + expect := &Preferences{ + Theme: "", + HomeDashboardId: 0, + Timezone: "", + } + + t.Run("check data", func(t *testing.T) { + if expect.Theme != resp.Theme || expect.HomeDashboardId != resp.HomeDashboardId { + t.Error("Not correctly data") + } + }) +} + +func TestUpdateTeamPreferences(t *testing.T) { + server, client := gapiTestTools(200, updateTeamPreferencesJSON) + defer server.Close() + + id := int64(1) + theme := "" + homeDashboardId := int64(0) + timezone := "" + + if err := client.UpdateTeamPreferences(id, theme, homeDashboardId, timezone); err != nil { + t.Error(err) + } +} From 3eff3182a76461fce16ff4f24f09a89ee352369a Mon Sep 17 00:00:00 2001 From: ko-da-k Date: Tue, 28 Jan 2020 21:48:19 +0900 Subject: [PATCH 4/7] impl team API --- team.go | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 241 insertions(+) create mode 100644 team.go diff --git a/team.go b/team.go new file mode 100644 index 0000000..b17b353 --- /dev/null +++ b/team.go @@ -0,0 +1,241 @@ +package gapi + +import ( + "bytes" + "encoding/json" + "fmt" + "io/ioutil" +) + +// Team consists of a get response +// It's used in Add and Update API +type Team struct { + Id int64 `json:"id,omitempty"` + OrgId int64 `json:"orgId,omitempty"` + Name string `json:"name"` + Email string `json:"email,omitempty"` + AvatarUrl string `json:"avatarUrl,omitempty"` + MemberCount int64 `json:"memberCount,omitempty"` + Permission int64 `json:"permission,omitempty"` +} + +// TeamMember +type TeamMember struct { + OrgId int64 `json:"orgId,omitempty"` + TeamId int64 `json:"teamId,omitempty"` + UserId int64 `json:"userId,omitempty"` + Email string `json:"email,omitempty"` + Login string `json:"login,omitempty"` + AvatarUrl string `json:"avatarUrl,omitempty"` + Permission int64 `json:"permission,omitempty"` +} + +type Preferences struct { + Theme string `json:"theme"` + HomeDashboardId int64 `json:"homeDashboardId"` + Timezone string `json:"timezone"` +} + +func (c *Client) Team(id int64) (*Team, error) { + var team Team + + req, err := c.newRequest("GET", fmt.Sprintf("/api/teams/%d", id), nil, nil) + if err != nil { + return nil, err + } + resp, err := c.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, fmt.Errorf(resp.Status) + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if err := json.Unmarshal(data, &team); err != nil { + return nil, err + } + return &team, nil +} + +// AddTeam makes a new team +// email arg is an optional value. +// If you don't want to set email, please set "" (empty string). +func (c *Client) AddTeam(name string, email string) error { + path := fmt.Sprintf("/api/teams") + team := Team{ + Name: name, + Email: email, + } + data, err := json.Marshal(team) + if err != nil { + return err + } + req, err := c.newRequest("POST", path, nil, bytes.NewBuffer(data)) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return fmt.Errorf(resp.Status) + } + return nil +} + +func (c *Client) UpdateTeam(id int64, name string, email string) error { + path := fmt.Sprintf("/api/teams/%d", id) + team := Team{ + Name: name, + } + // add param if email exists + if email != "" { + team.Email = email + } + data, err := json.Marshal(team) + if err != nil { + return err + } + req, err := c.newRequest("PUT", path, nil, bytes.NewBuffer(data)) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return fmt.Errorf(resp.Status) + } + return nil +} + +func (c *Client) DeleteTeam(id int64) error { + req, err := c.newRequest("DELETE", fmt.Sprintf("/api/teams/%d", id), nil, nil) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return fmt.Errorf(resp.Status) + } + return nil +} + +func (c *Client) TeamMembers(id int64) ([]TeamMember, error) { + members := make([]TeamMember, 0) + + req, err := c.newRequest("GET", fmt.Sprintf("/api/teams/%d/members", id), nil, nil) + if err != nil { + return members, err + } + resp, err := c.Do(req) + if err != nil { + return members, err + } + if resp.StatusCode != 200 { + return members, fmt.Errorf(resp.Status) + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return members, err + } + if err := json.Unmarshal(data, &members); err != nil { + return members, err + } + return members, nil +} + +func (c *Client) AddTeamMember(id int64, userId int64) error { + path := fmt.Sprintf("/api/teams/%d/members", id) + member := TeamMember{UserId: userId} + data, err := json.Marshal(member) + if err != nil { + return err + } + req, err := c.newRequest("POST", path, nil, bytes.NewBuffer(data)) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return fmt.Errorf(resp.Status) + } + return nil +} + +func (c *Client) RemoveMemberFromTeam(id int64, userId int64) error { + path := fmt.Sprintf("/api/teams/%d/members/%d", id, userId) + + req, err := c.newRequest("DELETE", path, nil, nil) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return fmt.Errorf(resp.Status) + } + return nil +} + +func (c *Client) TeamPreferences(id int64) (*Preferences, error) { + var preferences Preferences + + req, err := c.newRequest("GET", fmt.Sprintf("/api/teams/%d/preferences", id), nil, nil) + if err != nil { + return nil, err + } + resp, err := c.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, fmt.Errorf(resp.Status) + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if err := json.Unmarshal(data, &preferences); err != nil { + return nil, err + } + return &preferences, nil +} + +func (c *Client) UpdateTeamPreferences(id int64, theme string, homeDashboardId int64, timezone string) error { + path := fmt.Sprintf("/api/teams/%d", id) + preferences := Preferences{ + Theme: theme, + HomeDashboardId: homeDashboardId, + Timezone: timezone, + } + data, err := json.Marshal(preferences) + if err != nil { + return err + } + req, err := c.newRequest("PUT", path, nil, bytes.NewBuffer(data)) + if err != nil { + return err + } + resp, err := c.Do(req) + if err != nil { + return err + } + if resp.StatusCode != 200 { + return fmt.Errorf(resp.Status) + } + return nil +} From 68e6f19b2767de352fe048ccac8ef80d379a209a Mon Sep 17 00:00:00 2001 From: ko-da-k Date: Wed, 29 Jan 2020 11:32:08 +0900 Subject: [PATCH 5/7] add search api --- team.go | 40 ++++++++++++++++++++++++++++++++++++ teams_test.go | 56 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/team.go b/team.go index b17b353..178615c 100644 --- a/team.go +++ b/team.go @@ -5,8 +5,16 @@ import ( "encoding/json" "fmt" "io/ioutil" + "net/url" ) +type SearchTeam struct { + TotalCount int64 `json:"totalCount,omitempty"` + Teams []Team `json:"teams,omitempty"` + Page int64 `json:"page,omitempty"` + PerPage int64 `json:"perPage,omitempty"` +} + // Team consists of a get response // It's used in Add and Update API type Team struct { @@ -36,6 +44,38 @@ type Preferences struct { Timezone string `json:"timezone"` } +func (c *Client) SearchTeam(query string) (*SearchTeam, error) { + var result SearchTeam + + page := "1" + perPage := "1000" + path := "/api/teams/search" + queryValues := url.Values{} + queryValues.Set("page", page) + queryValues.Set("perPage", perPage) + queryValues.Set("query", query) + + req, err := c.newRequest("GET", path, queryValues, nil) + if err != nil { + return nil, err + } + resp, err := c.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != 200 { + return nil, fmt.Errorf(resp.Status) + } + data, err := ioutil.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if err := json.Unmarshal(data, &result); err != nil { + return nil, err + } + return &result, nil +} + func (c *Client) Team(id int64) (*Team, error) { var team Team diff --git a/teams_test.go b/teams_test.go index 5adfa80..1b43198 100644 --- a/teams_test.go +++ b/teams_test.go @@ -6,6 +6,23 @@ import ( ) const ( + searchTeamJSON = ` +{ + "totalCount": 1, + "teams": [ + { + "id": 1, + "orgId": 1, + "name": "MyTestTeam", + "email": "", + "avatarUrl": "/avatar/3f49c15916554246daa714b9bd0ee398", + "memberCount": 1 + } + ], + "page": 1, + "perPage": 1000 +} +` getTeamJSON = ` { "id": 1, @@ -34,7 +51,7 @@ const ( "auth_module": "oauth_github", "email": "user1@email.com", "login": "user1", - "avatarUrl": "\/avatar\/1b3c32f6386b0185c40d359cdc733a79", + "avatarUrl": "/avatar/1b3c32f6386b0185c40d359cdc733a79", "labels": [], "permission": 0 }, @@ -45,7 +62,7 @@ const ( "auth_module": "oauth_github", "email": "user2@email.com", "login": "user2", - "avatarUrl": "\/avatar\/cad3c68da76e45d10269e8ef02f8e73e", + "avatarUrl": "/avatar/cad3c68da76e45d10269e8ef02f8e73e", "labels": [], "permission": 0 } @@ -71,6 +88,41 @@ const ( ` ) +func TestSearchTeam(t *testing.T) { + server, client := gapiTestTools(200, searchTeamJSON) + defer server.Close() + + query := "myteam" + resp, err := client.SearchTeam(query) + if err != nil { + t.Error(err) + } + + t.Log(pretty.PrettyFormat(resp)) + + expect := &SearchTeam{ + TotalCount: 1, + Teams: []Team{ + { + Id: 1, + OrgId: 1, + Name: "MyTestTeam", + Email: "", + AvatarUrl: "avatar/3f49c15916554246daa714b9bd0ee398", + MemberCount: 1, + Permission: 0, + }, + }, + Page: 1, + PerPage: 1000, + } + t.Run("check data", func(t *testing.T) { + if expect.TotalCount != resp.TotalCount || expect.Teams[0].Name != resp.Teams[0].Name { + t.Error("Not correctly data") + } + }) +} + func TestTeam(t *testing.T) { server, client := gapiTestTools(200, getTeamJSON) defer server.Close() From b5beb26cdbabc0657d2f436bc792450ee7cfa4a4 Mon Sep 17 00:00:00 2001 From: ko-da-k Date: Wed, 29 Jan 2020 18:33:51 +0900 Subject: [PATCH 6/7] use pointer --- team.go | 12 ++++++------ teams_test.go | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/team.go b/team.go index 178615c..1233854 100644 --- a/team.go +++ b/team.go @@ -9,10 +9,10 @@ import ( ) type SearchTeam struct { - TotalCount int64 `json:"totalCount,omitempty"` - Teams []Team `json:"teams,omitempty"` - Page int64 `json:"page,omitempty"` - PerPage int64 `json:"perPage,omitempty"` + TotalCount int64 `json:"totalCount,omitempty"` + Teams []*Team `json:"teams,omitempty"` + Page int64 `json:"page,omitempty"` + PerPage int64 `json:"perPage,omitempty"` } // Team consists of a get response @@ -169,8 +169,8 @@ func (c *Client) DeleteTeam(id int64) error { return nil } -func (c *Client) TeamMembers(id int64) ([]TeamMember, error) { - members := make([]TeamMember, 0) +func (c *Client) TeamMembers(id int64) ([]*TeamMember, error) { + members := make([]*TeamMember, 0) req, err := c.newRequest("GET", fmt.Sprintf("/api/teams/%d/members", id), nil, nil) if err != nil { diff --git a/teams_test.go b/teams_test.go index 1b43198..1863047 100644 --- a/teams_test.go +++ b/teams_test.go @@ -102,7 +102,7 @@ func TestSearchTeam(t *testing.T) { expect := &SearchTeam{ TotalCount: 1, - Teams: []Team{ + Teams: []*Team{ { Id: 1, OrgId: 1, @@ -200,7 +200,7 @@ func TestTeamMembers(t *testing.T) { if err != nil { t.Error(err) } - expects := []TeamMember{ + expects := []*TeamMember{ { OrgId: 1, TeamId: 1, From 0267d88500c971b04f8ac971266f0825cc231c0e Mon Sep 17 00:00:00 2001 From: Tony Li Date: Tue, 2 Jun 2020 01:10:52 -0700 Subject: [PATCH 7/7] Update teams_test.go --- teams_test.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/teams_test.go b/teams_test.go index 1863047..88b7249 100644 --- a/teams_test.go +++ b/teams_test.go @@ -40,7 +40,7 @@ const ( "teamId":2 } ` - updateTeamJSON = `{ "message":"Team updated"}` + updateTeamJSON = `{"message":"Team updated"}` deleteTeamJSON = `{"message":"Team deleted"}` getTeamMembersJSON = ` [ @@ -118,7 +118,7 @@ func TestSearchTeam(t *testing.T) { } t.Run("check data", func(t *testing.T) { if expect.TotalCount != resp.TotalCount || expect.Teams[0].Name != resp.Teams[0].Name { - t.Error("Not correctly data") + t.Error("Not correctly parsing returned team search.") } }) } @@ -146,7 +146,7 @@ func TestTeam(t *testing.T) { } t.Run("check data", func(t *testing.T) { if expect.Id != resp.Id || expect.Name != expect.Name { - t.Error("Not correctly data") + t.Error("Not correctly parsing returned team.") } }) } @@ -224,7 +224,7 @@ func TestTeamMembers(t *testing.T) { for i, expect := range expects { t.Run("check data", func(t *testing.T) { if expect.Email != resp[i].Email || expect.AvatarUrl != resp[i].AvatarUrl { - t.Error("Not correctly data") + t.Error("Not correctly parsing returned team members.") } }) } @@ -272,7 +272,7 @@ func TestTeamPreferences(t *testing.T) { t.Run("check data", func(t *testing.T) { if expect.Theme != resp.Theme || expect.HomeDashboardId != resp.HomeDashboardId { - t.Error("Not correctly data") + t.Error("Not correctly parsing returned team preferences.") } }) }