diff --git a/pkg/setup/item.go b/pkg/setup/item.go index d275d0ff38fa33e7c2a77010344b5f6117d2310d..a17512d0c0ce38714cc52cd7752ec7149ae292b3 100644 --- a/pkg/setup/item.go +++ b/pkg/setup/item.go @@ -18,18 +18,21 @@ var ( ) type ItemsOption func(c *ItemConfig) +type PublishItemFn func(s *Setup, item *items.Item) (*items.Item, bool) type UpdateItemFn func(s *Setup, exist, new *items.Item) (*items.Item, bool) type DeleteItemFn func(s *Setup, col *items.Item) bool type ItemConfig struct { - item *items.Item - UpdateFn UpdateItemFn - DeleteFn DeleteItemFn + item *items.Item + PublishFn PublishItemFn + UpdateFn UpdateItemFn + DeleteFn DeleteItemFn } func NewItemConfig(item *items.Item, opt ...ItemsOption) ItemConfig { c := ItemConfig{item: item} + PublishItem()(&c) KeepExistingItem()(&c) DeleteItemIfRemove()(&c) @@ -120,6 +123,18 @@ func DeleteItemIfRemove() ItemsOption { } } +func PublishItem() ItemsOption { + return func(c *ItemConfig) { + c.PublishFn = func(s *Setup, item *items.Item) (*items.Item, bool) { return item, true } + } +} + +func KeepDraft() ItemsOption { + return func(c *ItemConfig) { + c.PublishFn = func(s *Setup, item *items.Item) (*items.Item, bool) { return item, false } + } +} + func (s *Setup) InstallItems(ctx context.Context) error { if len(s.Items) == 0 { return nil @@ -153,11 +168,27 @@ func (s *Setup) InstallItem(ctx context.Context, exists map[string]*items.Item, exist, ok := exists[item.ID] if !ok { - return items.CreateAndPublishItem(ctx, s.content.Items, item) + if item, publish := c.PublishFn(s, item); publish { + return items.CreateAndPublishItem(ctx, s.content.Items, item) + } + if _, err := s.content.Items.Create(ctx, item); err != nil { + return errors.Wrap(err, "create item") + } + return nil } - if item, changed := c.UpdateFn(s, exist, c.item); changed { - return items.UpdateAndPublishItem(ctx, s.content.Items, item) + if item, changed := c.UpdateFn(s, exist, item); changed { + if _, publish := c.PublishFn(s, item); publish { + return items.UpdateAndPublishItem(ctx, s.content.Items, item) + } + if err := s.content.Items.Update(ctx, item); err != nil { + return errors.Wrap(err, "update item") + } + if err := s.content.Items.Unpublish(ctx, item); err != nil { + return errors.Wrap(err, "unpublish item") + } + return nil + } return nil diff --git a/pkg/setup/item_test.go b/pkg/setup/item_test.go index 920292f501cf9e469150621b3894bcad41326aa8..2d2e1a7705a80be6d4eb783af5ad81daf431e886 100644 --- a/pkg/setup/item_test.go +++ b/pkg/setup/item_test.go @@ -277,3 +277,89 @@ func TestSetup_InstallItems(t *testing.T) { }) } } + +func TestSetup_CreateDraft(t *testing.T) { + + tests := []struct { + name string + items []*items.Item + itemsCall func(svc *itemsMock.Items) + wantErr func(t *testing.T, err error) + }{ + { + name: "Install one item", + items: []*items.Item{{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}}, + itemsCall: func(svc *itemsMock.Items) { + svc.On("Find", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, 0, nil).Once() + svc.On("Create", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}).Return(&items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, nil).Once() + }, + wantErr: func(t *testing.T, err error) { + assert.NoError(t, err) + }, + }, + { + name: "Install multiple items success", + items: []*items.Item{ + {ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, + {ID: "2", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, + }, + itemsCall: func(svc *itemsMock.Items) { + svc.On("Find", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil, 0, nil).Once() + svc.On("Create", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}).Return(&items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, nil).Once() + svc.On("Create", mock.Anything, &items.Item{ID: "2", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}).Return(&items.Item{ID: "2", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}, nil).Once() + }, + wantErr: func(t *testing.T, err error) { + assert.NoError(t, err) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i := &itemsMock.Items{} + if tt.itemsCall != nil { + tt.itemsCall(i) + } + + s := NewSetup(&content.Content{Items: i}, "sp", "env", nil) + s.AddItems(tt.items, KeepDraft()) + tt.wantErr(t, s.InstallItems(context.Background())) + }) + } +} + +func TestSetup_UpdateDraft(t *testing.T) { + + tests := []struct { + name string + items []*items.Item + itemsCall func(svc *itemsMock.Items) + wantErr func(t *testing.T, err error) + }{ + { + name: "Update one item that was published", + items: []*items.Item{{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", Data: map[string]interface{}{"text": "test"}}}, + itemsCall: func(svc *itemsMock.Items) { + svc.On("Find", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]*items.Item{{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", State: items.StatePublished, Data: map[string]interface{}{"text": "test"}}}, 1, nil).Once() + svc.On("Update", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", State: items.StatePublished, Data: map[string]interface{}{"text": "test"}}).Return(nil).Once() + svc.On("Unpublish", mock.Anything, &items.Item{ID: "1", SpaceID: "sp", EnvID: "env", CollectionID: "coll", State: items.StatePublished, Data: map[string]interface{}{"text": "test"}}).Return(nil).Once() + }, + wantErr: func(t *testing.T, err error) { + assert.NoError(t, err) + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + i := &itemsMock.Items{} + if tt.itemsCall != nil { + tt.itemsCall(i) + } + + s := NewSetup(&content.Content{Items: i}, "sp", "env", nil) + s.AddItems(tt.items, KeepDraft()) + tt.wantErr(t, s.InstallItems(context.Background())) + }) + } +}