From e4c59a965b9b864dd3759fe75836a8b6896d9688 Mon Sep 17 00:00:00 2001 From: Islam Aliev Date: Fri, 3 May 2024 22:41:57 +0200 Subject: [PATCH] test: Add more ACP integration tests (#2583) Resolves #2474 and #2475 Add integration tests for ACP on relation objects and `_avg` and `_count` methods. --- tests/integration/acp/query/avg_test.go | 98 +++++++ tests/integration/acp/query/count_test.go | 183 +++++++++++++ tests/integration/acp/query/fixture.go | 148 +++++++++++ .../acp/query/relation_objects_test.go | 242 ++++++++++++++++++ 4 files changed, 671 insertions(+) create mode 100644 tests/integration/acp/query/avg_test.go create mode 100644 tests/integration/acp/query/count_test.go create mode 100644 tests/integration/acp/query/fixture.go create mode 100644 tests/integration/acp/query/relation_objects_test.go diff --git a/tests/integration/acp/query/avg_test.go b/tests/integration/acp/query/avg_test.go new file mode 100644 index 0000000000..cd540f83ad --- /dev/null +++ b/tests/integration/acp/query/avg_test.go @@ -0,0 +1,98 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" +) + +func TestACP_QueryAverageWithoutIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query average without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Request: ` + query { + _avg(Employee: {field: salary}) + } + `, + Results: []map[string]any{ + { + // 2 public employees, 1 with salary 10k, 1 with salary 20k + "_avg": int(15000), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryAverageWithIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query average with identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor1Identity, + Request: ` + query { + _avg(Employee: {field: salary}) + } + `, + Results: []map[string]any{ + { + // 4 employees with salaries 10k, 20k, 30k, 40k + "_avg": int(25000), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryAverageWithWrongIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query average without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor2Identity, + Request: ` + query { + _avg(Employee: {field: salary}) + } + `, + Results: []map[string]any{ + { + // 2 public employees, 1 with salary 10k, 1 with salary 20k + "_avg": int(15000), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/query/count_test.go b/tests/integration/acp/query/count_test.go new file mode 100644 index 0000000000..74c4025c22 --- /dev/null +++ b/tests/integration/acp/query/count_test.go @@ -0,0 +1,183 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" +) + +func TestACP_QueryCountDocumentsWithoutIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query documents' count without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Request: ` + query { + _count(Employee: {}) + } + `, + Results: []map[string]any{ + { + "_count": int(2), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryCountRelatedObjectsWithoutIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query count of related objects without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Request: ` + query { + Company { + _count(employees: {}) + } + } + `, + Results: []map[string]any{ + { + // 1 of 2 companies is public and has 1 public employee out of 2 + "_count": int(1), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryCountDocumentsWithIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query documents' count with identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor1Identity, + Request: ` + query { + _count(Employee: {}) + } + `, + Results: []map[string]any{ + { + "_count": int(4), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryCountRelatedObjectsWithIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query count of related objects with identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor1Identity, + Request: ` + query { + Company { + _count(employees: {}) + } + } + `, + Results: []map[string]any{ + { + "_count": int(2), + }, + { + "_count": int(2), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryCountDocumentsWithWrongIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query documents' count without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor2Identity, + Request: ` + query { + _count(Employee: {}) + } + `, + Results: []map[string]any{ + { + "_count": int(2), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryCountRelatedObjectsWithWrongIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query count of related objects without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor2Identity, + Request: ` + query { + Company { + _count(employees: {}) + } + } + `, + Results: []map[string]any{ + { + // 1 of 2 companies is public and has 1 public employee out of 2 + "_count": int(1), + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} diff --git a/tests/integration/acp/query/fixture.go b/tests/integration/acp/query/fixture.go new file mode 100644 index 0000000000..ed81ed0633 --- /dev/null +++ b/tests/integration/acp/query/fixture.go @@ -0,0 +1,148 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp + +import ( + testUtils "github.com/sourcenetwork/defradb/tests/integration" + acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" +) + +const employeeCompanyPolicy = ` +description: A Valid DefraDB Policy Interface (DPI) + +actor: + name: actor + +resources: + employees: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor + + companies: + permissions: + read: + expr: owner + reader + write: + expr: owner + + relations: + owner: + types: + - actor + reader: + types: + - actor +` + +func getSetupEmployeeCompanyActions() []any { + return []any{ + testUtils.AddPolicy{ + Identity: acpUtils.Actor1Identity, + Policy: employeeCompanyPolicy, + ExpectedPolicyID: "67607eb2a2a873f4a69eb6876323cee7601d8a4d4fedcc18154aaee65cf38e7f", + }, + + testUtils.SchemaUpdate{ + Schema: ` + type Employee @policy( + id: "67607eb2a2a873f4a69eb6876323cee7601d8a4d4fedcc18154aaee65cf38e7f", + resource: "employees" + ) { + name: String + salary: Int + company: Company + } + + type Company @policy( + id: "67607eb2a2a873f4a69eb6876323cee7601d8a4d4fedcc18154aaee65cf38e7f", + resource: "companies" + ) { + name: String + capital: Int + employees: [Employee] + } + `, + }, + + testUtils.CreateDoc{ + CollectionID: 1, + Doc: ` + { + "name": "Public Company", + "capital": 100000 + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 1, + Identity: acpUtils.Actor1Identity, + Doc: ` + { + "name": "Private Company", + "capital": 200000 + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: ` + { + "name": "PubEmp in PubCompany", + "salary": 10000, + "company": "bae-1ab7ac86-3c68-5abb-b526-803858c9dccf" + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Doc: ` + { + "name": "PubEmp in PrivateCompany", + "salary": 20000, + "company": "bae-4aef4bd6-e2ee-5075-85a5-4d64bbf80bca" + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Identity: acpUtils.Actor1Identity, + Doc: ` + { + "name": "PrivateEmp in PubCompany", + "salary": 30000, + "company": "bae-1ab7ac86-3c68-5abb-b526-803858c9dccf" + } + `, + }, + testUtils.CreateDoc{ + CollectionID: 0, + Identity: acpUtils.Actor1Identity, + Doc: ` + { + "name": "PrivateEmp in PrivateCompany", + "salary": 40000, + "company": "bae-4aef4bd6-e2ee-5075-85a5-4d64bbf80bca" + } + `, + }, + } +} diff --git a/tests/integration/acp/query/relation_objects_test.go b/tests/integration/acp/query/relation_objects_test.go new file mode 100644 index 0000000000..76bd264ac8 --- /dev/null +++ b/tests/integration/acp/query/relation_objects_test.go @@ -0,0 +1,242 @@ +// Copyright 2024 Democratized Data Foundation +// +// Use of this software is governed by the Business Source License +// included in the file licenses/BSL.txt. +// +// As of the Change Date specified in that file, in accordance with +// the Business Source License, use of this software will be governed +// by the Apache License, Version 2.0, included in the file +// licenses/APL.txt. + +package test_acp + +import ( + "testing" + + testUtils "github.com/sourcenetwork/defradb/tests/integration" + acpUtils "github.com/sourcenetwork/defradb/tests/integration/acp" +) + +func TestACP_QueryManyToOneRelationObjectsWithoutIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query employees with their companies without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Request: ` + query { + Employee { + name + company { + name + } + } + } + `, + Results: []map[string]any{ + { + "name": "PubEmp in PrivateCompany", + "company": nil, + }, + { + "name": "PubEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryOneToManyRelationObjectsWithoutIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query companies with their employees without identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Request: ` + query { + Company { + name + employees { + name + } + } + } + `, + Results: []map[string]any{ + { + "name": "Public Company", + "employees": []map[string]any{ + {"name": "PubEmp in PubCompany"}, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryManyToOneRelationObjectsWithIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query employees with their companies with identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor1Identity, + Request: ` + query { + Employee { + name + company { + name + } + } + } + `, + Results: []map[string]any{ + { + "name": "PrivateEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + { + "name": "PrivateEmp in PrivateCompany", + "company": map[string]any{"name": "Private Company"}, + }, + { + "name": "PubEmp in PrivateCompany", + "company": map[string]any{"name": "Private Company"}, + }, + { + "name": "PubEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryOneToManyRelationObjectsWithIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query companies with their employees with identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor1Identity, + Request: ` + query { + Company { + name + employees { + name + } + } + } + `, + Results: []map[string]any{ + { + "name": "Public Company", + "employees": []map[string]any{ + {"name": "PrivateEmp in PubCompany"}, + {"name": "PubEmp in PubCompany"}, + }, + }, + { + "name": "Private Company", + "employees": []map[string]any{ + {"name": "PrivateEmp in PrivateCompany"}, + {"name": "PubEmp in PrivateCompany"}, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryManyToOneRelationObjectsWithWrongIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query employees with their companies with wrong identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor2Identity, + Request: ` + query { + Employee { + name + company { + name + } + } + } + `, + Results: []map[string]any{ + { + "name": "PubEmp in PrivateCompany", + "company": nil, + }, + { + "name": "PubEmp in PubCompany", + "company": map[string]any{"name": "Public Company"}, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +} + +func TestACP_QueryOneToManyRelationObjectsWithWrongIdentity(t *testing.T) { + test := testUtils.TestCase{ + Description: "Test acp, query companies with their employees with wrong identity", + + Actions: []any{ + getSetupEmployeeCompanyActions(), + + testUtils.Request{ + Identity: acpUtils.Actor2Identity, + Request: ` + query { + Company { + name + employees { + name + } + } + } + `, + Results: []map[string]any{ + { + "name": "Public Company", + "employees": []map[string]any{ + {"name": "PubEmp in PubCompany"}, + }, + }, + }, + }, + }, + } + + testUtils.ExecuteTestCase(t, test) +}