Skip to content

Commit

Permalink
More tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dkyanakiev authored and Dimitar Yanakiev committed Nov 29, 2023
1 parent 1f548a8 commit 03b385c
Show file tree
Hide file tree
Showing 19 changed files with 1,244 additions and 38 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ If anyone decides to use this and wants to request a specific feature or even fi

## Short term TODO list:
1. [x] Change the logger (current one is a mess)
2. [ ] Finish adding tests (wip in another branch)
2. [x] Finish adding tests (initial batch of tests)
3. [ ] Finish implementing Update to existing secrets
- [ ] Bonus: Create net new ones.
4. [ ] Support for namespace changes.
2 changes: 1 addition & 1 deletion component/mounts_table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (

func TestMountsTable_Pass(t *testing.T) {
r := require.New(t)
t.Run("When the component is bound", func(t *testing.T) {
t.Run("When there is data to render", func(t *testing.T) {

fakeTable := &componentfakes.FakeTable{}
mTable := component.NewMountsTable()
Expand Down
101 changes: 101 additions & 0 deletions component/search_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

package component_test

import (
"errors"
"testing"

"github.com/dkyanakiev/vaulty/component"
"github.com/dkyanakiev/vaulty/component/componentfakes"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/stretchr/testify/require"
)

func TestSearch_Pass(t *testing.T) {
r := require.New(t)

input := &componentfakes.FakeInputField{}
search := component.NewSearchField("test")
search.InputField = input

var changedCalled bool
search.Props.ChangedFunc = func(text string) {
changedCalled = true
}

var doneCalled bool
search.Props.DoneFunc = func(key tcell.Key) {
doneCalled = true
}
search.Bind(tview.NewFlex())

err := search.Render()
r.NoError(err)

actualDoneFunc := input.SetDoneFuncArgsForCall(0)
actualChangedFunc := input.SetChangedFuncArgsForCall(0)

actualChangedFunc("")
actualDoneFunc(tcell.KeyACK)

r.True(changedCalled)
r.True(doneCalled)
}

func TestSearch_Fail(t *testing.T) {
r := require.New(t)

t.Run("When the component isn't bound", func(t *testing.T) {
input := &componentfakes.FakeInputField{}
search := component.NewSearchField("test")
search.InputField = input
search.Props.ChangedFunc = func(text string) {}
search.Props.DoneFunc = func(key tcell.Key) {}

err := search.Render()
r.Error(err)

// It provides the correct error message
r.EqualError(err, "component not bound")

// It is the correct error
r.True(errors.Is(err, component.ErrComponentNotBound))
})

t.Run("When DoneFunc is not set", func(t *testing.T) {
input := &componentfakes.FakeInputField{}
search := component.NewSearchField("test")
search.InputField = input
search.Props.ChangedFunc = func(text string) {}
search.Bind(tview.NewFlex())

err := search.Render()
r.Error(err)

// It provides the correct error message
r.EqualError(err, "component properties not set")

// It is the correct error
r.True(errors.Is(err, component.ErrComponentPropsNotSet))
})

t.Run("When ChangedFunc is not set", func(t *testing.T) {
input := &componentfakes.FakeInputField{}
search := component.NewSearchField("test")
search.InputField = input
search.Props.DoneFunc = func(key tcell.Key) {}
search.Bind(tview.NewFlex())

err := search.Render()
r.Error(err)

// It provides the correct error message
r.EqualError(err, "component properties not set")

// It is the correct error
r.True(errors.Is(err, component.ErrComponentPropsNotSet))
})
}
143 changes: 143 additions & 0 deletions component/secret_obj_table_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package component_test

import (
"encoding/json"
"testing"

"github.com/dkyanakiev/vaulty/component"
"github.com/dkyanakiev/vaulty/component/componentfakes"
"github.com/gdamore/tcell/v2"
"github.com/hashicorp/vault/api"
"github.com/rivo/tview"
"github.com/stretchr/testify/require"
)

func TestSecretObjTable_Pass(t *testing.T) {
r := require.New(t)

t.Run("Render data as table", func(t *testing.T) {
fakeTable := &componentfakes.FakeTable{}
fakeTextView := &componentfakes.FakeTextView{}
st := component.NewSecretObjTable()

st.Table = fakeTable
st.TextView = fakeTextView
st.ShowJson = false
st.Editable = false

mockSecret := &api.Secret{
RequestID: "mockRequestID",
LeaseID: "mockLeaseID",
LeaseDuration: 3600,
Renewable: true,
Data: map[string]interface{}{
"data": map[string]interface{}{
"key1": "dZpT6XnlnktMXaYF",
"key2": "10mNsYOLfd1OfohW",
},
},
}

st.Props.Data = mockSecret

st.Props.SelectPath = func(id string) {}
st.Props.HandleNoResources = func(format string, args ...interface{}) {}
slot := tview.NewFlex()
st.Bind(slot)
// It doesn't error
err := st.Render()
r.NoError(err)

// Render header rows
renderHeaderCount := fakeTable.RenderHeaderCallCount()
r.Equal(renderHeaderCount, 1)
headers := fakeTable.RenderHeaderArgsForCall(0)
r.Equal(headers, component.SecretObjTableHeaderJobs)

// Render rows
renderRowCallCount := fakeTable.RenderRowCallCount()
r.Equal(renderRowCallCount, 2)

row1, index1, c1 := fakeTable.RenderRowArgsForCall(0)
row2, index2, c2 := fakeTable.RenderRowArgsForCall(1)

expectedRow1 := []string{"key1", "dZpT6XnlnktMXaYF"}
expectedRow2 := []string{"key2", "10mNsYOLfd1OfohW"}

r.Equal(expectedRow1, row1)
r.Equal(expectedRow2, row2)
r.Equal(index1, 1)
r.Equal(index2, 2)
r.Equal(c1, tcell.ColorYellow)
r.Equal(c2, tcell.ColorYellow)

})

t.Run("Render data as json", func(t *testing.T) {
fakeTable := &componentfakes.FakeTable{}
fakeTextView := &componentfakes.FakeTextView{}
st := component.NewSecretObjTable()

st.Table = fakeTable
st.TextView = fakeTextView
st.ShowJson = true
st.Editable = false

mockSecret := &api.Secret{
RequestID: "mockRequestID",
LeaseID: "mockLeaseID",
LeaseDuration: 3600,
Renewable: true,
Data: map[string]interface{}{
"data": map[string]interface{}{
"key1": "dZpT6XnlnktMXaYF",
"key2": "10mNsYOLfd1OfohW",
},
},
}

st.Props.Data = mockSecret
correctText, _ := json.Marshal(mockSecret.Data["data"])

st.Props.SelectPath = func(id string) {}
st.Props.HandleNoResources = func(format string, args ...interface{}) {}
slot := tview.NewFlex()
st.Bind(slot)
// It doesn't error
err := st.Render()
r.NoError(err)

// Renders correct text

fakeTextView.GetTextReturns(string(correctText))
renderedText := fakeTextView.GetText(true)

r.Equal(string(correctText), renderedText)
})

t.Run("No data to render", func(t *testing.T) {
fakeTable := &componentfakes.FakeTable{}
fakeTextView := &componentfakes.FakeTextView{}
st := component.NewSecretObjTable()

st.Table = fakeTable
st.TextView = fakeTextView
st.ShowJson = false
st.Editable = false

st.Props.Data = nil

var NoResourcesCalled bool
st.Props.HandleNoResources = func(format string, args ...interface{}) {
NoResourcesCalled = true
}

slot := tview.NewFlex()
st.Bind(slot)
// It doesn't error
err := st.Render()
r.NoError(err)

r.True(NoResourcesCalled)
})
}
101 changes: 101 additions & 0 deletions component/secrets_table_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package component_test

import (
"testing"

"github.com/dkyanakiev/vaulty/component"
"github.com/dkyanakiev/vaulty/component/componentfakes"
"github.com/dkyanakiev/vaulty/models"
"github.com/dkyanakiev/vaulty/styles"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
"github.com/stretchr/testify/require"
)

func TestSecretsTable_Pass(t *testing.T) {
r := require.New(t)
t.Run("When there is data to render", func(t *testing.T) {

fakeTable := &componentfakes.FakeTable{}
st := component.NewSecretsTable()

st.Table = fakeTable
st.Props.Namespace = "default"
mockData := []models.SecretPath{
{
PathName: "mockPathName1",
IsSecret: true,
},
{
PathName: "mockPathName2",
IsSecret: false,
},
}

st.Props.Data = mockData
st.Props.SelectPath = func(id string) {}
st.Props.HandleNoResources = func(format string, args ...interface{}) {}

slot := tview.NewFlex()
st.Bind(slot)
// It doesn't error
err := st.Render()
r.NoError(err)

// Render header rows
renderHeaderCount := fakeTable.RenderHeaderCallCount()
r.Equal(renderHeaderCount, 1)

// Correct headers
header := fakeTable.RenderHeaderArgsForCall(0)
r.Equal(component.SecretsTableHeaderJobs, header)

// It renders the correct number of rows
renderRowCallCount := fakeTable.RenderRowCallCount()
r.Equal(renderRowCallCount, 2)

row1, index1, c1 := fakeTable.RenderRowArgsForCall(0)
row2, index2, c2 := fakeTable.RenderRowArgsForCall(1)
expectedRow1 := []string{"mockPathName1", "true"}
expectedRow2 := []string{"mockPathName2", "false"}

r.Equal(expectedRow1, row1)
r.Equal(expectedRow2, row2)

r.Equal(index1, 1)
r.Equal(index2, 2)
r.Equal(c1, tcell.ColorYellow)
r.Equal(c2, tcell.ColorYellow)

})

t.Run("No data to render", func(t *testing.T) {
fakeTable := &componentfakes.FakeTable{}
st := component.NewSecretsTable()

st.Table = fakeTable
st.Props.Namespace = "default"

st.Props.Data = nil
st.Props.SelectPath = func(id string) {}
st.Props.HandleNoResources = func(format string, args ...interface{}) {}

var NoResourcesCalled bool
st.Props.HandleNoResources = func(format string, args ...interface{}) {
NoResourcesCalled = true

r.Equal("%sno secrets available\n¯%s\\_( ͡• ͜ʖ ͡•)_/¯", format)
r.Len(args, 2)
r.Equal(args[0], styles.HighlightPrimaryTag)
r.Equal(args[1], styles.HighlightSecondaryTag)
}
slot := tview.NewFlex()
st.Bind(slot)
// It doesn't error
err := st.Render()
r.NoError(err)
r.True(NoResourcesCalled)

})

}
Loading

0 comments on commit 03b385c

Please sign in to comment.