Skip to content

Commit

Permalink
feat: add api to activate subscriptions to offers
Browse files Browse the repository at this point in the history
  • Loading branch information
MelvinKim committed Jun 14, 2023
1 parent d399b2f commit 7436e41
Show file tree
Hide file tree
Showing 3 changed files with 234 additions and 0 deletions.
15 changes: 15 additions & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,18 @@ type PremiumSMSResponse struct {
Direction string `json:"direction"`
State string `json:"state"`
}

// Subscription
type Subscription struct {
GUID string `json:"guid"`
Gateway string `json:"gateway"`
Offer string `json:"offer"`
Msisdn string `json:"msisdn"`
LinkID string `json:"link_id"`
ActivationDate string `json:"activation_date"`
DeactivationDate any `json:"deactivation_date"`
DeactivationType string `json:"deactivation_type"`
Sms []any `json:"sms"`
Created string `json:"created"`
Updated string `json:"updated"`
}
58 changes: 58 additions & 0 deletions sms.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,61 @@ func (l CommsLib) SendPremiumSMS(ctx context.Context, message, msisdn, subscript

return &premiumSMS, nil
}

// ActivateSubscription is used activate a subscription to an offer on SILCOMMS
func (l CommsLib) ActivateSubscription(ctx context.Context, offer string, msisdn string) (*APIResponse, error) {
path := "/v1/sms/subscriptions/"
payload := struct {
Offer string `json:"offer"`
Msisdn string `json:"msisdn"`
}{
Offer: offer,
Msisdn: msisdn,
}

response, err := l.client.MakeRequest(ctx, http.MethodPost, path, nil, payload, true)
if err != nil {
return nil, fmt.Errorf("failed to make activate subscription request: %v", err)
}
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("invalid activate subscription response code, got: %d", response.StatusCode)
}

var resp APIResponse
err = json.NewDecoder(response.Body).Decode(&resp)
if err != nil {
return nil, fmt.Errorf("failed to decode activate subscription api response: %w", err)
}

return &resp, nil
}

// GetSubscription fetches a subscription from SILCOMMs based on the msisdn and offercode
func (l CommsLib) GetSubscription(ctx context.Context, msisdn string, offer string) (*Subscription, error) {
path := "/v1/sms/subscriptions/"
params := make(map[string]string)
params["msisdn"] = msisdn
params["offercode"] = offer

response, err := l.client.MakeRequest(ctx, http.MethodGet, path, params, nil, true)
if err != nil {
return nil, fmt.Errorf("failed to make get subscription request: %v", err)
}
if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("invalid get subscription response code, got: %d", response.StatusCode)
}

var resp APIResponse
err = json.NewDecoder(response.Body).Decode(&resp)
if err != nil {
return nil, fmt.Errorf("failed to decode get subscription api response: %w", err)
}

var subscription Subscription
subscriptions := resp.Data.(map[string]interface{})["results"].([]interface{})
err = mapstructure.Decode(subscriptions[0].(map[string]interface{}), &subscription)
if err != nil {
return nil, fmt.Errorf("failed to decode get subscription data in api response: %w", err)
}
return &subscription, nil
}
161 changes: 161 additions & 0 deletions sms_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,3 +250,164 @@ func TestSILCommsLib_SendPremiumSMS(t *testing.T) {
})
}
}

func TestSILCommsLib_ActivateSubscription(t *testing.T) {
ctx := context.Background()
type args struct {
ctx context.Context
offer string
msisdn string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Happy case: activate subscription",
args: args{
ctx: ctx,
offer: "01262626626",
msisdn: gofakeit.Phone(),
},
wantErr: false,
},
{
name: "Sad case: invalid status code",
args: args{
ctx: ctx,
offer: "01262626626",
msisdn: gofakeit.Phone(),
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
silcomms.MockLogin()

l := silcomms.MustNewSILCommsLib()

if tt.name == "Happy case: activate subscription" {
httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/v1/sms/subscriptions/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
resp := silcomms.APIResponse{
Status: silcomms.StatusSuccess,
Message: "success",
Data: map[string]interface{}{
"guid": "123456",
"offer": "123456",
"msisdn": "123456",
},
}
return httpmock.NewJsonResponse(http.StatusOK, resp)
})
}

if tt.name == "Sad case: invalid status code" {
httpmock.RegisterResponder(http.MethodPost, fmt.Sprintf("%s/v1/sms/subscriptions/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
return httpmock.NewJsonResponse(http.StatusUnauthorized, nil)
})
}

got, err := l.ActivateSubscription(tt.args.ctx, tt.args.offer, tt.args.msisdn)
if (err != nil) != tt.wantErr {
t.Errorf("SILCommsLib.ActivateSubscription() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && got == nil {
t.Errorf("SILCommsLib.ActivateSubscription() expected response not to be nil for %v", tt.name)
return
}
})
}
}

func TestSILCommsLib_GetSubscription(t *testing.T) {
ctx := context.Background()
type args struct {
ctx context.Context
msisdn string
offer string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
name: "Happy case: get subscription",
args: args{
ctx: ctx,
msisdn: gofakeit.Phone(),
offer: "01262626626",
},
wantErr: false,
},
{
name: "Sad case: invalid status code",
args: args{
ctx: ctx,
msisdn: gofakeit.Phone(),
offer: "01262626626",
},
wantErr: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
silcomms.MockLogin()

l := silcomms.MustNewSILCommsLib()

if tt.name == "Happy case: get subscription" {
httpmock.RegisterResponder(http.MethodGet, fmt.Sprintf("%s/v1/sms/subscriptions/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
resp := silcomms.APIResponse{
Status: silcomms.StatusSuccess,
Message: "success",
Data: map[string]interface{}{
"count": 1,
"next": nil,
"previous": nil,
"results": []map[string]interface{}{
{
"guid": "e602b8b8-9591-4526-915d-57ef2579d8c4",
"gateway": "SAFARICOM",
"offer": "0022345234",
"msisdn": "+254722345678",
"link_id": "123123123123123",
"activation_date": "2022-08-04 14:11:17.206377+03:00",
"deactivation_date": nil,
"deactivation_type": "USER_INITIATED",
"sms": []string{},
"created": "2022-08-04 14:11:17.206377+03:00",
"updated": "2022-08-04 14:11:17.206377+03:00",
},
},
},
}
return httpmock.NewJsonResponse(http.StatusOK, resp)
})
}

if tt.name == "Sad case: invalid status code" {
httpmock.RegisterResponder(http.MethodGet, fmt.Sprintf("%s/v1/sms/subscriptions/", silcomms.BaseURL), func(r *http.Request) (*http.Response, error) {
return httpmock.NewJsonResponse(http.StatusUnauthorized, nil)
})
}

got, err := l.GetSubscription(tt.args.ctx, tt.args.msisdn, tt.args.offer)
if (err != nil) != tt.wantErr {
t.Errorf("SILCommsLib.GetSubscription() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && got == nil {
t.Errorf("SILCommsLib.GetSubscription() expected response not to be nil for %v", tt.name)
return
}
})
}
}

0 comments on commit 7436e41

Please sign in to comment.