Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create agent with a custom agent-profile #76

Merged
merged 1 commit into from
Aug 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions pkg/onboarding/domain/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -361,3 +361,47 @@ func (e *EmploymentType) UnmarshalGQL(v interface{}) error {
func (e EmploymentType) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}

//AgentType is the different kind of agent groups
type AgentType string

// Valid AgentTypes that can possibly be given to a user
const (
//FreelanceAgent are agents that work at part time with savannah
FreelanceAgent AgentType = "Independent Agent"

//CompanyAgent are agents who are fully employed by savannah
CompanyAgent AgentType = "SIL Agent"
)

// IsValid ..
func (e AgentType) IsValid() bool {
switch e {
case FreelanceAgent, CompanyAgent:
return true
}
return false
}

func (e AgentType) String() string {
return string(e)
}

// UnmarshalGQL ..
func (e *AgentType) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}

*e = AgentType(str)
if !e.IsValid() {
return fmt.Errorf("%s is not a valid AgentType", str)
}
return nil
}

// MarshalGQL ..
func (e AgentType) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}
117 changes: 117 additions & 0 deletions pkg/onboarding/domain/enum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -632,3 +632,120 @@ func TestPractitionerService_MarshalGQL(t *testing.T) {
})
}
}

func TestAgentType_IsValid(t *testing.T) {
tests := []struct {
name string
e domain.AgentType
want bool
}{
{
name: "valid",
e: domain.CompanyAgent,
want: true,
},
{
name: "invalid",
e: domain.AgentType("FreelanceAgent"),
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.e.IsValid(); got != tt.want {
t.Errorf("AgentType.IsValid() = %v, want %v", got, tt.want)
}
})
}
}

func TestAgentType_String(t *testing.T) {
tests := []struct {
name string
e domain.AgentType
want string
}{
{
name: "valid",
e: domain.CompanyAgent,
want: "SIL Agent",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := tt.e.String(); got != tt.want {
t.Errorf("AgentType.String() = %v, want %v", got, tt.want)
}
})
}
}

func TestAgentType_UnmarshalGQL(t *testing.T) {
valid := domain.CompanyAgent
invalid := domain.AgentType("CompanyAgent")

type args struct {
v interface{}
}
tests := []struct {
name string
e *domain.AgentType
args args
wantErr bool
}{
{
name: "invalid type",
e: &invalid,
args: args{
v: 1,
},
wantErr: true,
},
{
name: "invalid string",
e: &invalid,
args: args{
v: "CompanyAgent",
},
wantErr: true,
},
{
name: "valid type",
e: &valid,
args: args{
v: "SIL Agent",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if err := tt.e.UnmarshalGQL(tt.args.v); (err != nil) != tt.wantErr {
t.Errorf("AgentType.UnmarshalGQL() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

func TestAgentType_MarshalGQL(t *testing.T) {
tests := []struct {
name string
e domain.AgentType
wantW string
}{
{
name: "valid",
e: domain.CompanyAgent,
wantW: strconv.Quote("SIL Agent"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
w := &bytes.Buffer{}
tt.e.MarshalGQL(w)
if gotW := w.String(); gotW != tt.wantW {
t.Errorf("AgentType.MarshalGQL() = %v, want %v", gotW, tt.wantW)
}
})
}
}
14 changes: 14 additions & 0 deletions pkg/onboarding/domain/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,17 @@ type RoleRevocationLog struct {
// Created is the timestamp indicating when the role was created
Created time.Time `json:"created" firestore:"created"`
}

//AdminProfile is the profile of all users who permform admin tasks
type AdminProfile struct {
ID string `json:"id,omitempty"`
ProfileID string `json:"profileID,omitempty"`
OrganizationID string `json:"organizationID,omitempty"`
}

//AgentProfile is the profile of all users who permform agent tasks
type AgentProfile struct {
ID string `json:"id,omitempty"`
ProfileID string `json:"profileID,omitempty"`
AgentType AgentType `json:"agentType,omitempty"`
}
122 changes: 122 additions & 0 deletions pkg/onboarding/infrastructure/database/fb/firebase.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const (
coverLinkingEventsCollectionName = "coverlinking_events"
rolesRevocationCollectionName = "role_revocations"
rolesCollectionName = "user_roles"
adminProfileCollectionName = "admin_profiles"
agentProfileCollectionName = "agent_profiles"
)

// Repository accesses and updates an item that is stored on Firebase
Expand Down Expand Up @@ -174,6 +176,18 @@ func (fr Repository) GetRolesRevocationCollectionName() string {
return suffixed
}

// GetAdminProfileCollectionName ...
func (fr Repository) GetAdminProfileCollectionName() string {
suffixed := firebasetools.SuffixCollection(adminProfileCollectionName)
return suffixed
}

// GetAgentProfileCollectionName ...
func (fr Repository) GetAgentProfileCollectionName() string {
suffixed := firebasetools.SuffixCollection(agentProfileCollectionName)
return suffixed
}

// GetUserProfileByUID retrieves the user profile by UID
func (fr *Repository) GetUserProfileByUID(
ctx context.Context,
Expand Down Expand Up @@ -4372,3 +4386,111 @@ func (fr *Repository) CheckIfUserHasPermission(

return false, nil
}

//CreateAdminProfile creates an admin profile related to user profile
func (fr *Repository) CreateAdminProfile(ctx context.Context, adminProfile domain.AdminProfile) error {

ctx, span := tracer.Start(ctx, "CreateAdminProfile")
defer span.End()

exists, err := fr.CheckIfAdminProfileExists(ctx, adminProfile.ProfileID)
if err != nil {
utils.RecordSpanError(span, err)
return err
}

if exists {
err := fmt.Errorf("user %s already has admin profile", adminProfile.ProfileID)
utils.RecordSpanError(span, err)
return err
}

createCommad := &CreateCommand{
CollectionName: fr.GetAdminProfileCollectionName(),
Data: adminProfile,
}

_, err = fr.FirestoreClient.Create(ctx, createCommad)
if err != nil {
utils.RecordSpanError(span, err)
return exceptions.InternalServerError(err)
}

return nil
}

//CheckIfAdminProfileExists return true if admin profile with profile ID provide
//exists, otherwise false
func (fr *Repository) CheckIfAdminProfileExists(ctx context.Context, profileID string) (bool, error) {
ctx, span := tracer.Start(ctx, "CheckIfAdminProfileExists")
defer span.End()

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

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

return len(docs) == 1, nil
}

//CreateAgentProfile creates an agent profile related to user profile
func (fr *Repository) CreateAgentProfile(ctx context.Context, agentProfile domain.AgentProfile) error {

ctx, span := tracer.Start(ctx, "CreateAgentProfile")
defer span.End()

exists, err := fr.CheckIfAgentProfileExists(ctx, agentProfile.ProfileID)
if err != nil {
utils.RecordSpanError(span, err)
return err
}

if exists {
err := fmt.Errorf("user %s already has agent profile", agentProfile.ProfileID)
utils.RecordSpanError(span, err)
return err
}

createCommad := &CreateCommand{
CollectionName: fr.GetAgentProfileCollectionName(),
Data: agentProfile,
}

_, err = fr.FirestoreClient.Create(ctx, createCommad)
if err != nil {
utils.RecordSpanError(span, err)
return exceptions.InternalServerError(err)
}

return nil
}

//CheckIfAgentProfileExists return true if agent profile with profile ID provide
//exists, otherwise false
func (fr *Repository) CheckIfAgentProfileExists(ctx context.Context, profileID string) (bool, error) {
ctx, span := tracer.Start(ctx, "CheckIfAgentProfileExists")
defer span.End()

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

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

return len(docs) == 1, nil
}
Loading