Skip to content

Commit

Permalink
chore: roles repository interface changes and tests
Browse files Browse the repository at this point in the history
changes:
- ensure unique name in role creation
- add update/updated by in update operation
- firebase role interface tests
  • Loading branch information
Muchogoc authored and NYARAS committed Jul 28, 2021
1 parent cf4aea1 commit 1ee8a73
Show file tree
Hide file tree
Showing 13 changed files with 661 additions and 100 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/savannahghi/feedlib v0.0.1
github.com/savannahghi/firebasetools v0.0.13
github.com/savannahghi/interserviceclient v0.0.13
github.com/savannahghi/profileutils v0.0.12
github.com/savannahghi/profileutils v0.0.13
github.com/savannahghi/pubsubtools v0.0.2
github.com/savannahghi/scalarutils v0.0.2
github.com/savannahghi/serverutils v0.0.3
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,8 @@ github.com/savannahghi/interserviceclient v0.0.13 h1:hKUrWkUQW7mNZLp/wxJNnzORDpN
github.com/savannahghi/interserviceclient v0.0.13/go.mod h1:aGGEc+40bBVHVDs1k0CzK5uPb5080vv4fb25T/cuXQk=
github.com/savannahghi/profileutils v0.0.6/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/profileutils v0.0.7/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/profileutils v0.0.12 h1:7ZYbvNVKS2XPHhlw6nRl4Lec8O0CLKQrBYkWEGeyFfI=
github.com/savannahghi/profileutils v0.0.12/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/profileutils v0.0.13 h1:qAGoINpVBVxH02Tbn22vQlo5nRpiYBBYeBor6vEdyEI=
github.com/savannahghi/profileutils v0.0.13/go.mod h1:Ct0sjzOW9zjDN58ynT5GTV6M2hHMY3nsFDV08I6gpO4=
github.com/savannahghi/pubsubtools v0.0.2 h1:5JqgynuuzduYu57y8TM0bU8unZD/7ob36sZ9BKPmt9o=
github.com/savannahghi/pubsubtools v0.0.2/go.mod h1:FQ+BxO4uA1ZkcziY4dR0uT9CKHVHb+4L1lUURBV2UD0=
github.com/savannahghi/scalarutils v0.0.0-20210622091443-bad5089abdad/go.mod h1:Z+Dl3wc3vy5zKvthctHAtYzol1p8w27zEVRfOYueoks=
Expand Down
4 changes: 2 additions & 2 deletions pkg/onboarding/application/dto/input.go
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,6 @@ type RoleInput struct {

// RolePermissionInput input required to create a permission
type RolePermissionInput struct {
RoleID string `json:"roleID"`
Scope string `json:"scope"`
RoleID string `json:"roleID"`
Scopes []string `json:"scopes"`
}
1 change: 1 addition & 0 deletions pkg/onboarding/application/dto/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ type RoleOutput struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
Active bool `json:"active"`
Scopes []string `json:"scopes"`
Permissions []profileutils.Permission `json:"permissions"`
}
122 changes: 86 additions & 36 deletions pkg/onboarding/infrastructure/database/fb/firebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/savannahghi/pubsubtools"
"github.com/savannahghi/scalarutils"
"github.com/savannahghi/serverutils"
"github.com/sirupsen/logrus"
)

// Package that generates trace information
Expand Down Expand Up @@ -3333,8 +3332,6 @@ func (fr *Repository) SaveCoverAutolinkingEvents(
ctx, span := tracer.Start(ctx, "SaveCoverAutolinkingEvents")
defer span.End()

logrus.Print("SaveCoverAutolinkingEvents")

coverLinkingEvent := &dto.CoverLinkingEvent{
ID: input.ID,
CoverLinkingEventTime: input.CoverLinkingEventTime,
Expand Down Expand Up @@ -3672,84 +3669,110 @@ func (fr *Repository) UpdateAITSessionDetails(ctx context.Context, phoneNumber s
return nil
}

// CreateRole role details to database
// CreateRole creates a new role and persists it to the database
func (fr *Repository) CreateRole(
ctx context.Context,
roleDetails profileutils.Role,
profileID string,
input dto.RoleInput,
) (*profileutils.Role, error) {
ctx, span := tracer.Start(ctx, "CreateRole")
defer span.End()

createCommad := &CreateCommand{
CollectionName: fr.GetRolesCollectionName(),
Data: roleDetails,
exists, err := fr.CheckIfRoleNameExists(ctx, input.Name)
if err != nil {
utils.RecordSpanError(span, err)
return nil, err
}

docRef, err := fr.FirestoreClient.Create(ctx, createCommad)
if err != nil {
if exists {
err := fmt.Errorf("role with similar name exists:%v", input.Name)
utils.RecordSpanError(span, err)
return nil, exceptions.InternalServerError(err)
return nil, err
}

getRoleQuery := &GetSingleQuery{
CollectionName: fr.GetCoverLinkingEventsCollectionName(),
Value: docRef.ID,
timestamp := time.Now().In(pubsubtools.TimeLocation)

role := profileutils.Role{
ID: uuid.New().String(),
Name: input.Name,
Description: input.Description,
CreatedBy: profileID,
Created: timestamp,
Active: true,
Scopes: input.Scopes,
}

docsnapshot, err := fr.FirestoreClient.Get(ctx, getRoleQuery)
if err != nil {
utils.RecordSpanError(span, err)
return nil, exceptions.InternalServerError(err)
createCommad := &CreateCommand{
CollectionName: fr.GetRolesCollectionName(),
Data: role,
}

role := &profileutils.Role{}
err = docsnapshot.DataTo(role)
_, err = fr.FirestoreClient.Create(ctx, createCommad)
if err != nil {
utils.RecordSpanError(span, err)
return nil, exceptions.InternalServerError(err)
}

return role, nil
return &role, nil
}

// UpdateRoleDetails ...
func (fr *Repository) UpdateRoleDetails(ctx context.Context, roleDetails profileutils.Role) error {
// UpdateRoleDetails updates the details of a role
func (fr *Repository) UpdateRoleDetails(
ctx context.Context,
profileID string,
role profileutils.Role,
) (*profileutils.Role, error) {
ctx, span := tracer.Start(ctx, "UpdateRoleDetails")
defer span.End()

collectionName := fr.GetRolesCollectionName()
query := &GetAllQuery{
CollectionName: collectionName,
CollectionName: fr.GetRolesCollectionName(),
Value: role.ID,
FieldName: "id",
Value: roleDetails.ID,
Operator: "==",
}

docs, err := fr.FirestoreClient.GetAll(ctx, query)
if err != nil {
return err
utils.RecordSpanError(span, err)
return nil, err
}

timestamp := time.Now().In(pubsubtools.TimeLocation)

updatedRole := profileutils.Role{
ID: role.ID,
Name: role.Name,
Description: role.Description,
Active: role.Active,
Scopes: role.Scopes,
CreatedBy: role.CreatedBy,
Created: role.Created,
UpdatedBy: profileID,
Updated: timestamp,
}

updateCommand := &UpdateCommand{
CollectionName: collectionName,
CollectionName: fr.GetRolesCollectionName(),
ID: docs[0].Ref.ID,
Data: roleDetails,
Data: updatedRole,
}
err = fr.FirestoreClient.Update(ctx, updateCommand)
if err != nil {
return exceptions.InternalServerError(err)
utils.RecordSpanError(span, err)
return nil, exceptions.InternalServerError(err)
}
return nil

return &updatedRole, nil
}

// GetRoleByID gets role with matching id
func (fr *Repository) GetRoleByID(ctx context.Context, roleID string) (*profileutils.Role, error) {
ctx, span := tracer.Start(ctx, "GetRoleByID")
defer span.End()

collectionName := fr.GetRolesCollectionName()
query := &GetAllQuery{
CollectionName: collectionName,
CollectionName: fr.GetRolesCollectionName(),
FieldName: "id",
Value: roleID,
Operator: "==",
Expand All @@ -3761,20 +3784,21 @@ func (fr *Repository) GetRoleByID(ctx context.Context, roleID string) (*profileu
return nil, exceptions.InternalServerError(err)
}

if len(docs) == 0 {
if len(docs) != 1 {
err = exceptions.ProfileNotFoundError(fmt.Errorf("role not found"))
utils.RecordSpanError(span, err)
return nil, err
}

dsnap := docs[0]
role := &profileutils.Role{}
err = dsnap.DataTo(role)

err = docs[0].DataTo(role)
if err != nil {
utils.RecordSpanError(span, err)
err = fmt.Errorf("unable to read role")
return nil, exceptions.InternalServerError(err)
}

return role, nil
}

Expand All @@ -3797,3 +3821,29 @@ func (fr *Repository) GetRolesByIDs(

return &roles, nil
}

// CheckIfRoleNameExists checks if a role with a similar name exists
// Ensures unique name for each role during creation
func (fr *Repository) CheckIfRoleNameExists(ctx context.Context, name string) (bool, error) {
ctx, span := tracer.Start(ctx, "CheckIfRoleNameExists")
defer span.End()

query := &GetAllQuery{
CollectionName: fr.GetRolesCollectionName(),
FieldName: "name",
Operator: "==",
Value: name,
}

docs, err := fr.FirestoreClient.GetAll(ctx, query)
if err != nil {
utils.RecordSpanError(span, err)
return false, exceptions.InternalServerError(err)
}

if len(docs) == 1 {
return true, nil
}

return false, nil
}

0 comments on commit 1ee8a73

Please sign in to comment.