@@ -20,7 +20,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/e2e/internal/factory"
|
||||
"go.probo.inc/probo/e2e/internal/testutil"
|
||||
)
|
||||
|
||||
@@ -28,9 +27,8 @@ func TestAsset_Create(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Asset Owner").
|
||||
Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
const query = `
|
||||
mutation($input: CreateAssetInput!) {
|
||||
@@ -73,7 +71,7 @@ func TestAsset_Create(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"name": "Production Database Server",
|
||||
"amount": 5,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "Customer PII, Financial Records",
|
||||
},
|
||||
@@ -86,16 +84,15 @@ func TestAsset_Create(t *testing.T) {
|
||||
assert.Equal(t, 5, asset.Amount)
|
||||
assert.Equal(t, "VIRTUAL", asset.AssetType)
|
||||
assert.Equal(t, "Customer PII, Financial Records", asset.DataTypesStored)
|
||||
assert.Equal(t, peopleID, asset.Owner.ID)
|
||||
assert.Equal(t, profileID.String(), asset.Owner.ID)
|
||||
}
|
||||
|
||||
func TestAsset_Update(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Asset Owner for Update").
|
||||
Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
const createQuery = `
|
||||
mutation($input: CreateAssetInput!) {
|
||||
@@ -124,7 +121,7 @@ func TestAsset_Update(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"name": "Test Asset",
|
||||
"amount": 10,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "Test data",
|
||||
},
|
||||
@@ -175,9 +172,8 @@ func TestAsset_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Asset Owner for Delete").
|
||||
Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
const createQuery = `
|
||||
mutation($input: CreateAssetInput!) {
|
||||
@@ -206,7 +202,7 @@ func TestAsset_Delete(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"name": "Asset to delete",
|
||||
"amount": 1,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "None",
|
||||
},
|
||||
@@ -241,9 +237,8 @@ func TestAsset_List(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Asset Owner for List").
|
||||
Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
// Create multiple assets
|
||||
for i := 0; i < 3; i++ {
|
||||
@@ -274,7 +269,7 @@ func TestAsset_List(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"name": fmt.Sprintf("Asset %c", 'A'+i),
|
||||
"amount": i + 1,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"assetType": "VIRTUAL",
|
||||
"dataTypesStored": "Test data",
|
||||
},
|
||||
@@ -329,9 +324,8 @@ func TestAsset_Types(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Asset Owner for Types").
|
||||
Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
assetTypes := []string{"PHYSICAL", "VIRTUAL"}
|
||||
|
||||
@@ -366,7 +360,7 @@ func TestAsset_Types(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"name": "Asset " + assetType,
|
||||
"amount": 1,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"assetType": assetType,
|
||||
"dataTypesStored": "Test data",
|
||||
},
|
||||
|
||||
@@ -21,14 +21,14 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/e2e/internal/factory"
|
||||
"go.probo.inc/probo/e2e/internal/testutil"
|
||||
)
|
||||
|
||||
func TestContinualImprovement_Create(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("CI Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
query := `
|
||||
mutation CreateContinualImprovement($input: CreateContinualImprovementInput!) {
|
||||
@@ -68,7 +68,7 @@ func TestContinualImprovement_Create(t *testing.T) {
|
||||
"referenceId": fmt.Sprintf("CI-%d", time.Now().UnixNano()),
|
||||
"description": "Improve security training program",
|
||||
"source": "Internal Audit",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
"priority": "HIGH",
|
||||
},
|
||||
@@ -86,7 +86,8 @@ func TestContinualImprovement_Create(t *testing.T) {
|
||||
func TestContinualImprovement_Update(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("CI Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
createQuery := `
|
||||
mutation CreateContinualImprovement($input: CreateContinualImprovementInput!) {
|
||||
@@ -115,7 +116,7 @@ func TestContinualImprovement_Update(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"referenceId": fmt.Sprintf("CI-UPDATE-%d", time.Now().UnixNano()),
|
||||
"description": "Original description",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
"priority": "LOW",
|
||||
},
|
||||
@@ -166,7 +167,8 @@ func TestContinualImprovement_Update(t *testing.T) {
|
||||
func TestContinualImprovement_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("CI Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
createQuery := `
|
||||
mutation CreateContinualImprovement($input: CreateContinualImprovementInput!) {
|
||||
@@ -194,7 +196,7 @@ func TestContinualImprovement_Delete(t *testing.T) {
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"referenceId": fmt.Sprintf("CI-DELETE-%d", time.Now().UnixNano()),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
"priority": "LOW",
|
||||
},
|
||||
@@ -228,7 +230,8 @@ func TestContinualImprovement_Delete(t *testing.T) {
|
||||
func TestContinualImprovement_List(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("CI Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
createQuery := `
|
||||
mutation CreateContinualImprovement($input: CreateContinualImprovementInput!) {
|
||||
@@ -248,7 +251,7 @@ func TestContinualImprovement_List(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"referenceId": fmt.Sprintf("CI-LIST-%d-%d", i, time.Now().UnixNano()),
|
||||
"description": fmt.Sprintf("Improvement %d", i),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
"priority": "MEDIUM",
|
||||
},
|
||||
@@ -302,7 +305,8 @@ func TestContinualImprovement_List(t *testing.T) {
|
||||
func TestContinualImprovement_StatusAndPriorityValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("CI Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
t.Run("status values", func(t *testing.T) {
|
||||
statuses := []string{"OPEN", "IN_PROGRESS", "CLOSED"}
|
||||
@@ -337,7 +341,7 @@ func TestContinualImprovement_StatusAndPriorityValues(t *testing.T) {
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"referenceId": fmt.Sprintf("CI-STATUS-%s-%d", status, time.Now().UnixNano()),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": status,
|
||||
"priority": "LOW",
|
||||
},
|
||||
@@ -381,7 +385,7 @@ func TestContinualImprovement_StatusAndPriorityValues(t *testing.T) {
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"referenceId": fmt.Sprintf("CI-PRIORITY-%s-%d", priority, time.Now().UnixNano()),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
"priority": priority,
|
||||
},
|
||||
|
||||
@@ -29,7 +29,8 @@ import (
|
||||
func TestDatum_Create(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -102,7 +103,7 @@ func TestDatum_Create(t *testing.T) {
|
||||
|
||||
input := map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
}
|
||||
for k, v := range tt.input {
|
||||
input[k] = v
|
||||
@@ -139,7 +140,8 @@ func TestDatum_Create(t *testing.T) {
|
||||
func TestDatum_Create_Validation(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Validation Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -259,7 +261,7 @@ func TestDatum_Create_Validation(t *testing.T) {
|
||||
input["organizationId"] = owner.GetOrganizationID().String()
|
||||
}
|
||||
if !tt.skipOwner {
|
||||
input["ownerId"] = peopleID
|
||||
input["ownerId"] = profileID
|
||||
}
|
||||
for k, v := range tt.input {
|
||||
input[k] = v
|
||||
@@ -275,7 +277,8 @@ func TestDatum_Create_Validation(t *testing.T) {
|
||||
func TestDatum_Update(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Update Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -287,7 +290,7 @@ func TestDatum_Update(t *testing.T) {
|
||||
{
|
||||
name: "update name",
|
||||
setup: func() string {
|
||||
return factory.NewDatum(owner, peopleID).
|
||||
return factory.NewDatum(owner, profileID.String()).
|
||||
WithName("Datum to Update").
|
||||
Create()
|
||||
},
|
||||
@@ -303,7 +306,7 @@ func TestDatum_Update(t *testing.T) {
|
||||
{
|
||||
name: "update to PUBLIC classification",
|
||||
setup: func() string {
|
||||
return factory.NewDatum(owner, peopleID).
|
||||
return factory.NewDatum(owner, profileID.String()).
|
||||
WithName("Classification Test").
|
||||
WithDataClassification("INTERNAL").
|
||||
Create()
|
||||
@@ -317,7 +320,7 @@ func TestDatum_Update(t *testing.T) {
|
||||
{
|
||||
name: "update to SECRET classification",
|
||||
setup: func() string {
|
||||
return factory.NewDatum(owner, peopleID).
|
||||
return factory.NewDatum(owner, profileID.String()).
|
||||
WithName("Classification Test").
|
||||
Create()
|
||||
},
|
||||
@@ -372,8 +375,9 @@ func TestDatum_Update(t *testing.T) {
|
||||
func TestDatum_Update_Validation(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Update Validation Owner").Create()
|
||||
baseDatumID := factory.NewDatum(owner, peopleID).WithName("Validation Test Datum").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
baseDatumID := factory.NewDatum(owner, profileID.String()).WithName("Validation Test Datum").Create()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -487,10 +491,11 @@ func TestDatum_Update_Validation(t *testing.T) {
|
||||
func TestDatum_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Delete Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
t.Run("delete existing datum", func(t *testing.T) {
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("Datum to Delete").Create()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("Datum to Delete").Create()
|
||||
|
||||
query := `
|
||||
mutation DeleteDatum($input: DeleteDatumInput!) {
|
||||
@@ -552,11 +557,12 @@ func TestDatum_Delete_Validation(t *testing.T) {
|
||||
func TestDatum_List(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum List Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
datumNames := []string{"Datum A", "Datum B", "Datum C"}
|
||||
for _, name := range datumNames {
|
||||
factory.NewDatum(owner, peopleID).WithName(name).Create()
|
||||
factory.NewDatum(owner, profileID.String()).WithName(name).Create()
|
||||
}
|
||||
|
||||
query := `
|
||||
@@ -624,7 +630,8 @@ func TestDatum_Query(t *testing.T) {
|
||||
func TestDatum_Timestamps(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Timestamps Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
t.Run("createdAt and updatedAt are set on create", func(t *testing.T) {
|
||||
beforeCreate := time.Now().Add(-time.Second)
|
||||
@@ -658,7 +665,7 @@ func TestDatum_Timestamps(t *testing.T) {
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"name": "Timestamp Test Datum",
|
||||
"dataClassification": "INTERNAL",
|
||||
},
|
||||
@@ -670,7 +677,7 @@ func TestDatum_Timestamps(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("updatedAt changes on update", func(t *testing.T) {
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("Timestamp Update Test").Create()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("Timestamp Update Test").Create()
|
||||
|
||||
getQuery := `
|
||||
query($id: ID!) {
|
||||
@@ -734,8 +741,9 @@ func TestDatum_Timestamps(t *testing.T) {
|
||||
func TestDatum_SubResolvers(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum SubResolver Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("SubResolver Test Datum").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("SubResolver Test Datum").Create()
|
||||
|
||||
t.Run("owner sub-resolver", func(t *testing.T) {
|
||||
query := `
|
||||
@@ -764,7 +772,7 @@ func TestDatum_SubResolvers(t *testing.T) {
|
||||
|
||||
err := owner.Execute(query, map[string]any{"id": datumID}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peopleID, result.Node.Owner.ID)
|
||||
assert.Equal(t, profileID.String(), result.Node.Owner.ID)
|
||||
})
|
||||
|
||||
t.Run("organization sub-resolver", func(t *testing.T) {
|
||||
@@ -805,7 +813,8 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("create", func(t *testing.T) {
|
||||
t.Run("owner can create", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
_, err := owner.Do(`
|
||||
mutation CreateDatum($input: CreateDatumInput!) {
|
||||
@@ -816,7 +825,7 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"name": "RBAC Test Datum",
|
||||
"dataClassification": "INTERNAL",
|
||||
},
|
||||
@@ -827,7 +836,8 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("admin can create", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
_, err := admin.Do(`
|
||||
mutation CreateDatum($input: CreateDatumInput!) {
|
||||
@@ -838,7 +848,7 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": admin.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"name": "RBAC Test Datum",
|
||||
"dataClassification": "INTERNAL",
|
||||
},
|
||||
@@ -849,7 +859,8 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("viewer cannot create", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
_, err := viewer.Do(`
|
||||
mutation CreateDatum($input: CreateDatumInput!) {
|
||||
@@ -860,7 +871,7 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": viewer.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"name": "RBAC Test Datum",
|
||||
"dataClassification": "INTERNAL",
|
||||
},
|
||||
@@ -872,8 +883,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("update", func(t *testing.T) {
|
||||
t.Run("owner can update", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Update Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Update Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Update Test").Create()
|
||||
|
||||
_, err := owner.Do(`
|
||||
mutation UpdateDatum($input: UpdateDatumInput!) {
|
||||
@@ -893,8 +905,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("admin can update", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Update Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Update Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Update Test").Create()
|
||||
|
||||
_, err := admin.Do(`
|
||||
mutation UpdateDatum($input: UpdateDatumInput!) {
|
||||
@@ -914,8 +927,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("viewer cannot update", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Update Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Update Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Update Test").Create()
|
||||
|
||||
_, err := viewer.Do(`
|
||||
mutation UpdateDatum($input: UpdateDatumInput!) {
|
||||
@@ -936,8 +950,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("delete", func(t *testing.T) {
|
||||
t.Run("owner can delete", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Delete Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Delete Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Delete Test").Create()
|
||||
|
||||
_, err := owner.Do(`
|
||||
mutation DeleteDatum($input: DeleteDatumInput!) {
|
||||
@@ -954,8 +969,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("admin can delete", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Delete Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Delete Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Delete Test").Create()
|
||||
|
||||
_, err := admin.Do(`
|
||||
mutation DeleteDatum($input: DeleteDatumInput!) {
|
||||
@@ -972,8 +988,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("viewer cannot delete", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Delete Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Delete Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Delete Test").Create()
|
||||
|
||||
_, err := viewer.Do(`
|
||||
mutation DeleteDatum($input: DeleteDatumInput!) {
|
||||
@@ -991,8 +1008,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("read", func(t *testing.T) {
|
||||
t.Run("owner can read", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Read Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Read Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Read Test").Create()
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
@@ -1015,8 +1033,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("admin can read", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Read Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Read Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Read Test").Create()
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
@@ -1039,8 +1058,9 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
t.Run("viewer can read", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Read Owner").Create()
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("RBAC Read Test").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("RBAC Read Test").Create()
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
@@ -1065,7 +1085,8 @@ func TestDatum_RBAC(t *testing.T) {
|
||||
func TestDatum_MaxLength_Validation(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Max Length Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
longName := strings.Repeat("a", 1001)
|
||||
|
||||
@@ -1083,7 +1104,7 @@ func TestDatum_MaxLength_Validation(t *testing.T) {
|
||||
_, err := owner.Do(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"name": longName,
|
||||
"dataClassification": "INTERNAL",
|
||||
},
|
||||
@@ -1093,7 +1114,7 @@ func TestDatum_MaxLength_Validation(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("update", func(t *testing.T) {
|
||||
datumID := factory.NewDatum(owner, peopleID).WithName("Max Length Test").Create()
|
||||
datumID := factory.NewDatum(owner, profileID.String()).WithName("Max Length Test").Create()
|
||||
|
||||
query := `
|
||||
mutation UpdateDatum($input: UpdateDatumInput!) {
|
||||
@@ -1117,10 +1138,11 @@ func TestDatum_MaxLength_Validation(t *testing.T) {
|
||||
func TestDatum_Pagination(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Pagination Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
factory.NewDatum(owner, peopleID).
|
||||
factory.NewDatum(owner, profileID.String()).
|
||||
WithName(fmt.Sprintf("Pagination Datum %d", i)).
|
||||
Create()
|
||||
}
|
||||
@@ -1266,8 +1288,9 @@ func TestDatum_TenantIsolation(t *testing.T) {
|
||||
org1Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
org2Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(org1Owner).WithFullName("Org1 Datum Owner").Create()
|
||||
datumID := factory.NewDatum(org1Owner, peopleID).WithName("Org1 Datum").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, org1Owner).GetProfileID()
|
||||
datumID := factory.NewDatum(org1Owner, profileID.String()).WithName("Org1 Datum").Create()
|
||||
|
||||
t.Run("cannot read datum from another organization", func(t *testing.T) {
|
||||
query := `
|
||||
@@ -1373,10 +1396,11 @@ func TestDatum_TenantIsolation(t *testing.T) {
|
||||
func TestDatum_Ordering(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Datum Ordering Owner").Create()
|
||||
// TODO: right now we need to invite and accept invite to get new profile.
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
factory.NewDatum(owner, peopleID).WithName("AAA Order Test").Create()
|
||||
factory.NewDatum(owner, peopleID).WithName("ZZZ Order Test").Create()
|
||||
factory.NewDatum(owner, profileID.String()).WithName("AAA Order Test").Create()
|
||||
factory.NewDatum(owner, profileID.String()).WithName("ZZZ Order Test").Create()
|
||||
|
||||
t.Run("order by created_at descending", func(t *testing.T) {
|
||||
query := `
|
||||
|
||||
@@ -29,7 +29,7 @@ import (
|
||||
func TestDocument_Create(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -113,7 +113,7 @@ func TestDocument_Create(t *testing.T) {
|
||||
|
||||
input := map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": ownerPeopleID,
|
||||
"ownerId": ownerProfileID.String(),
|
||||
}
|
||||
for k, v := range tt.input {
|
||||
input[k] = v
|
||||
@@ -151,7 +151,7 @@ func TestDocument_Create(t *testing.T) {
|
||||
func TestDocument_Create_Validation(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Validation Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -293,7 +293,7 @@ func TestDocument_Create_Validation(t *testing.T) {
|
||||
input["organizationId"] = owner.GetOrganizationID().String()
|
||||
}
|
||||
if !tt.skipOwner {
|
||||
input["ownerId"] = ownerPeopleID
|
||||
input["ownerId"] = ownerProfileID.String()
|
||||
}
|
||||
for k, v := range tt.input {
|
||||
input[k] = v
|
||||
@@ -309,7 +309,7 @@ func TestDocument_Create_Validation(t *testing.T) {
|
||||
func TestDocument_Update(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Update Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -321,7 +321,7 @@ func TestDocument_Update(t *testing.T) {
|
||||
{
|
||||
name: "update title",
|
||||
setup: func() string {
|
||||
return factory.NewDocument(owner, ownerPeopleID).
|
||||
return factory.NewDocument(owner, ownerProfileID.String()).
|
||||
WithTitle("Document to Update").
|
||||
Create()
|
||||
},
|
||||
@@ -337,7 +337,7 @@ func TestDocument_Update(t *testing.T) {
|
||||
{
|
||||
name: "update document type",
|
||||
setup: func() string {
|
||||
return factory.NewDocument(owner, ownerPeopleID).
|
||||
return factory.NewDocument(owner, ownerProfileID.String()).
|
||||
WithTitle("Type Test").
|
||||
WithDocumentType("POLICY").
|
||||
Create()
|
||||
@@ -393,8 +393,8 @@ func TestDocument_Update(t *testing.T) {
|
||||
func TestDocument_Update_Validation(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Update Validation Owner").Create()
|
||||
baseDocumentID := factory.NewDocument(owner, ownerPeopleID).WithTitle("Validation Test Document").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
baseDocumentID := factory.NewDocument(owner, ownerProfileID.String()).WithTitle("Validation Test Document").Create()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -484,10 +484,10 @@ func TestDocument_Update_Validation(t *testing.T) {
|
||||
func TestDocument_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Delete Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
t.Run("delete existing document", func(t *testing.T) {
|
||||
documentID := factory.NewDocument(owner, ownerPeopleID).WithTitle("Document to Delete").Create()
|
||||
documentID := factory.NewDocument(owner, ownerProfileID.String()).WithTitle("Document to Delete").Create()
|
||||
|
||||
query := `
|
||||
mutation DeleteDocument($input: DeleteDocumentInput!) {
|
||||
@@ -549,11 +549,11 @@ func TestDocument_Delete_Validation(t *testing.T) {
|
||||
func TestDocument_List(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document List Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
documentTitles := []string{"Document A", "Document B", "Document C"}
|
||||
for _, title := range documentTitles {
|
||||
factory.NewDocument(owner, ownerPeopleID).WithTitle(title).Create()
|
||||
factory.NewDocument(owner, ownerProfileID.String()).WithTitle(title).Create()
|
||||
}
|
||||
|
||||
query := `
|
||||
@@ -621,7 +621,7 @@ func TestDocument_Query(t *testing.T) {
|
||||
func TestDocument_Timestamps(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Timestamps Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
t.Run("createdAt and updatedAt are set on create", func(t *testing.T) {
|
||||
beforeCreate := time.Now().Add(-time.Second)
|
||||
@@ -655,7 +655,7 @@ func TestDocument_Timestamps(t *testing.T) {
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": ownerPeopleID,
|
||||
"ownerId": ownerProfileID.String(),
|
||||
"title": "Timestamp Test Document",
|
||||
"content": "Test content",
|
||||
"documentType": "POLICY",
|
||||
@@ -669,7 +669,7 @@ func TestDocument_Timestamps(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("updatedAt changes on update", func(t *testing.T) {
|
||||
documentID := factory.NewDocument(owner, ownerPeopleID).WithTitle("Timestamp Update Test").Create()
|
||||
documentID := factory.NewDocument(owner, ownerProfileID.String()).WithTitle("Timestamp Update Test").Create()
|
||||
|
||||
getQuery := `
|
||||
query($id: ID!) {
|
||||
@@ -733,8 +733,8 @@ func TestDocument_Timestamps(t *testing.T) {
|
||||
func TestDocument_SubResolvers(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document SubResolver Owner").Create()
|
||||
documentID := factory.NewDocument(owner, ownerPeopleID).WithTitle("SubResolver Test Document").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, ownerProfileID.String()).WithTitle("SubResolver Test Document").Create()
|
||||
|
||||
t.Run("owner sub-resolver", func(t *testing.T) {
|
||||
query := `
|
||||
@@ -763,7 +763,7 @@ func TestDocument_SubResolvers(t *testing.T) {
|
||||
|
||||
err := owner.Execute(query, map[string]any{"id": documentID}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, ownerPeopleID, result.Node.Owner.ID)
|
||||
assert.Equal(t, ownerProfileID.String(), result.Node.Owner.ID)
|
||||
})
|
||||
|
||||
t.Run("organization sub-resolver", func(t *testing.T) {
|
||||
@@ -804,7 +804,7 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("create", func(t *testing.T) {
|
||||
t.Run("owner can create", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
_, err := owner.Do(`
|
||||
mutation CreateDocument($input: CreateDocumentInput!) {
|
||||
@@ -815,7 +815,7 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"title": "RBAC Test Document",
|
||||
"content": "Test content",
|
||||
"documentType": "POLICY",
|
||||
@@ -828,7 +828,7 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("admin can create", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
_, err := admin.Do(`
|
||||
mutation CreateDocument($input: CreateDocumentInput!) {
|
||||
@@ -839,7 +839,7 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": admin.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"title": "RBAC Test Document",
|
||||
"content": "Test content",
|
||||
"documentType": "POLICY",
|
||||
@@ -852,7 +852,7 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("viewer cannot create", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
_, err := viewer.Do(`
|
||||
mutation CreateDocument($input: CreateDocumentInput!) {
|
||||
@@ -863,7 +863,7 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
`, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": viewer.GetOrganizationID().String(),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"title": "RBAC Test Document",
|
||||
"content": "Test content",
|
||||
"documentType": "POLICY",
|
||||
@@ -877,8 +877,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("update", func(t *testing.T) {
|
||||
t.Run("owner can update", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Update Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Update Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Update Test").Create()
|
||||
|
||||
_, err := owner.Do(`
|
||||
mutation UpdateDocument($input: UpdateDocumentInput!) {
|
||||
@@ -898,8 +898,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("admin can update", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Update Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Update Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Update Test").Create()
|
||||
|
||||
_, err := admin.Do(`
|
||||
mutation UpdateDocument($input: UpdateDocumentInput!) {
|
||||
@@ -919,8 +919,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("viewer cannot update", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Update Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Update Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Update Test").Create()
|
||||
|
||||
_, err := viewer.Do(`
|
||||
mutation UpdateDocument($input: UpdateDocumentInput!) {
|
||||
@@ -941,8 +941,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("delete", func(t *testing.T) {
|
||||
t.Run("owner can delete", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Delete Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Delete Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Delete Test").Create()
|
||||
|
||||
_, err := owner.Do(`
|
||||
mutation DeleteDocument($input: DeleteDocumentInput!) {
|
||||
@@ -959,8 +959,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("admin can delete", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Delete Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Delete Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Delete Test").Create()
|
||||
|
||||
_, err := admin.Do(`
|
||||
mutation DeleteDocument($input: DeleteDocumentInput!) {
|
||||
@@ -977,8 +977,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("viewer cannot delete", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Delete Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Delete Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Delete Test").Create()
|
||||
|
||||
_, err := viewer.Do(`
|
||||
mutation DeleteDocument($input: DeleteDocumentInput!) {
|
||||
@@ -996,8 +996,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("read", func(t *testing.T) {
|
||||
t.Run("owner can read", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Read Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Read Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Read Test").Create()
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
@@ -1020,8 +1020,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("admin can read", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
admin := testutil.NewClientInOrg(t, testutil.RoleAdmin, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Admin Read Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Read Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Read Test").Create()
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
@@ -1044,8 +1044,8 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
t.Run("viewer can read", func(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
viewer := testutil.NewClientInOrg(t, testutil.RoleViewer, owner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Viewer Read Owner").Create()
|
||||
documentID := factory.NewDocument(owner, peopleID).WithTitle("RBAC Read Test").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
documentID := factory.NewDocument(owner, profileID.String()).WithTitle("RBAC Read Test").Create()
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
@@ -1070,7 +1070,7 @@ func TestDocument_RBAC(t *testing.T) {
|
||||
func TestDocument_MaxLength_Validation(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Max Length Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
longTitle := strings.Repeat("a", 1001)
|
||||
|
||||
@@ -1088,7 +1088,7 @@ func TestDocument_MaxLength_Validation(t *testing.T) {
|
||||
_, err := owner.Do(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"ownerId": ownerPeopleID,
|
||||
"ownerId": ownerProfileID.String(),
|
||||
"title": longTitle,
|
||||
"content": "Test content",
|
||||
"documentType": "POLICY",
|
||||
@@ -1100,7 +1100,7 @@ func TestDocument_MaxLength_Validation(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("update", func(t *testing.T) {
|
||||
documentID := factory.NewDocument(owner, ownerPeopleID).WithTitle("Max Length Test").Create()
|
||||
documentID := factory.NewDocument(owner, ownerProfileID.String()).WithTitle("Max Length Test").Create()
|
||||
|
||||
query := `
|
||||
mutation UpdateDocument($input: UpdateDocumentInput!) {
|
||||
@@ -1124,10 +1124,10 @@ func TestDocument_MaxLength_Validation(t *testing.T) {
|
||||
func TestDocument_Pagination(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Pagination Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
factory.NewDocument(owner, ownerPeopleID).
|
||||
factory.NewDocument(owner, ownerProfileID.String()).
|
||||
WithTitle(fmt.Sprintf("Pagination Document %d", i)).
|
||||
Create()
|
||||
}
|
||||
@@ -1273,8 +1273,8 @@ func TestDocument_TenantIsolation(t *testing.T) {
|
||||
org1Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
org2Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(org1Owner).WithFullName("Org1 Document Owner").Create()
|
||||
documentID := factory.NewDocument(org1Owner, peopleID).WithTitle("Org1 Document").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, org1Owner).GetProfileID()
|
||||
documentID := factory.NewDocument(org1Owner, profileID.String()).WithTitle("Org1 Document").Create()
|
||||
|
||||
t.Run("cannot read document from another organization", func(t *testing.T) {
|
||||
query := `
|
||||
@@ -1380,10 +1380,10 @@ func TestDocument_TenantIsolation(t *testing.T) {
|
||||
func TestDocument_Ordering(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
ownerPeopleID := factory.NewPeople(owner).WithFullName("Document Ordering Owner").Create()
|
||||
ownerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
factory.NewDocument(owner, ownerPeopleID).WithTitle("AAA Order Test").Create()
|
||||
factory.NewDocument(owner, ownerPeopleID).WithTitle("ZZZ Order Test").Create()
|
||||
factory.NewDocument(owner, ownerProfileID.String()).WithTitle("AAA Order Test").Create()
|
||||
factory.NewDocument(owner, ownerProfileID.String()).WithTitle("ZZZ Order Test").Create()
|
||||
|
||||
t.Run("order by created_at descending", func(t *testing.T) {
|
||||
query := `
|
||||
|
||||
@@ -19,14 +19,13 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/e2e/internal/factory"
|
||||
"go.probo.inc/probo/e2e/internal/testutil"
|
||||
)
|
||||
|
||||
// createTestDocument creates a document and returns its ID and the document version ID
|
||||
func createTestDocument(t *testing.T, owner *testutil.Client) (docID string, docVersionID string) {
|
||||
t.Helper()
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Doc Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
query := `
|
||||
mutation CreateDocument($input: CreateDocumentInput!) {
|
||||
@@ -69,7 +68,7 @@ func createTestDocument(t *testing.T, owner *testutil.Client) (docID string, doc
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"title": "Test Document",
|
||||
"content": "Initial content",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"documentType": "POLICY",
|
||||
"classification": "INTERNAL",
|
||||
},
|
||||
@@ -264,7 +263,7 @@ func TestDocumentVersion_RequestSignature(t *testing.T) {
|
||||
publishedVersionID := publishResult.PublishDocumentVersion.DocumentVersion.ID
|
||||
|
||||
// Create a person to sign
|
||||
signerID := factory.NewPeople(owner).WithFullName("Document Signer").Create()
|
||||
signerProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
query := `
|
||||
mutation RequestSignature($input: RequestSignatureInput!) {
|
||||
@@ -301,14 +300,14 @@ func TestDocumentVersion_RequestSignature(t *testing.T) {
|
||||
err = owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"documentVersionId": publishedVersionID,
|
||||
"signatoryId": signerID,
|
||||
"signatoryId": signerProfileID.String(),
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotEmpty(t, result.RequestSignature.DocumentVersionSignatureEdge.Node.ID)
|
||||
assert.Equal(t, "REQUESTED", result.RequestSignature.DocumentVersionSignatureEdge.Node.State)
|
||||
assert.Equal(t, signerID, result.RequestSignature.DocumentVersionSignatureEdge.Node.SignedBy.ID)
|
||||
assert.Equal(t, signerProfileID.String(), result.RequestSignature.DocumentVersionSignatureEdge.Node.SignedBy.ID)
|
||||
}
|
||||
|
||||
func TestDocumentVersion_BulkPublish(t *testing.T) {
|
||||
@@ -383,8 +382,8 @@ func TestDocumentVersion_BulkRequestSignatures(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create multiple signers
|
||||
signer1ID := factory.NewPeople(owner).WithFullName("Bulk Signer 1").Create()
|
||||
signer2ID := factory.NewPeople(owner).WithFullName("Bulk Signer 2").Create()
|
||||
signer1ProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
signer2ProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
query := `
|
||||
mutation BulkRequestSignatures($input: BulkRequestSignaturesInput!) {
|
||||
@@ -413,7 +412,7 @@ func TestDocumentVersion_BulkRequestSignatures(t *testing.T) {
|
||||
err = owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"documentIds": []string{docID},
|
||||
"signatoryIds": []string{signer1ID, signer2ID},
|
||||
"signatoryIds": []string{signer1ProfileID.String(), signer2ProfileID.String()},
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -19,7 +19,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/e2e/internal/factory"
|
||||
"go.probo.inc/probo/e2e/internal/testutil"
|
||||
)
|
||||
|
||||
@@ -370,7 +369,7 @@ func TestControlDocumentMapping_CreateDelete(t *testing.T) {
|
||||
controlID := createControlResult.CreateControl.ControlEdge.Node.ID
|
||||
|
||||
// Create a document
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Doc Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
var createDocumentResult struct {
|
||||
CreateDocument struct {
|
||||
DocumentEdge struct {
|
||||
@@ -395,7 +394,7 @@ func TestControlDocumentMapping_CreateDelete(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"title": "Document for Control Mapping",
|
||||
"content": "Document content",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"documentType": "POLICY",
|
||||
"classification": "INTERNAL",
|
||||
},
|
||||
@@ -760,7 +759,7 @@ func TestRiskDocumentMapping_CreateDelete(t *testing.T) {
|
||||
riskID := createRiskResult.CreateRisk.RiskEdge.Node.ID
|
||||
|
||||
// Create a document
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Doc Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
var createDocumentResult struct {
|
||||
CreateDocument struct {
|
||||
DocumentEdge struct {
|
||||
@@ -785,7 +784,7 @@ func TestRiskDocumentMapping_CreateDelete(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"title": "Document for Risk Mapping",
|
||||
"content": "Document content",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"documentType": "POLICY",
|
||||
"classification": "INTERNAL",
|
||||
},
|
||||
@@ -874,7 +873,7 @@ func TestRiskObligationMapping_CreateDelete(t *testing.T) {
|
||||
riskID := createRiskResult.CreateRisk.RiskEdge.Node.ID
|
||||
|
||||
// Create an obligation
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Obligation Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
var createObligationResult struct {
|
||||
CreateObligation struct {
|
||||
ObligationEdge struct {
|
||||
@@ -899,7 +898,7 @@ func TestRiskObligationMapping_CreateDelete(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"area": "Risk Management",
|
||||
"requirement": "Obligation for Risk Mapping",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "NON_COMPLIANT",
|
||||
"type": "LEGAL",
|
||||
},
|
||||
|
||||
@@ -690,8 +690,8 @@ func TestMeeting_SubResolvers_WithData(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
attendee1 := factory.NewPeople(owner).WithFullName("Attendee One").Create()
|
||||
attendee2 := factory.NewPeople(owner).WithFullName("Attendee Two").Create()
|
||||
attendee1ProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
attendee2ProfileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
var result struct {
|
||||
CreateMeeting struct {
|
||||
@@ -730,7 +730,7 @@ func TestMeeting_SubResolvers_WithData(t *testing.T) {
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"name": "Meeting With Attendees",
|
||||
"date": time.Now().Format(time.RFC3339Nano),
|
||||
"attendeeIds": []string{attendee1, attendee2},
|
||||
"attendeeIds": []string{attendee1ProfileID.String(), attendee2ProfileID.String()},
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/e2e/internal/factory"
|
||||
"go.probo.inc/probo/e2e/internal/testutil"
|
||||
)
|
||||
|
||||
@@ -100,7 +99,7 @@ func createAuditForNC(t *testing.T, owner *testutil.Client, name string) string
|
||||
func TestNonconformity_Create(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("NC Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
auditID := createAuditForNC(t, owner, "NC Test Audit")
|
||||
|
||||
query := `
|
||||
@@ -143,7 +142,7 @@ func TestNonconformity_Create(t *testing.T) {
|
||||
"auditId": auditID,
|
||||
"rootCause": "Insufficient access controls",
|
||||
"correctiveAction": "Implement MFA",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
},
|
||||
}, &result)
|
||||
@@ -159,7 +158,7 @@ func TestNonconformity_Create(t *testing.T) {
|
||||
func TestNonconformity_Update(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("NC Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
auditID := createAuditForNC(t, owner, "NC Update Test Audit")
|
||||
|
||||
// Create a nonconformity to update
|
||||
@@ -191,7 +190,7 @@ func TestNonconformity_Update(t *testing.T) {
|
||||
"referenceId": fmt.Sprintf("NC-UPDATE-%d", time.Now().UnixNano()),
|
||||
"auditId": auditID,
|
||||
"rootCause": "Original root cause",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
},
|
||||
}, &createResult)
|
||||
@@ -242,7 +241,7 @@ func TestNonconformity_Update(t *testing.T) {
|
||||
func TestNonconformity_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("NC Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
auditID := createAuditForNC(t, owner, "NC Delete Test Audit")
|
||||
|
||||
// Create a nonconformity to delete
|
||||
@@ -274,7 +273,7 @@ func TestNonconformity_Delete(t *testing.T) {
|
||||
"referenceId": fmt.Sprintf("NC-DELETE-%d", time.Now().UnixNano()),
|
||||
"auditId": auditID,
|
||||
"rootCause": "Test root cause",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
},
|
||||
}, &createResult)
|
||||
@@ -307,7 +306,7 @@ func TestNonconformity_Delete(t *testing.T) {
|
||||
func TestNonconformity_List(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("NC Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
auditID := createAuditForNC(t, owner, "NC List Test Audit")
|
||||
|
||||
// Create multiple nonconformities
|
||||
@@ -340,7 +339,7 @@ func TestNonconformity_List(t *testing.T) {
|
||||
"referenceId": fmt.Sprintf("NC-LIST-%d-%d", i, time.Now().UnixNano()),
|
||||
"auditId": auditID,
|
||||
"rootCause": fmt.Sprintf("Root cause %d", i),
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "OPEN",
|
||||
},
|
||||
}, &createResult)
|
||||
@@ -391,7 +390,7 @@ func TestNonconformity_List(t *testing.T) {
|
||||
func TestNonconformity_StatusValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("NC Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
auditID := createAuditForNC(t, owner, "NC Status Test Audit")
|
||||
|
||||
statuses := []string{"OPEN", "IN_PROGRESS", "CLOSED"}
|
||||
@@ -428,7 +427,7 @@ func TestNonconformity_StatusValues(t *testing.T) {
|
||||
"referenceId": fmt.Sprintf("NC-STATUS-%s-%d", status, time.Now().UnixNano()),
|
||||
"auditId": auditID,
|
||||
"rootCause": "Test root cause",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": status,
|
||||
},
|
||||
}, &result)
|
||||
|
||||
@@ -19,14 +19,13 @@ import (
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/e2e/internal/factory"
|
||||
"go.probo.inc/probo/e2e/internal/testutil"
|
||||
)
|
||||
|
||||
func TestObligation_Create(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Obligation Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
query := `
|
||||
mutation CreateObligation($input: CreateObligationInput!) {
|
||||
@@ -67,7 +66,7 @@ func TestObligation_Create(t *testing.T) {
|
||||
"source": "GDPR Article 5",
|
||||
"requirement": "Data must be processed lawfully",
|
||||
"regulator": "ICO",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "NON_COMPLIANT",
|
||||
"type": "LEGAL",
|
||||
},
|
||||
@@ -85,7 +84,7 @@ func TestObligation_Create(t *testing.T) {
|
||||
func TestObligation_Update(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Obligation Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
// Create an obligation to update
|
||||
createQuery := `
|
||||
@@ -114,7 +113,7 @@ func TestObligation_Update(t *testing.T) {
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"area": "Original Area",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "NON_COMPLIANT",
|
||||
"type": "LEGAL",
|
||||
},
|
||||
@@ -162,7 +161,7 @@ func TestObligation_Update(t *testing.T) {
|
||||
func TestObligation_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Obligation Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
// Create an obligation to delete
|
||||
createQuery := `
|
||||
@@ -191,7 +190,7 @@ func TestObligation_Delete(t *testing.T) {
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"area": "Obligation to Delete",
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "NON_COMPLIANT",
|
||||
"type": "LEGAL",
|
||||
},
|
||||
@@ -226,7 +225,7 @@ func TestObligation_Delete(t *testing.T) {
|
||||
func TestObligation_List(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Obligation Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
// Create multiple obligations
|
||||
areas := []string{"Area A", "Area B", "Area C"}
|
||||
@@ -257,7 +256,7 @@ func TestObligation_List(t *testing.T) {
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"area": area,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": "NON_COMPLIANT",
|
||||
"type": "LEGAL",
|
||||
},
|
||||
@@ -310,7 +309,7 @@ func TestObligation_List(t *testing.T) {
|
||||
func TestObligation_StatusValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Obligation Owner").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
statuses := []string{"NON_COMPLIANT", "PARTIALLY_COMPLIANT", "COMPLIANT"}
|
||||
|
||||
@@ -344,7 +343,7 @@ func TestObligation_StatusValues(t *testing.T) {
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"area": "Status Test " + status,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
"status": status,
|
||||
"type": "LEGAL",
|
||||
},
|
||||
|
||||
@@ -1,677 +0,0 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package console_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/e2e/internal/factory"
|
||||
"go.probo.inc/probo/e2e/internal/testutil"
|
||||
)
|
||||
|
||||
func TestPeople_Create(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
t.Run("with full details", func(t *testing.T) {
|
||||
query := `
|
||||
mutation CreatePeople($input: CreatePeopleInput!) {
|
||||
createPeople(input: $input) {
|
||||
peopleEdge {
|
||||
node {
|
||||
id
|
||||
fullName
|
||||
kind
|
||||
position
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
CreatePeople struct {
|
||||
PeopleEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
Kind string `json:"kind"`
|
||||
Position *string `json:"position"`
|
||||
} `json:"node"`
|
||||
} `json:"peopleEdge"`
|
||||
} `json:"createPeople"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"organizationId": owner.GetOrganizationID().String(),
|
||||
"fullName": "John Doe",
|
||||
"primaryEmailAddress": "john.doe@example.com",
|
||||
"additionalEmailAddresses": []string{},
|
||||
"kind": "EMPLOYEE",
|
||||
"position": "Software Engineer",
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
people := result.CreatePeople.PeopleEdge.Node
|
||||
assert.NotEmpty(t, people.ID)
|
||||
assert.Equal(t, "John Doe", people.FullName)
|
||||
assert.Equal(t, "EMPLOYEE", people.Kind)
|
||||
assert.Equal(t, "Software Engineer", *people.Position)
|
||||
})
|
||||
|
||||
t.Run("with different kinds", func(t *testing.T) {
|
||||
kinds := []struct {
|
||||
name string
|
||||
kind string
|
||||
}{
|
||||
{"Employee", "EMPLOYEE"},
|
||||
{"Contractor", "CONTRACTOR"},
|
||||
{"Service Account", "SERVICE_ACCOUNT"},
|
||||
}
|
||||
|
||||
for _, tt := range kinds {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
peopleID := factory.CreatePeople(owner, factory.Attrs{
|
||||
"fullName": "Person " + tt.kind,
|
||||
"kind": tt.kind,
|
||||
})
|
||||
|
||||
query := `
|
||||
query GetPeople($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on People {
|
||||
id
|
||||
kind
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
Kind string `json:"kind"`
|
||||
} `json:"node"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{"id": peopleID}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, tt.kind, result.Node.Kind)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("with additional emails", func(t *testing.T) {
|
||||
t.Skip("additionalEmailAddresses feature not fully implemented")
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeople_Update(t *testing.T) {
|
||||
t.Skip("updatePeople has server bug with additional_email_addresses null constraint")
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.CreatePeople(owner, factory.Attrs{
|
||||
"fullName": "Person to Update",
|
||||
})
|
||||
|
||||
query := `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
UpdatePeople struct {
|
||||
People struct {
|
||||
ID string `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
} `json:"people"`
|
||||
} `json:"updatePeople"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": peopleID,
|
||||
"fullName": "Updated Name",
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, peopleID, result.UpdatePeople.People.ID)
|
||||
assert.Equal(t, "Updated Name", result.UpdatePeople.People.FullName)
|
||||
}
|
||||
|
||||
func TestPeople_Delete(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
peopleID := factory.CreatePeople(owner, factory.Attrs{
|
||||
"fullName": "Person to Delete",
|
||||
})
|
||||
|
||||
query := `
|
||||
mutation DeletePeople($input: DeletePeopleInput!) {
|
||||
deletePeople(input: $input) {
|
||||
deletedPeopleId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
DeletePeople struct {
|
||||
DeletedPeopleID string `json:"deletedPeopleId"`
|
||||
} `json:"deletePeople"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"peopleId": peopleID,
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peopleID, result.DeletePeople.DeletedPeopleID)
|
||||
}
|
||||
|
||||
func TestPeople_List(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
// Create multiple people
|
||||
peopleNames := []string{"Person A", "Person B", "Person C"}
|
||||
for _, name := range peopleNames {
|
||||
factory.CreatePeople(owner, factory.Attrs{"fullName": name})
|
||||
}
|
||||
|
||||
query := `
|
||||
query ListPeoples($orgId: ID!) {
|
||||
node(id: $orgId) {
|
||||
... on Organization {
|
||||
peoples(first: 10) {
|
||||
edges {
|
||||
node {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
}
|
||||
totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
Node struct {
|
||||
Peoples struct {
|
||||
Edges []struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
} `json:"node"`
|
||||
} `json:"edges"`
|
||||
TotalCount int `json:"totalCount"`
|
||||
} `json:"peoples"`
|
||||
} `json:"node"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"orgId": owner.GetOrganizationID().String(),
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.GreaterOrEqual(t, result.Node.Peoples.TotalCount, 3)
|
||||
}
|
||||
|
||||
func TestPeople_RequiredFields(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input map[string]any
|
||||
skipOrganization bool
|
||||
wantErrorContains string
|
||||
}{
|
||||
{
|
||||
name: "missing organizationId",
|
||||
input: map[string]any{
|
||||
"fullName": "Test Person",
|
||||
"primaryEmailAddress": "test@example.com",
|
||||
"additionalEmailAddresses": []string{},
|
||||
"kind": "EMPLOYEE",
|
||||
},
|
||||
skipOrganization: true,
|
||||
wantErrorContains: "organizationId",
|
||||
},
|
||||
{
|
||||
name: "missing fullName",
|
||||
input: map[string]any{
|
||||
"primaryEmailAddress": "test@example.com",
|
||||
"additionalEmailAddresses": []string{},
|
||||
"kind": "EMPLOYEE",
|
||||
},
|
||||
wantErrorContains: "fullName",
|
||||
},
|
||||
{
|
||||
name: "missing primaryEmailAddress",
|
||||
input: map[string]any{
|
||||
"fullName": "Test Person",
|
||||
"additionalEmailAddresses": []string{},
|
||||
"kind": "EMPLOYEE",
|
||||
},
|
||||
wantErrorContains: "primaryEmailAddress",
|
||||
},
|
||||
{
|
||||
name: "missing kind",
|
||||
input: map[string]any{
|
||||
"fullName": "Test Person",
|
||||
"primaryEmailAddress": "test@example.com",
|
||||
"additionalEmailAddresses": []string{},
|
||||
},
|
||||
wantErrorContains: "kind",
|
||||
},
|
||||
{
|
||||
name: "empty fullName",
|
||||
input: map[string]any{
|
||||
"fullName": "",
|
||||
"primaryEmailAddress": "test@example.com",
|
||||
"additionalEmailAddresses": []string{},
|
||||
"kind": "EMPLOYEE",
|
||||
},
|
||||
wantErrorContains: "full_name",
|
||||
},
|
||||
{
|
||||
name: "invalid kind enum",
|
||||
input: map[string]any{
|
||||
"fullName": "Test Person",
|
||||
"primaryEmailAddress": "test@example.com",
|
||||
"additionalEmailAddresses": []string{},
|
||||
"kind": "INVALID_KIND",
|
||||
},
|
||||
wantErrorContains: "kind",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
query := `
|
||||
mutation CreatePeople($input: CreatePeopleInput!) {
|
||||
createPeople(input: $input) {
|
||||
peopleEdge {
|
||||
node {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
input := make(map[string]any)
|
||||
if !tt.skipOrganization {
|
||||
input["organizationId"] = owner.GetOrganizationID().String()
|
||||
}
|
||||
for k, v := range tt.input {
|
||||
input[k] = v
|
||||
}
|
||||
|
||||
_, err := owner.Do(query, map[string]any{"input": input})
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), tt.wantErrorContains)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeople_KindEnum(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
kinds := []string{
|
||||
"EMPLOYEE",
|
||||
"CONTRACTOR",
|
||||
}
|
||||
|
||||
for _, kind := range kinds {
|
||||
t.Run("create with kind "+kind, func(t *testing.T) {
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Kind Test " + kind).
|
||||
WithKind(kind).
|
||||
Create()
|
||||
|
||||
query := `
|
||||
query($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on People {
|
||||
id
|
||||
kind
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
Kind string `json:"kind"`
|
||||
} `json:"node"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{"id": peopleID}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, kind, result.Node.Kind)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPeople_SubResolvers(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("SubResolver Test Person").
|
||||
Create()
|
||||
|
||||
t.Run("people node query", func(t *testing.T) {
|
||||
query := `
|
||||
query GetPeople($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on People {
|
||||
id
|
||||
fullName
|
||||
primaryEmailAddress
|
||||
kind
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
PrimaryEmailAddress string `json:"primaryEmailAddress"`
|
||||
Kind string `json:"kind"`
|
||||
} `json:"node"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{"id": peopleID}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peopleID, result.Node.ID)
|
||||
assert.Equal(t, "SubResolver Test Person", result.Node.FullName)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestPeople_InvalidID(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
t.Run("update with invalid ID", func(t *testing.T) {
|
||||
query := `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
_, err := owner.Do(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": "invalid-id-format",
|
||||
"fullName": "Test",
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "base64")
|
||||
})
|
||||
|
||||
t.Run("delete with invalid ID", func(t *testing.T) {
|
||||
query := `
|
||||
mutation DeletePeople($input: DeletePeopleInput!) {
|
||||
deletePeople(input: $input) {
|
||||
deletedPeopleId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
_, err := owner.Do(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"peopleId": "invalid-id-format",
|
||||
},
|
||||
})
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "base64")
|
||||
})
|
||||
|
||||
t.Run("query with non-existent ID", func(t *testing.T) {
|
||||
query := `
|
||||
query GetPeople($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on People {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
err := owner.ExecuteShouldFail(query, map[string]any{
|
||||
"id": "V0wtM0tMNmJBQ1lBQUFBQUFackhLSTJfbXJJRUFZVXo",
|
||||
})
|
||||
require.Error(t, err, "Non-existent ID should return error")
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeople_OmittablePosition(t *testing.T) {
|
||||
t.Skip("Skipped: server returns internal error when updating position field")
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Position Test Person").
|
||||
Create()
|
||||
|
||||
t.Run("set position", func(t *testing.T) {
|
||||
query := `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people {
|
||||
id
|
||||
position
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
UpdatePeople struct {
|
||||
People struct {
|
||||
ID string `json:"id"`
|
||||
Position *string `json:"position"`
|
||||
} `json:"people"`
|
||||
} `json:"updatePeople"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": peopleID,
|
||||
"position": "Software Engineer",
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result.UpdatePeople.People.Position)
|
||||
assert.Equal(t, "Software Engineer", *result.UpdatePeople.People.Position)
|
||||
})
|
||||
|
||||
t.Run("clear position with null", func(t *testing.T) {
|
||||
query := `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people {
|
||||
id
|
||||
position
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
UpdatePeople struct {
|
||||
People struct {
|
||||
ID string `json:"id"`
|
||||
Position *string `json:"position"`
|
||||
} `json:"people"`
|
||||
} `json:"updatePeople"`
|
||||
}
|
||||
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": peopleID,
|
||||
"position": nil,
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Nil(t, result.UpdatePeople.People.Position)
|
||||
})
|
||||
|
||||
t.Run("update without position preserves value", func(t *testing.T) {
|
||||
// First set a position
|
||||
setQuery := `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
err := owner.Execute(setQuery, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": peopleID,
|
||||
"position": "Senior Engineer",
|
||||
},
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Update only fullName
|
||||
query := `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people {
|
||||
id
|
||||
fullName
|
||||
position
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
UpdatePeople struct {
|
||||
People struct {
|
||||
ID string `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
Position *string `json:"position"`
|
||||
} `json:"people"`
|
||||
} `json:"updatePeople"`
|
||||
}
|
||||
|
||||
err = owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": peopleID,
|
||||
"fullName": "Updated Name",
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result.UpdatePeople.People.Position)
|
||||
assert.Equal(t, "Senior Engineer", *result.UpdatePeople.People.Position)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPeople_TenantIsolation(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
org1Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
org2Owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
peopleID := factory.NewPeople(org1Owner).WithFullName("Org1 Person").Create()
|
||||
|
||||
t.Run("cannot read people from another organization", func(t *testing.T) {
|
||||
query := `
|
||||
query($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on People {
|
||||
id
|
||||
fullName
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
Node *struct {
|
||||
ID string `json:"id"`
|
||||
FullName string `json:"fullName"`
|
||||
} `json:"node"`
|
||||
}
|
||||
|
||||
err := org2Owner.Execute(query, map[string]any{"id": peopleID}, &result)
|
||||
testutil.AssertNodeNotAccessible(t, err, result.Node == nil, "people")
|
||||
})
|
||||
|
||||
t.Run("cannot update people from another organization", func(t *testing.T) {
|
||||
query := `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people { id }
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
_, err := org2Owner.Do(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": peopleID,
|
||||
"fullName": "Hijacked Person",
|
||||
},
|
||||
})
|
||||
require.Error(t, err, "Should not be able to update people from another org")
|
||||
})
|
||||
|
||||
t.Run("cannot delete people from another organization", func(t *testing.T) {
|
||||
query := `
|
||||
mutation DeletePeople($input: DeletePeopleInput!) {
|
||||
deletePeople(input: $input) {
|
||||
deletedPeopleId
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
_, err := org2Owner.Do(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"peopleId": peopleID,
|
||||
},
|
||||
})
|
||||
require.Error(t, err, "Should not be able to delete people from another org")
|
||||
})
|
||||
}
|
||||
@@ -174,36 +174,6 @@ const (
|
||||
}
|
||||
}`
|
||||
|
||||
createPeopleMutation = `
|
||||
mutation CreatePeople($input: CreatePeopleInput!) {
|
||||
createPeople(input: $input) {
|
||||
peopleEdge { node { id } }
|
||||
}
|
||||
}`
|
||||
|
||||
updatePeopleMutation = `
|
||||
mutation UpdatePeople($input: UpdatePeopleInput!) {
|
||||
updatePeople(input: $input) {
|
||||
people { id }
|
||||
}
|
||||
}`
|
||||
|
||||
deletePeopleMutation = `
|
||||
mutation DeletePeople($input: DeletePeopleInput!) {
|
||||
deletePeople(input: $input) {
|
||||
deletedPeopleId
|
||||
}
|
||||
}`
|
||||
|
||||
listPeoplesQuery = `
|
||||
query GetPeoples($id: ID!) {
|
||||
node(id: $id) {
|
||||
... on Organization {
|
||||
peoples(first: 10) { totalCount }
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
createVendorMutation = `
|
||||
mutation CreateVendor($input: CreateVendorInput!) {
|
||||
createVendor(input: $input) {
|
||||
@@ -274,7 +244,6 @@ func TestRBAC(t *testing.T) {
|
||||
measureID := factory.NewMeasure(owner).WithName("RBAC Test Measure").Create()
|
||||
taskID := factory.NewTask(owner, measureID).WithName("RBAC Test Task").Create()
|
||||
riskID := factory.NewRisk(owner).WithName("RBAC Test Risk").Create()
|
||||
peopleID := factory.NewPeople(owner).WithFullName("RBAC Test Person").Create()
|
||||
vendorID := factory.NewVendor(owner).WithName("RBAC Test Vendor").Create()
|
||||
|
||||
tests := []struct {
|
||||
@@ -904,130 +873,6 @@ func TestRBAC(t *testing.T) {
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "owner can create people",
|
||||
role: "owner",
|
||||
client: owner,
|
||||
query: createPeopleMutation,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"input": map[string]any{"organizationId": owner.GetOrganizationID().String(), "fullName": factory.SafeName("Person"), "primaryEmailAddress": factory.SafeEmail(), "additionalEmailAddresses": []string{}, "kind": "EMPLOYEE"}}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "admin can create people",
|
||||
role: "admin",
|
||||
client: admin,
|
||||
query: createPeopleMutation,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"input": map[string]any{"organizationId": owner.GetOrganizationID().String(), "fullName": factory.SafeName("Person"), "primaryEmailAddress": factory.SafeEmail(), "additionalEmailAddresses": []string{}, "kind": "EMPLOYEE"}}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "viewer cannot create people",
|
||||
role: "viewer",
|
||||
client: viewer,
|
||||
query: createPeopleMutation,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"input": map[string]any{"organizationId": owner.GetOrganizationID().String(), "fullName": factory.SafeName("Person"), "primaryEmailAddress": factory.SafeEmail(), "additionalEmailAddresses": []string{}, "kind": "EMPLOYEE"}}
|
||||
},
|
||||
shouldAllow: false,
|
||||
},
|
||||
// TODO: Fix server-side issue - updatePeople mutation returns internal server error
|
||||
// {
|
||||
// name: "owner can update people",
|
||||
// role: "owner",
|
||||
// client: owner,
|
||||
// query: updatePeopleMutation,
|
||||
// variables: func() map[string]any {
|
||||
// return map[string]any{"input": map[string]any{"id": peopleID, "fullName": factory.SafeName("Updated Person")}}
|
||||
// },
|
||||
// shouldAllow: true,
|
||||
// },
|
||||
// {
|
||||
// name: "admin can update people",
|
||||
// role: "admin",
|
||||
// client: admin,
|
||||
// query: updatePeopleMutation,
|
||||
// variables: func() map[string]any {
|
||||
// return map[string]any{"input": map[string]any{"id": peopleID, "fullName": factory.SafeName("Updated Person")}}
|
||||
// },
|
||||
// shouldAllow: true,
|
||||
// },
|
||||
{
|
||||
name: "viewer cannot update people",
|
||||
role: "viewer",
|
||||
client: viewer,
|
||||
query: updatePeopleMutation,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"input": map[string]any{"id": peopleID, "fullName": factory.SafeName("Updated Person")}}
|
||||
},
|
||||
shouldAllow: false,
|
||||
},
|
||||
{
|
||||
name: "owner can delete people",
|
||||
role: "owner",
|
||||
client: owner,
|
||||
query: deletePeopleMutation,
|
||||
variables: func() map[string]any {
|
||||
id := factory.NewPeople(owner).WithFullName(factory.SafeName("ToDelete")).Create()
|
||||
return map[string]any{"input": map[string]any{"peopleId": id}}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "admin can delete people",
|
||||
role: "admin",
|
||||
client: admin,
|
||||
query: deletePeopleMutation,
|
||||
variables: func() map[string]any {
|
||||
id := factory.NewPeople(owner).WithFullName(factory.SafeName("ToDelete")).Create()
|
||||
return map[string]any{"input": map[string]any{"peopleId": id}}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "viewer cannot delete people",
|
||||
role: "viewer",
|
||||
client: viewer,
|
||||
query: deletePeopleMutation,
|
||||
variables: func() map[string]any {
|
||||
id := factory.NewPeople(owner).WithFullName(factory.SafeName("ToDelete")).Create()
|
||||
return map[string]any{"input": map[string]any{"peopleId": id}}
|
||||
},
|
||||
shouldAllow: false,
|
||||
},
|
||||
{
|
||||
name: "owner can list peoples",
|
||||
role: "owner",
|
||||
client: owner,
|
||||
query: listPeoplesQuery,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"id": owner.GetOrganizationID().String()}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "admin can list peoples",
|
||||
role: "admin",
|
||||
client: admin,
|
||||
query: listPeoplesQuery,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"id": owner.GetOrganizationID().String()}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "viewer can list peoples",
|
||||
role: "viewer",
|
||||
client: viewer,
|
||||
query: listPeoplesQuery,
|
||||
variables: func() map[string]any {
|
||||
return map[string]any{"id": owner.GetOrganizationID().String()}
|
||||
},
|
||||
shouldAllow: true,
|
||||
},
|
||||
{
|
||||
name: "owner can create vendor",
|
||||
role: "owner",
|
||||
|
||||
@@ -881,13 +881,8 @@ func TestRisk_OmittableOwner(t *testing.T) {
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
// Create a people for owner assignment
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Risk Owner Person").
|
||||
Create()
|
||||
|
||||
riskID := factory.NewRisk(owner).
|
||||
WithName("Owner Test Risk").
|
||||
Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
riskID := factory.NewRisk(owner).WithName("Owner Test Risk").Create()
|
||||
|
||||
t.Run("set owner", func(t *testing.T) {
|
||||
query := `
|
||||
@@ -919,11 +914,11 @@ func TestRisk_OmittableOwner(t *testing.T) {
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": riskID,
|
||||
"ownerId": peopleID,
|
||||
"ownerId": profileID.String(),
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peopleID, result.UpdateRisk.Risk.Owner.ID)
|
||||
assert.Equal(t, profileID.String(), result.UpdateRisk.Risk.Owner.ID)
|
||||
})
|
||||
|
||||
t.Run("clear owner with null", func(t *testing.T) {
|
||||
|
||||
@@ -30,7 +30,7 @@ func TestTask_Assign(t *testing.T) {
|
||||
// Create measure and task
|
||||
measureID := factory.NewMeasure(owner).Create()
|
||||
taskID := factory.NewTask(owner, measureID).Create()
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Task Assignee").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
query := `
|
||||
mutation UpdateTask($input: UpdateTaskInput!) {
|
||||
@@ -61,14 +61,13 @@ func TestTask_Assign(t *testing.T) {
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"taskId": taskID,
|
||||
"assignedToId": peopleID,
|
||||
"assignedToId": profileID.String(),
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, taskID, result.UpdateTask.Task.ID)
|
||||
assert.Equal(t, peopleID, result.UpdateTask.Task.AssignedTo.ID)
|
||||
assert.Equal(t, "Task Assignee", result.UpdateTask.Task.AssignedTo.FullName)
|
||||
assert.Equal(t, profileID.String(), result.UpdateTask.Task.AssignedTo.ID)
|
||||
}
|
||||
|
||||
func TestTask_Unassign(t *testing.T) {
|
||||
@@ -78,7 +77,7 @@ func TestTask_Unassign(t *testing.T) {
|
||||
// Create measure, task, people and assign
|
||||
measureID := factory.NewMeasure(owner).Create()
|
||||
taskID := factory.NewTask(owner, measureID).Create()
|
||||
peopleID := factory.NewPeople(owner).WithFullName("Person to Unassign").Create()
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
|
||||
// First assign the task
|
||||
assignQuery := `
|
||||
@@ -94,7 +93,7 @@ func TestTask_Unassign(t *testing.T) {
|
||||
_, err := owner.Do(assignQuery, map[string]any{
|
||||
"input": map[string]any{
|
||||
"taskId": taskID,
|
||||
"assignedToId": peopleID,
|
||||
"assignedToId": profileID.String(),
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -649,11 +649,8 @@ func TestTask_OmittableAssignee(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
// Create a people for assignee
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Task Assignee Person").
|
||||
Create()
|
||||
|
||||
// Create a profile for assignee
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
measureID := factory.NewMeasure(owner).
|
||||
WithName("Task Assignee Test").
|
||||
Create()
|
||||
@@ -692,11 +689,11 @@ func TestTask_OmittableAssignee(t *testing.T) {
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"taskId": taskID,
|
||||
"assignedToId": peopleID,
|
||||
"assignedToId": profileID.String(),
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peopleID, result.UpdateTask.Task.AssignedTo.ID)
|
||||
assert.Equal(t, profileID.String(), result.UpdateTask.Task.AssignedTo.ID)
|
||||
})
|
||||
|
||||
t.Run("clear assignee", func(t *testing.T) {
|
||||
|
||||
@@ -754,11 +754,8 @@ func TestVendor_OmittableBusinessOwner(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
// Create a people for owner assignment
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Business Owner Person").
|
||||
Create()
|
||||
|
||||
// Create a profile for owner assignment
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
vendorID := factory.NewVendor(owner).
|
||||
WithName("BusinessOwner Test Vendor").
|
||||
Create()
|
||||
@@ -793,11 +790,11 @@ func TestVendor_OmittableBusinessOwner(t *testing.T) {
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": vendorID,
|
||||
"businessOwnerId": peopleID,
|
||||
"businessOwnerId": profileID.String(),
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peopleID, result.UpdateVendor.Vendor.BusinessOwner.ID)
|
||||
assert.Equal(t, profileID.String(), result.UpdateVendor.Vendor.BusinessOwner.ID)
|
||||
})
|
||||
|
||||
t.Run("clear business owner with null", func(t *testing.T) {
|
||||
@@ -840,14 +837,9 @@ func TestVendor_OmittableSecurityOwner(t *testing.T) {
|
||||
t.Parallel()
|
||||
owner := testutil.NewClient(t, testutil.RoleOwner)
|
||||
|
||||
// Create a people for owner assignment
|
||||
peopleID := factory.NewPeople(owner).
|
||||
WithFullName("Security Owner Person").
|
||||
Create()
|
||||
|
||||
vendorID := factory.NewVendor(owner).
|
||||
WithName("SecurityOwner Test Vendor").
|
||||
Create()
|
||||
// Create a profile for owner assignment
|
||||
profileID := testutil.NewClientInOrg(t, testutil.RoleViewer, owner).GetProfileID()
|
||||
vendorID := factory.NewVendor(owner).WithName("SecurityOwner Test Vendor").Create()
|
||||
|
||||
t.Run("set security owner", func(t *testing.T) {
|
||||
query := `
|
||||
@@ -879,11 +871,11 @@ func TestVendor_OmittableSecurityOwner(t *testing.T) {
|
||||
err := owner.Execute(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"id": vendorID,
|
||||
"securityOwnerId": peopleID,
|
||||
"securityOwnerId": profileID.String(),
|
||||
},
|
||||
}, &result)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, peopleID, result.UpdateVendor.Vendor.SecurityOwner.ID)
|
||||
assert.Equal(t, profileID.String(), result.UpdateVendor.Vendor.SecurityOwner.ID)
|
||||
})
|
||||
|
||||
t.Run("clear security owner with null", func(t *testing.T) {
|
||||
|
||||
@@ -371,48 +371,6 @@ func CreateRisk(c *testutil.Client, attrs ...Attrs) string {
|
||||
return result.CreateRisk.RiskEdge.Node.ID
|
||||
}
|
||||
|
||||
func CreatePeople(c *testutil.Client, attrs ...Attrs) string {
|
||||
c.T.Helper()
|
||||
|
||||
var a Attrs
|
||||
if len(attrs) > 0 {
|
||||
a = attrs[0]
|
||||
}
|
||||
|
||||
const query = `
|
||||
mutation($input: CreatePeopleInput!) {
|
||||
createPeople(input: $input) {
|
||||
peopleEdge {
|
||||
node { id }
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
input := map[string]any{
|
||||
"organizationId": c.GetOrganizationID().String(),
|
||||
"fullName": a.getString("fullName", SafeName("Person")),
|
||||
"primaryEmailAddress": a.getString("primaryEmailAddress", SafeEmail()),
|
||||
"additionalEmailAddresses": a.getSlice("additionalEmailAddresses", []string{}),
|
||||
"kind": a.getString("kind", "EMPLOYEE"),
|
||||
}
|
||||
|
||||
var result struct {
|
||||
CreatePeople struct {
|
||||
PeopleEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"node"`
|
||||
} `json:"peopleEdge"`
|
||||
} `json:"createPeople"`
|
||||
}
|
||||
|
||||
err := c.Execute(query, map[string]any{"input": input}, &result)
|
||||
require.NoError(c.T, err, "createPeople mutation failed")
|
||||
|
||||
return result.CreatePeople.PeopleEdge.Node.ID
|
||||
}
|
||||
|
||||
type VendorBuilder struct {
|
||||
client *testutil.Client
|
||||
attrs Attrs
|
||||
@@ -607,29 +565,6 @@ func (b *RiskBuilder) Create() string {
|
||||
return CreateRisk(b.client, b.attrs)
|
||||
}
|
||||
|
||||
type PeopleBuilder struct {
|
||||
client *testutil.Client
|
||||
attrs Attrs
|
||||
}
|
||||
|
||||
func NewPeople(c *testutil.Client) *PeopleBuilder {
|
||||
return &PeopleBuilder{client: c, attrs: Attrs{}}
|
||||
}
|
||||
|
||||
func (b *PeopleBuilder) WithFullName(name string) *PeopleBuilder {
|
||||
b.attrs["fullName"] = name
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PeopleBuilder) WithKind(kind string) *PeopleBuilder {
|
||||
b.attrs["kind"] = kind
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *PeopleBuilder) Create() string {
|
||||
return CreatePeople(b.client, b.attrs)
|
||||
}
|
||||
|
||||
func CreateAudit(c *testutil.Client, frameworkID string, attrs ...Attrs) string {
|
||||
c.T.Helper()
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@ type Client struct {
|
||||
baseURL string
|
||||
role TestRole
|
||||
userID gid.GID
|
||||
profileID gid.GID
|
||||
organizationID gid.GID
|
||||
}
|
||||
|
||||
@@ -89,7 +90,7 @@ func NewClientInOrg(t testing.TB, role TestRole, ownerClient *Client) *Client {
|
||||
},
|
||||
}
|
||||
|
||||
client.setupTestUserInOrg(ownerClient)
|
||||
client.SetupTestUserInOrg(ownerClient)
|
||||
|
||||
return client
|
||||
}
|
||||
@@ -105,7 +106,7 @@ func (c *Client) setupTestUser() {
|
||||
|
||||
// Create organization (this makes the user an OWNER)
|
||||
orgName := fmt.Sprintf("Test Org %s", uniqueID)
|
||||
c.organizationID = c.createOrganization(orgName)
|
||||
c.organizationID, c.profileID = c.createOrganization(orgName)
|
||||
|
||||
// Assume organization session to use console API
|
||||
c.assumeOrganizationSession()
|
||||
@@ -116,7 +117,7 @@ func (c *Client) setupTestUser() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) setupTestUserInOrg(ownerClient *Client) {
|
||||
func (c *Client) SetupTestUserInOrg(ownerClient *Client) {
|
||||
uniqueID := generateUniqueID()
|
||||
email := fmt.Sprintf("test-%s@e2e.probo.test", uniqueID)
|
||||
password := "TestPassword123!"
|
||||
@@ -129,7 +130,7 @@ func (c *Client) setupTestUserInOrg(ownerClient *Client) {
|
||||
invitationID := ownerClient.inviteMember(email, fullName, coredata.MembershipRole(c.role))
|
||||
|
||||
// New user accepts invitation
|
||||
c.acceptInvitation(invitationID)
|
||||
c.profileID = c.acceptInvitation(invitationID)
|
||||
|
||||
// Assume organization session to use console API
|
||||
c.assumeOrganizationSession()
|
||||
@@ -167,11 +168,16 @@ func (c *Client) signUp(email, password, fullName string) gid.GID {
|
||||
return userID
|
||||
}
|
||||
|
||||
func (c *Client) createOrganization(name string) gid.GID {
|
||||
func (c *Client) createOrganization(name string) (gid.GID, gid.GID) {
|
||||
const query = `
|
||||
mutation($input: CreateOrganizationInput!) {
|
||||
createOrganization(input: $input) {
|
||||
organization { id }
|
||||
membershipEdge {
|
||||
node {
|
||||
profile { id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
@@ -181,6 +187,14 @@ func (c *Client) createOrganization(name string) gid.GID {
|
||||
Organization struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"organization"`
|
||||
MembershipEdge struct {
|
||||
Node struct {
|
||||
ID string `json:"id"`
|
||||
Profile struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"profile"`
|
||||
} `json:"node"`
|
||||
} `json:"membershipEdge"`
|
||||
} `json:"createOrganization"`
|
||||
}
|
||||
|
||||
@@ -192,7 +206,10 @@ func (c *Client) createOrganization(name string) gid.GID {
|
||||
orgID, err := gid.ParseGID(result.CreateOrganization.Organization.ID)
|
||||
require.NoError(c.T, err, "cannot parse organization ID")
|
||||
|
||||
return orgID
|
||||
profileID, err := gid.ParseGID(result.CreateOrganization.MembershipEdge.Node.Profile.ID)
|
||||
require.NoError(c.T, err, "cannot parse profile ID")
|
||||
|
||||
return orgID, profileID
|
||||
}
|
||||
|
||||
func (c *Client) updateOwnMembershipRole(role coredata.MembershipRole) {
|
||||
@@ -304,23 +321,42 @@ func (c *Client) inviteMember(email, fullName string, role coredata.MembershipRo
|
||||
return invitationID
|
||||
}
|
||||
|
||||
func (c *Client) acceptInvitation(invitationID gid.GID) {
|
||||
func (c *Client) acceptInvitation(invitationID gid.GID) gid.GID {
|
||||
const query = `
|
||||
mutation($input: AcceptInvitationInput!) {
|
||||
acceptInvitation(input: $input) {
|
||||
membershipEdge {
|
||||
node { id }
|
||||
node {
|
||||
profile { id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
var result struct {
|
||||
AcceptInvitation struct {
|
||||
MembershipEdge struct {
|
||||
Node struct {
|
||||
Profile struct {
|
||||
ID string `json:"id"`
|
||||
} `json:"profile"`
|
||||
} `json:"node"`
|
||||
} `json:"membershipEdge"`
|
||||
} `json:"acceptInvitation"`
|
||||
}
|
||||
|
||||
err := c.ExecuteConnect(query, map[string]any{
|
||||
"input": map[string]any{
|
||||
"invitationId": invitationID.String(),
|
||||
},
|
||||
}, nil)
|
||||
}, &result)
|
||||
require.NoError(c.T, err, "acceptInvitation mutation failed")
|
||||
|
||||
profileID, err := gid.ParseGID(result.AcceptInvitation.MembershipEdge.Node.Profile.ID)
|
||||
require.NoError(c.T, err, "cannot parse profile ID")
|
||||
|
||||
return profileID
|
||||
}
|
||||
|
||||
func (c *Client) assumeOrganizationSession() {
|
||||
@@ -349,6 +385,10 @@ func (c *Client) GetUserID() gid.GID {
|
||||
return c.userID
|
||||
}
|
||||
|
||||
func (c *Client) GetProfileID() gid.GID {
|
||||
return c.profileID
|
||||
}
|
||||
|
||||
func (c *Client) GetOrganizationID() gid.GID {
|
||||
return c.organizationID
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
"sync"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"go.gearno.de/kit/log"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -65,7 +67,7 @@ func Setup() {
|
||||
done: make(chan error, 1),
|
||||
}
|
||||
|
||||
cmd := exec.Command(binaryPath, "-cfg-file", configPath)
|
||||
cmd := exec.Command(binaryPath, "-cfg-file", configPath, "-format", log.FormatPretty)
|
||||
if coverDir != "" {
|
||||
cmd.Env = append(os.Environ(), "GOCOVERDIR="+coverDir)
|
||||
} else {
|
||||
|
||||
@@ -61,7 +61,7 @@ func (p MembershipProfile) CursorKey(orderBy MembershipProfileOrderField) page.C
|
||||
}
|
||||
|
||||
func (p *MembershipProfile) AuthorizationAttributes(ctx context.Context, conn pg.Conn) (map[string]string, error) {
|
||||
q := `SELECT m.organization_id FROM iam_membership_profiles mp JOIN iam_memberships m ON mp.membership_id = m.id WHERE mp.id = $1 LIMIT 1;`
|
||||
q := `SELECT m.organization_id, mp.identity_id FROM iam_membership_profiles mp JOIN iam_memberships m ON mp.membership_id = m.id WHERE mp.id = $1 LIMIT 1;`
|
||||
|
||||
var organizationID gid.GID
|
||||
if err := conn.QueryRow(ctx, q, p.ID).Scan(&organizationID); err != nil {
|
||||
@@ -241,6 +241,7 @@ func (p *MembershipProfiles) LoadByMeetingID(
|
||||
WITH attendees AS (
|
||||
SELECT
|
||||
p.id,
|
||||
p.tenant_id,
|
||||
p.identity_id,
|
||||
p.membership_id,
|
||||
i.email_address,
|
||||
|
||||
@@ -445,6 +445,8 @@ WHERE
|
||||
-- 8. Now that references are filled, add the NOT NULL constraints to those who need it
|
||||
ALTER TABLE
|
||||
assets
|
||||
ALTER COLUMN
|
||||
owner_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
owner_profile_id
|
||||
SET
|
||||
@@ -452,6 +454,8 @@ SET
|
||||
|
||||
ALTER TABLE
|
||||
continual_improvements
|
||||
ALTER COLUMN
|
||||
owner_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
owner_profile_id
|
||||
SET
|
||||
@@ -459,6 +463,8 @@ SET
|
||||
|
||||
ALTER TABLE
|
||||
data
|
||||
ALTER COLUMN
|
||||
owner_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
owner_profile_id
|
||||
SET
|
||||
@@ -466,20 +472,28 @@ SET
|
||||
|
||||
ALTER TABLE
|
||||
document_versions
|
||||
ALTER COLUMN
|
||||
owner_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
owner_profile_id
|
||||
SET
|
||||
NOT NULL;
|
||||
|
||||
ALTER TABLE
|
||||
meeting_attendees
|
||||
meeting_attendees DROP CONSTRAINT meeting_attendees_pkey,
|
||||
ALTER COLUMN
|
||||
attendee_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
attendee_profile_id
|
||||
SET
|
||||
NOT NULL;
|
||||
NOT NULL,
|
||||
ADD
|
||||
PRIMARY KEY (attendee_profile_id);
|
||||
|
||||
ALTER TABLE
|
||||
nonconformities
|
||||
ALTER COLUMN
|
||||
owner_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
owner_profile_id
|
||||
SET
|
||||
@@ -487,6 +501,8 @@ SET
|
||||
|
||||
ALTER TABLE
|
||||
obligations
|
||||
ALTER COLUMN
|
||||
owner_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
owner_profile_id
|
||||
SET
|
||||
@@ -494,6 +510,8 @@ SET
|
||||
|
||||
ALTER TABLE
|
||||
document_version_signatures
|
||||
ALTER COLUMN
|
||||
signed_by DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
signed_by_profile_id
|
||||
SET
|
||||
@@ -501,6 +519,8 @@ SET
|
||||
|
||||
ALTER TABLE
|
||||
states_of_applicability
|
||||
ALTER COLUMN
|
||||
owner_id DROP NOT NULL,
|
||||
ALTER COLUMN
|
||||
owner_profile_id
|
||||
SET
|
||||
|
||||
@@ -84,6 +84,18 @@ var IAMSelfManageInvitationPolicy = policy.NewPolicy(
|
||||
).
|
||||
WithDescription("Allows users to view and accept invitations sent to them")
|
||||
|
||||
// IAMSelfManageProfilePolicy allows users to view their own profiles.
|
||||
var IAMSelfManageProfilePolicy = policy.NewPolicy(
|
||||
"iam:self-manage-profile",
|
||||
"Self-Manage Profiles",
|
||||
|
||||
// Users can view their own profiles
|
||||
policy.Allow(ActionMembershipProfileGet).
|
||||
WithSID("view-own-profiles").
|
||||
When(policy.Equals("principal.id", "resource.identity_id")),
|
||||
).
|
||||
WithDescription("Allows users to view their organization profiles")
|
||||
|
||||
// IAMSelfManageMembershipPolicy allows users to view their own memberships.
|
||||
var IAMSelfManageMembershipPolicy = policy.NewPolicy(
|
||||
"iam:self-manage-membership",
|
||||
|
||||
@@ -504,9 +504,9 @@ func (s *OrganizationService) CreateOrganization(
|
||||
ctx context.Context,
|
||||
identityID gid.GID,
|
||||
req *CreateOrganizationRequest,
|
||||
) (*coredata.Organization, error) {
|
||||
) (*coredata.Organization, *coredata.Membership, error) {
|
||||
if err := req.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("invalid request: %w", err)
|
||||
return nil, nil, fmt.Errorf("invalid request: %w", err)
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -584,7 +584,7 @@ func (s *OrganizationService) CreateOrganization(
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot upload logo file: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot upload logo file: %w", err)
|
||||
}
|
||||
|
||||
logoFile.FileSize = fileSize
|
||||
@@ -621,7 +621,7 @@ func (s *OrganizationService) CreateOrganization(
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot upload logo file: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot upload logo file: %w", err)
|
||||
}
|
||||
|
||||
horizontalLogoFile.FileSize = fileSize
|
||||
@@ -713,10 +713,10 @@ func (s *OrganizationService) CreateOrganization(
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot insert organization: %w", err)
|
||||
return nil, nil, fmt.Errorf("cannot insert organization: %w", err)
|
||||
}
|
||||
|
||||
return organization, nil
|
||||
return organization, membership, nil
|
||||
}
|
||||
|
||||
func (s *OrganizationService) UpdateOrganization(ctx context.Context, organizationID gid.GID, req *UpdateOrganizationRequest) (*coredata.Organization, error) {
|
||||
|
||||
@@ -66,6 +66,7 @@ func IAMPolicySet() *PolicySet {
|
||||
IAMSelfManageIdentityPolicy,
|
||||
IAMSelfManageSessionPolicy,
|
||||
IAMSelfManageInvitationPolicy,
|
||||
IAMSelfManageProfilePolicy,
|
||||
IAMSelfManageMembershipPolicy,
|
||||
IAMSelfManagePersonalAPIKeyPolicy,
|
||||
)
|
||||
|
||||
@@ -196,8 +196,8 @@ func (s MeetingService) Create(
|
||||
}
|
||||
|
||||
if len(req.AttendeeIDs) > 0 {
|
||||
var attendeePeople coredata.MembershipProfiles
|
||||
if err := attendeePeople.LoadByIDs(ctx, conn, s.svc.scope, req.AttendeeIDs); err != nil {
|
||||
var attendeeProfiles coredata.MembershipProfiles
|
||||
if err := attendeeProfiles.LoadByIDs(ctx, conn, s.svc.scope, req.AttendeeIDs); err != nil {
|
||||
return fmt.Errorf("cannot load attendee profiles: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ func (r *membershipResolver) Identity(ctx context.Context, obj *types.Membership
|
||||
|
||||
// Profile is the resolver for the profile field.
|
||||
func (r *membershipResolver) Profile(ctx context.Context, obj *types.Membership) (*types.MembershipProfile, error) {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet); err != nil {
|
||||
if err := r.authorize(ctx, obj.ID, iam.ActionMembershipProfileGet, authz.WithSkipAssumptionCheck()); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -833,7 +833,7 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C
|
||||
Size: input.HorizontalLogoFile.Size,
|
||||
}
|
||||
}
|
||||
organization, err := r.iam.OrganizationService.CreateOrganization(
|
||||
organization, membership, err := r.iam.OrganizationService.CreateOrganization(
|
||||
ctx,
|
||||
identity.ID,
|
||||
&iam.CreateOrganizationRequest{
|
||||
@@ -848,7 +848,8 @@ func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.C
|
||||
}
|
||||
|
||||
return &types.CreateOrganizationPayload{
|
||||
Organization: types.NewOrganization(organization),
|
||||
Organization: types.NewOrganization(organization),
|
||||
MembershipEdge: types.NewMembershipEdge(membership, coredata.MembershipOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user