diff --git a/mockns1/account_activity.go b/mockns1/account_activity.go new file mode 100644 index 0000000..9c09709 --- /dev/null +++ b/mockns1/account_activity.go @@ -0,0 +1,21 @@ +package mockns1 + +import ( + "net/http" + + api "gopkg.in/ns1/ns1-go.v2/rest" + "gopkg.in/ns1/ns1-go.v2/rest/model/account" +) + +// AddActivityListTestCase sets up a test case for the api.Client.Activity.List() +// function +func (s *Service) AddActivityListTestCase( + requestHeaders, responseHeaders http.Header, + response []*account.Activity, + params ...api.Param, +) error { + return s.AddTestCase( + http.MethodGet, "/account/activity", http.StatusOK, requestHeaders, + responseHeaders, "", response, params..., + ) +} diff --git a/rest/_examples/account.go b/rest/_examples/account.go index a9ccacb..a8b0584 100644 --- a/rest/_examples/account.go +++ b/rest/_examples/account.go @@ -67,4 +67,14 @@ func main() { if _, err := client.APIKeys.Create(&key); err != nil { log.Fatal(err) } + + activity, _, err := client.Activity.List() + if err != nil { + log.Fatal(err) + } + + for _, a := range activity { + b, _ := json.MarshalIndent(a, "", " ") + fmt.Println(string(b)) + } } diff --git a/rest/account_activity.go b/rest/account_activity.go new file mode 100644 index 0000000..ed095f5 --- /dev/null +++ b/rest/account_activity.go @@ -0,0 +1,31 @@ +package rest + +import ( + "net/http" + + "gopkg.in/ns1/ns1-go.v2/rest/model/account" +) + +// ActivityService handles 'account/activity' endpoint. +type ActivityService service + +// List returns all activity in the account. It accepts a variadic number of +// optional URL parameters that can be used to edit the endpoint's behavior. +// Parameters are in the form of a `rest.Param` struct. The full list of valid +// parameters for this endpoint are available in the documentation. +// +// NS1 API docs: https://developer.ibm.com/apis/catalog/ns1--ibm-ns1-connect-api/api/API--ns1--ibm-ns1-connect-api#getActivity +func (s *ActivityService) List(params ...Param) ([]*account.Activity, *http.Response, error) { + req, err := s.client.NewRequest("GET", "account/activity", nil) + if err != nil { + return nil, nil, err + } + + al := []*account.Activity{} + resp, err := s.client.Do(req, &al, params...) + if err != nil { + return nil, resp, err + } + + return al, resp, nil +} diff --git a/rest/account_activity_test.go b/rest/account_activity_test.go new file mode 100644 index 0000000..5b8a745 --- /dev/null +++ b/rest/account_activity_test.go @@ -0,0 +1,91 @@ +package rest_test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/require" + "gopkg.in/ns1/ns1-go.v2/mockns1" + api "gopkg.in/ns1/ns1-go.v2/rest" + "gopkg.in/ns1/ns1-go.v2/rest/model/account" +) + +func TestActivity(t *testing.T) { + mock, doer, err := mockns1.New(t) + require.Nil(t, err) + defer mock.Shutdown() + client := api.NewClient(doer, api.SetEndpoint("https://"+mock.Address+"/v1/")) + + t.Run("List", func(t *testing.T) { + activity := []*account.Activity{ + { + UserID: "user-1", + ResourceID: "resource-id-1", + Timestamp: 567, + UserType: "apikey", + Action: "create", + UserName: "username-1", + ID: "id-1", + ResourceType: "record", + }, + { + UserID: "user-2", + ResourceID: "resource-id-2", + Timestamp: 567, + UserType: "apikey", + Action: "delete", + UserName: "username-2", + ID: "id-2", + ResourceType: "record", + }, + } + + t.Run("list default activity", func(t *testing.T) { + defer mock.ClearTestCases() + + require.Nil(t, mock.AddActivityListTestCase(nil, nil, activity)) + + respActivity, _, err := client.Activity.List() + require.Nil(t, err) + require.NotNil(t, respActivity) + require.Equal(t, len(activity), len(respActivity)) + + for i := range activity { + require.Equal(t, activity[i], respActivity[i], i) + } + }) + + t.Run("list most recent 1 activity", func(t *testing.T) { + defer mock.ClearTestCases() + + limit := 1 + params := []api.Param{{Key: "limit", Value: fmt.Sprintf("%d", limit)}} + + require.Nil(t, mock.AddActivityListTestCase(nil, nil, []*account.Activity{activity[0]}, params...)) + + respActivity, _, err := client.Activity.List(params...) + require.Nil(t, err) + require.NotNil(t, respActivity) + require.Equal(t, limit, len(respActivity)) + require.Equal(t, activity[0], respActivity[0]) + }) + + t.Run("list all dns record activity, multiple params", func(t *testing.T) { + defer mock.ClearTestCases() + + limit := 1000 + params := []api.Param{{Key: "limit", Value: fmt.Sprintf("%d", limit)}, {Key: "resource_type", Value: "record"}} + + require.Nil(t, mock.AddActivityListTestCase(nil, nil, activity, params...)) + + respActivity, _, err := client.Activity.List(params...) + require.Nil(t, err) + require.NotNil(t, respActivity) + require.Equal(t, len(activity), len(respActivity)) + + for i := range activity { + require.Equal(t, activity[i], respActivity[i], i) + } + }) + }) +} diff --git a/rest/client.go b/rest/client.go index 038b9d7..e8846f2 100644 --- a/rest/client.go +++ b/rest/client.go @@ -91,6 +91,7 @@ type Client struct { Network *NetworkService GlobalIPWhitelist *GlobalIPWhitelistService Datasets *DatasetsService + Activity *ActivityService } // NewClient constructs and returns a reference to an instantiated Client. @@ -139,6 +140,7 @@ func NewClient(httpClient Doer, options ...func(*Client)) *Client { c.Network = (*NetworkService)(&c.common) c.GlobalIPWhitelist = (*GlobalIPWhitelistService)(&c.common) c.Datasets = (*DatasetsService)(&c.common) + c.Activity = (*ActivityService)(&c.common) for _, option := range options { option(c) diff --git a/rest/model/account/activity.go b/rest/model/account/activity.go new file mode 100644 index 0000000..1427ecc --- /dev/null +++ b/rest/model/account/activity.go @@ -0,0 +1,13 @@ +package account + +// Activity wraps an NS1 /account/activity resource +type Activity struct { + UserID string `json:"user_id,omitempty"` + ResourceID string `json:"resource_id,omitempty"` + Timestamp int `json:"timestamp,omitempty"` + UserType string `json:"user_type,omitempty"` + Action string `json:"action,omitempty"` + UserName string `json:"user_name,omitempty"` + ID string `json:"id,omitempty"` + ResourceType string `json:"resource_type,omitempty"` +}