Files
bridge/internal/service/projects_test.go
2023-07-19 14:33:15 +00:00

304 lines
7.2 KiB
Go

package service_test
import (
"context"
"testing"
"github.com/stretchr/testify/require"
"go.infratographer.com/x/events"
"go.infratographer.com/x/gidx"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/models"
"go.equinixmetal.net/infra9-metal-bridge/internal/metal/providers"
"go.equinixmetal.net/infra9-metal-bridge/internal/permissions"
"go.equinixmetal.net/infra9-metal-bridge/internal/service"
)
func TestTouchProjectEmpty(t *testing.T) {
rootTenantID := gidx.PrefixedID("tnntten-root1")
roleMap := map[string][]string{
"owner": {
"action1",
"action2",
},
}
userID := gidx.PrefixedID("idntusr-2s-9kVNPJBaInlHpRs3lAMsvU_kVkLaSlD4R_RhavDw")
user := &models.UserDetails{
ID: "usr1",
}
orgID := gidx.PrefixedID("metlorg-org1")
org := &models.OrganizationDetails{
ID: "org1",
}
projectID := gidx.PrefixedID("metlprj-prj1")
project := &models.ProjectDetails{
ID: "prj1",
Organization: org,
Memberships: []*models.Membership[models.ProjectDetails]{
{
User: user,
Roles: []string{
"owner",
},
},
},
}
var (
mMetal = new(providers.MockProvider)
mPerms = new(permissions.MockClient)
mPublisher = new(mockPublisher)
)
// Relationships
mMetal.On("GetProjectDetails", projectID).Return(project, nil)
mPerms.On("ListResourceRelationshipsFrom", projectID).Return([]permissions.ResourceRelationship{}, nil)
relateParentChangeMessage := events.ChangeMessage{
SubjectID: projectID,
EventType: string(events.CreateChangeType),
AdditionalSubjectIDs: []gidx.PrefixedID{
orgID,
},
}
mPublisher.On("PublishChange", "metalproject", relateParentChangeMessage).Return(nil)
// Memberships
newRoleID := gidx.PrefixedID("permrol-role1")
mPerms.On("ListResourceRoles", projectID).Return(permissions.ResourceRoles{}, nil)
mPerms.On("CreateRole", projectID, roleMap["owner"]).Return(newRoleID, nil)
mPerms.On("AssignRole", newRoleID, userID).Return(nil)
// Run scenario
svc, err := service.New(mPublisher, mMetal, mPerms,
service.WithRootTenant(rootTenantID.String()),
service.WithRoles(roleMap),
)
require.NoError(t, err)
err = svc.TouchProject(context.Background(), projectID)
require.NoError(t, err)
require.True(t, mMetal.AssertExpectations(t), "unexpected calls to metal provider")
require.True(t, mPerms.AssertExpectations(t), "unexpected calls to permissions client")
require.True(t, mPublisher.AssertExpectations(t), "unexpected calls to events publisher")
}
func TestTouchProjectCleanup(t *testing.T) {
rootTenantID := gidx.PrefixedID("tnntten-root1")
roleMap := map[string][]string{
"owner": {
"action1",
"action2",
},
"collaborator": {
"action1",
},
}
oldUserID := gidx.PrefixedID("idntusr-2s-9kVNPJBaInlHpRs3lAMsvU_kVkLaSlD4R_RhavDw")
oldOrgID := gidx.PrefixedID("metlorg-org1")
userID := gidx.PrefixedID("idntusr-RnKvdujrwqm4o1dBDgfgaqeCpKFMaGeOtGnNbZky0Kg")
user := &models.UserDetails{
ID: "usr2",
}
orgID := gidx.PrefixedID("metlorg-org2")
org := &models.OrganizationDetails{
ID: "org2",
}
projectID := gidx.PrefixedID("metlprj-prj2")
project := &models.ProjectDetails{
ID: "prj2",
Organization: org,
Memberships: []*models.Membership[models.ProjectDetails]{
{
User: user,
Roles: []string{
"owner",
},
},
},
}
var (
mMetal = new(providers.MockProvider)
mPerms = new(permissions.MockClient)
mPublisher = new(mockPublisher)
)
// Relationships
mMetal.On("GetProjectDetails", projectID).Return(project, nil)
existingRelsFrom := []permissions.ResourceRelationship{
{
Relation: string(service.RelateParent),
SubjectID: oldOrgID,
},
}
mPerms.On("ListResourceRelationshipsFrom", projectID).Return(existingRelsFrom, nil)
mPerms.On("DeleteResourceRelationship", projectID, string(service.RelateParent), oldOrgID).Return(nil)
relateParentChangeMessage := events.ChangeMessage{
SubjectID: projectID,
EventType: string(events.CreateChangeType),
AdditionalSubjectIDs: []gidx.PrefixedID{
orgID,
},
}
mPublisher.On("PublishChange", "metalproject", relateParentChangeMessage).Return(nil)
// Memberships
oldRoleID := gidx.PrefixedID("permrol-role1")
newRoleID := gidx.PrefixedID("permrol-role2")
existingRoles := permissions.ResourceRoles{
{
ID: oldRoleID,
Actions: roleMap["collaborator"],
},
}
mPerms.On("ListResourceRoles", projectID).Return(existingRoles, nil)
existingRoleAssignments := []gidx.PrefixedID{
oldUserID,
}
mPerms.On("ListRoleAssignments", oldRoleID).Return(existingRoleAssignments, nil)
mPerms.On("CreateRole", projectID, roleMap["owner"]).Return(newRoleID, nil)
mPerms.On("DeleteRole", oldRoleID).Return(nil)
mPerms.On("AssignRole", newRoleID, userID).Return(nil)
mPerms.On("UnassignRole", oldRoleID, oldUserID).Return(nil)
// Run scenario
svc, err := service.New(mPublisher, mMetal, mPerms,
service.WithRootTenant(rootTenantID.String()),
service.WithRoles(roleMap),
)
require.NoError(t, err)
err = svc.TouchProject(context.Background(), projectID)
require.NoError(t, err)
require.True(t, mMetal.AssertExpectations(t), "unexpected calls to metal provider")
require.True(t, mPerms.AssertExpectations(t), "unexpected calls to permissions client")
require.True(t, mPublisher.AssertExpectations(t), "unexpected calls to events publisher")
}
func TestTouchProjectNoChange(t *testing.T) {
rootTenantID := gidx.PrefixedID("tnntten-root1")
roleMap := map[string][]string{
"owner": {
"action1",
"action2",
},
}
userID := gidx.PrefixedID("idntusr-2s-9kVNPJBaInlHpRs3lAMsvU_kVkLaSlD4R_RhavDw")
user := &models.UserDetails{
ID: "usr1",
}
orgID := gidx.PrefixedID("metlorg-org1")
org := &models.OrganizationDetails{
ID: "org1",
}
projectID := gidx.PrefixedID("metlprj-prj1")
project := &models.ProjectDetails{
ID: "prj1",
Organization: org,
Memberships: []*models.Membership[models.ProjectDetails]{
{
User: user,
Roles: []string{
"owner",
},
},
},
}
var (
mMetal = new(providers.MockProvider)
mPerms = new(permissions.MockClient)
mPublisher = new(mockPublisher)
)
// Relationships
mMetal.On("GetProjectDetails", projectID).Return(project, nil)
existingRelsFrom := []permissions.ResourceRelationship{
{
Relation: string(service.RelateParent),
SubjectID: orgID,
},
}
mPerms.On("ListResourceRelationshipsFrom", projectID).Return(existingRelsFrom, nil)
// Memberships
roleID := gidx.PrefixedID("permrol-role1")
existingRoles := permissions.ResourceRoles{
{
ID: roleID,
Actions: roleMap["owner"],
},
}
mPerms.On("ListResourceRoles", projectID).Return(existingRoles, nil)
existingRoleAssignments := []gidx.PrefixedID{
userID,
}
mPerms.On("ListRoleAssignments", roleID).Return(existingRoleAssignments, nil)
// Run scenario
svc, err := service.New(mPublisher, mMetal, mPerms,
service.WithRootTenant(rootTenantID.String()),
service.WithRoles(roleMap),
)
require.NoError(t, err)
err = svc.TouchProject(context.Background(), projectID)
require.NoError(t, err)
require.True(t, mMetal.AssertExpectations(t), "unexpected calls to metal provider")
require.True(t, mPerms.AssertExpectations(t), "unexpected calls to permissions client")
require.True(t, mPublisher.AssertExpectations(t), "unexpected calls to events publisher")
}