package user import ( "context" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/stretchr/testify/assert" "gorm.io/driver/mysql" "gorm.io/gorm" ) func setupMockDBForShipping(t *testing.T) (*gorm.DB, sqlmock.Sqlmock) { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } gormDB, err := gorm.Open(mysql.New(mysql.Config{ Conn: db, SkipInitializeWithVersion: true, }), &gorm.Config{}) if err != nil { t.Fatalf("an error '%s' was not expected when opening gorm database", err) } return gormDB, mock } func TestRequestShippings_EmptyInventoryIDs(t *testing.T) { db, _ := setupMockDBForShipping(t) svc := newTestService(db) _, _, _, _, failed, err := svc.RequestShippings(context.Background(), 1, []int64{}, nil) assert.NoError(t, err) assert.Len(t, failed, 1) assert.Equal(t, "invalid_params", failed[0].Reason) } func TestRequestShippings_AllZeroInventoryIDs(t *testing.T) { db, _ := setupMockDBForShipping(t) svc := newTestService(db) _, _, _, _, failed, err := svc.RequestShippings(context.Background(), 1, []int64{0, -1, 0}, nil) assert.NoError(t, err) assert.Len(t, failed, 1) assert.Equal(t, "invalid_params", failed[0].Reason) } func TestRequestShippings_NoDefaultAddress(t *testing.T) { db, mock := setupMockDBForShipping(t) svc := newTestService(db) mock.ExpectQuery("SELECT .* FROM `user_addresses`"). WillReturnRows(sqlmock.NewRows(nil)) mock.ExpectQuery("SELECT .* FROM `user_addresses`"). WillReturnRows(sqlmock.NewRows(nil)) _, _, _, _, failed, err := svc.RequestShippings(context.Background(), 1, []int64{1, 2}, nil) assert.NoError(t, err) assert.Len(t, failed, 1) assert.Equal(t, "no_default_address", failed[0].Reason) } func TestCheckShippingFeeRequirement_BelowThreshold(t *testing.T) { db, mock := setupMockDBForShipping(t) svc := newTestService(db) mock.ExpectQuery("SELECT .* FROM `user_inventory`"). WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "product_id"}). AddRow(1, 99, 101). AddRow(2, 99, 102). AddRow(3, 99, 103). AddRow(4, 99, 104)) mock.ExpectQuery("SELECT .* FROM `products`"). WillReturnRows(sqlmock.NewRows([]string{"id", "category_id"}). AddRow(101, 1). AddRow(102, 2). AddRow(103, 3). AddRow(104, 4)) needFee, reason, err := svc.CheckShippingFeeRequirement(context.Background(), 99, []int64{1, 2, 3, 4}) assert.NoError(t, err) assert.True(t, needFee) assert.Equal(t, shippingFeeReasonBelowThreshold, reason) } func TestCheckShippingFeeRequirement_FreeWhenThresholdReached(t *testing.T) { db, mock := setupMockDBForShipping(t) svc := newTestService(db) mock.ExpectQuery("SELECT .* FROM `user_inventory`"). WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "product_id"}). AddRow(1, 99, 101). AddRow(2, 99, 102). AddRow(3, 99, 103). AddRow(4, 99, 104). AddRow(5, 99, 105)) mock.ExpectQuery("SELECT .* FROM `products`"). WillReturnRows(sqlmock.NewRows([]string{"id", "category_id"}). AddRow(101, 1). AddRow(102, 2). AddRow(103, 3). AddRow(104, 4). AddRow(105, 5)) needFee, reason, err := svc.CheckShippingFeeRequirement(context.Background(), 99, []int64{1, 2, 3, 4, 5}) assert.NoError(t, err) assert.False(t, needFee) assert.Equal(t, "", reason) } func TestCheckShippingFeeRequirement_NonFreeCategoryOverridesThreshold(t *testing.T) { db, mock := setupMockDBForShipping(t) svc := newTestService(db) mock.ExpectQuery("SELECT .* FROM `user_inventory`"). WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "product_id"}). AddRow(1, 99, 101). AddRow(2, 99, 102). AddRow(3, 99, 103). AddRow(4, 99, 104). AddRow(5, 99, 105). AddRow(6, 99, 106)) mock.ExpectQuery("SELECT .* FROM `products`"). WillReturnRows(sqlmock.NewRows([]string{"id", "category_id"}). AddRow(101, 1). AddRow(102, 2). AddRow(103, 3). AddRow(104, 4). AddRow(105, 14). AddRow(106, 5)) needFee, reason, err := svc.CheckShippingFeeRequirement(context.Background(), 99, []int64{1, 2, 3, 4, 5, 6}) assert.NoError(t, err) assert.True(t, needFee) assert.Equal(t, shippingFeeReasonContainsNonFreeShipping, reason) }