diff --git a/pkg/onboarding/infrastructure/database/fb/firebase_integration_test.go b/pkg/onboarding/infrastructure/database/fb/firebase_integration_test.go index 9a4e265b..b779d785 100644 --- a/pkg/onboarding/infrastructure/database/fb/firebase_integration_test.go +++ b/pkg/onboarding/infrastructure/database/fb/firebase_integration_test.go @@ -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) diff --git a/pkg/onboarding/infrastructure/services/edi/mock/service_mock.go b/pkg/onboarding/infrastructure/services/edi/mock/service_mock.go index 09e524a5..5527ef99 100644 --- a/pkg/onboarding/infrastructure/services/edi/mock/service_mock.go +++ b/pkg/onboarding/infrastructure/services/edi/mock/service_mock.go @@ -3,6 +3,8 @@ package mock import ( "context" "net/http" + + "gitlab.slade360emr.com/go/apiclient" ) // FakeServiceEDI is an `EDI` service mock @@ -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 ... @@ -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) +} diff --git a/pkg/onboarding/infrastructure/services/edi/service.go b/pkg/onboarding/infrastructure/services/edi/service.go index 3428e2c5..089c9ec1 100644 --- a/pkg/onboarding/infrastructure/services/edi/service.go +++ b/pkg/onboarding/infrastructure/services/edi/service.go @@ -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 @@ -22,6 +25,8 @@ const ( // CoverLinkingStatusCompleted ... CoverLinkingStatusCompleted = "coverlinking completed" + + getSladerDataEndpoint = "internal/slader_data?%s" ) // ServiceEdi defines the business logic required to interact with EDI @@ -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, } } @@ -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: ¤tTime, - CoverStatus: CoverLinkingStatusCompleted, - MemberNumber: userMarketingData.MemberNumber, - PhoneNumber: userMarketingData.Properties.Phone, - } + currentTime := time.Now() + coverLinkingEvent := &dto.CoverLinkingEvent{ + ID: uuid.NewString(), + CoverLinkingEventTime: ¤tTime, + 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 } diff --git a/pkg/onboarding/infrastructure/services/edi/service_test.go b/pkg/onboarding/infrastructure/services/edi/service_test.go index 9392fbcc..cebe8a16 100644 --- a/pkg/onboarding/infrastructure/services/edi/service_test.go +++ b/pkg/onboarding/infrastructure/services/edi/service_test.go @@ -1,9 +1,12 @@ package edi_test import ( + "bytes" "context" "fmt" + "io/ioutil" "net/http" + "reflect" "testing" "github.com/google/uuid" @@ -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" @@ -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 @@ -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 } @@ -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 } @@ -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) + } + }) + } +} diff --git a/pkg/onboarding/infrastructure/services/engagement/mock/service_mock.go b/pkg/onboarding/infrastructure/services/engagement/mock/service_mock.go index a8feb126..80efa316 100644 --- a/pkg/onboarding/infrastructure/services/engagement/mock/service_mock.go +++ b/pkg/onboarding/infrastructure/services/engagement/mock/service_mock.go @@ -7,7 +7,6 @@ import ( "github.com/savannahghi/feedlib" "github.com/savannahghi/onboarding/pkg/onboarding/application/dto" "github.com/savannahghi/profileutils" - "gitlab.slade360emr.com/go/apiclient" ) // FakeServiceEngagement is an `engagement` service mock . @@ -35,8 +34,6 @@ type FakeServiceEngagement struct { VerifyEmailOTPFn func(ctx context.Context, email, OTP string) (bool, error) SendSMSFn func(ctx context.Context, phoneNumbers []string, message string) error - - GetSladerDataFn func(ctx context.Context, phoneNumber string) (*apiclient.Segment, error) } // PublishKYCNudge ... @@ -128,8 +125,3 @@ func (f *FakeServiceEngagement) NotifySupplierOnSuspension(ctx context.Context, func (f *FakeServiceEngagement) SendSMS(ctx context.Context, phoneNumbers []string, message string) error { return f.SendSMSFn(ctx, phoneNumbers, message) } - -// GetSladerData ... -func (f *FakeServiceEngagement) GetSladerData(ctx context.Context, phoneNumber string) (*apiclient.Segment, error) { - return f.GetSladerDataFn(ctx, phoneNumber) -} diff --git a/pkg/onboarding/infrastructure/services/engagement/service.go b/pkg/onboarding/infrastructure/services/engagement/service.go index 0dabece8..90d7b47f 100644 --- a/pkg/onboarding/infrastructure/services/engagement/service.go +++ b/pkg/onboarding/infrastructure/services/engagement/service.go @@ -7,11 +7,8 @@ import ( "fmt" "io/ioutil" "net/http" - "net/url" "text/template" - "gitlab.slade360emr.com/go/apiclient" - "github.com/asaskevich/govalidator" "github.com/savannahghi/enumutils" "github.com/savannahghi/feedlib" @@ -42,8 +39,6 @@ const ( VerifyOTPEndPoint = "internal/verify_otp/" sendSMS = "internal/send_sms" - - getSladerDataEndpoint = "internal/slader_data?%s" ) // ServiceEngagement represents engagement usecases @@ -96,8 +91,6 @@ type ServiceEngagement interface { VerifyEmailOTP(ctx context.Context, email, OTP string) (bool, error) SendSMS(ctx context.Context, phoneNumbers []string, message string) error - - GetSladerData(ctx context.Context, phoneNumber string) (*apiclient.Segment, error) } // ServiceEngagementImpl represents engagement usecases @@ -505,41 +498,3 @@ func (en *ServiceEngagementImpl) SendSMS(ctx context.Context, phoneNumbers []str return nil } - -// GetSladerData calls the `engagement service` to fetch the details of a particular slader -// It searches by the phoneNumber -func (en *ServiceEngagementImpl) GetSladerData(ctx context.Context, phoneNumber string) (*apiclient.Segment, error) { - params := url.Values{} - params.Add("phoneNumber", phoneNumber) - - resp, err := en.Engage.MakeRequest( - ctx, - http.MethodGet, - fmt.Sprintf( - getSladerDataEndpoint, - params.Encode(), - ), - nil, - ) - - if err != nil { - return nil, fmt.Errorf("failed to get slader data:%w", err) - } - - 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.Segment - err = json.Unmarshal(data, &sladerData) - if err != nil { - return nil, fmt.Errorf("failed to unmarshal slader data: %v", err) - } - - return &sladerData, nil -} diff --git a/pkg/onboarding/presentation/config.go b/pkg/onboarding/presentation/config.go index b282546e..d1cad15e 100644 --- a/pkg/onboarding/presentation/config.go +++ b/pkg/onboarding/presentation/config.go @@ -117,7 +117,7 @@ func Router(ctx context.Context) (*mux.Router, error) { erp := erp.NewAccounting() chrg := chargemaster.NewChargeMasterUseCasesImpl() engage := engagement.NewServiceEngagementImpl(engagementClient, baseExt) - edi := edi.NewEdiService(ediClient, repo, engage) + edi := edi.NewEdiService(ediClient, repo) mes := messaging.NewServiceMessagingImpl(baseExt) pinExt := extension.NewPINExtensionImpl() diff --git a/pkg/onboarding/usecases/login_test.go b/pkg/onboarding/usecases/login_test.go index 3c1b0f56..9b12a7d7 100644 --- a/pkg/onboarding/usecases/login_test.go +++ b/pkg/onboarding/usecases/login_test.go @@ -194,7 +194,7 @@ func InitializeTestService(ctx context.Context) (*interactor.Interactor, error) engagementClient := utils.NewInterServiceClient(engagementService, ext) ediClient := utils.NewInterServiceClient(ediService, ext) engage := engagement.NewServiceEngagementImpl(engagementClient, ext) - edi := edi.NewEdiService(ediClient, repo, engage) + edi := edi.NewEdiService(ediClient, repo) erp := erp.NewAccounting() chrg := chargemaster.NewChargeMasterUseCasesImpl() diff --git a/pkg/onboarding/usecases/supplier_internal_test.go b/pkg/onboarding/usecases/supplier_internal_test.go index d93b3e11..386ccad9 100644 --- a/pkg/onboarding/usecases/supplier_internal_test.go +++ b/pkg/onboarding/usecases/supplier_internal_test.go @@ -77,7 +77,7 @@ func TestParseKYCAsMap(t *testing.T) { engagementClient := utils.NewInterServiceClient(engagementService, ext) ediClient := utils.NewInterServiceClient(ediService, ext) engage := engagement.NewServiceEngagementImpl(engagementClient, ext) - edi := edi.NewEdiService(ediClient, repo, engage) + edi := edi.NewEdiService(ediClient, repo) erp := erp.NewAccounting() chrg := chargemaster.NewChargeMasterUseCasesImpl() // hubspot usecases diff --git a/pkg/onboarding/usecases/ussd/main_integration_test.go b/pkg/onboarding/usecases/ussd/main_integration_test.go index d039bab1..80a1849c 100644 --- a/pkg/onboarding/usecases/ussd/main_integration_test.go +++ b/pkg/onboarding/usecases/ussd/main_integration_test.go @@ -106,7 +106,7 @@ func InitializeTestService(ctx context.Context) (*interactor.Interactor, error) hubspotUsecases := hubspotUsecases.NewHubSpotUsecases(hubspotfr) crmExt := crmExt.NewCrmService(hubspotUsecases) engage := engagement.NewServiceEngagementImpl(engagementClient, ext) - edi := edi.NewEdiService(ediClient, repo, engage) + edi := edi.NewEdiService(ediClient, repo) ps, err := pubsubmessaging.NewServicePubSubMessaging( pubSubClient, ext, diff --git a/tests/config_test.go b/tests/config_test.go index 573a6d0d..67a224e2 100644 --- a/tests/config_test.go +++ b/tests/config_test.go @@ -129,7 +129,7 @@ func InitializeTestService(ctx context.Context) (*interactor.Interactor, error) hubspotUsecases := hubspotUsecases.NewHubSpotUsecases(hubspotfr) crmExt := crmExt.NewCrmService(hubspotUsecases) engage := engagement.NewServiceEngagementImpl(engagementClient, ext) - edi := edi.NewEdiService(ediClient, repo, engage) + edi := edi.NewEdiService(ediClient, repo) ps, err := pubsubmessaging.NewServicePubSubMessaging( pubSubClient, ext,