From a45fac194c96ed057cb54662da4886aa84c5bec4 Mon Sep 17 00:00:00 2001 From: Pawel Date: Sun, 19 Mar 2023 22:17:01 -0700 Subject: [PATCH 1/5] added API for listing project's teams --- client/paths.go | 3 +- client/project.go | 35 +++++++++++++-------- client/team.go | 76 ++++++++++++++++++++++----------------------- client/team_test.go | 43 ++++++++++++------------- 4 files changed, 84 insertions(+), 73 deletions(-) diff --git a/client/paths.go b/client/paths.go index 47720604..e0c4941d 100644 --- a/client/paths.go +++ b/client/paths.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Rollbar, Inc. + * Copyright (c) 2023 Rollbar, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ const ( pathProjectRead = "/api/1/project/{projectID}" pathProjectToken = "/api/1/project/{projectID}/access_token/{accessToken}" pathProjectTokens = "/api/1/project/{projectID}/access_tokens" + pathProjectTeams = "/api/1/project/{projectID}/teams" pathTeamCreate = "/api/1/teams" pathTeamRead = "/api/1/team/{teamID}" pathTeamList = "/api/1/teams" diff --git a/client/project.go b/client/project.go index 194adee0..f0be82cf 100644 --- a/client/project.go +++ b/client/project.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Rollbar, Inc. + * Copyright (c) 2023 Rollbar, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -23,8 +23,9 @@ package client import ( - "github.com/rs/zerolog/log" "strconv" + + "github.com/rs/zerolog/log" ) // Project represents a Rollbar project. @@ -212,22 +213,30 @@ func (c *RollbarAPIClient) FindProjectTeamIDs(projectID int) ([]int, error) { l.Debug().Msg("Finding teams assigned to project") var projectTeamIDs []int - allTeams, err := c.ListCustomTeams() + u := c.BaseURL + pathProjectTeams + resp, err := c.Resty.R(). + SetResult(teamProjectListResponse{}). + SetError(ErrorResult{}). + SetQueryParams(map[string]string{ + "exclude_builtin_teams": "true"}). + SetPathParams(map[string]string{ + "projectID": strconv.Itoa(projectID), + }). + Get(u) if err != nil { l.Err(err).Send() return nil, err } + err = errorFromResponse(resp) + if err != nil { + l.Err(err).Send() + return nil, err + } + allTeams := resp.Result().(*teamProjectListResponse).Result + for _, t := range allTeams { - teamID := t.ID - projectIDs, err := c.ListTeamProjectIDs(teamID) - if err != nil && err != ErrNotFound { - l.Err(err).Send() - return nil, err - } - for _, id := range projectIDs { - if id == projectID { - projectTeamIDs = append(projectTeamIDs, teamID) - } + if t.ProjectID == projectID { + projectTeamIDs = append(projectTeamIDs, t.TeamID) } } count := len(projectTeamIDs) diff --git a/client/team.go b/client/team.go index 0ac9da0f..1555d13e 100644 --- a/client/team.go +++ b/client/team.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Rollbar, Inc. + * Copyright (c) 2023 Rollbar, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -307,43 +307,43 @@ func (c *RollbarAPIClient) FindTeamID(name string) (int, error) { // ListTeamProjectIDs lists IDs of all Rollbar projects to which a given team is // assigned. -func (c *RollbarAPIClient) ListTeamProjectIDs(teamID int) ([]int, error) { - - projectIDs := []int{} - hasNextPage := true - page := 1 - - l := log.With().Int("teamID", teamID).Logger() - - for hasNextPage { - l.Debug().Msg(fmt.Sprintf("Listing projects for team (page: %d)", page)) - resp, err := c.Resty.R(). - SetPathParams(map[string]string{ - "teamID": strconv.Itoa(teamID), - }). - SetResult(teamProjectListResponse{}). - SetError(ErrorResult{}). - Get(c.BaseURL + pathTeamProjects + fmt.Sprintf("?page=%d", page)) - if err != nil { - l.Err(err).Msg("Error listing projects for team") - return nil, err - } - err = errorFromResponse(resp) - if err != nil { - l.Err(err).Msg("Error listing projects for team") - return nil, err - } - result := resp.Result().(*teamProjectListResponse).Result - l.Debug().Msg(fmt.Sprintf("%+v\n", result)) - hasNextPage = len(result) > 0 - for _, item := range result { - projectIDs = append(projectIDs, item.ProjectID) - } - page++ - } - l.Debug().Msg("Successfully listed projects for team") - return projectIDs, nil -} +//func (c *RollbarAPIClient) ListTeamProjectIDs(teamID int) ([]int, error) { +// +// projectIDs := []int{} +// hasNextPage := true +// page := 1 +// +// l := log.With().Int("teamID", teamID).Logger() +// +// for hasNextPage { +// l.Debug().Msg(fmt.Sprintf("Listing projects for team (page: %d)", page)) +// resp, err := c.Resty.R(). +// SetPathParams(map[string]string{ +// "teamID": strconv.Itoa(teamID), +// }). +// SetResult(teamProjectListResponse{}). +// SetError(ErrorResult{}). +// Get(c.BaseURL + pathTeamProjects + fmt.Sprintf("?page=%d", page)) +// if err != nil { +// l.Err(err).Msg("Error listing projects for team") +// return nil, err +// } +// err = errorFromResponse(resp) +// if err != nil { +// l.Err(err).Msg("Error listing projects for team") +// return nil, err +// } +// result := resp.Result().(*teamProjectListResponse).Result +// l.Debug().Msg(fmt.Sprintf("%+v\n", result)) +// hasNextPage = len(result) > 0 +// for _, item := range result { +// projectIDs = append(projectIDs, item.ProjectID) +// } +// page++ +// } +// l.Debug().Msg("Successfully listed projects for team") +// return projectIDs, nil +//} // AssignTeamToProject assigns a Rollbar team to a project. func (c *RollbarAPIClient) AssignTeamToProject(teamID, projectID int) error { diff --git a/client/team_test.go b/client/team_test.go index f9293f13..35a48f54 100644 --- a/client/team_test.go +++ b/client/team_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020 Rollbar, Inc. + * Copyright (c) 2023 Rollbar, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,10 +24,11 @@ package client import ( "encoding/json" - "github.com/jarcoal/httpmock" "net/http" "strconv" "strings" + + "github.com/jarcoal/httpmock" ) func (s *Suite) TestCreateTeam() { @@ -296,25 +297,25 @@ func (s *Suite) TestFindTeamID() { }) } -func (s *Suite) TestListTeamProjects() { - teamID := 689492 - expected := []int{423092} - u := s.client.BaseURL + pathTeamProjects - u = strings.ReplaceAll(u, "{teamID}", strconv.Itoa(teamID)) - r := responderFromFixture("team/list_projects_689492.json", http.StatusOK) - httpmock.RegisterResponder("GET", u+"?page=1", r) - r = responderFromFixture("team/list_projects_689493.json", http.StatusOK) - httpmock.RegisterResponder("GET", u+"?page=2", r) - - actual, err := s.client.ListTeamProjectIDs(teamID) - s.Nil(err) - s.Equal(expected, actual) - - s.checkServerErrors("GET", u+"?page=1", func() error { - _, err := s.client.ListTeamProjectIDs(teamID) - return err - }) -} +//func (s *Suite) TestListTeamProjects() { +// teamID := 689492 +// expected := []int{423092} +// u := s.client.BaseURL + pathTeamProjects +// u = strings.ReplaceAll(u, "{teamID}", strconv.Itoa(teamID)) +// r := responderFromFixture("team/list_projects_689492.json", http.StatusOK) +// httpmock.RegisterResponder("GET", u+"?page=1", r) +// r = responderFromFixture("team/list_projects_689493.json", http.StatusOK) +// httpmock.RegisterResponder("GET", u+"?page=2", r) +// +// actual, err := s.client.ListTeamProjectIDs(teamID) +// s.Nil(err) +// s.Equal(expected, actual) +// +// s.checkServerErrors("GET", u+"?page=1", func() error { +// _, err := s.client.ListTeamProjectIDs(teamID) +// return err +// }) +//} // TestAssignTeamToProject tests assigning a Rollbar team to a project. func (s *Suite) TestAssignTeamToProject() { From e19e83ecd8e05d4cba63e99e0a5d8b3c95bb6bd6 Mon Sep 17 00:00:00 2001 From: Pawel Date: Sun, 19 Mar 2023 22:28:10 -0700 Subject: [PATCH 2/5] cleanup linters --- client/paths.go | 1 - client/project_test.go | 61 +++++------------------------------------- client/team_test.go | 20 -------------- 3 files changed, 6 insertions(+), 76 deletions(-) diff --git a/client/paths.go b/client/paths.go index e0c4941d..7a1e8c0f 100644 --- a/client/paths.go +++ b/client/paths.go @@ -37,7 +37,6 @@ const ( pathTeamDelete = "/api/1/team/{teamID}" pathTeamUser = "/api/1/team/{teamID}/user/{userID}" pathTeamProject = "/api/1/team/{teamID}/project/{projectID}" - pathTeamProjects = "/api/1/team/{teamID}/projects" pathUser = "/api/1/user/{userID}" pathUserTeams = "/api/1/user/{userID}/teams" pathUsers = "/api/1/users" diff --git a/client/project_test.go b/client/project_test.go index 2542e86d..3e9091a6 100644 --- a/client/project_test.go +++ b/client/project_test.go @@ -24,16 +24,17 @@ package client import ( "encoding/json" - "github.com/brianvoe/gofakeit/v5" - "github.com/dnaeon/go-vcr/cassette" - "github.com/dnaeon/go-vcr/recorder" - "github.com/jarcoal/httpmock" - "github.com/stretchr/testify/assert" "net/http" "os" "strconv" "strings" "testing" + + "github.com/brianvoe/gofakeit/v5" + "github.com/dnaeon/go-vcr/cassette" + "github.com/dnaeon/go-vcr/recorder" + "github.com/jarcoal/httpmock" + "github.com/stretchr/testify/assert" ) // TestListProjects tests listing Rollbar projects. @@ -148,56 +149,6 @@ func (s *Suite) TestDeleteProject() { }) } -// TestFindProjectTeamIDs tests finding the team IDs for a Rollbar project. -func (s *Suite) TestFindProjectTeamIDs() { - var u string // URL - var r httpmock.Responder - projectID := 423092 - teamID := 689492 - expected := []int{teamID} - // https://api.rollbar.com/api/1/team/689493/projects?page=1 - // Mock list team projects - u = s.client.BaseURL + pathTeamProjects - u = strings.ReplaceAll(u, "{teamID}", strconv.Itoa(teamID)) - r = responderFromFixture("team/list_projects_689492.json", http.StatusOK) - httpmock.RegisterResponderWithQuery("GET", u, "page=1", r) - u = s.client.BaseURL + pathTeamProjects - u = strings.ReplaceAll(u, "{teamID}", strconv.Itoa(teamID)) - r = responderFromFixture("team/list_projects_689493.json", http.StatusOK) - httpmock.RegisterResponderWithQuery("GET", u, "page=2", r) - - u = s.client.BaseURL + pathTeamProjects - u = strings.ReplaceAll(u, "{teamID}", "689493") - r = responderFromFixture("team/list_projects_689493.json", http.StatusOK) - httpmock.RegisterResponderWithQuery("GET", u, "page=1", r) - - // Mock list teams - u = s.client.BaseURL + pathTeamList - r = responderFromFixture("team/list_2.json", http.StatusOK) - httpmock.RegisterResponder("GET", u, r) - - actual, err := s.client.FindProjectTeamIDs(projectID) - s.Nil(err) - s.Equal(expected, actual) - - expectedCallCount := - map[string]int{ - "GET https://api.rollbar.com/api/1/team/689492/projects?page=1": 1, - "GET https://api.rollbar.com/api/1/team/689492/projects?page=2": 1, - "GET https://api.rollbar.com/api/1/team/689493/projects?page=1": 1, - "GET https://api.rollbar.com/api/1/teams": 1, - } - actualCallCount := httpmock.GetCallCountInfo() - for call, count := range expectedCallCount { - s.Equal(count, actualCallCount[call]) - } - - s.checkServerErrors("GET", u, func() error { - _, err := s.client.FindProjectTeamIDs(projectID) - return err - }) -} - // TestUpdateProjectTeams tests updating the set of teams attached to a Rollbar // project. func TestUpdateProjectTeams(t *testing.T) { diff --git a/client/team_test.go b/client/team_test.go index 35a48f54..ab6c5f3e 100644 --- a/client/team_test.go +++ b/client/team_test.go @@ -297,26 +297,6 @@ func (s *Suite) TestFindTeamID() { }) } -//func (s *Suite) TestListTeamProjects() { -// teamID := 689492 -// expected := []int{423092} -// u := s.client.BaseURL + pathTeamProjects -// u = strings.ReplaceAll(u, "{teamID}", strconv.Itoa(teamID)) -// r := responderFromFixture("team/list_projects_689492.json", http.StatusOK) -// httpmock.RegisterResponder("GET", u+"?page=1", r) -// r = responderFromFixture("team/list_projects_689493.json", http.StatusOK) -// httpmock.RegisterResponder("GET", u+"?page=2", r) -// -// actual, err := s.client.ListTeamProjectIDs(teamID) -// s.Nil(err) -// s.Equal(expected, actual) -// -// s.checkServerErrors("GET", u+"?page=1", func() error { -// _, err := s.client.ListTeamProjectIDs(teamID) -// return err -// }) -//} - // TestAssignTeamToProject tests assigning a Rollbar team to a project. func (s *Suite) TestAssignTeamToProject() { teamID := 689492 From 60bbd42e2de078ab5dbf162dc5f364795d5184a7 Mon Sep 17 00:00:00 2001 From: Pawel Date: Sun, 19 Mar 2023 22:30:30 -0700 Subject: [PATCH 3/5] fix linters --- client/team.go | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/client/team.go b/client/team.go index 1555d13e..48bdfa22 100644 --- a/client/team.go +++ b/client/team.go @@ -305,46 +305,6 @@ func (c *RollbarAPIClient) FindTeamID(name string) (int, error) { return 0, ErrNotFound } -// ListTeamProjectIDs lists IDs of all Rollbar projects to which a given team is -// assigned. -//func (c *RollbarAPIClient) ListTeamProjectIDs(teamID int) ([]int, error) { -// -// projectIDs := []int{} -// hasNextPage := true -// page := 1 -// -// l := log.With().Int("teamID", teamID).Logger() -// -// for hasNextPage { -// l.Debug().Msg(fmt.Sprintf("Listing projects for team (page: %d)", page)) -// resp, err := c.Resty.R(). -// SetPathParams(map[string]string{ -// "teamID": strconv.Itoa(teamID), -// }). -// SetResult(teamProjectListResponse{}). -// SetError(ErrorResult{}). -// Get(c.BaseURL + pathTeamProjects + fmt.Sprintf("?page=%d", page)) -// if err != nil { -// l.Err(err).Msg("Error listing projects for team") -// return nil, err -// } -// err = errorFromResponse(resp) -// if err != nil { -// l.Err(err).Msg("Error listing projects for team") -// return nil, err -// } -// result := resp.Result().(*teamProjectListResponse).Result -// l.Debug().Msg(fmt.Sprintf("%+v\n", result)) -// hasNextPage = len(result) > 0 -// for _, item := range result { -// projectIDs = append(projectIDs, item.ProjectID) -// } -// page++ -// } -// l.Debug().Msg("Successfully listed projects for team") -// return projectIDs, nil -//} - // AssignTeamToProject assigns a Rollbar team to a project. func (c *RollbarAPIClient) AssignTeamToProject(teamID, projectID int) error { l := log.With(). From 988984b20d1fa9b3133769f69bbfe6f3ae6e7f7a Mon Sep 17 00:00:00 2001 From: Pawel Date: Sun, 19 Mar 2023 23:56:22 -0700 Subject: [PATCH 4/5] adjust tape --- client/fixtures/vcr/update_project_teams.yaml | 209 ++++++++++++++---- 1 file changed, 170 insertions(+), 39 deletions(-) diff --git a/client/fixtures/vcr/update_project_teams.yaml b/client/fixtures/vcr/update_project_teams.yaml index cccafa8a..0b1afa94 100644 --- a/client/fixtures/vcr/update_project_teams.yaml +++ b/client/fixtures/vcr/update_project_teams.yaml @@ -315,7 +315,7 @@ interactions: headers: User-Agent: - go-resty/2.3.0 (https://github.com/go-resty/resty) - url: https://api.rollbar.com/api/1/teams + url: https://api.rollbar.com/api/1/project/423511/teams?exclude_builtin_teams=true method: GET response: body: |- @@ -323,46 +323,12 @@ interactions: "err": 0, "result": [ { - "id": 689493, - "account_id": 317418, - "name": "bar", - "access_level": "standard" - }, - { - "id": 662037, - "account_id": 317418, - "name": "Everyone", - "access_level": "everyone" - }, - { - "id": 689492, - "account_id": 317418, - "name": "foo", - "access_level": "standard" - }, - { - "id": 662036, - "account_id": 317418, - "name": "Owners", - "access_level": "owner" + "team_id": 693607, + "project_id": 423511 }, { - "id": 693606, - "account_id": 317418, - "name": "tf-acc-test-updateprojectteams-0", - "access_level": "standard" - }, - { - "id": 693607, - "account_id": 317418, - "name": "tf-acc-test-updateprojectteams-1", - "access_level": "standard" - }, - { - "id": 693608, - "account_id": 317418, - "name": "tf-acc-test-updateprojectteams-2", - "access_level": "standard" + "team_id": 693608, + "project_id": 423511 } ] } @@ -398,6 +364,171 @@ interactions: status: 200 OK code: 200 duration: "" +- request: + body: "" + form: {} + headers: + User-Agent: + - go-resty/2.3.0 (https://github.com/go-resty/resty) + url: https://api.rollbar.com/api/1/project/423511/teams?exclude_builtin_teams=true + method: GET + response: + body: |- + { + "err": 0, + "result": [ + { + "team_id": 693607, + "project_id": 423511 + }, + { + "team_id": 693608, + "project_id": 423511 + } + ] + } + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Origin: + - '*' + Alt-Svc: + - clear + Content-Length: + - "929" + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 11 Nov 2020 09:14:52 GMT + Etag: + - '"-271558731"' + Server: + - nginx/1.17.9 + Via: + - 1.1 google + X-Rate-Limit-Limit: + - "5000" + X-Rate-Limit-Remaining: + - "4993" + X-Rate-Limit-Remaining-Seconds: + - "55" + X-Rate-Limit-Reset: + - "1605086147" + X-Response-Time: + - 10ms + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + User-Agent: + - go-resty/2.3.0 (https://github.com/go-resty/resty) + url: https://api.rollbar.com/api/1/project/0/teams?exclude_builtin_teams=true + method: GET + response: + body: |- + { + "err": 0, + "result": [ + { + "team_id": 693607, + "project_id": 423511 + }, + { + "team_id": 693608, + "project_id": 423511 + } + ] + } + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Origin: + - '*' + Alt-Svc: + - clear + Content-Length: + - "929" + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 11 Nov 2020 09:14:52 GMT + Etag: + - '"-271558731"' + Server: + - nginx/1.17.9 + Via: + - 1.1 google + X-Rate-Limit-Limit: + - "5000" + X-Rate-Limit-Remaining: + - "4993" + X-Rate-Limit-Remaining-Seconds: + - "55" + X-Rate-Limit-Reset: + - "1605086147" + X-Response-Time: + - 10ms + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + User-Agent: + - go-resty/2.3.0 (https://github.com/go-resty/resty) + url: https://api.rollbar.com/api/1/project/423511/teams?exclude_builtin_teams=true + method: GET + response: + body: |- + { + "err": 0, + "result": [ + { + "team_id": 693607, + "project_id": 423511 + }, + { + "team_id": 693608, + "project_id": 423511 + } + ] + } + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Origin: + - '*' + Alt-Svc: + - clear + Content-Length: + - "929" + Content-Type: + - application/json; charset=utf-8 + Date: + - Wed, 11 Nov 2020 09:14:52 GMT + Etag: + - '"-271558731"' + Server: + - nginx/1.17.9 + Via: + - 1.1 google + X-Rate-Limit-Limit: + - "5000" + X-Rate-Limit-Remaining: + - "4993" + X-Rate-Limit-Remaining-Seconds: + - "55" + X-Rate-Limit-Reset: + - "1605086147" + X-Response-Time: + - 10ms + status: 200 OK + code: 200 + duration: "" - request: body: "" form: {} From e19795b43d9fb22db59e4382f9372b6389998eea Mon Sep 17 00:00:00 2001 From: Pawel Date: Mon, 20 Mar 2023 00:08:06 -0700 Subject: [PATCH 5/5] reflecting bad output --- client/fixtures/vcr/update_project_teams.yaml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/client/fixtures/vcr/update_project_teams.yaml b/client/fixtures/vcr/update_project_teams.yaml index 0b1afa94..de2e2dac 100644 --- a/client/fixtures/vcr/update_project_teams.yaml +++ b/client/fixtures/vcr/update_project_teams.yaml @@ -430,17 +430,8 @@ interactions: response: body: |- { - "err": 0, - "result": [ - { - "team_id": 693607, - "project_id": 423511 - }, - { - "team_id": 693608, - "project_id": 423511 - } - ] + "err": 1, + "message": "Invalid or missing project id" } headers: Access-Control-Allow-Credentials: