Skip to content
Snippets Groups Projects
Commit d2067726 authored by Anton Sattarov's avatar Anton Sattarov :cucumber:
Browse files

fix tests

parent 7139be18
No related branches found
No related tags found
No related merge requests found
package filter package filter
import ( import (
"context"
"fmt"
"os"
"testing" "testing"
"time" "time"
"git.perx.ru/perxis/perxis-go/pkg/schema" "git.perx.ru/perxis/perxis-go/pkg/schema"
"git.perx.ru/perxis/perxis-go/pkg/schema/field" "git.perx.ru/perxis/perxis-go/pkg/schema/field"
"git.perx.ru/perxis/perxis-go/pkg/schema/validate"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.mongodb.org/mongo-driver/bson/primitive" "go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
) )
func TestFilterHandler(t *testing.T) { func TestFilterHandler(t *testing.T) {
...@@ -227,253 +221,253 @@ func TestFilterHandler(t *testing.T) { ...@@ -227,253 +221,253 @@ func TestFilterHandler(t *testing.T) {
}) })
} }
func TestFilterHandler_Integration(t *testing.T) { //func TestFilterHandler_Integration(t *testing.T) {
ctx := context.Background() // ctx := context.Background()
//
uri := os.Getenv("MONGO_URL") // uri := os.Getenv("MONGO_URL")
if uri == "" { // if uri == "" {
uri = "mongodb://localhost:27017" // uri = "mongodb://localhost:27017"
} // }
opts := options.Client().SetConnectTimeout(15 * time.Second).ApplyURI(uri) // opts := options.Client().SetConnectTimeout(15 * time.Second).ApplyURI(uri)
client, err := mongo.Connect(context.Background(), opts) // client, err := mongo.Connect(context.Background(), opts)
require.NoError(t, err) // require.NoError(t, err)
err = client.Ping(ctx, nil) // err = client.Ping(ctx, nil)
require.NoError(t, err) // require.NoError(t, err)
//
sch := schema.New( // sch := schema.New(
"name", field.String(validate.Required()), // "name", field.String(validate.Required()),
"color", field.String(), // "color", field.String(),
"qty", field.Number(field.NumberFormatInt), // "qty", field.Number(field.NumberFormatInt),
"info", field.Object( // "info", field.Object(
"is_fruit", field.Bool(), // "is_fruit", field.Bool(),
"similar", field.Array( // "similar", field.Array(
field.Object( // field.Object(
"name", field.Number(field.NumberFormatFloat), // "name", field.Number(field.NumberFormatFloat),
"color", field.String(), // "color", field.String(),
), // ),
), // ),
"desc", field.String(), // "desc", field.String(),
), // ),
"produced", field.Time(), // "produced", field.Time(),
"shipment", field.Array(field.String()), // "shipment", field.Array(field.String()),
) // )
//
w1, _ := time.Parse(time.RFC3339, "2020-01-01T10:08:41Z") // w1, _ := time.Parse(time.RFC3339, "2020-01-01T10:08:41Z")
w2, _ := time.Parse(time.RFC3339, "2020-05-01T10:08:41Z") // w2, _ := time.Parse(time.RFC3339, "2020-05-01T10:08:41Z")
w3, _ := time.Parse(time.RFC3339, "2020-10-01T10:08:41Z") // w3, _ := time.Parse(time.RFC3339, "2020-10-01T10:08:41Z")
//
items := []map[string]interface{}{ // items := []map[string]interface{}{
{ // {
"name": "apple", // "name": "apple",
"color": "red", // "color": "red",
"qty": 25, // "qty": 25,
"info": map[string]interface{}{ // "info": map[string]interface{}{
"is_fruit": true, // "is_fruit": true,
"similar": []interface{}{ // "similar": []interface{}{
map[string]interface{}{"name": "pear", "color": "yellow"}, // map[string]interface{}{"name": "pear", "color": "yellow"},
map[string]interface{}{"name": "lemon", "color": "yellow"}, // map[string]interface{}{"name": "lemon", "color": "yellow"},
}, // },
"desc": "An apple is the edible fruit . Apple trees are cultivated worldwide and have religious and mythological " + // "desc": "An apple is the edible fruit . Apple trees are cultivated worldwide and have religious and mythological " +
"significance in many cultures. Apples are eaten with honey at the Jewish New Year of Rosh Hashanah to symbolize a sweet new year.", // "significance in many cultures. Apples are eaten with honey at the Jewish New Year of Rosh Hashanah to symbolize a sweet new year.",
}, // },
"produced": w1, // "produced": w1,
"shipment": []interface{}{"Russia", "Iran"}, // "shipment": []interface{}{"Russia", "Iran"},
"storepoint": map[string]interface{}{"type": "Point", "coordinates": []float64{55.751472, 37.618727}}, // "storepoint": map[string]interface{}{"type": "Point", "coordinates": []float64{55.751472, 37.618727}},
}, // },
{ // {
"name": "orange", // "name": "orange",
"color": "orange", // "color": "orange",
"qty": 10, // "qty": 10,
"info": map[string]interface{}{ // "info": map[string]interface{}{
"is_fruit": true, // "is_fruit": true,
"similar": []interface{}{ // "similar": []interface{}{
map[string]interface{}{"name": "lemon", "color": "yellow"}, // map[string]interface{}{"name": "lemon", "color": "yellow"},
map[string]interface{}{"name": "grapefruit", "color": "red"}, // map[string]interface{}{"name": "grapefruit", "color": "red"},
}, // },
"desc": "The orange is the edible fruit of various citrus species; a hybrid between pomelo and mandarin. Orange trees are widely grown" + // "desc": "The orange is the edible fruit of various citrus species; a hybrid between pomelo and mandarin. Orange trees are widely grown" +
" in tropical and subtropical climates for their sweet fruit. The fruit of the orange tree can be eaten fresh, or processed for its juice or fragrant peel.", // " in tropical and subtropical climates for their sweet fruit. The fruit of the orange tree can be eaten fresh, or processed for its juice or fragrant peel.",
}, // },
"produced": w2, // "produced": w2,
"shipment": []interface{}{"Egypt", "Iran"}, // "shipment": []interface{}{"Egypt", "Iran"},
"storepoint": map[string]interface{}{"type": "Point", "coordinates": []float64{55.716797, 37.552809}}, // "storepoint": map[string]interface{}{"type": "Point", "coordinates": []float64{55.716797, 37.552809}},
}, // },
{ // {
"name": "tomato", // "name": "tomato",
"color": "red", // "color": "red",
"qty": 1, // "qty": 1,
"info": map[string]interface{}{ // "info": map[string]interface{}{
"is_fruit": false, // "is_fruit": false,
"similar": []interface{}{ // "similar": []interface{}{
map[string]interface{}{"name": "cucumber", "color": "green"}, // map[string]interface{}{"name": "cucumber", "color": "green"},
map[string]interface{}{"name": "apple", "color": "yellow"}, // map[string]interface{}{"name": "apple", "color": "yellow"},
}, // },
"desc": "The tomato is the edible red berry. The tomato is consumed in diverse ways, raw or cooked, in many dishes, " + // "desc": "The tomato is the edible red berry. The tomato is consumed in diverse ways, raw or cooked, in many dishes, " +
"sauces, salads, and drinks. Numerous varieties of the tomato plant are widely grown in temperate climates across the world.", // "sauces, salads, and drinks. Numerous varieties of the tomato plant are widely grown in temperate climates across the world.",
}, // },
"produced": w3, // "produced": w3,
"shipment": []interface{}{"Russia", "Italy"}, // "shipment": []interface{}{"Russia", "Italy"},
"storepoint": map[string]interface{}{"type": "Point", "coordinates": []float64{55.760688, 37.619125}}, // "storepoint": map[string]interface{}{"type": "Point", "coordinates": []float64{55.760688, 37.619125}},
}, // },
} // }
//
db := client.Database("perxis_test_filter") // db := client.Database("perxis_test_filter")
coll := db.Collection("items") // coll := db.Collection("items")
coll.Drop(ctx) // coll.Drop(ctx)
//
for _, item := range items { // for _, item := range items {
_, err = coll.InsertOne(ctx, item) // _, err = coll.InsertOne(ctx, item)
require.NoError(t, err) // require.NoError(t, err)
} // }
//
h := NewFilterHandler(sch) // h := NewFilterHandler(sch)
h.SetQueryBuilder(NewMongoQueryBuilder()) // h.SetQueryBuilder(NewMongoQueryBuilder())
//
t.Run("By Color [Equal/NotEqual]", func(t *testing.T) { // t.Run("By Color [Equal/NotEqual]", func(t *testing.T) {
t.Run("Red", func(t *testing.T) { // t.Run("Red", func(t *testing.T) {
query := h.Query(&Filter{Op: Equal, Field: "color", Value: "red"}) // query := h.Query(&Filter{Op: Equal, Field: "color", Value: "red"})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 2) // require.Len(t, data, 2)
assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]}) // assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]})
}) // })
t.Run("Not Red", func(t *testing.T) { // t.Run("Not Red", func(t *testing.T) {
query := h.Query(&Filter{Op: NotEqual, Field: "color", Value: "red"}) // query := h.Query(&Filter{Op: NotEqual, Field: "color", Value: "red"})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 1) // require.Len(t, data, 1)
assert.Equal(t, "orange", data[0]["name"]) // assert.Equal(t, "orange", data[0]["name"])
}) // })
}) // })
t.Run("By Quantity [Less/Greater]", func(t *testing.T) { // t.Run("By Quantity [Less/Greater]", func(t *testing.T) {
query := h.Query(&Filter{Op: LessOrEqual, Field: "qty", Value: 25}, &Filter{Op: Greater, Field: "qty", Value: 1}) // query := h.Query(&Filter{Op: LessOrEqual, Field: "qty", Value: 25}, &Filter{Op: Greater, Field: "qty", Value: 1})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 2) // require.Len(t, data, 2)
assert.ElementsMatch(t, []interface{}{"apple", "orange"}, []interface{}{data[0]["name"], data[1]["name"]}) // assert.ElementsMatch(t, []interface{}{"apple", "orange"}, []interface{}{data[0]["name"], data[1]["name"]})
}) // })
t.Run("Not Fruit [Equal embedded field]", func(t *testing.T) { // t.Run("Not Fruit [Equal embedded field]", func(t *testing.T) {
query := h.Query(&Filter{Op: Equal, Field: "info.is_fruit", Value: false}) // query := h.Query(&Filter{Op: Equal, Field: "info.is_fruit", Value: false})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 1) // require.Len(t, data, 1)
assert.Equal(t, "tomato", data[0]["name"]) // assert.Equal(t, "tomato", data[0]["name"])
}) // })
t.Run("By Similar [In/NotIn]", func(t *testing.T) { // t.Run("By Similar [In/NotIn]", func(t *testing.T) {
t.Run("Similar to cucumber, pear", func(t *testing.T) { // t.Run("Similar to cucumber, pear", func(t *testing.T) {
query := h.Query(&Filter{Op: In, Field: "info.similar.name", Value: []string{"cucumber", "pear"}}) // query := h.Query(&Filter{Op: In, Field: "info.similar.name", Value: []string{"cucumber", "pear"}})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 2) // require.Len(t, data, 2)
assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]}) // assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]})
}) // })
t.Run("Not Similar to cucumber, pear", func(t *testing.T) { // t.Run("Not Similar to cucumber, pear", func(t *testing.T) {
query := h.Query(&Filter{Op: NotIn, Field: "info.similar.name", Value: []string{"cucumber", "grapefruit"}}) // query := h.Query(&Filter{Op: NotIn, Field: "info.similar.name", Value: []string{"cucumber", "grapefruit"}})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 1) // require.Len(t, data, 1)
assert.Equal(t, "apple", data[0]["name"]) // assert.Equal(t, "apple", data[0]["name"])
}) // })
}) // })
t.Run("By Description [Contains/NotContains]", func(t *testing.T) { // t.Run("By Description [Contains/NotContains]", func(t *testing.T) {
t.Run("Contains", func(t *testing.T) { // t.Run("Contains", func(t *testing.T) {
query := h.Query(&Filter{Op: And, Value: []*Filter{ // query := h.Query(&Filter{Op: And, Value: []*Filter{
&Filter{Op: In, Field: "info.similar.color", Value: []string{"yellow"}}, // &Filter{Op: In, Field: "info.similar.color", Value: []string{"yellow"}},
&Filter{Op: Contains, Field: "info.desc", Value: "edible fruit"}, // &Filter{Op: Contains, Field: "info.desc", Value: "edible fruit"},
}}) // }})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 2) // require.Len(t, data, 2)
assert.ElementsMatch(t, []interface{}{"apple", "orange"}, []interface{}{data[0]["name"], data[1]["name"]}) // assert.ElementsMatch(t, []interface{}{"apple", "orange"}, []interface{}{data[0]["name"], data[1]["name"]})
}) // })
t.Run("Not Contains", func(t *testing.T) { // t.Run("Not Contains", func(t *testing.T) {
query := h.Query(&Filter{Op: NotContains, Field: "info.desc", Value: "fruit"}) // query := h.Query(&Filter{Op: NotContains, Field: "info.desc", Value: "fruit"})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
for _, d := range data { // for _, d := range data {
fmt.Println(d["name"]) // fmt.Println(d["name"])
} // }
require.Len(t, data, 1) // require.Len(t, data, 1)
assert.Equal(t, "tomato", data[0]["name"]) // assert.Equal(t, "tomato", data[0]["name"])
}) // })
}) // })
t.Run("By Shipment [Contains/NotContains]", func(t *testing.T) { // t.Run("By Shipment [Contains/NotContains]", func(t *testing.T) {
t.Run("Contains", func(t *testing.T) { // t.Run("Contains", func(t *testing.T) {
query := h.Query( // query := h.Query(
&Filter{Op: Contains, Field: "shipment", Value: "Russia"}, // &Filter{Op: Contains, Field: "shipment", Value: "Russia"},
) // )
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 2) // require.Len(t, data, 2)
assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]}) // assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]})
}) // })
t.Run("Not Contains", func(t *testing.T) { // t.Run("Not Contains", func(t *testing.T) {
query := h.Query(&Filter{Op: NotContains, Field: "shipment", Value: "Iran"}) // query := h.Query(&Filter{Op: NotContains, Field: "shipment", Value: "Iran"})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
for _, d := range data { // for _, d := range data {
fmt.Println(d["name"]) // fmt.Println(d["name"])
} // }
require.Len(t, data, 1) // require.Len(t, data, 1)
assert.Equal(t, "tomato", data[0]["name"]) // assert.Equal(t, "tomato", data[0]["name"])
}) // })
}) // })
t.Run("Compound Query", func(t *testing.T) { // t.Run("Compound Query", func(t *testing.T) {
query := h.Query(&Filter{Op: Or, Value: []*Filter{ // query := h.Query(&Filter{Op: Or, Value: []*Filter{
&Filter{Op: And, Value: []*Filter{ // &Filter{Op: And, Value: []*Filter{
&Filter{Op: In, Field: "color", Value: []interface{}{"red", "yellow", "green"}}, // &Filter{Op: In, Field: "color", Value: []interface{}{"red", "yellow", "green"}},
&Filter{Op: Less, Field: "qty", Value: 10}, // &Filter{Op: Less, Field: "qty", Value: 10},
}}, // 1 - tomato // }}, // 1 - tomato
&Filter{Op: Equal, Field: "name", Value: "pepper"}, // 0 // &Filter{Op: Equal, Field: "name", Value: "pepper"}, // 0
&Filter{Op: And, Value: []*Filter{ // &Filter{Op: And, Value: []*Filter{
&Filter{Op: GreaterOrEqual, Field: "produced", Value: w1}, // &Filter{Op: GreaterOrEqual, Field: "produced", Value: w1},
&Filter{Op: Less, Field: "produced", Value: w2}, // 1 - apple // &Filter{Op: Less, Field: "produced", Value: w2}, // 1 - apple
}}, // }},
}}) // }})
res, err := coll.Find(ctx, query) // res, err := coll.Find(ctx, query)
require.NoError(t, err) // require.NoError(t, err)
//
var data []map[string]interface{} // var data []map[string]interface{}
err = res.All(ctx, &data) // err = res.All(ctx, &data)
require.NoError(t, err) // require.NoError(t, err)
require.Len(t, data, 2) // require.Len(t, data, 2)
assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]}) // assert.ElementsMatch(t, []interface{}{"apple", "tomato"}, []interface{}{data[0]["name"], data[1]["name"]})
}) // })
} //}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment