diff --git a/selvpcclient/resell/v2/users/doc.go b/selvpcclient/resell/v2/users/doc.go new file mode 100644 index 0000000..43147ca --- /dev/null +++ b/selvpcclient/resell/v2/users/doc.go @@ -0,0 +1,15 @@ +/* +Package users provides the ability to retrieve and manage users through the +Resell v2 API. + +Example of getting all users + + allUsers, _, err := users.List(ctx, resellClient) + if err != nil { + log.Fatal(err) + } + for _, user := range allUsers { + fmt.Println(user) + } +*/ +package users diff --git a/selvpcclient/resell/v2/users/requests.go b/selvpcclient/resell/v2/users/requests.go new file mode 100644 index 0000000..1dbad0d --- /dev/null +++ b/selvpcclient/resell/v2/users/requests.go @@ -0,0 +1,33 @@ +package users + +import ( + "context" + "strings" + + "github.com/selectel/go-selvpcclient/selvpcclient" +) + +const resourceURL = "users" + +// List gets a list of users in the current domain. +func List(ctx context.Context, client *selvpcclient.ServiceClient) ([]*User, *selvpcclient.ResponseResult, error) { + url := strings.Join([]string{client.Endpoint, resourceURL}, "/") + responseResult, err := client.DoRequest(ctx, "GET", url, nil) + if err != nil { + return nil, nil, err + } + if responseResult.Err != nil { + return nil, responseResult, responseResult.Err + } + + // Extract users from the response body. + var result struct { + Users []*User `json:"users"` + } + err = responseResult.ExtractResult(&result) + if err != nil { + return nil, responseResult, err + } + + return result.Users, responseResult, nil +} diff --git a/selvpcclient/resell/v2/users/schemas.go b/selvpcclient/resell/v2/users/schemas.go new file mode 100644 index 0000000..26d78be --- /dev/null +++ b/selvpcclient/resell/v2/users/schemas.go @@ -0,0 +1,13 @@ +package users + +// User represents a single user of a Resell project. +type User struct { + // ID is a unique id of a user. + ID string `json:"id"` + + // Name represents the name of a user. + Name string `json:"name"` + + // Enabled shows if user is active or it was disabled. + Enabled bool `json:"enabled"` +} diff --git a/selvpcclient/resell/v2/users/testing/fixtures.go b/selvpcclient/resell/v2/users/testing/fixtures.go new file mode 100644 index 0000000..c1a92cb --- /dev/null +++ b/selvpcclient/resell/v2/users/testing/fixtures.go @@ -0,0 +1,43 @@ +package testing + +import "github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/users" + +// TestListUsersResponseRaw represents a raw response from the List request. +const TestListUsersResponseRaw = ` +{ + "users": [ + { + "enabled": false, + "id": "c4b7e0581b964c52a1597fe0931eccdf", + "name": "User2" + }, + { + "enabled": true, + "id": "4b2e452ed4c940bd87a88499eaf14c4f", + "name": "User1" + } + ] +} +` + +// TestListUsersSingleUserResponseRaw represents a raw response with a single user from the List request. +const TestListUsersSingleUserResponseRaw = ` +{ + "users": [ + { + "enabled": true, + "id": "4b2e452ed4c940bd87a88499eaf14c4f", + "name": "User1" + } + ] +} +` + +// TestListUsersSingleUserResponse represents the unmarshalled TestListUsersSingleUserResponseRaw response. +var TestListUsersSingleUserResponse = []*users.User{ + { + Enabled: true, + Name: "User1", + ID: "4b2e452ed4c940bd87a88499eaf14c4f", + }, +} diff --git a/selvpcclient/resell/v2/users/testing/requests_test.go b/selvpcclient/resell/v2/users/testing/requests_test.go new file mode 100644 index 0000000..3fe1318 --- /dev/null +++ b/selvpcclient/resell/v2/users/testing/requests_test.go @@ -0,0 +1,61 @@ +package testing + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" + + "github.com/selectel/go-selvpcclient/selvpcclient/resell/v2/users" + "github.com/selectel/go-selvpcclient/selvpcclient/testutils" +) + +func TestListUsers(t *testing.T) { + testEnv := testutils.SetupTestEnv() + defer testEnv.TearDownTestEnv() + testEnv.NewTestResellV2Client() + testEnv.Mux.HandleFunc("/resell/v2/users", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, TestListUsersResponseRaw) + }) + + ctx := context.Background() + actual, _, err := users.List(ctx, testEnv.Client) + if err != nil { + t.Fatal(err) + } + + if actual == nil { + t.Fatal("didn't get users") + } + actualKind := reflect.TypeOf(actual).Kind() + if actualKind != reflect.Slice { + t.Errorf("expected slice of pointers to users, but got %v", actualKind) + } + if len(actual) != 2 { + t.Errorf("expected 2 users, but got %d", len(actual)) + } +} + +func TestListUsersSingle(t *testing.T) { + testEnv := testutils.SetupTestEnv() + defer testEnv.TearDownTestEnv() + testEnv.NewTestResellV2Client() + testEnv.Mux.HandleFunc("/resell/v2/users", func(w http.ResponseWriter, r *http.Request) { + w.Header().Add("Content-Type", "application/json") + fmt.Fprintf(w, TestListUsersSingleUserResponseRaw) + }) + + ctx := context.Background() + actual, _, err := users.List(ctx, testEnv.Client) + if err != nil { + t.Fatal(err) + } + + expected := TestListUsersSingleUserResponse + + if !reflect.DeepEqual(actual, expected) { + t.Fatalf("expected %#v, but got %#v", expected, actual) + } +}