Refactor repository
This commit is contained in:
parent
f1c6820d66
commit
2716580834
@ -7,7 +7,7 @@ import (
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
driver "go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
@ -28,11 +28,11 @@ type RepositoryInterface[T Document] interface {
|
||||
}
|
||||
|
||||
type Repository[T Document] struct {
|
||||
collection *driver.Collection
|
||||
indexes []driver.IndexModel
|
||||
collection *mongo.Collection
|
||||
indexes []mongo.IndexModel
|
||||
}
|
||||
|
||||
func NewRepository[T Document](collection *driver.Collection, indexes []driver.IndexModel) *Repository[T] {
|
||||
func NewRepository[T Document](collection *mongo.Collection, indexes []mongo.IndexModel) *Repository[T] {
|
||||
return &Repository[T]{collection: collection, indexes: withTimestampIndexes(indexes)}
|
||||
}
|
||||
|
||||
@ -112,6 +112,6 @@ func (s *Repository[T]) EnsureIndexes(ctx context.Context, createIndexes bool) (
|
||||
return ensureIndexes(ctx, s.collection, s.indexes, createIndexes)
|
||||
}
|
||||
|
||||
func repositoryError(collection *driver.Collection, op string, err error) error {
|
||||
func repositoryError(collection *mongo.Collection, op string, err error) error {
|
||||
return fmt.Errorf("%s.%s: %v", collection.Name(), op, err)
|
||||
}
|
||||
|
195
repository_test.go
Normal file
195
repository_test.go
Normal file
@ -0,0 +1,195 @@
|
||||
package leaf
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/integration/mtest"
|
||||
)
|
||||
|
||||
type tModel struct {
|
||||
Name string `bson:"name"`
|
||||
Base `bson:",inline"`
|
||||
}
|
||||
|
||||
func tModelToBSON(model *tModel) bson.D {
|
||||
raw, _ := bson.Marshal(model)
|
||||
|
||||
var doc bson.D
|
||||
bson.Unmarshal(raw, &doc)
|
||||
|
||||
return doc
|
||||
}
|
||||
|
||||
func tModelsToBSON(models []*tModel) []bson.D {
|
||||
docs := make([]bson.D, len(models))
|
||||
for i := range models {
|
||||
docs[i] = tModelToBSON(models[i])
|
||||
}
|
||||
|
||||
return docs
|
||||
}
|
||||
|
||||
func TestRepository_Find(t *testing.T) {
|
||||
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
|
||||
ctx := context.Background()
|
||||
|
||||
mt.Run("returns data on success", func(mt *mtest.T) {
|
||||
data := []*tModel{{Name: "test1"}, {Name: "test2"}}
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
mt.AddMockResponses(mtest.CreateCursorResponse(0, "test.foo", mtest.FirstBatch, tModelsToBSON(data)...))
|
||||
result, err := repo.Find(ctx, bson.M{})
|
||||
assert.Nil(mt, err)
|
||||
assert.Equal(mt, data, result)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepository_FindOne(t *testing.T) {
|
||||
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
|
||||
ctx := context.Background()
|
||||
|
||||
mt.Run("returns data on success", func(mt *mtest.T) {
|
||||
data := &tModel{Name: "test"}
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
mt.AddMockResponses((mtest.CreateCursorResponse(0, "test.foo", mtest.FirstBatch, tModelToBSON(data))))
|
||||
result, err := repo.FindOne(ctx, bson.M{"name": "test"})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, data, result)
|
||||
})
|
||||
|
||||
mt.Run("returns error on failure", func(mt *mtest.T) {
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
mt.AddMockResponses((mtest.CreateCursorResponse(0, "test.foo", mtest.FirstBatch)))
|
||||
_, err := repo.FindOne(ctx, bson.M{"name": "test"})
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepository_FindByID(t *testing.T) {
|
||||
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
|
||||
ctx := context.Background()
|
||||
|
||||
mt.Run("returns data on success", func(mt *mtest.T) {
|
||||
data := &tModel{Base: Base{ObjectID: primitive.NewObjectID()}, Name: "test"}
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
mt.AddMockResponses(mtest.CreateCursorResponse(0, "test.foo", mtest.FirstBatch, tModelToBSON(data)))
|
||||
result, err := repo.FindByID(ctx, data.ID().Hex())
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, data, result)
|
||||
})
|
||||
|
||||
mt.Run("returns error on failure", func(mt *mtest.T) {
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
mt.AddMockResponses(mtest.CreateCursorResponse(0, "test.foo", mtest.FirstBatch))
|
||||
_, err := repo.FindByID(ctx, "invalid")
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepository_Create(t *testing.T) {
|
||||
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
|
||||
ctx := context.Background()
|
||||
|
||||
mt.Run("creates a new document successfully", func(mt *mtest.T) {
|
||||
data := &tModel{Name: "test"}
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
mt.AddMockResponses(mtest.CreateSuccessResponse())
|
||||
result, err := repo.Create(ctx, data)
|
||||
assert.Nil(t, err)
|
||||
assert.NotEmpty(t, result.ObjectID)
|
||||
assert.WithinDuration(t, time.Now(), result.CreatedAt, time.Second)
|
||||
assert.WithinDuration(t, time.Now(), result.UpdatedAt, time.Second)
|
||||
})
|
||||
|
||||
mt.Run("returns error on failure", func(mt *mtest.T) {
|
||||
data := &tModel{Name: "test"}
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
errResponse := mtest.CreateWriteErrorsResponse(mtest.WriteError{Index: 0, Code: 11000, Message: "duplicate key error"})
|
||||
mt.AddMockResponses(errResponse)
|
||||
_, err := repo.Create(ctx, data)
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepository_UpdateOne(t *testing.T) {
|
||||
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
|
||||
ctx := context.Background()
|
||||
|
||||
mt.Run("updates a document successfully", func(mt *mtest.T) {
|
||||
data := &tModel{Name: "test"}
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
successResponse := mtest.CreateSuccessResponse(
|
||||
bson.E{Key: "n", Value: 1},
|
||||
bson.E{Key: "nModified", Value: 1},
|
||||
)
|
||||
|
||||
mt.AddMockResponses(successResponse)
|
||||
result, err := repo.UpdateOne(ctx, bson.M{"name": "test"}, data)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, data, result)
|
||||
assert.WithinDuration(t, time.Now(), result.UpdatedAt, time.Second)
|
||||
})
|
||||
|
||||
mt.Run("returns error on failure", func(mt *mtest.T) {
|
||||
data := &tModel{Name: "test"}
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
errResponse := mtest.CreateWriteErrorsResponse(mtest.WriteError{Index: 0, Code: 11000, Message: "duplicate key error"})
|
||||
mt.AddMockResponses(errResponse)
|
||||
_, err := repo.UpdateOne(ctx, bson.M{"name": "test"}, data)
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepository_DeleteOne(t *testing.T) {
|
||||
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
|
||||
ctx := context.Background()
|
||||
|
||||
mt.Run("deletes a document successfully", func(mt *mtest.T) {
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
successResponse := mtest.CreateSuccessResponse(
|
||||
bson.E{Key: "n", Value: 1},
|
||||
)
|
||||
|
||||
mt.AddMockResponses(successResponse)
|
||||
err := repo.DeleteOne(ctx, bson.M{"name": "test"})
|
||||
assert.Nil(t, err)
|
||||
})
|
||||
|
||||
mt.Run("returns error on failure", func(mt *mtest.T) {
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
errResponse := mtest.CreateWriteErrorsResponse(mtest.WriteError{Index: 0, Code: 11000, Message: "delete error"})
|
||||
mt.AddMockResponses(errResponse)
|
||||
err := repo.DeleteOne(ctx, bson.M{"name": "test"})
|
||||
assert.NotNil(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRepository_CountDocuments(t *testing.T) {
|
||||
mt := mtest.New(t, mtest.NewOptions().ClientType(mtest.Mock))
|
||||
ctx := context.Background()
|
||||
|
||||
mt.Run("returns count on success", func(mt *mtest.T) {
|
||||
repo := NewRepository[*tModel](mt.Coll, []mongo.IndexModel{})
|
||||
|
||||
mt.AddMockResponses(mtest.CreateCursorResponse(1, "test.foo", mtest.FirstBatch, bson.D{bson.E{Key: "n", Value: 2}}))
|
||||
count, err := repo.CountDocuments(ctx, bson.M{"name": "test"})
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, 2, count)
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user