Skip to content

Commit

Permalink
chore: update autolinking feature
Browse files Browse the repository at this point in the history
Signed-off-by: Salaton <salaton@healthcloud.co.ke>
  • Loading branch information
Salaton authored and NYARAS committed Jul 29, 2021
1 parent 414ae70 commit 12712f7
Show file tree
Hide file tree
Showing 11 changed files with 215 additions and 110 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func InitializeTestService(ctx context.Context) (*interactor.Interactor, error)
fr := fb.NewFirebaseRepository(firestoreExtension, fbc)
erp := erp.NewAccounting()
engage := engagement.NewServiceEngagementImpl(engagementClient, ext)
edi := edi.NewEdiService(ediClient, fr, engage)
edi := edi.NewEdiService(ediClient, fr)
// hubspot usecases
hubspotService := hubspot.NewHubSpotService()
hubspotfr, err := hubspotRepo.NewHubSpotFirebaseRepository(ctx, hubspotService)
Expand Down
15 changes: 15 additions & 0 deletions pkg/onboarding/infrastructure/services/edi/mock/service_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package mock
import (
"context"
"net/http"

"gitlab.slade360emr.com/go/apiclient"
)

// FakeServiceEDI is an `EDI` service mock
Expand All @@ -13,6 +15,11 @@ type FakeServiceEDI struct {
uid string,
pushToken []string,
) (*http.Response, error)

GetSladerDataFn func(
ctx context.Context,
phoneNumber string,
) (*[]apiclient.MarketingData, error)
}

// LinkCover ...
Expand All @@ -24,3 +31,11 @@ func (f *FakeServiceEDI) LinkCover(
) (*http.Response, error) {
return f.LinkCoverFn(ctx, phoneNumber, uid, pushToken)
}

// GetSladerData represents a mock for the GetSladerData method
func (f *FakeServiceEDI) GetSladerData(
ctx context.Context,
phoneNumber string,
) (*[]apiclient.MarketingData, error) {
return f.GetSladerDataFn(ctx, phoneNumber)
}
114 changes: 77 additions & 37 deletions pkg/onboarding/infrastructure/services/edi/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ package edi

import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"net/url"
"strconv"
"time"

"github.com/google/uuid"
"github.com/savannahghi/onboarding/pkg/onboarding/application/dto"
"github.com/savannahghi/onboarding/pkg/onboarding/application/extension"
"github.com/savannahghi/onboarding/pkg/onboarding/infrastructure/services/engagement"
"github.com/savannahghi/onboarding/pkg/onboarding/repository"
"gitlab.slade360emr.com/go/apiclient"
)

// internal apis definitions
Expand All @@ -22,6 +25,8 @@ const (

// CoverLinkingStatusCompleted ...
CoverLinkingStatusCompleted = "coverlinking completed"

getSladerDataEndpoint = "internal/slader_data?%s"
)

// ServiceEdi defines the business logic required to interact with EDI
Expand All @@ -32,25 +37,24 @@ type ServiceEdi interface {
uid string,
pushToken []string,
) (*http.Response, error)

GetSladerData(ctx context.Context, phoneNumber string) (*[]apiclient.MarketingData, error)
}

// ServiceEDIImpl represents EDI usecases
type ServiceEDIImpl struct {
EdiExt extension.ISCClientExtension
onboardingRepository repository.OnboardingRepository
engagement engagement.ServiceEngagement
}

// NewEdiService returns a new instance of edi implementations
func NewEdiService(
edi extension.ISCClientExtension,
r repository.OnboardingRepository,
engagement engagement.ServiceEngagement,
) ServiceEdi {
return &ServiceEDIImpl{
EdiExt: edi,
onboardingRepository: r,
engagement: engagement,
}
}

Expand All @@ -61,48 +65,84 @@ func (e *ServiceEDIImpl) LinkCover(
uid string,
pushToken []string,
) (*http.Response, error) {
userMarketingData, err := e.engagement.GetSladerData(ctx, phoneNumber)
userMarketingData, err := e.GetSladerData(ctx, phoneNumber)
if err != nil {
return nil, fmt.Errorf("failed to query the user's marketing details :%w", err)
}

if userMarketingData != nil {
sladeCode, err := strconv.Atoi(userMarketingData.PayerSladeCode)
if err != nil {
return nil, fmt.Errorf("failed to convert slade code to an int: %w", err)
}
payload := dto.CoverInput{
PayerSladeCode: sladeCode,
MemberNumber: userMarketingData.MemberNumber,
UID: uid,
PushToken: pushToken,
}
for _, userData := range *userMarketingData {
if userMarketingData != nil {
sladeCode, err := strconv.Atoi(userData.PayerSladeCode)
if err != nil {
return nil, fmt.Errorf("failed to convert slade code to an int: %w", err)
}
payload := dto.CoverInput{
PayerSladeCode: sladeCode,
MemberNumber: userData.MemberNumber,
UID: uid,
PushToken: pushToken,
}

resp, err := e.EdiExt.MakeRequest(
ctx,
http.MethodPost,
LinkCover,
payload,
)
if err != nil {
return nil, fmt.Errorf("failed to make an edi request for coverlinking: %w", err)
}
resp, err := e.EdiExt.MakeRequest(
ctx,
http.MethodPost,
LinkCover,
payload,
)
if err != nil {
return nil, fmt.Errorf("failed to make an edi request for coverlinking: %w", err)
}

currentTime := time.Now()
coverLinkingEvent := &dto.CoverLinkingEvent{
ID: uuid.NewString(),
CoverLinkingEventTime: &currentTime,
CoverStatus: CoverLinkingStatusCompleted,
MemberNumber: userMarketingData.MemberNumber,
PhoneNumber: userMarketingData.Properties.Phone,
}
currentTime := time.Now()
coverLinkingEvent := &dto.CoverLinkingEvent{
ID: uuid.NewString(),
CoverLinkingEventTime: &currentTime,
CoverStatus: CoverLinkingStatusCompleted,
MemberNumber: userData.MemberNumber,
PhoneNumber: userData.Phone,
}

if _, err := e.onboardingRepository.SaveCoverAutolinkingEvents(ctx, coverLinkingEvent); err != nil {
log.Printf("failed to save coverlinking `completed` event: %v", err)
if _, err := e.onboardingRepository.SaveCoverAutolinkingEvents(ctx, coverLinkingEvent); err != nil {
log.Printf("failed to save coverlinking `completed` event: %v", err)
}
return resp, nil
}
}
return nil, nil
}

// GetSladerData calls the `edi service` to fetch the details of a particular slader
// It searches by the phoneNumber
func (e *ServiceEDIImpl) GetSladerData(ctx context.Context, phoneNumber string) (*[]apiclient.MarketingData, error) {
params := url.Values{}
params.Add("phoneNumber", phoneNumber)

return resp, nil
resp, err := e.EdiExt.MakeRequest(
ctx,
http.MethodGet,
fmt.Sprintf(
getSladerDataEndpoint,
params.Encode(),
),
nil,
)

if err != nil {
return nil, fmt.Errorf("failed to get slader data:%w", err)
}
return nil, nil

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unable to get data, with status code %v", resp.StatusCode)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("unable to convert response to string: %v", err)
}

var sladerData []apiclient.MarketingData
err = json.Unmarshal(data, &sladerData)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal slader data: %v", err)
}
return &sladerData, nil
}
131 changes: 117 additions & 14 deletions pkg/onboarding/infrastructure/services/edi/service_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package edi_test

import (
"bytes"
"context"
"fmt"
"io/ioutil"
"net/http"
"reflect"
"testing"

"github.com/google/uuid"
Expand All @@ -12,8 +15,7 @@ import (
"github.com/savannahghi/onboarding/pkg/onboarding/application/extension"
extMock "github.com/savannahghi/onboarding/pkg/onboarding/application/extension/mock"
"github.com/savannahghi/onboarding/pkg/onboarding/infrastructure/services/edi"
"github.com/savannahghi/onboarding/pkg/onboarding/infrastructure/services/engagement"
engagementMock "github.com/savannahghi/onboarding/pkg/onboarding/infrastructure/services/engagement/mock"
ediMock "github.com/savannahghi/onboarding/pkg/onboarding/infrastructure/services/edi/mock"
"github.com/savannahghi/onboarding/pkg/onboarding/repository"
mockRepo "github.com/savannahghi/onboarding/pkg/onboarding/repository/mock"
"gitlab.slade360emr.com/go/apiclient"
Expand All @@ -23,11 +25,10 @@ var fakeISCExt extMock.ISCClientExtension
var ediClient extension.ISCClientExtension = &fakeISCExt
var fakeRepo mockRepo.FakeOnboardingRepository
var r repository.OnboardingRepository = &fakeRepo
var fakeEngagementSvs engagementMock.FakeServiceEngagement
var engagementSvc engagement.ServiceEngagement = &fakeEngagementSvs
var fakeEDIsvs ediMock.FakeServiceEDI

func TestServiceEDIImpl_LinkCover(t *testing.T) {
e := edi.NewEdiService(ediClient, r, engagementSvc)
e := edi.NewEdiService(ediClient, r)

type args struct {
ctx context.Context
Expand Down Expand Up @@ -64,12 +65,13 @@ func TestServiceEDIImpl_LinkCover(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {

if tt.name == "Happy Case - Successfully link a cover" {
fakeEngagementSvs.GetSladerDataFn = func(ctx context.Context, phoneNumber string) (*apiclient.Segment, error) {
return &apiclient.Segment{
MemberNumber: uuid.New().String(),
PayerSladeCode: "457",
fakeEDIsvs.GetSladerDataFn = func(ctx context.Context, phoneNumber string) (*[]apiclient.MarketingData, error) {
return &[]apiclient.MarketingData{
{
MemberNumber: uuid.New().String(),
PayerSladeCode: "457",
},
}, nil
}

Expand All @@ -91,10 +93,12 @@ func TestServiceEDIImpl_LinkCover(t *testing.T) {
}

if tt.name == "Sad Case - Fail to link a cover" {
fakeEngagementSvs.GetSladerDataFn = func(ctx context.Context, phoneNumber string) (*apiclient.Segment, error) {
return &apiclient.Segment{
MemberNumber: uuid.New().String(),
PayerSladeCode: "457",
fakeEDIsvs.GetSladerDataFn = func(ctx context.Context, phoneNumber string) (*[]apiclient.MarketingData, error) {
return &[]apiclient.MarketingData{
{
MemberNumber: uuid.New().String(),
PayerSladeCode: "457",
},
}, nil
}

Expand Down Expand Up @@ -126,3 +130,102 @@ func TestServiceEDIImpl_LinkCover(t *testing.T) {
})
}
}

func TestServiceEDIImpl_GetSladerData(t *testing.T) {
e := edi.NewEdiService(ediClient, r)
ctx := context.Background()
type args struct {
ctx context.Context
phoneNumber string
}
payload := []apiclient.MarketingData{
{
FirstName: "Test",
LastName: "User",
Email: "+254700000000@users.bewell.co.ke",
Phone: "+254700000000",
Payor: "Resolution Insurance",
PayerSladeCode: "1234",
MemberNumber: "1234",
Segment: "test_segment",
},
}
validRespPayload := `
[
{
"firstname":"Test",
"lastname":"User",
"email":"+254700000000@users.bewell.co.ke",
"phone":"+254700000000",
"payor":"Resolution Insurance",
"payer_slade_code":"1234",
"member_number":"1234",
"segment":"test_segment"
}
]
`
respReader := ioutil.NopCloser(bytes.NewReader([]byte(validRespPayload)))

tests := []struct {
name string
args args
want *[]apiclient.MarketingData
wantErr bool
}{
{
name: "Happy Case -> Successfully Get a slader data",
args: args{
ctx: ctx,
phoneNumber: interserviceclient.TestUserPhoneNumber,
},
want: &payload,
wantErr: false,
},
{
name: "Sad Case -> Fail to Get a slader data",
args: args{
ctx: ctx,
phoneNumber: interserviceclient.TestUserPhoneNumber,
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.name == "Happy Case -> Successfully Get a slader data" {
fakeISCExt.MakeRequestFn = func(
ctx context.Context,
method string,
path string,
body interface{},
) (*http.Response, error) {
return &http.Response{
Status: "OK",
StatusCode: 200,
Body: respReader,
}, nil
}
}

if tt.name == "Sad Case -> Fail to Get a slader data" {
fakeISCExt.MakeRequestFn = func(
ctx context.Context,
method string,
path string,
body interface{},
) (*http.Response, error) {
return nil, fmt.Errorf("failed to get slader data")
}
}

got, err := e.GetSladerData(tt.args.ctx, tt.args.phoneNumber)
if (err != nil) != tt.wantErr {
t.Errorf("ServiceEDIImpl.GetSladerData() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("ServiceEDIImpl.GetSladerData() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 12712f7

Please sign in to comment.