Files
supermarket-api/internal/produce/produce_test.go
T
2021-06-20 18:16:33 -04:00

280 lines
6.9 KiB
Go

package produce
import (
"errors"
"testing"
"github.com/Rhymond/go-money"
"github.com/davidlick/supermarket-api/internal/mocks"
"github.com/davidlick/supermarket-api/pkg/ramdb"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
)
func TestService_Add(t *testing.T) {
tests := []struct {
test string
expectFunc func(t *testing.T, mockRamDB *mocks.MockRamDB) []Item
expectedError error
}{
{
test: "it should add all Items",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) []Item {
items := []Item{
{Code: "code-1", Name: "name-1", Price: money.New(101, "USD")},
{Code: "code-2", Name: "name-2", Price: money.New(202, "USD")},
{Code: "code-3", Name: "name-3", Price: money.New(303, "USD")},
{Code: "code-4", Name: "name-4", Price: money.New(404, "USD")},
{Code: "code-5", Name: "name-5", Price: money.New(505, "USD")},
}
for _, item := range items {
rec, err := ramdb.NewRecord(item.Code, KeyProduceCode, item)
if err != nil {
t.Error(err)
}
mockRamDB.EXPECT().Insert(rec).Return(nil)
}
return items
},
},
{
test: "it should return an error from ramdb",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) []Item {
mockRamDB.EXPECT().Insert(gomock.Any()).Return(errors.New("test error"))
return []Item{
{Code: "code-1", Name: "name-1", Price: money.New(101, "USD")},
}
},
expectedError: errors.New("test error"),
},
}
for _, tc := range tests {
t.Run(tc.test, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRamDB := mocks.NewMockRamDB(ctrl)
items := tc.expectFunc(t, mockRamDB)
svc := NewService(mockRamDB)
err := svc.Add(items)
assert.Equal(t, tc.expectedError, err)
})
}
}
func TestService_Add_Lowercased(t *testing.T) {
t.Run("it should store produce codes lowercased", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
item := Item{
Code: "TEST_CODE",
Name: "Name",
Price: money.New(101, "USD"),
}
mockRamDB := mocks.NewMockRamDB(ctrl)
rec, err := ramdb.NewRecord("test_code", KeyProduceCode, item)
if err != nil {
t.Error(err)
}
mockRamDB.EXPECT().Insert(rec).Return(nil)
svc := NewService(mockRamDB)
err = svc.Add([]Item{item})
assert.Nil(t, err)
})
}
func TestService_Remove(t *testing.T) {
tests := []struct {
test string
expectFunc func(t *testing.T, mockRamDB *mocks.MockRamDB) Item
expectedError error
}{
{
test: "it should successfully remove an item",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) Item {
item := Item{Code: "code-1", Name: "name-1", Price: money.New(101, "USD")}
rec, err := ramdb.NewRecord(item.Code, KeyProduceCode, item)
if err != nil {
t.Error(err)
}
mockRamDB.EXPECT().Delete(rec).Return(nil)
return item
},
},
{
test: "it should return an error from ramdb",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) Item {
mockRamDB.EXPECT().Delete(gomock.Any()).Return(errors.New("test error"))
return Item{}
},
expectedError: errors.New("test error"),
},
}
for _, tc := range tests {
t.Run(tc.test, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRamDB := mocks.NewMockRamDB(ctrl)
item := tc.expectFunc(t, mockRamDB)
svc := NewService(mockRamDB)
err := svc.Remove(item)
assert.Equal(t, tc.expectedError, err)
})
}
}
func TestService_Get(t *testing.T) {
tests := []struct {
test string
expectFunc func(t *testing.T, mockRamDB *mocks.MockRamDB) Item
expectedError error
}{
{
test: "it should return the item successfully",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) Item {
item := Item{Code: "produce_code", Name: "name-1", Price: money.New(101, "USD")}
rec, err := ramdb.NewRecord(item.Code, KeyProduceCode, item)
if err != nil {
t.Error(err)
}
mockRamDB.EXPECT().Get(KeyProduceCode, "test_code").Return(rec, nil)
return item
},
},
{
test: "it should return an error from ramdb",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) Item {
mockRamDB.EXPECT().Get(KeyProduceCode, "test_code").Return(nil, errors.New("test error"))
return Item{}
},
expectedError: errors.New("test error"),
},
}
for _, tc := range tests {
t.Run(tc.test, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRamDB := mocks.NewMockRamDB(ctrl)
expectedItem := tc.expectFunc(t, mockRamDB)
svc := NewService(mockRamDB)
item, err := svc.Get("test_code")
assert.Equal(t, expectedItem, item)
assert.Equal(t, tc.expectedError, err)
})
}
}
func TestService_Get_CaseInsensitive(t *testing.T) {
t.Run("it should lowercase produce codes before getting", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
searchItem := Item{
Code: "TEST_CODE",
}
expectedItem := Item{
Code: "test_code",
}
rec, err := ramdb.NewRecord("test_code", KeyProduceCode, expectedItem)
if err != nil {
t.Error(err)
}
mockRamDB := mocks.NewMockRamDB(ctrl)
mockRamDB.EXPECT().Get(KeyProduceCode, "test_code").Return(rec, nil)
svc := NewService(mockRamDB)
item, err := svc.Get(searchItem.Code)
assert.Equal(t, item, expectedItem)
assert.Nil(t, err)
})
}
func TestService_All(t *testing.T) {
tests := []struct {
test string
expectFunc func(t *testing.T, mockRamDB *mocks.MockRamDB) []Item
expectedError error
}{
{
test: "it should return all items",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) []Item {
items := []Item{
{Code: "code-1", Name: "name-1", Price: money.New(101, "USD")},
{Code: "code-2", Name: "name-2", Price: money.New(202, "USD")},
{Code: "code-3", Name: "name-3", Price: money.New(303, "USD")},
{Code: "code-4", Name: "name-4", Price: money.New(404, "USD")},
{Code: "code-5", Name: "name-5", Price: money.New(505, "USD")},
}
var recs []*ramdb.Record
for _, item := range items {
rec, err := ramdb.NewRecord(item.Code, KeyProduceCode, item)
if err != nil {
t.Error(err)
}
recs = append(recs, rec)
}
mockRamDB.EXPECT().Select(KeyProduceCode).Return(recs, nil)
return items
},
},
{
test: "it should return a ramdb error",
expectFunc: func(t *testing.T, mockRamDB *mocks.MockRamDB) []Item {
mockRamDB.EXPECT().Select(gomock.Any()).Return(nil, errors.New("test error"))
return nil
},
expectedError: errors.New("test error"),
},
}
for _, tc := range tests {
t.Run(tc.test, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockRamDB := mocks.NewMockRamDB(ctrl)
expectedItems := tc.expectFunc(t, mockRamDB)
svc := NewService(mockRamDB)
items, err := svc.All()
assert.Equal(t, expectedItems, items)
assert.Equal(t, tc.expectedError, err)
})
}
}