diff --git a/internal/dynamo-browse/controllers/tablewrite.go b/internal/dynamo-browse/controllers/tablewrite.go index 8099779..ca6abd6 100644 --- a/internal/dynamo-browse/controllers/tablewrite.go +++ b/internal/dynamo-browse/controllers/tablewrite.go @@ -89,6 +89,64 @@ func (twc *TableWriteController) PutItem(idx int) tea.Cmd { } } +func (twc *TableWriteController) TouchItem(idx int) tea.Cmd { + return func() tea.Msg { + resultSet := twc.state.ResultSet() + if resultSet.IsDirty(idx) { + return events.Error(errors.New("cannot touch dirty items")) + } + + return events.PromptForInputMsg{ + Prompt: "touch item? ", + OnDone: func(value string) tea.Cmd { + return func() tea.Msg { + if value != "y" { + return nil + } + + if err := twc.tableService.PutItemAt(context.Background(), resultSet, idx); err != nil { + return events.Error(err) + } + return ResultSetUpdated{} + } + }, + } + } +} + +func (twc *TableWriteController) NoisyTouchItem(idx int) tea.Cmd { + return func() tea.Msg { + resultSet := twc.state.ResultSet() + if resultSet.IsDirty(idx) { + return events.Error(errors.New("cannot noisy touch dirty items")) + } + + return events.PromptForInputMsg{ + Prompt: "noisy touch item? ", + OnDone: func(value string) tea.Cmd { + return func() tea.Msg { + ctx := context.Background() + + if value != "y" { + return nil + } + + item := resultSet.Items()[0] + if err := twc.tableService.Delete(ctx, resultSet.TableInfo, []models.Item{item}); err != nil { + return events.Error(err) + } + + if err := twc.tableService.Put(ctx, resultSet.TableInfo, item); err != nil { + return events.Error(err) + } + + return twc.tableReadControllers.doScan(ctx, resultSet) + } + }, + } + } +} + func (twc *TableWriteController) DeleteMarked() tea.Cmd { return func() tea.Msg { resultSet := twc.state.ResultSet() diff --git a/internal/dynamo-browse/controllers/tablewrite_test.go b/internal/dynamo-browse/controllers/tablewrite_test.go index 589f628..3eea9a5 100644 --- a/internal/dynamo-browse/controllers/tablewrite_test.go +++ b/internal/dynamo-browse/controllers/tablewrite_test.go @@ -313,5 +313,106 @@ func TestTableWriteController_PutItem(t *testing.T) { invokeCommandExpectingError(t, writeController.PutItem(0)) }) - +} + +func TestTableWriteController_TouchItem(t *testing.T) { + t.Run("should put the selected item if unmodified", func(t *testing.T) { + client, cleanupFn := testdynamo.SetupTestTable(t, testData) + defer cleanupFn() + + provider := dynamo.NewProvider(client) + service := tables.NewService(provider) + + state := controllers.NewState() + readController := controllers.NewTableReadController(state, service, "alpha-table") + writeController := controllers.NewTableWriteController(state, service, readController) + + // Read the table + invokeCommand(t, readController.Init()) + before, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha") + assert.Equal(t, "This is some value", before) + assert.False(t, state.ResultSet().IsDirty(0)) + + // Modify the item and put it + invokeCommandWithPrompt(t, writeController.TouchItem(0), "y") + + // Rescan the table + invokeCommand(t, readController.Rescan()) + after, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha") + assert.Equal(t, "This is some value", after) + assert.False(t, state.ResultSet().IsDirty(0)) + }) + + t.Run("should not put the selected item if modified", func(t *testing.T) { + client, cleanupFn := testdynamo.SetupTestTable(t, testData) + defer cleanupFn() + + provider := dynamo.NewProvider(client) + service := tables.NewService(provider) + + state := controllers.NewState() + readController := controllers.NewTableReadController(state, service, "alpha-table") + writeController := controllers.NewTableWriteController(state, service, readController) + + // Read the table + invokeCommand(t, readController.Init()) + before, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha") + assert.Equal(t, "This is some value", before) + assert.False(t, state.ResultSet().IsDirty(0)) + + // Modify the item and put it + invokeCommandWithPrompt(t, writeController.SetStringValue(0, "alpha"), "a new value") + invokeCommandExpectingError(t, writeController.TouchItem(0)) + }) +} + +func TestTableWriteController_NoisyTouchItem(t *testing.T) { + t.Run("should delete and put the selected item if unmodified", func(t *testing.T) { + client, cleanupFn := testdynamo.SetupTestTable(t, testData) + defer cleanupFn() + + provider := dynamo.NewProvider(client) + service := tables.NewService(provider) + + state := controllers.NewState() + readController := controllers.NewTableReadController(state, service, "alpha-table") + writeController := controllers.NewTableWriteController(state, service, readController) + + // Read the table + invokeCommand(t, readController.Init()) + before, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha") + assert.Equal(t, "This is some value", before) + assert.False(t, state.ResultSet().IsDirty(0)) + + // Modify the item and put it + invokeCommandWithPrompt(t, writeController.NoisyTouchItem(0), "y") + + // Rescan the table + invokeCommand(t, readController.Rescan()) + after, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha") + assert.Equal(t, "This is some value", after) + assert.False(t, state.ResultSet().IsDirty(0)) + }) + + t.Run("should not put the selected item if modified", func(t *testing.T) { + client, cleanupFn := testdynamo.SetupTestTable(t, testData) + defer cleanupFn() + + provider := dynamo.NewProvider(client) + service := tables.NewService(provider) + + state := controllers.NewState() + readController := controllers.NewTableReadController(state, service, "alpha-table") + writeController := controllers.NewTableWriteController(state, service, readController) + + // Read the table + invokeCommand(t, readController.Init()) + before, _ := state.ResultSet().Items()[0].AttributeValueAsString("alpha") + assert.Equal(t, "This is some value", before) + assert.False(t, state.ResultSet().IsDirty(0)) + + // Modify the item and put it + invokeCommandWithPrompt(t, writeController.SetStringValue(0, "alpha"), "a new value") + invokeCommandExpectingError(t, writeController.NoisyTouchItem(0)) + }) } diff --git a/internal/dynamo-browse/ui/model.go b/internal/dynamo-browse/ui/model.go index c048d15..e5fb64f 100644 --- a/internal/dynamo-browse/ui/model.go +++ b/internal/dynamo-browse/ui/model.go @@ -60,6 +60,12 @@ func NewModel(rc *controllers.TableReadController, wc *controllers.TableWriteCon "put": func(args []string) tea.Cmd { return wc.PutItem(dtv.SelectedItemIndex()) }, + "touch": func(args []string) tea.Cmd { + return wc.TouchItem(dtv.SelectedItemIndex()) + }, + "noisy-touch": func(args []string) tea.Cmd { + return wc.NoisyTouchItem(dtv.SelectedItemIndex()) + }, }, })