/* This program has been developed by students from the bachelor Computer Science at Utrecht University within the Software Project course. © Copyright Utrecht University (Department of Information and Computing Sciences) */ package aql import ( "encoding/json" "errors" "strings" "testing" "git.science.uu.nl/graphpolaris/query-conversion/entity" "github.com/stretchr/testify/assert" ) /* Tests an empty query t: *testing.T, makes go recognise this as a test */ func TestEmptyQueryConversion(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [], "relations": [] }, "entities": [], "relations": [], "groupBys": [], "filters": [], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET nodes = first(RETURN UNION_DISTINCT([],[])) LET edges = first(RETURN UNION_DISTINCT([],[])) RETURN {"vertices":nodes, "edges":edges }` assert.Equal(t, correctConvertedResult, *convertedResult) } /* Tests multiple entity types t: *testing.T, makes go recognise this as a test */ func TestMultipleEntityTypes(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "databaseName": "test", "return": { "entities": [ 0, 1 ], "relations": [ 0 ] }, "entities": [ { "name": "kamerleden", "ID": 0 }, { "name": "partijen", "ID": 1 } ], "relations": [ { "ID": 0, "name": "lid_van", "depth": { "min": 1, "max": 1 }, "fromType": "entity", "fromID": 0, "toType": "entity", "toID": 1 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "partij", "value": "GL", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 1, "fromType": "entity", "fromID": 1, "toType": "relation", "toID": 0, "attribute": "zetels", "value": "6", "dataType": "int", "matchType": "GT", "inType": "", "inID": -1 } ], "limit": 5000, "modifiers": [] }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET e0 = (FOR x IN kamerledenRETURN x)LET e1 = (FOR x IN partijenRETURN x)LET f0 = (FOR x IN e0FILTER x.partij == GLRETURN x)LET f1 = (FOR x IN e1FILTER x.zetels > 6RETURN x)LET r0 = (FOR x IN lid_vanFOR y in f0FOR z in f1FILTER x._from == y._id AND x._to == z._idLET nodes = APPEND([], [y, z])RETURN DISTINCT {"edges": x,"vertices": nodes})LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices),[],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges),[],[]))RETURN {"vertices":nodes, "edges":edges }` //cleanedResult := strings.ReplaceAll(correctConvertedResult, "\n", "") //cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") convertedCleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") convertedCleanedResult = strings.ReplaceAll(convertedCleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, convertedCleanedResult) } /* Tests a query with one attribute t: *testing.T, makes go recognise this as a test */ func TestEntityOneAttributeQuery(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [] }, "entities": [ { "name": "airports", "ID": 0 } ], "groupBys": [], "relations": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "", "toID": -1, "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET nodes = first(RETURN UNION_DISTINCT(n0,[],[]))LET edges = first(RETURN UNION_DISTINCT([],[]))RETURN {"vertices":nodes, "edges":edges }` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Test a relation with a constraint t: *testing.T, makes go recognise this as a test */ func TestRelationWithConstraint(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports", "constraints": [ { "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact" } ] } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 1 }, "FromType": "entity", "fromID": 0, "ToType": "", "toID": -1, "constraints": [ { } ] } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "Day", "value": "15", "dataType": "int", "matchType": "EQ", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests the count modifier t: *testing.T, makes go recognise this as a test */ func TestModifierCountEntity(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [] }, "entities": [ { "ID": 0, "type": "airports", "constraints": [ {} ] } ], "relations": [], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000, "modifiers": [ { "type": "COUNT", "selectedType": "entity", "id": 0, "attributeIndex": -1 } ] }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)RETURN LENGTH (n0)` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests the count modifer with an attribute t: *testing.T, makes go recognise this as a test */ func TestModifierCountEntityAttribute(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "", "toID": -1, "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000, "modifiers": [ { "type": "SUM", "selectedType": "entity", "id": 0, "attributeIndex": 0 } ] }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)RETURN SUM (n0[*].state)` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests the count modifier on a relation t: *testing.T, makes go recognise this as a test */ func TestModifierCountRelation(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "entity", "fromID": 0, "toType": "", "toID": -1 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 1, "fromType": "relation", "fromID": 0, "toType": "entity", "toID": 0, "attribute": "Day", "value": "15", "dataType": "int", "matchType": "EQ", "inType": "", "inID": -1 } ], "limit": 5000, "modifiers": [ { "type": "COUNT", "selectedType": "relation", "id": 0, "attributeIndex": -1 } ] }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 RETURN DISTINCT p )RETURN LENGTH (unique(r0[*].edges[**]))` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests the count modifier with an entity swap t: *testing.T, makes go recognise this as a test */ func TestModifierCountEntitySwap(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "databaseName": "TweedeKamer", "return": { "entities": [ 0, 1 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "partijen" }, { "ID": 1, "type": "kamerleden" } ], "relations": [ { "ID": 0, "type": "lid_van", "depth": { "min": 1, "max": 1 }, "fromType": "entity", "fromID": 1, "toType": "entity", "toID": 0 } ], "groupBys": [], "filters": [], "limit": 5000, "modifiers": [ { "type": "COUNT", "selectedType": "entity", "selectedTypeId": 1, "attributeIndex": -1 } ] }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `WITH partijenLET n1 = (FOR x IN kamerleden RETURN x)LET r0 = (FOR x IN n1 FOR v, e, p IN 1..1 OUTBOUND x lid_van OPTIONS { uniqueEdges: "path" }RETURN DISTINCT p )RETURN LENGTH (unique(r0[*].vertices[0]))` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests the count modifier on a relation and attribute t: *testing.T, makes go recognise this as a test */ func TestModifierCountRelationAttribute(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [ { "ID":0, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "entity", "fromID": 0, "toType": "", "toID": -1 } ], "groupBys": [ ], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 1, "fromType": "relation", "fromID": 0, "toType": "", "toID": -1, "attribute": "Day", "value": "15", "dataType": "int", "matchType": "EQ", "inType": "", "inID": -1 } ], "limit": 5000, "modifiers": [ { "type": "AVG", "selectedType": "relation", "id": 0, "attributeIndex": 0 } ] }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER p.edges[*].Day ALL == 15 RETURN DISTINCT p )RETURN AVG (r0[*].edges[**].Day)` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests a relation with an in out constraint t: *testing.T, makes go recognise this as a test */ func TestRelationWithInOutConstraint(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0, 1 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports", "constraints": [ { "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact" } ] }, { "ID": 1, "type": "airports", "constraints": [ { "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact" } ] } ], "relations": [ { "ID":0, "type": "flights", "depth": { "min": 1, "max": 3 }, "fromType": "entity", "fromID": 1, "toType": "entity", "toID": 0 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 1, "fromType": "entity", "fromID": 1, "toType": "relation", "toID": 0, "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 2, "fromType": "relation", "fromID": 0, "toType": "", "toID": -1, "attribute": "Day", "value": "15", "dataType": "int", "matchType": "EQ", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n1 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n1 FOR v, e, p IN 1..3 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER v.city == "San Francisco" FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests two relations t: *testing.T, makes go recognise this as a test */ func TestTwoRelations(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0, 1, 2 ], "relations": [ 0, 1 ] }, "entities": [ { "ID": 0, "type": "airports" }, { "ID": 1, "type": "airports" }, { "ID": 2, "type": "airports" } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 3 }, "fromType": "entity", "fromID": 2, "toType": "entity", "toID": 1 }, { "ID":1, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "entity", "fromID": 0, "toType": "", "toID": -1 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 1, "attribute": "city", "value": "New York", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 1, "fromType": "entity", "fromID": 1, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 2, "fromType": "entity", "fromID": 2, "toType": "relation", "toID": 0, "attribute": "state", "value": "HI", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 }, { "ID": 3, "fromType": "relation", "fromID": 0, "toType": "", "toID": -1, "attribute": "Day", "value": "15", "dataType": "int", "matchType": "EQ", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n2 = (FOR x IN airports FILTER x.state == "HI" RETURN x)LET r0 = (FOR x IN n2 FOR v, e, p IN 1..3 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }FILTER v.city == "San Francisco" FILTER p.edges[*].Day ALL == 15 LIMIT 5000 RETURN DISTINCT p )LET n0 = (FOR x IN airports FILTER x.city == "New York" RETURN x)LET r1 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x flights OPTIONS { uniqueEdges: "path" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), flatten(r1[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), flatten(r1[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests a relation with only a to node t: *testing.T, makes go recognise this as a test */ func TestRelationWithOnlyToNode(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "", "fromID": -1, "toType": "entity", "toID": 0 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.city == "San Francisco" RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 INBOUND x flights OPTIONS { uniqueEdges: "path" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), [],[]))RETURN {"vertices":nodes, "edges":edges }` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests too manu return entities t: *testing.T, makes go recognise this as a test */ func TestTooManyReturnEntities(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0, 1, 2 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "", "fromID": -1, "toType": "entity", "toID": 0 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) _, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.Equal(t, errors.New("non-existing entity referenced in return"), err) } /* Tests too manu return relations t: *testing.T, makes go recognise this as a test */ func TestTooManyReturnRelations(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [ 0, 1, 2 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "", "fromID": -1, "toType": "entity", "toID": 0 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) _, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.Equal(t, errors.New("non-existing relation referenced in return"), err) } /* Tests negative return entities t: *testing.T, makes go recognise this as a test */ func TestNegativeReturnEntities(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0, -1 ], "relations": [ 0, 1, 2 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "", "fromID": -1, "toType": "entity", "toID": 0 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) _, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.Equal(t, errors.New("non-existing entity referenced in return"), err) } /* Tests a query with no relation field t: *testing.T, makes go recognise this as a test */ func TestNoRelationsField(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := `LET n0 = (FOR x IN airports FILTER x.city == "San Francisco" RETURN x)LET nodes = first(RETURN UNION_DISTINCT(n0,[],[]))LET edges = first(RETURN UNION_DISTINCT([],[]))RETURN {"vertices":nodes, "edges":edges }` cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests a query with double WITH t: *testing.T, makes go recognise this as a test */ func TestDoubleWITH(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "databaseName": "test", "return": { "entities": [ 0, 1, 2, 3 ], "relations": [ 0, 1 ] }, "entities": [ { "ID": 0, "type": "kamerleden" }, { "ID": 1, "type": "partijen" }, { "ID": 2, "type": "kamerleden" }, { "ID": 3, "type": "commissies" } ], "relations": [ { "ID": 0, "type": "lid_van", "depth": { "min": 1, "max": 1 }, "fromType": "entity", "fromID": 0, "toType": "entity", "toID": 1 }, { "ID": 1, "type": "onderdeel_van", "depth": { "min": 1, "max": 1 }, "fromType": "entity", "fromID": 2, "toType": "entity", "toID": 3 } ], "groupBys": [], "filters": [], "limit": 5000, "modifiers": [] }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) convertedResult, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) // Assert that the result and the expected result are the same correctConvertedResult := "WITH partijen, commissiesLET n0 = (FOR x IN kamerleden RETURN x)LET r0 = (FOR x IN n0 FOR v, e, p IN 1..1 OUTBOUND x lid_van OPTIONS { uniqueEdges: \"path\" }LIMIT 5000 RETURN DISTINCT p )LET n2 = (FOR x IN kamerleden RETURN x)LET r1 = (FOR x IN n2 FOR v, e, p IN 1..1 OUTBOUND x onderdeel_van OPTIONS { uniqueEdges: \"path\" }LIMIT 5000 RETURN DISTINCT p )LET nodes = first(RETURN UNION_DISTINCT(flatten(r0[**].vertices), flatten(r1[**].vertices), [],[]))LET edges = first(RETURN UNION_DISTINCT(flatten(r0[**].edges), flatten(r1[**].edges), [],[]))RETURN {\"vertices\":nodes, \"edges\":edges }" cleanedResult := strings.ReplaceAll(*convertedResult, "\n", "") cleanedResult = strings.ReplaceAll(cleanedResult, "\t", "") assert.Equal(t, correctConvertedResult, cleanedResult) } /* Tests an entity with a lower than -1 in a relation t: *testing.T, makes go recognise this as a test */ func TestEntityFromLowerThanNegativeOneInRelation(t *testing.T) { // Setup for test // Create query conversion service service := NewService() query := []byte(`{ "return": { "entities": [ 0 ], "relations": [ 0 ] }, "entities": [ { "ID": 0, "type": "airports" } ], "relations": [ { "ID": 0, "type": "flights", "depth": { "min": 1, "max": 1 }, "fromType": "", "fromID": -4, "toType": "entity", "toID": 0 } ], "groupBys": [], "filters": [ { "ID": 0, "fromType": "entity", "fromID": 0, "toType": "relation", "toID": 0, "attribute": "city", "value": "San Francisco", "dataType": "string", "matchType": "exact", "inType": "", "inID": -1 } ], "limit": 5000 }`) // Unmarshall the incoming message into an IncomingJSONQuery object var JSONQuery entity.IncomingQueryJSON json.Unmarshal(query, &JSONQuery) _, err := service.ConvertQuery(&JSONQuery) // Assert that there is no error assert.NoError(t, err) }