Untitled
unknown
plain_text
9 months ago
12 kB
13
Indexable
package orderv1
import (
"context"
"database/sql"
"errors"
"testing"
"connectrpc.com/connect"
"github.com/google/uuid"
"github.com/newmo-oss/ctxtime"
"go.uber.org/mock/gomock"
"google.golang.org/genproto/googleapis/type/money"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/kouzoh/mercari-globalone/internal/layers/tier2/modules/order/infrastructure/db"
"github.com/kouzoh/mercari-globalone/internal/mercari/authx"
"github.com/kouzoh/mercari-globalone/internal/pkg/pkgcmp"
i18n "github.com/kouzoh/mercari-globalone/internal/pkg/proto/framework/i18n/v1"
orderv1 "github.com/kouzoh/mercari-globalone/internal/pkg/proto/layers/tier2/modules/order/applications/order/v1"
"github.com/kouzoh/mercari-globalone/internal/pkg/types"
)
func TestListOrders_Success(t *testing.T) {
t.Parallel()
type args struct {
ctx context.Context
req *connect.Request[orderv1.ListOrdersRequest]
}
type fields struct {
db func(ctrl *gomock.Controller) DB
}
fakeUserID := "123"
now := ctxtime.Now(context.Background())
defUUID1 := uuid.MustParse("bbebb006-5582-405a-b54e-be16c02a23fd")
defUUID2 := uuid.MustParse("75c78443-b3ec-439d-a420-ec6ccb73a2f7")
tests := []struct {
name string
args args
fields fields
want *connect.Response[orderv1.ListOrdersResponse]
}{
{
name: "success: list orders",
args: args{
ctx: authx.GetFakeMercariPAT(context.Background(), t, fakeUserID),
req: connect.NewRequest(&orderv1.ListOrdersRequest{
BuyerId: fakeUserID,
PageSize: 2,
}),
},
fields: fields{
db: mockDBWithOrders(defUUID1, defUUID2, fakeUserID),
},
want: createSuccessResponse(defUUID1, defUUID2, fakeUserID),
},
{
name: "success: list orders not found",
args: args{
ctx: authx.GetFakeMercariPAT(context.Background(), t, fakeUserID),
req: connect.NewRequest(&orderv1.ListOrdersRequest{
BuyerId: fakeUserID,
PageSize: 1,
PageToken: func() string {
token, err := buildListOrdersPageToken(uuid.New().String(), now)
if err != nil {
return ""
}
return token
}(),
}),
},
fields: fields{db: mockDBWithNoOrders()},
want: connect.NewResponse(&orderv1.ListOrdersResponse{}),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
app := NewApplication(nil, tt.fields.db(gomock.NewController(t)))
res, err := app.ListOrders(tt.args.ctx, tt.args.req)
if err != nil {
t.Errorf("ListOrders() failed - error = %v", err)
}
if diff := pkgcmp.Diff(tt.want, res); diff != "" {
t.Errorf("ListOrders() response mismatch = (-want +got):\n%s, %v", diff, err)
}
})
}
}
func mockDBWithOrders(defUUID1, defUUID2 uuid.UUID, fakeUserID string) func(ctrl *gomock.Controller) DB {
return func(ctrl *gomock.Controller) DB {
mockDB := NewMockDB(ctrl)
// Mock the ListOrdersByBuyerID function
mockDB.EXPECT().ListOrdersByBuyerID(gomock.Any(), db.ListOrdersByBuyerIDParams{
BuyerID: "123",
Limit: 3,
}).Return([]db.Order{
{ID: defUUID1, BuyerID: fakeUserID},
{ID: defUUID2, BuyerID: fakeUserID},
}, nil)
// Mock the ListOrderProductsWithSnapshotByOrderIDs function
mockDB.EXPECT().ListOrderProductsWithSnapshotByOrderIDs(gomock.Any(), db.ListOrderProductsWithSnapshotByOrderIDsParams{
OrderIds: []uuid.UUID{defUUID1, defUUID2},
IsDeleted: false,
}).Return([]db.ListOrderProductsWithSnapshotByOrderIDsRow{
{
OrderProduct: db.OrderProduct{
ID: defUUID1,
OrderID: defUUID1,
ProductIdentifier: "product-3456",
SellerID: "seller-9012",
Status: db.OrderProductStatusPlaced,
Quantity: 2,
UnitPrice: "1000.0",
CurrencyCode: "USD",
LifecycleID: types.StringToNullUUID(types.Ptr("e540af23-4561-4989-a9f4-a566d15ef78c")),
},
OrderProductSnapshot: db.OrderProductSnapshot{
OrderProductID: defUUID1,
Title: "Sample Product",
Body: sql.NullString{String: "This is a sample product", Valid: true},
LanguageCode: "en",
},
},
{
OrderProduct: db.OrderProduct{
ID: defUUID2,
OrderID: defUUID2,
ProductIdentifier: "product-3456",
SellerID: "seller-9012",
Status: db.OrderProductStatusPlaced,
Quantity: 2,
UnitPrice: "1000.0",
CurrencyCode: "USD",
LifecycleID: types.StringToNullUUID(types.Ptr("e540af23-4561-4989-a9f4-a566d15ef78c")),
},
OrderProductSnapshot: db.OrderProductSnapshot{
OrderProductID: defUUID2,
Title: "Sample Product",
Body: sql.NullString{String: "This is a sample product", Valid: true},
LanguageCode: "en",
},
},
}, nil)
// Mock the ListOrderExtraFeesByOrderIDs function
mockDB.EXPECT().ListOrderExtraFeesByOrderIDs(gomock.Any(), db.ListOrderExtraFeesByOrderIDsParams{
OrderIds: []uuid.UUID{defUUID1, defUUID2},
IsDeleted: false,
}).Return([]db.OrderExtraFee{
{
ID: defUUID1,
OrderID: defUUID1,
Payer: OrderExtraFeePayertoDB(orderv1.OrderExtraFee_EXTRA_FEE_PAYER_BUYER),
Type: OrderExtraFeeTypetoDB(orderv1.OrderExtraFee_EXTRA_FEE_TYPE_PROXY_SERVICE_PLAN_FEE),
Amount: "100.0",
CurrencyCode: "USD",
},
{
ID: defUUID2,
OrderID: defUUID2,
Payer: OrderExtraFeePayertoDB(orderv1.OrderExtraFee_EXTRA_FEE_PAYER_BUYER),
Type: OrderExtraFeeTypetoDB(orderv1.OrderExtraFee_EXTRA_FEE_TYPE_PROXY_SERVICE_PLAN_FEE),
Amount: "100.0",
CurrencyCode: "USD",
},
}, nil)
return mockDB
}
}
func mockDBWithNoOrders() func(ctrl *gomock.Controller) DB {
return func(ctrl *gomock.Controller) DB {
mockDB := NewMockDB(ctrl)
mockDB.EXPECT().ListOrdersByCursor(gomock.Any(), gomock.Any()).Return([]db.Order{}, sql.ErrNoRows).Times(1)
return mockDB
}
}
func createSuccessResponse(defUUID1, defUUID2 uuid.UUID, fakeUserID string) *connect.Response[orderv1.ListOrdersResponse] {
return connect.NewResponse(&orderv1.ListOrdersResponse{
Orders: []*orderv1.Order{
{
OrderId: defUUID1.String(),
BuyerId: fakeUserID,
OrderProducts: []*orderv1.OrderProduct{
{
OrderProductId: defUUID1.String(),
SellerId: "seller-9012",
State: orderv1.OrderProduct_ORDER_PRODUCT_STATE_PLACED,
ProductIdentifier: "product-3456",
Title: "Sample Product",
Body: "This is a sample product",
UnitPrice: &money.Money{
CurrencyCode: "USD",
Units: 1000,
},
Quantity: 2,
LifecycleId: "e540af23-4561-4989-a9f4-a566d15ef78c",
Language: &i18n.Language{Code: "en"},
Events: []orderv1.Event{
orderv1.Event_EVENT_XB_PROXY_PARTNER_PURCHASED,
orderv1.Event_EVENT_CANCELED,
},
},
},
},
{
OrderId: defUUID2.String(),
BuyerId: fakeUserID,
OrderProducts: []*orderv1.OrderProduct{
{
OrderProductId: defUUID2.String(),
SellerId: "seller-9012",
State: orderv1.OrderProduct_ORDER_PRODUCT_STATE_PLACED,
ProductIdentifier: "product-3456",
Title: "Sample Product",
Body: "This is a sample product",
UnitPrice: &money.Money{
CurrencyCode: "USD",
Units: 1000,
},
Quantity: 2,
LifecycleId: "e540af23-4561-4989-a9f4-a566d15ef78c",
Language: &i18n.Language{Code: "en"},
Events: []orderv1.Event{
orderv1.Event_EVENT_XB_PROXY_PARTNER_PURCHASED,
orderv1.Event_EVENT_CANCELED,
},
},
},
},
},
})
}
func TestListOrders_Error(t *testing.T) {
t.Parallel()
type args struct {
ctx context.Context
req *connect.Request[orderv1.ListOrdersRequest]
}
type fields struct {
db func(ctrl *gomock.Controller) DB
}
fakeUserID := "123"
tests := []struct {
name string
args args
fields fields
wantErrCode connect.Code
}{
{
name: "error: proto validation",
args: args{
ctx: authx.GetFakeMercariPAT(context.Background(), t, "789"),
req: connect.NewRequest(&orderv1.ListOrdersRequest{
PageSize: 2,
}),
},
fields: fields{db: func(ctrl *gomock.Controller) DB {
mockDB := NewMockDB(ctrl)
return mockDB
}},
wantErrCode: connect.CodeInvalidArgument,
},
{
name: "error: anonymous user not allowed",
args: args{
ctx: context.Background(),
req: connect.NewRequest(&orderv1.ListOrdersRequest{
BuyerId: fakeUserID,
PageSize: 2,
}),
},
fields: fields{db: func(ctrl *gomock.Controller) DB {
mockDB := NewMockDB(ctrl)
return mockDB
}},
wantErrCode: connect.CodeUnauthenticated,
},
{
name: "error: permission denied",
args: args{
ctx: authx.GetFakeMercariPAT(context.Background(), t, "789"),
req: connect.NewRequest(&orderv1.ListOrdersRequest{
BuyerId: fakeUserID,
PageSize: 2,
}),
},
fields: fields{db: func(ctrl *gomock.Controller) DB {
mockDB := NewMockDB(ctrl)
return mockDB
}},
wantErrCode: connect.CodePermissionDenied,
},
{
name: "error: invalid page_token",
args: args{
ctx: authx.GetFakeMercariPAT(context.Background(), t, fakeUserID),
req: connect.NewRequest(&orderv1.ListOrdersRequest{
BuyerId: fakeUserID,
PageSize: 2,
PageToken: "yo",
}),
},
fields: fields{db: func(ctrl *gomock.Controller) DB {
mockDB := NewMockDB(ctrl)
return mockDB
}},
wantErrCode: connect.CodeInvalidArgument,
},
{
name: "error: list orders",
args: args{
ctx: authx.GetFakeMercariPAT(context.Background(), t, fakeUserID),
req: connect.NewRequest(&orderv1.ListOrdersRequest{
BuyerId: fakeUserID,
PageSize: 2,
}),
},
fields: fields{db: func(ctrl *gomock.Controller) DB {
mockDB := NewMockDB(ctrl)
mockDB.EXPECT().ListOrdersByBuyerID(gomock.Any(), gomock.Any()).Return([]db.Order{}, connect.NewError(connect.CodeInvalidArgument, errors.New("invalid argument"))).Times(1)
return mockDB
}},
wantErrCode: connect.CodeInvalidArgument,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
app := NewApplication(nil, tt.fields.db(gomock.NewController(t)))
_, err := app.ListOrders(tt.args.ctx, tt.args.req)
if got := connect.CodeOf(err); got != tt.wantErrCode {
t.Errorf("ListOrders() error_code = %v, want %v", got, tt.wantErrCode)
}
})
}
}
func getBaseReqOrder() *orderv1.Order {
return &orderv1.Order{
BuyerId: "buyer-5678",
OrderProducts: []*orderv1.OrderProduct{
{
SellerId: "seller-9012",
ProductIdentifier: "product-3456",
Title: "Sample Product",
Body: "This is a sample product",
UnitPrice: &money.Money{
Units: 1000,
Nanos: 0,
CurrencyCode: "USD",
},
Quantity: 2,
Language: &i18n.Language{
Code: "en",
},
Metadata: map[string]string{"size": "M"},
LifecycleId: xbLifecycleID,
},
},
OrderExtraFees: []*orderv1.OrderExtraFee{{
OrderProductId: "",
Type: orderv1.OrderExtraFee_EXTRA_FEE_TYPE_PROXY_SERVICE_PLAN_FEE,
Amount: &money.Money{
CurrencyCode: "USD",
Units: 100,
Nanos: 0,
},
Payer: orderv1.OrderExtraFee_EXTRA_FEE_PAYER_BUYER,
}},
CreateTime: ×tamppb.Timestamp{Seconds: 1688208000},
}
}
func getBaseRespOrder(uuid uuid.UUID) *orderv1.Order {
order := getBaseReqOrder()
order.OrderId = uuid.String()
order.GetOrderProducts()[0].OrderProductId = uuid.String()
order.GetOrderProducts()[0].State = orderv1.OrderProduct_ORDER_PRODUCT_STATE_PLACED
order.GetOrderProducts()[0].LifecycleId = xbLifecycleID
order.GetOrderProducts()[0].Events = []orderv1.Event{
orderv1.Event_EVENT_XB_PROXY_PARTNER_PURCHASED,
orderv1.Event_EVENT_CANCELED,
}
order.GetOrderExtraFees()[0].OrderExtraFeeId = uuid.String()
return order
}
Editor is loading...
Leave a Comment