diff --git a/team.go b/team.go new file mode 100644 index 0000000..1233854 --- /dev/null +++ b/team.go @@ -0,0 +1,281 @@ +package gapi + +import ( + "bytes" + "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 { + 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) 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 + + 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 +} diff --git a/teams_test.go b/teams_test.go new file mode 100644 index 0000000..88b7249 --- /dev/null +++ b/teams_test.go @@ -0,0 +1,292 @@ +package gapi + +import ( + "github.com/gobs/pretty" + "testing" +) + +const ( + searchTeamJSON = ` +{ + "totalCount": 1, + "teams": [ + { + "id": 1, + "orgId": 1, + "name": "MyTestTeam", + "email": "", + "avatarUrl": "/avatar/3f49c15916554246daa714b9bd0ee398", + "memberCount": 1 + } + ], + "page": 1, + "perPage": 1000 +} +` + getTeamJSON = ` +{ + "id": 1, + "orgId": 1, + "name": "MyTestTeam", + "email": "", + "avatarUrl": "avatar/abcdef", + "memberCount": 1, + "permission": 0 +} +` + addTeamsJSON = ` +{ + "message":"Team created", + "teamId":2 +} +` + updateTeamJSON = `{"message":"Team updated"}` + deleteTeamJSON = `{"message":"Team deleted"}` + getTeamMembersJSON = ` +[ + { + "orgId": 1, + "teamId": 1, + "userId": 3, + "auth_module": "oauth_github", + "email": "user1@email.com", + "login": "user1", + "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", + "labels": [], + "permission": 0 + } +] +` + addTeamMemberJSON = ` +{ + "userId": 2 +} +` + removeMemberFromTeamJSON = `{"message":"Team Member removed"}` + getTeamPreferencesJSON = ` +{ + "theme": "", + "homeDashboardId": 0, + "timezone": "" +} +` + updateTeamPreferencesJSON = ` +{ + "message":"Preferences updated" +} +` +) + +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 parsing returned team search.") + } + }) +} + +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 parsing returned team.") + } + }) +} + +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, updateTeamJSON) + 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, deleteTeamJSON) + defer server.Close() + + id := int64(1) + + err := client.DeleteTeam(id) + if err != nil { + 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 parsing returned team members.") + } + }) + } +} + +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 parsing returned team preferences.") + } + }) +} + +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) + } +}