Skip to content

Commit

Permalink
CLOUDP-238932: Validate maxDate and minDate before running command (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
blva committed Mar 22, 2024
1 parent fd1b38c commit 869f069
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 48 deletions.
70 changes: 49 additions & 21 deletions internal/cli/atlas/events/list.go
Expand Up @@ -17,6 +17,7 @@ package events
import (
"context"
"fmt"
"time"

"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/require"
Expand Down Expand Up @@ -62,33 +63,43 @@ func (opts *ListOpts) Run() error {
var err error

if opts.orgID != "" {
listEventsAPIParams := opts.NewOrgListOptions()
r, err = opts.store.OrganizationEvents(&listEventsAPIParams)
listEventsAPIParams, lErr := opts.NewOrgListOptions()
if lErr != nil {
return lErr
}

if r, err = opts.store.OrganizationEvents(listEventsAPIParams); err != nil {
return err
}
} else if opts.projectID != "" {
listEventsAPIParams := opts.NewProjectListOptions()
r, err = opts.store.ProjectEvents(&listEventsAPIParams)
}
if err != nil {
return err
listEventsAPIParams, lErr := opts.NewProjectListOptions()
if lErr != nil {
return lErr
}
if r, err = opts.store.ProjectEvents(listEventsAPIParams); err != nil {
return err
}
}

return opts.Print(r)
}

func (opts *ListOpts) NewOrgListOptions() admin.ListOrganizationEventsApiParams {
func (opts *ListOpts) NewOrgListOptions() (*admin.ListOrganizationEventsApiParams, error) {
var eventType *[]string
var err error

if len(opts.EventType) > 0 {
eventType = &opts.EventType
}
p := admin.ListOrganizationEventsApiParams{
p := &admin.ListOrganizationEventsApiParams{
OrgId: opts.orgID,
EventType: eventType,
}
if maxDate, err := convert.ParseTimestamp(opts.MaxDate); err == nil {
p.MaxDate = pointer.Get(maxDate)
if p.MaxDate, err = parseDate(opts.MaxDate); err != nil {
return p, err
}
if minDate, err := convert.ParseTimestamp(opts.MinDate); err == nil {
p.MinDate = pointer.Get(minDate)
if p.MinDate, err = parseDate(opts.MinDate); err != nil {
return p, err
}
if opts.ItemsPerPage > 0 {
p.ItemsPerPage = &opts.ItemsPerPage
Expand All @@ -99,24 +110,28 @@ func (opts *ListOpts) NewOrgListOptions() admin.ListOrganizationEventsApiParams
if opts.OmitCount {
p.IncludeCount = pointer.Get(false)
}
return p
return p, nil
}

func (opts *ListOpts) NewProjectListOptions() admin.ListProjectEventsApiParams {
func (opts *ListOpts) NewProjectListOptions() (*admin.ListProjectEventsApiParams, error) {
var eventType *[]string
var err error
if len(opts.EventType) > 0 {
eventType = &opts.EventType
}
p := admin.ListProjectEventsApiParams{
p := &admin.ListProjectEventsApiParams{
GroupId: opts.projectID,
EventType: eventType,
}
if maxDate, err := convert.ParseTimestamp(opts.MaxDate); err == nil {
p.MaxDate = pointer.Get(maxDate)

if p.MaxDate, err = parseDate(opts.MaxDate); err != nil {
return p, err
}
if minDate, err := convert.ParseTimestamp(opts.MinDate); err == nil {
p.MinDate = pointer.Get(minDate)

if p.MinDate, err = parseDate(opts.MinDate); err != nil {
return p, err
}

if opts.ItemsPerPage > 0 {
p.ItemsPerPage = &opts.ItemsPerPage
}
Expand All @@ -127,7 +142,19 @@ func (opts *ListOpts) NewProjectListOptions() admin.ListProjectEventsApiParams {
p.IncludeCount = pointer.Get(false)
}

return p
return p, nil
}

func parseDate(date string) (*time.Time, error) {
if date == "" {
return nil, nil
}

parsedDate, err := convert.ParseTimestamp(date)
if err != nil {
return nil, err
}
return &parsedDate, nil
}

// ListBuilder
Expand Down Expand Up @@ -164,6 +191,7 @@ func ListBuilder() *cobra.Command {
return fmt.Errorf("--%s or --%s must be set", flag.ProjectID, flag.OrgID)
}
opts.OutWriter = cmd.OutOrStdout()

return opts.initStore(cmd.Context())()
},
RunE: func(_ *cobra.Command, _ []string) error {
Expand Down
97 changes: 97 additions & 0 deletions internal/cli/atlas/events/list_test.go
Expand Up @@ -17,12 +17,14 @@
package events

import (
"strings"
"testing"

"github.com/golang/mock/gomock"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/flag"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/mocks"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/test"
"github.com/stretchr/testify/assert"
"go.mongodb.org/atlas-sdk/v20231115008/admin"
)

Expand Down Expand Up @@ -65,6 +67,101 @@ func TestList_Run(t *testing.T) {
t.Fatalf("Run() unexpected error: %v", err)
}
})

t.Run("for a org with dates", func(t *testing.T) {
expected := &admin.OrgPaginatedEvent{}
listOpts := &ListOpts{
store: mockStore,
EventListOpts: EventListOpts{
MaxDate: "2024-03-18T15:00:03-0000",
MinDate: "2024-03-18T14:40:03-0000",
},
}
listOpts.orgID = "1"
anyMock := gomock.Any()
mockStore.
EXPECT().OrganizationEvents(anyMock).
Return(expected, nil).
Times(1)

err := listOpts.Run()
if err != nil {
t.Fatalf("Run() unexpected error: %v", err)
}
})
t.Run("for an project with dates", func(t *testing.T) {
expected := &admin.GroupPaginatedEvent{}
listOpts := &ListOpts{
store: mockStore,
EventListOpts: EventListOpts{
MaxDate: "2024-03-18T15:00:03-0000",
MinDate: "2024-03-18T14:40:03-0000",
},
}

anyMock := gomock.Any()
listOpts.projectID = "1"
mockStore.
EXPECT().ProjectEvents(anyMock).
Return(expected, nil).
Times(1)

err := listOpts.Run()
if err != nil {
t.Fatalf("Run() unexpected error: %v", err)
}
})

t.Run("for a org with invalid dates", func(t *testing.T) {
listOpts := &ListOpts{
store: mockStore,
EventListOpts: EventListOpts{
MaxDate: "2024-03-18T15:00:03+00:00Z",
MinDate: "2024-03-18T13:00:03+00:00Z",
},
}
listOpts.orgID = "1"

err := listOpts.Run()
if err == nil {
t.Fatal("Run() expected an error, but got none")
}
assert.True(t, strings.Contains(err.Error(), "parsing time"))
})
t.Run("for an project with invalid dates", func(t *testing.T) {
listOpts := &ListOpts{
store: mockStore,
EventListOpts: EventListOpts{
MaxDate: "2024-03-18T15:00:03+00:00Z",
MinDate: "2024-03-18T13:00:03+00:00Z",
},
}

listOpts.projectID = "1"
err := listOpts.Run()
if err == nil {
t.Fatal("Run() expected an error, but got none")
}
assert.True(t, strings.Contains(err.Error(), "parsing time"))
})
}

func TestParseDate(t *testing.T) {
t.Run("valid date", func(t *testing.T) {
date := "2024-03-18T15:00:03-0000"
_, err := parseDate(date)
if err != nil {
t.Fatalf("parseDate() unexpected error: %v", err)
}
})
t.Run("invalid date", func(t *testing.T) {
date := "2024-03-18T15:00:03+00:00Z"
_, err := parseDate(date)
if err == nil {
t.Fatalf("expected error from parseDate() but got none")
}
assert.True(t, strings.Contains(err.Error(), "parsing time"))
})
}

func TestListBuilder(t *testing.T) {
Expand Down
29 changes: 17 additions & 12 deletions internal/cli/atlas/events/orgs_list.go
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/cli/require"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/config"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/convert"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/flag"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/pointer"
"github.com/mongodb/mongodb-atlas-cli/atlascli/internal/store"
Expand All @@ -45,23 +44,26 @@ func (opts *orgListOpts) initStore(ctx context.Context) func() error {
}

func (opts *orgListOpts) Run() error {
var r interface{}
var err error
listEventsAPIParams := opts.NewOrgListOptions()
r, err = opts.store.OrganizationEvents(&listEventsAPIParams)
listEventsAPIParams, err := opts.NewOrgListOptions()
if err != nil {
return err
}
r, err := opts.store.OrganizationEvents(listEventsAPIParams)
if err != nil {
return err
}

return opts.Print(r)
}

func (opts *orgListOpts) NewOrgListOptions() admin.ListOrganizationEventsApiParams {
func (opts *orgListOpts) NewOrgListOptions() (*admin.ListOrganizationEventsApiParams, error) {
var eventType []string
var err error

if len(opts.EventType) > 0 {
eventType = opts.EventType
}
p := admin.ListOrganizationEventsApiParams{
p := &admin.ListOrganizationEventsApiParams{
OrgId: opts.ConfigOrgID(),
EventType: &eventType,
}
Expand All @@ -74,13 +76,16 @@ func (opts *orgListOpts) NewOrgListOptions() admin.ListOrganizationEventsApiPara
if opts.OmitCount {
p.IncludeCount = pointer.Get(false)
}
if maxDate, err := convert.ParseTimestamp(opts.MaxDate); err == nil {
p.MaxDate = pointer.Get(maxDate)

if p.MaxDate, err = parseDate(opts.MaxDate); err != nil {
return p, err
}
if minDate, err := convert.ParseTimestamp(opts.MinDate); err == nil {
p.MinDate = pointer.Get(minDate)

if p.MinDate, err = parseDate(opts.MinDate); err != nil {
return p, err
}
return p

return p, nil
}

// OrgListBuilder
Expand Down
42 changes: 42 additions & 0 deletions internal/cli/atlas/events/orgs_list_test.go
Expand Up @@ -46,6 +46,48 @@ func Test_orgListOpts_Run(t *testing.T) {
}
}

func Test_orgListOpts_Run_WithDate(t *testing.T) {
ctrl := gomock.NewController(t)
mockStore := mocks.NewMockOrganizationEventLister(ctrl)

expected := &admin.OrgPaginatedEvent{}
listOpts := &orgListOpts{
store: mockStore,
EventListOpts: EventListOpts{
MaxDate: "2024-03-18T15:00:03-0000",
MinDate: "2024-03-18T14:40:03-0000",
},
}
listOpts.OrgID = "1"
anyMock := gomock.Any()
mockStore.
EXPECT().OrganizationEvents(anyMock).
Return(expected, nil).
Times(1)

if err := listOpts.Run(); err != nil {
t.Fatalf("Run() unexpected error: %v", err)
}
}

func Test_orgListOpts_Run_WithInvalidDate(t *testing.T) {
ctrl := gomock.NewController(t)
mockStore := mocks.NewMockOrganizationEventLister(ctrl)

listOpts := &orgListOpts{
store: mockStore,
EventListOpts: EventListOpts{
MaxDate: "2024-03-18T15:00:03+00:00Z",
MinDate: "2024-03-18T13:00:03+00:00Z",
},
}
listOpts.OrgID = "1"

if err := listOpts.Run(); err == nil {
t.Fatalf("Expected inavlid date error from Run() got none")
}
}

func TestOrgListBuilder(t *testing.T) {
test.CmdValidator(
t,
Expand Down

0 comments on commit 869f069

Please sign in to comment.