-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from latitudesh/PD-3584-SDK-Add-Account-endpoints
Add Accounts and Role endpoints
- Loading branch information
Showing
8 changed files
with
321 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
package latitude | ||
|
||
const userBasePath = "/user/profile" | ||
const userTeamsPath = "/user/teams" | ||
|
||
// UserService interface defines available Account methods | ||
type UserService interface { | ||
Get(*GetOptions) (*User, *Response, error) | ||
Update(string, *UserUpdateRequest) (*User, *Response, error) | ||
List(listOpt *ListOptions) ([]Team, *Response, error) | ||
} | ||
|
||
// UserServiceOp implements UserService | ||
type UserServiceOp struct { | ||
client requestDoer | ||
} | ||
|
||
type UserGetResponse struct { | ||
Data UserGetData `json:"data"` | ||
Meta meta `json:"meta"` | ||
} | ||
|
||
type UserGetData struct { | ||
ID string `json:"id"` | ||
Type string `json:"type"` | ||
Attributes UserAttributes `json:"attributes"` | ||
} | ||
|
||
type UserAttributes struct { | ||
FirstName string `json:"first_name"` | ||
LastName string `json:"last_name"` | ||
Email string `json:"email"` | ||
MfaEnabled bool `json:"mfa_enabled"` | ||
CreatedAt string `json:"created_at"` | ||
UpdatedAt string `json:"updated_at"` | ||
Role UserRole `json:"role"` | ||
} | ||
|
||
type UserUpdateRequest struct { | ||
Data UserUpdateData `json:"data"` | ||
} | ||
|
||
type UserUpdateData struct { | ||
ID string `json:"id"` | ||
Type string `json:"type"` | ||
Attributes UserUpdateAttributes `json:"attributes"` | ||
} | ||
|
||
type UserUpdateAttributes struct { | ||
FirstName string `json:"first_name"` | ||
LastName string `json:"last_name"` | ||
Role AvailableRole `json:"role"` | ||
AuthenticationFactorId string `json:"authentication_factor_id"` | ||
} | ||
|
||
type UserRole struct { | ||
Role | ||
createdAt string | ||
updatedAt string | ||
} | ||
|
||
type User struct { | ||
ID string `json:"id"` | ||
FirstName string `json:"first_name"` | ||
LastName string `json:"last_name"` | ||
Email string `json:"email"` | ||
MfaEnabled bool `json:"mfa_enabled"` | ||
CreatedAt string `json:"created_at"` | ||
UpdatedAt string `json:"updated_at"` | ||
Role string `json:"role"` | ||
} | ||
|
||
// Flatten latitude API data structure | ||
func NewFlatUser(md UserGetData) User { | ||
return User{ | ||
md.ID, | ||
md.Attributes.FirstName, | ||
md.Attributes.LastName, | ||
md.Attributes.Email, | ||
md.Attributes.MfaEnabled, | ||
md.Attributes.CreatedAt, | ||
md.Attributes.UpdatedAt, | ||
md.Attributes.Role.Name, | ||
} | ||
} | ||
|
||
// Get the current User profile | ||
func (s *UserServiceOp) Get(opts *GetOptions) (*User, *Response, error) { | ||
endpointPath := userBasePath | ||
apiPathQuery := opts.WithQuery(endpointPath) | ||
user := new(UserGetResponse) | ||
resp, err := s.client.DoRequest("GET", apiPathQuery, nil, user) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
flatUser := NewFlatUser(user.Data) | ||
return &flatUser, resp, err | ||
} | ||
|
||
// Update the User profile | ||
func (s *UserServiceOp) Update(id string, updateRequest *UserUpdateRequest) (*User, *Response, error) { | ||
apiPath := userBasePath | ||
user := new(UserGetResponse) | ||
|
||
resp, err := s.client.DoRequest("PATCH", apiPath, updateRequest, user) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
flatUser := NewFlatUser(user.Data) | ||
return &flatUser, resp, err | ||
} | ||
|
||
// List the current User teams | ||
func (s *UserServiceOp) List(opts *ListOptions) ([]Team, *Response, error) { | ||
apiPathQuery := userTeamsPath | ||
teams := []Team{} | ||
|
||
for { | ||
res := new(TeamGetResponse) | ||
|
||
resp, err := s.client.DoRequest("GET", apiPathQuery, nil, res) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
teams = append(teams, NewFlatTeamList(res.Data)...) | ||
|
||
if apiPathQuery = nextPage(res.Meta, opts); apiPathQuery != "" { | ||
continue | ||
} | ||
|
||
return teams, resp, nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package latitude | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestAccAccountsBasic(t *testing.T) { | ||
skipUnlessAcceptanceTestsAllowed(t) | ||
c, stopRecord := setup(t) | ||
defer stopRecord() | ||
|
||
t.Run("Get User Account", func(t *testing.T) { | ||
profile, _, err := c.Users.Get(nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if profile == nil { | ||
t.Fatal("Could not find user account") | ||
} | ||
}) | ||
|
||
t.Run("List user teams", func(t *testing.T) { | ||
teams, _, err := c.Users.List(nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if len(teams) < 1 { | ||
t.Fatal("Team must have at least a owner") | ||
} | ||
}) | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
package latitude | ||
|
||
import "path" | ||
|
||
const roleBasePath = "/roles" | ||
|
||
// RoleService interface defines available role methods | ||
type RoleService interface { | ||
Get(string, *GetOptions) (*Role, *Response, error) | ||
List(*ListOptions) ([]Role, *Response, error) | ||
} | ||
|
||
// RoleServiceOp implements RoleService | ||
type RoleServiceOp struct { | ||
client requestDoer | ||
} | ||
|
||
type AvailableRole string | ||
|
||
const ( | ||
Owner AvailableRole = "owner" | ||
Administrator AvailableRole = "administrator" | ||
Collaborator AvailableRole = "collaborator" | ||
Billing AvailableRole = "billing" | ||
) | ||
|
||
type RoleGetResponse struct { | ||
Data RoleData `json:"data"` | ||
Meta meta `json:"meta"` | ||
} | ||
|
||
type RoleData struct { | ||
ID string `json:"id"` | ||
Type string `json:"type"` | ||
Attributes RoleAttributes `json:"attributes"` | ||
} | ||
|
||
type RoleAttributes struct { | ||
Name string `json:"name"` | ||
} | ||
|
||
type RoleListResponse struct { | ||
Data []RoleData `json:"data"` | ||
Meta meta `json:"meta"` | ||
} | ||
|
||
type Role struct { | ||
ID string `json:"id"` | ||
Name string `json:"name"` | ||
} | ||
|
||
func NewFlatRole(rd RoleData) Role { | ||
return Role{ | ||
ID: rd.ID, | ||
Name: rd.Attributes.Name, | ||
} | ||
} | ||
|
||
func NewFlatRoleList(rd []RoleData) []Role { | ||
var res []Role | ||
for _, role := range rd { | ||
res = append(res, NewFlatRole(role)) | ||
} | ||
return res | ||
} | ||
|
||
func (s *RoleServiceOp) Get(RoleID string, opts *GetOptions) (*Role, *Response, error) { | ||
endpointPath := path.Join(roleBasePath, RoleID) | ||
apiPathQuery := opts.WithQuery(endpointPath) | ||
role := new(RoleGetResponse) | ||
resp, err := s.client.DoRequest("GET", apiPathQuery, nil, role) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
flatRole := NewFlatRole(role.Data) | ||
return &flatRole, resp, err | ||
} | ||
|
||
func (s *RoleServiceOp) List(opts *ListOptions) ([]Role, *Response, error) { | ||
apiPathQuery := opts.WithQuery(roleBasePath) | ||
roles := []Role{} | ||
|
||
for { | ||
res := new(RoleListResponse) | ||
|
||
resp, err := s.client.DoRequest("GET", apiPathQuery, nil, res) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
roles = append(roles, NewFlatRoleList(res.Data)...) | ||
|
||
if apiPathQuery = nextPage(res.Meta, opts); apiPathQuery != "" { | ||
continue | ||
} | ||
|
||
return roles, resp, nil | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package latitude | ||
|
||
import ( | ||
"testing" | ||
) | ||
|
||
func TestAccRolesBasic(t *testing.T) { | ||
skipUnlessAcceptanceTestsAllowed(t) | ||
c, stopRecord := setup(t) | ||
defer stopRecord() | ||
|
||
// List Roles | ||
roles, _, err := c.Roles.List(nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if len(roles) < 1 { | ||
t.Fatal("Team must have at least a role") | ||
} | ||
|
||
//Get Role | ||
role, _, err := c.Roles.Get(roles[0].ID, nil) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
// Check Role data | ||
if role.ID != roles[0].ID { | ||
t.Fatalf("Expected the id of the GOT role to be %s, not %s", roles[0].ID, role.ID) | ||
} | ||
if role.Name != roles[0].Name { | ||
t.Fatalf("Expected the line of the GOT plan to be %s, not %s", roles[0].Name, role.Name) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters