All checks were successful
Build docker and publish / build (20.15.1) (push) Successful in 5m6s
200 lines
6.2 KiB
Go
200 lines
6.2 KiB
Go
package orderLogic
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
modelOrder "github.com/perfect-panel/server/internal/model/order"
|
|
"github.com/perfect-panel/server/internal/model/subscribe"
|
|
"github.com/perfect-panel/server/internal/model/user"
|
|
"github.com/stretchr/testify/require"
|
|
"gorm.io/driver/sqlite"
|
|
"gorm.io/gorm"
|
|
"gorm.io/gorm/logger"
|
|
)
|
|
|
|
func setupActivationEligibilityDB(t *testing.T) *gorm.DB {
|
|
t.Helper()
|
|
|
|
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{
|
|
Logger: logger.Default.LogMode(logger.Silent),
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
sqls := []string{
|
|
`CREATE TABLE IF NOT EXISTS "user" (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
password VARCHAR(100) NOT NULL DEFAULT '',
|
|
created_at DATETIME,
|
|
updated_at DATETIME,
|
|
deleted_at DATETIME DEFAULT NULL
|
|
)`,
|
|
`CREATE TABLE IF NOT EXISTS "user_device" (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL DEFAULT 0,
|
|
identifier VARCHAR(255) NOT NULL DEFAULT '' UNIQUE,
|
|
created_at DATETIME,
|
|
updated_at DATETIME
|
|
)`,
|
|
`CREATE TABLE IF NOT EXISTS "user_family" (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
owner_user_id INTEGER NOT NULL DEFAULT 0,
|
|
status TINYINT NOT NULL DEFAULT 1,
|
|
deleted_at DATETIME DEFAULT NULL
|
|
)`,
|
|
`CREATE TABLE IF NOT EXISTS "user_family_member" (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
family_id INTEGER NOT NULL DEFAULT 0,
|
|
user_id INTEGER NOT NULL DEFAULT 0,
|
|
role TINYINT NOT NULL DEFAULT 0,
|
|
status TINYINT NOT NULL DEFAULT 0,
|
|
join_source VARCHAR(32) NOT NULL DEFAULT '',
|
|
deleted_at DATETIME DEFAULT NULL
|
|
)`,
|
|
`CREATE TABLE IF NOT EXISTS "order" (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
user_id INTEGER NOT NULL DEFAULT 0,
|
|
order_no VARCHAR(255) NOT NULL DEFAULT '' UNIQUE,
|
|
type TINYINT NOT NULL DEFAULT 1,
|
|
status TINYINT NOT NULL DEFAULT 1,
|
|
subscribe_id INTEGER NOT NULL DEFAULT 0,
|
|
quantity INTEGER NOT NULL DEFAULT 1,
|
|
created_at DATETIME,
|
|
updated_at DATETIME
|
|
)`,
|
|
}
|
|
for _, sql := range sqls {
|
|
require.NoError(t, db.Exec(sql).Error)
|
|
}
|
|
|
|
return db
|
|
}
|
|
|
|
func insertActivationUser(t *testing.T, db *gorm.DB, userID int64, createdAt time.Time) {
|
|
t.Helper()
|
|
require.NoError(t, db.Exec(
|
|
`INSERT INTO "user" (id, created_at, updated_at) VALUES (?, ?, datetime('now'))`,
|
|
userID,
|
|
createdAt.UTC().Format("2006-01-02 15:04:05"),
|
|
).Error)
|
|
}
|
|
|
|
func insertActivationDevice(t *testing.T, db *gorm.DB, userID int64, identifier string, createdAt time.Time) {
|
|
t.Helper()
|
|
require.NoError(t, db.Exec(
|
|
`INSERT INTO "user_device" (user_id, identifier, created_at, updated_at) VALUES (?, ?, ?, datetime('now'))`,
|
|
userID,
|
|
identifier,
|
|
createdAt.UTC().Format("2006-01-02 15:04:05"),
|
|
).Error)
|
|
}
|
|
|
|
func insertActivationFamily(t *testing.T, db *gorm.DB, familyID, ownerUserID int64) {
|
|
t.Helper()
|
|
require.NoError(t, db.Exec(
|
|
`INSERT INTO "user_family" (id, owner_user_id, status) VALUES (?, ?, 1)`,
|
|
familyID,
|
|
ownerUserID,
|
|
).Error)
|
|
}
|
|
|
|
func insertActivationFamilyMember(t *testing.T, db *gorm.DB, familyID, userID int64, role, status uint8, joinSource string) {
|
|
t.Helper()
|
|
require.NoError(t, db.Exec(
|
|
`INSERT INTO "user_family_member" (family_id, user_id, role, status, join_source) VALUES (?, ?, ?, ?, ?)`,
|
|
familyID,
|
|
userID,
|
|
role,
|
|
status,
|
|
joinSource,
|
|
).Error)
|
|
}
|
|
|
|
func insertActivationOrder(t *testing.T, db *gorm.DB, orderNo string, userID, subscribeID int64, status uint8) {
|
|
t.Helper()
|
|
require.NoError(t, db.Exec(
|
|
`INSERT INTO "order" (user_id, order_no, type, status, subscribe_id, quantity, created_at, updated_at)
|
|
VALUES (?, ?, 1, ?, ?, 1, datetime('now'), datetime('now'))`,
|
|
userID,
|
|
orderNo,
|
|
status,
|
|
subscribeID,
|
|
).Error)
|
|
}
|
|
|
|
func TestValidateNewUserOnlyEligibilityAtActivation_UsesEarliestBoundDeviceTime(t *testing.T) {
|
|
db := setupActivationEligibilityDB(t)
|
|
|
|
const (
|
|
ownerUserID = int64(1)
|
|
memberUserID = int64(2)
|
|
familyID = int64(10)
|
|
subscribeID = int64(100)
|
|
)
|
|
|
|
insertActivationUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour))
|
|
insertActivationUser(t, db, memberUserID, time.Now().Add(-72*time.Hour))
|
|
insertActivationDevice(t, db, memberUserID, "activation-old-device", time.Now().Add(-72*time.Hour))
|
|
insertActivationFamily(t, db, familyID, ownerUserID)
|
|
insertActivationFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init")
|
|
insertActivationFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification")
|
|
|
|
err := validateNewUserOnlyEligibilityAtActivation(
|
|
context.Background(),
|
|
db,
|
|
&modelOrder.Order{
|
|
UserId: ownerUserID,
|
|
OrderNo: "activation-check-old-device",
|
|
Type: OrderTypeSubscribe,
|
|
Quantity: 1,
|
|
SubscribeId: subscribeID,
|
|
},
|
|
&subscribe.Subscribe{
|
|
Id: subscribeID,
|
|
Discount: `[{"quantity":1,"discount":90,"new_user_only":true}]`,
|
|
},
|
|
)
|
|
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "is not a new user")
|
|
}
|
|
|
|
func TestValidateNewUserOnlyEligibilityAtActivation_SharesHistoryAcrossBoundScope(t *testing.T) {
|
|
db := setupActivationEligibilityDB(t)
|
|
|
|
const (
|
|
ownerUserID = int64(11)
|
|
memberUserID = int64(12)
|
|
familyID = int64(20)
|
|
subscribeID = int64(200)
|
|
)
|
|
|
|
insertActivationUser(t, db, ownerUserID, time.Now().Add(-1*time.Hour))
|
|
insertActivationUser(t, db, memberUserID, time.Now().Add(-2*time.Hour))
|
|
insertActivationDevice(t, db, memberUserID, "activation-shared-device", time.Now().Add(-2*time.Hour))
|
|
insertActivationFamily(t, db, familyID, ownerUserID)
|
|
insertActivationFamilyMember(t, db, familyID, ownerUserID, user.FamilyRoleOwner, user.FamilyMemberActive, "owner_init")
|
|
insertActivationFamilyMember(t, db, familyID, memberUserID, user.FamilyRoleMember, user.FamilyMemberActive, "bind_email_with_verification")
|
|
insertActivationOrder(t, db, "previous-finished-order", memberUserID, subscribeID, OrderStatusFinished)
|
|
|
|
err := validateNewUserOnlyEligibilityAtActivation(
|
|
context.Background(),
|
|
db,
|
|
&modelOrder.Order{
|
|
UserId: ownerUserID,
|
|
OrderNo: "current-paid-order",
|
|
Type: OrderTypeSubscribe,
|
|
Quantity: 1,
|
|
SubscribeId: subscribeID,
|
|
},
|
|
&subscribe.Subscribe{
|
|
Id: subscribeID,
|
|
Discount: `[{"quantity":1,"discount":90,"new_user_only":true}]`,
|
|
},
|
|
)
|
|
|
|
require.Error(t, err)
|
|
require.Contains(t, err.Error(), "already activated")
|
|
}
|