Files
ent/dialect/gremlin/response_test.go

565 lines
9.6 KiB
Go

// Copyright 2019-present Facebook Inc. All rights reserved.
// This source code is licensed under the Apache 2.0 license found
// in the LICENSE file in the root directory of this source tree.
package gremlin
import (
"reflect"
"testing"
"entgo.io/ent/dialect/gremlin/encoding/graphson"
"entgo.io/ent/dialect/gremlin/graph"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestDecodeResponse(t *testing.T) {
in := `{
"requestId": "a65f2d39-1efa-45d2-a06a-c736476500fc",
"result": {
"data": {
"@type": "g:List",
"@value": [
{
"@type": "g:Map",
"@value": [
{
"@type": "g:T",
"@value": "id"
},
{
"@type": "g:Int64",
"@value": 1
},
{
"@type": "g:T",
"@value": "label"
},
"person",
"name",
{
"@type": "g:List",
"@value": [
"marko"
]
},
"age",
{
"@type": "g:List",
"@value": [
{
"@type": "g:Int32",
"@value": 29
}
]
}
]
},
{
"@type": "g:Map",
"@value": [
{
"@type": "g:T",
"@value": "id"
},
{
"@type": "g:Int64",
"@value": 6
},
{
"@type": "g:T",
"@value": "label"
},
"person",
"name",
{
"@type": "g:List",
"@value": [
"peter"
]
},
"age",
{
"@type": "g:List",
"@value": [
{
"@type": "g:Int32",
"@value": 35
}
]
}
]
}
]
},
"meta": {
"@type": "g:Map",
"@value": []
}
},
"status": {
"attributes": {
"@type": "g:Map",
"@value": []
},
"code": 200,
"message": ""
}
}`
var rsp Response
err := graphson.UnmarshalFromString(in, &rsp)
require.NoError(t, err)
assert.Equal(t, "a65f2d39-1efa-45d2-a06a-c736476500fc", rsp.RequestID)
assert.Equal(t, 200, rsp.Status.Code)
assert.Empty(t, rsp.Status.Message)
assert.Empty(t, rsp.Status.Attributes)
assert.Empty(t, rsp.Result.Meta)
var vm graph.ValueMap
err = graphson.Unmarshal(rsp.Result.Data, &vm)
require.NoError(t, err)
require.Len(t, vm, 2)
type person struct {
ID int64 `json:"id"`
Name string `json:"name"`
Age int `json:"age"`
}
var people []person
err = vm.Decode(&people)
require.NoError(t, err)
assert.Equal(t, []person{
{1, "marko", 29},
{6, "peter", 35},
}, people)
}
func TestDecodeResponseWithError(t *testing.T) {
in := `{
"requestId": "41d2e28a-20a4-4ab0-b379-d810dede3786",
"result": {
"data": null,
"meta": {
"@type": "g:Map",
"@value": []
}
},
"status": {
"attributes": {
"@type": "g:Map",
"@value": []
},
"code": 500,
"message": "Database Down"
}
}`
var rsp Response
err := graphson.UnmarshalFromString(in, &rsp)
require.NoError(t, err)
err = rsp.Err()
require.Error(t, err)
assert.Contains(t, err.Error(), "Database Down")
rsp = Response{}
err = graphson.UnmarshalFromString(`{"status": null}`, &rsp)
require.NoError(t, err)
assert.Error(t, rsp.Err())
}
func TestResponseReadVal(t *testing.T) {
var rsp Response
rsp.Status.Code = StatusSuccess
rsp.Result.Data = []byte(`{"@type": "g:Int32", "@value": 15}`)
var v int32
err := rsp.ReadVal(&v)
assert.NoError(t, err)
assert.Equal(t, int32(15), v)
var s string
err = rsp.ReadVal(&s)
assert.Error(t, err)
rsp.Status.Code = StatusServerError
err = rsp.ReadVal(&v)
assert.Error(t, err)
}
func TestResponseReadGraphElements(t *testing.T) {
tests := []struct {
method string
data string
want interface{}
}{
{
method: "ReadVertices",
data: `{
"@type": "g:List",
"@value": [
{
"@type": "g:Vertex",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 1
},
"label": "person"
}
},
{
"@type": "g:Vertex",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 6
},
"label": "person"
}
}
]
}`,
want: []graph.Vertex{
graph.NewVertex(int64(1), "person"),
graph.NewVertex(int64(6), "person"),
},
},
{
method: "ReadVertexProperties",
data: `{
"@type": "g:List",
"@value": [
{
"@type": "g:VertexProperty",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 0
},
"label": "name",
"value": "marko"
}
},
{
"@type": "g:VertexProperty",
"@value": {
"id": {
"@type": "g:Int64",
"@value": 2
},
"label": "age",
"value": {
"@type": "g:Int32",
"@value": 29
}
}
}
]
}`,
want: []graph.VertexProperty{
graph.NewVertexProperty(int64(0), "name", "marko"),
graph.NewVertexProperty(int64(2), "age", int32(29)),
},
},
{
method: "ReadEdges",
data: `{
"@type": "g:List",
"@value": [
{
"@type": "g:Edge",
"@value": {
"id": {
"@type": "g:Int32",
"@value": 12
},
"inV": {
"@type": "g:Int64",
"@value": 3
},
"inVLabel": "software",
"label": "created",
"outV": {
"@type": "g:Int64",
"@value": 6
},
"outVLabel": "person"
}
}
]
}`,
want: []graph.Edge{
graph.NewEdge(int32(12), "created",
graph.NewVertex(int64(6), "person"),
graph.NewVertex(int64(3), "software"),
),
},
},
{
method: "ReadProperties",
data: `{
"@type": "g:List",
"@value": [
{
"@type": "g:Property",
"@value": {
"key": "weight",
"value": {
"@type": "g:Double",
"@value": 0.2
}
}
}
]
}`,
want: []graph.Property{
graph.NewProperty("weight", float64(0.2)),
},
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.method, func(t *testing.T) {
t.Parallel()
var rsp Response
rsp.Status.Code = StatusSuccess
rsp.Result.Data = []byte(tc.data)
vals := reflect.ValueOf(&rsp).MethodByName(tc.method).Call(nil)
require.Len(t, vals, 2)
require.True(t, vals[1].IsNil())
assert.Equal(t, tc.want, vals[0].Interface())
})
}
}
func TestResponseReadValueMap(t *testing.T) {
t.Parallel()
var rsp Response
rsp.Status.Code = StatusSuccess
rsp.Result.Data = []byte(`{
"@type": "g:List",
"@value": [
{
"@type": "g:Map",
"@value": [
"name",
{
"@type": "g:List",
"@value": [
"alex"
]
}
]
}
]
}`)
m, err := rsp.ReadValueMap()
require.NoError(t, err)
var name string
err = m.Decode(&struct {
Name *string `json:"name"`
}{&name})
require.NoError(t, err)
assert.Equal(t, "alex", name)
}
func TestResponseReadBool(t *testing.T) {
tests := []struct {
name string
data string
want bool
wantErr bool
}{
{
name: "Simple",
data: `{
"@type": "g:List",
"@value": [
true
]
}`,
want: true,
},
{
name: "Multi",
data: `{
"@type": "g:List",
"@value": [
false,
true
]
}`,
want: false,
},
{
name: "Empty",
data: `{
"@type": "g:List",
"@value": []
}`,
wantErr: true,
},
{
name: "BadType",
data: `{
"@type": "g:List",
"@value": [
"user"
]
}`,
wantErr: true,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var rsp Response
rsp.Status.Code = StatusSuccess
rsp.Result.Data = []byte(tc.data)
got, err := rsp.ReadBool()
if tc.wantErr {
assert.Error(t, err)
} else {
require.NoError(t, err)
assert.Equal(t, tc.want, got)
}
})
}
}
func TestResponseReadInt(t *testing.T) {
tests := []struct {
name string
data string
want int
wantErr bool
}{
{
name: "Simple",
data: `{
"@type": "g:List",
"@value": [
{
"@type": "g:Int64",
"@value": 42
}
]
}`,
want: 42,
},
{
name: "Multi",
data: `{
"@type": "g:List",
"@value": [
{
"@type": "g:Int64",
"@value": 55
},
{
"@type": "g:Int64",
"@value": 13
}
]
}`,
want: 55,
},
{
name: "Empty",
data: `{
"@type": "g:List",
"@value": []
}`,
wantErr: true,
},
{
name: "BadType",
data: `{
"@type": "g:List",
"@value": [
true
]
}`,
wantErr: true,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var rsp Response
rsp.Status.Code = StatusSuccess
rsp.Result.Data = []byte(tc.data)
got, err := rsp.ReadInt()
if tc.wantErr {
assert.Error(t, err)
} else {
require.NoError(t, err)
assert.Equal(t, tc.want, got)
}
})
}
}
func TestResponseReadString(t *testing.T) {
tests := []struct {
name string
data string
want string
wantErr bool
}{
{
name: "Simple",
data: `{
"@type": "g:List",
"@value": ["foo"]
}`,
want: "foo",
},
{
name: "Empty",
data: `{
"@type": "g:List",
"@value": []
}`,
wantErr: true,
},
{
name: "BadType",
data: `{
"@type": "g:List",
"@value": [
true
]
}`,
wantErr: true,
},
}
for _, tc := range tests {
tc := tc
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
var rsp Response
rsp.Status.Code = StatusSuccess
rsp.Result.Data = []byte(tc.data)
got, err := rsp.ReadString()
if tc.wantErr {
assert.Error(t, err)
} else {
require.NoError(t, err)
assert.Equal(t, tc.want, got)
}
})
}
}