Started working on proper controllers

This commit is contained in:
Leon Mika 2022-05-19 09:55:15 +10:00
parent 306640abdb
commit 6df67ce93b
9 changed files with 225 additions and 91 deletions

View file

@ -0,0 +1,13 @@
package controllers
import (
"context"
"github.com/lmika/awstools/internal/dynamo-browse/models"
)
type TableReadService interface {
ListTables(background context.Context) ([]string, error)
Describe(ctx context.Context, table string) (*models.TableInfo, error)
Scan(ctx context.Context, tableInfo *models.TableInfo) (*models.ResultSet, error)
Filter(resultSet *models.ResultSet, filter string) *models.ResultSet
}

View file

@ -5,13 +5,12 @@ import (
tea "github.com/charmbracelet/bubbletea"
"github.com/lmika/awstools/internal/common/ui/events"
"github.com/lmika/awstools/internal/dynamo-browse/models"
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
"github.com/pkg/errors"
"sync"
)
type TableReadController struct {
tableService *tables.Service
tableService TableReadService
tableName string
// state
@ -20,7 +19,7 @@ type TableReadController struct {
filter string
}
func NewTableReadController(tableService *tables.Service, tableName string) *TableReadController {
func NewTableReadController(tableService TableReadService, tableName string) *TableReadController {
return &TableReadController{
tableService: tableService,
tableName: tableName,

View file

@ -0,0 +1,107 @@
package controllers_test
import (
"github.com/lmika/awstools/internal/dynamo-browse/controllers"
"github.com/lmika/awstools/internal/dynamo-browse/providers/dynamo"
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
"github.com/lmika/awstools/test/testdynamo"
"github.com/stretchr/testify/assert"
"testing"
)
func TestTableReadController_InitTable(t *testing.T) {
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
service := tables.NewService(provider)
t.Run("should prompt for table if no table name provided", func(t *testing.T) {
readController := controllers.NewTableReadController(service, "")
cmd := readController.Init()
event := cmd()
assert.IsType(t, controllers.PromptForTableMsg{}, event)
})
t.Run("should scan table if table name provided", func(t *testing.T) {
readController := controllers.NewTableReadController(service, "")
cmd := readController.Init()
event := cmd()
assert.IsType(t, controllers.PromptForTableMsg{}, event)
})
}
func TestTableReadController_ListTables(t *testing.T) {
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
service := tables.NewService(provider)
readController := controllers.NewTableReadController(service, "")
t.Run("returns a list of tables", func(t *testing.T) {
cmd := readController.ListTables()
event := cmd().(controllers.PromptForTableMsg)
assert.Equal(t, []string{"alpha-table", "bravo-table"}, event.Tables)
selectedCmd := event.OnSelected("alpha-table")
selectedEvent := selectedCmd()
resultSet := selectedEvent.(controllers.NewResultSet)
assert.Equal(t, "alpha-table", resultSet.ResultSet.TableInfo.Name)
assert.Equal(t, "pk", resultSet.ResultSet.TableInfo.Keys.PartitionKey)
assert.Equal(t, "sk", resultSet.ResultSet.TableInfo.Keys.SortKey)
})
}
var testData = []testdynamo.TestData{
{
TableName: "alpha-table",
Data: []map[string]interface{}{
{
"pk": "abc",
"sk": "111",
"alpha": "This is some value",
},
{
"pk": "abc",
"sk": "222",
"alpha": "This is another some value",
"beta": 1231,
},
{
"pk": "bbb",
"sk": "131",
"beta": 2468,
"gamma": "foobar",
},
},
},
{
TableName: "bravo-table",
Data: []map[string]interface{}{
{
"pk": "foo",
"sk": "bar",
"alpha": "This is some value",
},
{
"pk": "abc",
"sk": "222",
"alpha": "This is another some value",
"beta": 1231,
},
{
"pk": "bbb",
"sk": "131",
"beta": 2468,
"gamma": "foobar",
},
},
},
}

View file

@ -2,11 +2,6 @@ package controllers_test
import (
"testing"
"github.com/lmika/awstools/internal/dynamo-browse/controllers"
"github.com/lmika/awstools/internal/dynamo-browse/providers/dynamo"
"github.com/lmika/awstools/internal/dynamo-browse/services/tables"
"github.com/lmika/awstools/test/testdynamo"
)
func TestTableWriteController_ToggleReadWrite(t *testing.T) {
@ -159,6 +154,7 @@ func TestTableWriteController_Delete(t *testing.T) {
*/
}
/*
type controller struct {
tableName string
tableService *tables.Service
@ -197,3 +193,4 @@ var testData = testdynamo.TestData{
"gamma": "foobar",
},
}
*/

View file

@ -11,9 +11,9 @@ import (
)
func TestProvider_ScanItems(t *testing.T) {
tableName := "provider-scanimages-test-table"
tableName := "test-table"
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
@ -24,9 +24,9 @@ func TestProvider_ScanItems(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, items, 3)
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[1]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[2]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[0]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[1]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[2]))
})
t.Run("should return error if table name does not exist", func(t *testing.T) {
@ -39,10 +39,10 @@ func TestProvider_ScanItems(t *testing.T) {
}
func TestProvider_DeleteItem(t *testing.T) {
tableName := "provider-deleteitem-test-table"
tableName := "test-table"
t.Run("should delete item if exists in table", func(t *testing.T) {
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
@ -57,14 +57,14 @@ func TestProvider_DeleteItem(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, items, 2)
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[2]))
assert.NotContains(t, items, testdynamo.TestRecordAsItem(t, testData[1]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[0]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[2]))
assert.NotContains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[1]))
})
t.Run("should do nothing if key does not exist", func(t *testing.T) {
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
@ -79,13 +79,13 @@ func TestProvider_DeleteItem(t *testing.T) {
assert.NoError(t, err)
assert.Len(t, items, 3)
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[1]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[2]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[0]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[1]))
assert.Contains(t, items, testdynamo.TestRecordAsItem(t, testData[0].Data[2]))
})
t.Run("should return error if table name does not exist", func(t *testing.T) {
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
@ -97,7 +97,10 @@ func TestProvider_DeleteItem(t *testing.T) {
})
}
var testData = testdynamo.TestData{
var testData = []testdynamo.TestData{
{
TableName: "test-table",
Data: []map[string]interface{}{
{
"pk": "abc",
"sk": "111",
@ -115,4 +118,6 @@ var testData = testdynamo.TestData{
"beta": 2468,
"gamma": "foobar",
},
},
},
}

View file

@ -11,9 +11,9 @@ import (
)
func TestService_Describe(t *testing.T) {
tableName := "service-describe-table"
tableName := "service-test-data"
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
@ -33,9 +33,9 @@ func TestService_Describe(t *testing.T) {
}
func TestService_Scan(t *testing.T) {
tableName := "service-scan-test-table"
tableName := "service-test-data"
client, cleanupFn := testdynamo.SetupTestTable(t, tableName, testData)
client, cleanupFn := testdynamo.SetupTestTable(t, testData)
defer cleanupFn()
provider := dynamo.NewProvider(client)
@ -58,7 +58,10 @@ func TestService_Scan(t *testing.T) {
})
}
var testData = testdynamo.TestData{
var testData = []testdynamo.TestData{
{
TableName: "service-test-data",
Data: []map[string]interface{}{
{
"pk": "abc",
"sk": "222",
@ -76,4 +79,6 @@ var testData = testdynamo.TestData{
"beta": 2468,
"gamma": "foobar",
},
},
},
}

View file

@ -49,6 +49,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
func (m *Model) ViewItem(item *models.LogLine) {
m.visible = true
m.lineDetails.SetSelectedItem(item)
m.lineDetails.SetFocused(true)
}
func (m *Model) View() string {

View file

@ -14,7 +14,7 @@ type itemTableRow struct {
func (mtr itemTableRow) Render(w io.Writer, model table.Model, index int) {
firstLine := strings.SplitN(mtr.item.Value, "\n", 2)[0]
line := fmt.Sprintf("%s\t%s\t%s", mtr.item.Name, "String", firstLine)
line := fmt.Sprintf("%s\t%s\t%s", mtr.item.Name, mtr.item.Type, firstLine)
if index == model.Cursor() {
fmt.Fprintln(w, model.Styles.SelectedRow.Render(line))

View file

@ -13,9 +13,12 @@ import (
"github.com/stretchr/testify/assert"
)
type TestData []map[string]interface{}
type TestData struct {
TableName string
Data []map[string]interface{}
}
func SetupTestTable(t *testing.T, tableName string, testData TestData) (*dynamodb.Client, func()) {
func SetupTestTable(t *testing.T, testData []TestData) (*dynamodb.Client, func()) {
t.Helper()
ctx := context.Background()
@ -27,8 +30,9 @@ func SetupTestTable(t *testing.T, tableName string, testData TestData) (*dynamod
dynamoClient := dynamodb.NewFromConfig(cfg,
dynamodb.WithEndpointResolver(dynamodb.EndpointResolverFromURL("http://localhost:8000")))
for _, table := range testData {
_, err = dynamoClient.CreateTable(ctx, &dynamodb.CreateTableInput{
TableName: aws.String(tableName),
TableName: aws.String(table.TableName),
KeySchema: []types.KeySchemaElement{
{AttributeName: aws.String("pk"), KeyType: types.KeyTypeHash},
{AttributeName: aws.String("sk"), KeyType: types.KeyTypeRange},
@ -44,20 +48,23 @@ func SetupTestTable(t *testing.T, tableName string, testData TestData) (*dynamod
})
assert.NoError(t, err)
for _, item := range testData {
for _, item := range table.Data {
m, err := attributevalue.MarshalMap(item)
assert.NoError(t, err)
_, err = dynamoClient.PutItem(ctx, &dynamodb.PutItemInput{
TableName: aws.String(tableName),
TableName: aws.String(table.TableName),
Item: m,
})
assert.NoError(t, err)
}
}
return dynamoClient, func() {
for _, table := range testData {
dynamoClient.DeleteTable(ctx, &dynamodb.DeleteTableInput{
TableName: aws.String(tableName),
TableName: aws.String(table.TableName),
})
}
}
}