341 lines
9.6 KiB
Go
341 lines
9.6 KiB
Go
package handlers
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"otaupdate/services"
|
|
"testing"
|
|
|
|
"github.com/fiskerinc/cloud-services/pkg/grpc/sms"
|
|
"github.com/fiskerinc/cloud-services/pkg/httpclient/tester"
|
|
th "github.com/fiskerinc/cloud-services/pkg/testhelper"
|
|
"github.com/pkg/errors"
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
)
|
|
|
|
type MockSmsClientSucc struct{}
|
|
|
|
// HandleSMSQueue implements sms.SMSServiceClient.
|
|
func (*MockSmsClientSucc) HandleSMSQueue(ctx context.Context, in *sms.SendSMSRequest, opts ...grpc.CallOption) (*sms.SMSQueueResponse, error) {
|
|
return &sms.SMSQueueResponse{
|
|
SmsMsgID: "1023",
|
|
SentSuccessful: false,
|
|
}, nil
|
|
}
|
|
|
|
func (m *MockSmsClientSucc) HandleSMSSend(ctx context.Context,in *sms.SendSMSRequest,opts ...grpc.CallOption,) (*sms.SMSDetailsResponse, error) {
|
|
return &sms.SMSDetailsResponse{
|
|
SmsMsgID: "123",
|
|
Status: 5,
|
|
MessageText: "messageText",
|
|
SenderLogin: "sender",
|
|
SentFrom: "from",
|
|
SentTo: "to",
|
|
DateSent: "dateSent",
|
|
MsgType: "type",
|
|
DateModified: "dateModified",
|
|
ICCID: "iccid",
|
|
}, nil
|
|
}
|
|
|
|
func (m *MockSmsClientSucc) HandleGetProducts(ctx context.Context, in *sms.GetAvailableProductsRequest, opts ...grpc.CallOption) (*sms.GetAvailableProductsResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientSucc) HandleChangeRatePlan(ctx context.Context, in *sms.ChangeRatePlanRequest, opts ...grpc.CallOption) (*sms.ChangeRatePlanResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientSucc) HandleCustomAttributes(ctx context.Context, in *sms.CustomAtributesRequest, opts ...grpc.CallOption) (*sms.CustomAtributeResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientSucc) HandleDeviceDetails(ctx context.Context, in *sms.DeviceDetailsRequest, opts ...grpc.CallOption) (*sms.DeviceDetailsResponse, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
type MockSmsClientFail struct{}
|
|
|
|
// HandleSMSQueue implements sms.SMSServiceClient.
|
|
func (*MockSmsClientFail) HandleSMSQueue(ctx context.Context, in *sms.SendSMSRequest, opts ...grpc.CallOption) (*sms.SMSQueueResponse, error) {
|
|
return &sms.SMSQueueResponse{
|
|
SmsMsgID: "1023",
|
|
SentSuccessful: false,
|
|
}, nil
|
|
}
|
|
|
|
func (m *MockSmsClientFail) HandleSMSSend(
|
|
ctx context.Context,
|
|
in *sms.SendSMSRequest,
|
|
opts ...grpc.CallOption,
|
|
) (*sms.SMSDetailsResponse, error) {
|
|
return nil, errors.New("unintelligable error")
|
|
}
|
|
|
|
func (m *MockSmsClientFail) HandleGetProducts(ctx context.Context, in *sms.GetAvailableProductsRequest, opts ...grpc.CallOption) (*sms.GetAvailableProductsResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientFail) HandleChangeRatePlan(ctx context.Context, in *sms.ChangeRatePlanRequest, opts ...grpc.CallOption) (*sms.ChangeRatePlanResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientFail) HandleCustomAttributes(ctx context.Context, in *sms.CustomAtributesRequest, opts ...grpc.CallOption) (*sms.CustomAtributeResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientFail) HandleDeviceDetails(ctx context.Context, in *sms.DeviceDetailsRequest, opts ...grpc.CallOption) (*sms.DeviceDetailsResponse, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
type MockSmsClientFailWithGoodErr struct{}
|
|
|
|
// HandleSMSQueue implements sms.SMSServiceClient.
|
|
func (*MockSmsClientFailWithGoodErr) HandleSMSQueue(ctx context.Context, in *sms.SendSMSRequest, opts ...grpc.CallOption) (*sms.SMSQueueResponse, error) {
|
|
return &sms.SMSQueueResponse{
|
|
SmsMsgID: "1023",
|
|
SentSuccessful: false,
|
|
}, nil
|
|
}
|
|
|
|
func (m *MockSmsClientFailWithGoodErr) HandleSMSSend(
|
|
ctx context.Context,
|
|
in *sms.SendSMSRequest,
|
|
opts ...grpc.CallOption,
|
|
) (*sms.SMSDetailsResponse, error) {
|
|
return nil, status.Error(codes.Internal, "bad message status")
|
|
}
|
|
|
|
func (m *MockSmsClientFailWithGoodErr) HandleGetProducts(ctx context.Context, in *sms.GetAvailableProductsRequest, opts ...grpc.CallOption) (*sms.GetAvailableProductsResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientFailWithGoodErr) HandleChangeRatePlan(ctx context.Context, in *sms.ChangeRatePlanRequest, opts ...grpc.CallOption) (*sms.ChangeRatePlanResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientFailWithGoodErr) HandleCustomAttributes(ctx context.Context, in *sms.CustomAtributesRequest, opts ...grpc.CallOption) (*sms.CustomAtributeResponse, error) {
|
|
return nil, nil
|
|
}
|
|
func (m *MockSmsClientFailWithGoodErr) HandleDeviceDetails(ctx context.Context, in *sms.DeviceDetailsRequest, opts ...grpc.CallOption) (*sms.DeviceDetailsResponse, error) {
|
|
return nil, nil
|
|
}
|
|
|
|
func Test_HandleSMSSend(t *testing.T) {
|
|
type testCase struct {
|
|
name string
|
|
doBefore func()
|
|
httpTC tester.HttpTestCase
|
|
}
|
|
|
|
testCases := []testCase{
|
|
{
|
|
name: "Valid",
|
|
doBefore: func() { services.SetSmsClient(&MockSmsClientSucc{}) },
|
|
httpTC: tester.HttpTestCase{
|
|
Request: th.MakeTestRequest(
|
|
"POST",
|
|
"http://example.com/sms",
|
|
sms.SendSMSRequest{ICCID: "iccid", MessageText: "messageText"}),
|
|
ExpectedStatus: http.StatusOK,
|
|
ExpectedRegexMap: map[string]string{"smsMsgID": "123", "status": "Delivered", "messageText": "messageText", "senderLogin": "sender", "sentTo": "to", "sentFrom": "from", "msgType": "type", "dateSent": "dateSent", "dateModified": "dateModified", "ICCID": "iccid"},
|
|
},
|
|
},
|
|
{
|
|
name: "InvalidJson",
|
|
doBefore: func() { services.SetSmsClient(&MockSmsClientSucc{}) },
|
|
httpTC: tester.HttpTestCase{
|
|
Request: th.MakeTestRequest(
|
|
"POST",
|
|
"http://example.com/sms",
|
|
"invalid"),
|
|
ExpectedStatus: http.StatusBadRequest,
|
|
ExpectedResponse: `{"message":"json: cannot unmarshal string into Go value of type sms.SendSMSRequest","error":"Bad Request"}`,
|
|
},
|
|
},
|
|
{
|
|
name: "Failing with bad error",
|
|
doBefore: func() { services.SetSmsClient(&MockSmsClientFail{}) },
|
|
httpTC: tester.HttpTestCase{
|
|
Request: th.MakeTestRequest(
|
|
"POST",
|
|
"http://example.com/sms",
|
|
sms.SendSMSRequest{ICCID: "iccid", MessageText: "messageText"}),
|
|
ExpectedStatus: http.StatusInternalServerError,
|
|
ExpectedResponse: `{"message":"unintelligable error","error":"Internal Server Error"}`,
|
|
},
|
|
},
|
|
{
|
|
name: "Failing with good error",
|
|
doBefore: func() { services.SetSmsClient(&MockSmsClientFailWithGoodErr{}) },
|
|
httpTC: tester.HttpTestCase{
|
|
Request: th.MakeTestRequest(
|
|
"POST",
|
|
"http://example.com/sms",
|
|
sms.SendSMSRequest{ICCID: "iccid", MessageText: "messageText"}),
|
|
ExpectedStatus: http.StatusExpectationFailed,
|
|
ExpectedResponse: `{"message":"bad message status","error":"Expectation Failed"}`,
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
tc.doBefore()
|
|
w := tc.httpTC.Test(HandleSMSSend)
|
|
tc.httpTC.ValidateHttp(t, tc.name, w)
|
|
}
|
|
}
|
|
|
|
func Test_grpcErrToHttpErr(t *testing.T) {
|
|
type args struct {
|
|
status *status.Status
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
wantCode int
|
|
wantMsg string
|
|
}{
|
|
{
|
|
name: "Internal",
|
|
args: args{
|
|
status: status.New(codes.Internal, "just"),
|
|
},
|
|
wantCode: 500,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "Internal with bad status",
|
|
args: args{
|
|
status: status.New(codes.Internal, "bad message status"),
|
|
},
|
|
wantCode: http.StatusExpectationFailed,
|
|
wantMsg: "bad message status",
|
|
},
|
|
|
|
{
|
|
name: "InvalidArgument",
|
|
args: args{
|
|
status: status.New(codes.InvalidArgument, "just"),
|
|
},
|
|
wantCode: 400,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "NotFound",
|
|
args: args{
|
|
status: status.New(codes.NotFound, "just"),
|
|
},
|
|
wantCode: 404,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "AlreadyExists",
|
|
args: args{
|
|
status: status.New(codes.AlreadyExists, "just"),
|
|
},
|
|
wantCode: 409,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "PermissionDenied",
|
|
args: args{
|
|
status: status.New(codes.PermissionDenied, "just"),
|
|
},
|
|
wantCode: 403,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "Unauthenticated",
|
|
args: args{
|
|
status: status.New(codes.Unauthenticated, "just"),
|
|
},
|
|
wantCode: 401,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "Unimplemented",
|
|
args: args{
|
|
status: status.New(codes.Unimplemented, "just"),
|
|
},
|
|
wantCode: 501,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "Unknown",
|
|
args: args{
|
|
status: status.New(codes.Unknown, "just"),
|
|
},
|
|
wantCode: 500,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "Unavailable",
|
|
args: args{
|
|
status: status.New(codes.Unavailable, "just"),
|
|
},
|
|
wantCode: 503,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "DeadlineExceeded",
|
|
args: args{
|
|
status: status.New(codes.DeadlineExceeded, "just"),
|
|
},
|
|
wantCode: http.StatusRequestTimeout,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "Canceled",
|
|
args: args{
|
|
status: status.New(codes.Canceled, "just"),
|
|
},
|
|
wantCode: 499,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "FailedPrecondition",
|
|
args: args{
|
|
status: status.New(codes.FailedPrecondition, "just"),
|
|
},
|
|
wantCode: 412,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "OutOfRange",
|
|
args: args{
|
|
status: status.New(codes.OutOfRange, "just"),
|
|
},
|
|
wantCode: 400,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "Aborted",
|
|
args: args{
|
|
status: status.New(codes.Aborted, "just"),
|
|
},
|
|
wantCode: 409,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "ResourceExhausted",
|
|
args: args{
|
|
status: status.New(codes.ResourceExhausted, "just"),
|
|
},
|
|
wantCode: 429,
|
|
wantMsg: "just",
|
|
},
|
|
{
|
|
name: "DataLoss",
|
|
args: args{
|
|
status: status.New(codes.DataLoss, "just"),
|
|
},
|
|
wantCode: http.StatusInternalServerError,
|
|
wantMsg: "just",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if gotMsg, gotCode := grpcErrToHttpErr(tt.args.status); gotCode != tt.wantCode || gotMsg != tt.wantMsg {
|
|
t.Errorf("grpcErrToHttpErr() = (%v, %v), want (%v, %v)", gotCode, gotMsg, tt.wantCode, tt.wantMsg)
|
|
}
|
|
})
|
|
}
|
|
}
|