Refactor teams API package

This commit is contained in:
Murat Kabilov
2017-05-30 10:14:30 +02:00
committed by GitHub
parent f7aaf8863d
commit 1fb05212a9
5 changed files with 222 additions and 41 deletions
+7 -19
View File
@@ -38,34 +38,22 @@ type Team struct {
}
type API struct {
url string
httpClient *http.Client
logger *logrus.Entry
RefreshTokenAction func() (string, error)
enabled bool
url string
httpClient *http.Client
logger *logrus.Entry
}
func NewTeamsAPI(url string, log *logrus.Logger, enabled bool) *API {
func NewTeamsAPI(url string, log *logrus.Logger) *API {
t := API{
url: strings.TrimRight(url, "/"),
httpClient: &http.Client{},
logger: log.WithField("pkg", "teamsapi"),
enabled: enabled,
}
return &t
}
func (t *API) TeamInfo(teamID string) (*Team, error) {
// TODO: avoid getting a new token on every call to the Teams API.
if !t.enabled {
t.logger.Debug("Team API is disabled, returning empty list of members")
return &Team{}, nil
}
token, err := t.RefreshTokenAction()
if err != nil {
return nil, err
}
func (t *API) TeamInfo(teamID, token string) (*Team, error) {
url := fmt.Sprintf("%s/teams/%s", t.url, teamID)
t.logger.Debugf("Request url: %s", url)
req, err := http.NewRequest("GET", url, nil)
@@ -84,7 +72,7 @@ func (t *API) TeamInfo(teamID string) (*Team, error) {
d := json.NewDecoder(resp.Body)
err = d.Decode(&raw)
if err != nil {
return nil, err
return nil, fmt.Errorf("team API query failed with status code %d and malformed response: %v", resp.StatusCode, err)
}
if errMessage, ok := raw["error"]; ok {
@@ -97,7 +85,7 @@ func (t *API) TeamInfo(teamID string) (*Team, error) {
d := json.NewDecoder(resp.Body)
err = d.Decode(teamInfo)
if err != nil {
return nil, err
return nil, fmt.Errorf("could not parse team API response: %v", err)
}
return teamInfo, nil
+182
View File
@@ -0,0 +1,182 @@
package teams
import (
"fmt"
"github.com/Sirupsen/logrus"
"net/http"
"net/http/httptest"
"reflect"
"testing"
)
var (
logger = logrus.New()
token = "ec45b1cfbe7100c6315d183a3eb6cec0M2U1LWJkMzEtZDgzNzNmZGQyNGM3IiwiYXV0aF90aW1lIjoxNDkzNzMwNzQ1LCJpc3MiOiJodHRwcz"
)
var teamsAPItc = []struct {
in string
inCode int
out *Team
err error
}{
{`{
"dn": "cn=100100,ou=official,ou=foobar,dc=zalando,dc=net",
"id": "acid",
"id_name": "ACID",
"team_id": "111222",
"type": "official",
"name": "Acid team name",
"mail": [
"email1@example.com",
"email2@example.com"
],
"alias": [
"acid"
],
"member": [
"member1",
"member2",
"member3"
],
"infrastructure-accounts": [
{
"id": "1234512345",
"name": "acid",
"provider": "aws",
"type": "aws",
"description": "",
"owner": "acid",
"owner_dn": "cn=100100,ou=official,ou=foobar,dc=zalando,dc=net",
"disabled": false
},
{
"id": "5432154321",
"name": "db",
"provider": "aws",
"type": "aws",
"description": "",
"owner": "acid",
"owner_dn": "cn=100100,ou=official,ou=foobar,dc=zalando,dc=net",
"disabled": false
}
],
"cost_center": "00099999",
"delivery_lead": "member4",
"parent_team_id": "111221"
}`,
200,
&Team{
Dn: "cn=100100,ou=official,ou=foobar,dc=zalando,dc=net",
ID: "acid",
TeamName: "ACID",
TeamID: "111222",
Type: "official",
FullName: "Acid team name",
Aliases: []string{"acid"},
Mails: []string{"email1@example.com", "email2@example.com"},
Members: []string{"member1", "member2", "member3"},
CostCenter: "00099999",
DeliveryLead: "member4",
ParentTeamID: "111221",
InfrastructureAccounts: []InfrastructureAccount{
{
ID: "1234512345",
Name: "acid",
Provider: "aws",
Type: "aws",
Description: "",
Owner: "acid",
OwnerDn: "cn=100100,ou=official,ou=foobar,dc=zalando,dc=net",
Disabled: false},
{
ID: "5432154321",
Name: "db",
Provider: "aws",
Type: "aws",
Description: "",
Owner: "acid",
OwnerDn: "cn=100100,ou=official,ou=foobar,dc=zalando,dc=net",
Disabled: false},
},
},
nil}, {
`{"error": "Access Token not valid"}`,
401,
nil,
fmt.Errorf(`team API query failed with status code 401 and message: '"Access Token not valid"'`),
},
{
`{"status": "I'm a teapot'"}`,
418,
nil,
fmt.Errorf(`team API query failed with status code 418`),
},
{
`{"status": "I'm a teapot`,
418,
nil,
fmt.Errorf(`team API query failed with status code 418 and malformed response: unexpected EOF`),
},
{
`{"status": "I'm a teapot`,
200,
nil,
fmt.Errorf(`could not parse team API response: unexpected EOF`),
},
}
var requestsURLtc = []struct {
url string
err error
}{
{
"coffee://localhost/",
fmt.Errorf(`Get coffee://localhost/teams/acid: unsupported protocol scheme "coffee"`),
},
{
"http://192.168.0.%31/",
fmt.Errorf(`parse http://192.168.0.%%31/teams/acid: invalid URL escape "%%31"`),
},
}
func TestInfo(t *testing.T) {
for _, tc := range teamsAPItc {
func() {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer " + token {
t.Errorf("Authorization token is wrong or not provided")
}
w.WriteHeader(tc.inCode)
fmt.Fprint(w, tc.in)
}))
defer ts.Close()
api := NewTeamsAPI(ts.URL, logger)
actual, err := api.TeamInfo("acid", token)
if err != nil && err.Error() != tc.err.Error() {
t.Errorf("Expected error: %v, got: %v", tc.err, err)
return
}
if !reflect.DeepEqual(actual, tc.out) {
t.Errorf("Expected %#v, got: %#v", tc.out, actual)
}
}()
}
}
func TestRequest(t *testing.T) {
for _, tc := range requestsURLtc {
api := NewTeamsAPI(tc.url, logger)
resp, err := api.TeamInfo("acid", token)
if resp != nil {
t.Errorf("Response expected to be nil")
continue
}
if err.Error() != tc.err.Error() {
t.Errorf("Expected error: %v, got: %v", tc.err, err)
}
}
}