Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLOUDP-238932: Validate maxDate and minDate before running command #2794

Merged
merged 8 commits into from Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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 @@ -15,12 +15,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 @@ -63,6 +65,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 @@ -44,6 +44,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