196 lines
6.0 KiB
Go
196 lines
6.0 KiB
Go
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)
|
|
})
|
|
}
|