package threshold_activity import ( "testing" "time" "bindbox-game/internal/repository/mysql" "gorm.io/gorm" ) func newThresholdTestService(t *testing.T) (*service, mysql.Repo, *gorm.DB) { t.Helper() repo, err := mysql.NewSQLiteRepoForTest() if err != nil { t.Fatalf("create sqlite repo failed: %v", err) } db := repo.GetDbW() initThresholdTestTables(t, db) return &service{repo: repo}, repo, db } func initThresholdTestTables(t *testing.T, db *gorm.DB) { t.Helper() stmts := []string{ `CREATE TABLE threshold_activities ( id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT NOT NULL, type TEXT NOT NULL, qualification_mode TEXT NOT NULL, spend_threshold_amount INTEGER NOT NULL DEFAULT 0, invite_threshold_count INTEGER NOT NULL DEFAULT 0, invite_effective_amount INTEGER NOT NULL DEFAULT 0, min_participants INTEGER NOT NULL DEFAULT 1, start_time DATETIME NOT NULL, end_time DATETIME NOT NULL, draw_time DATETIME NOT NULL, status TEXT NOT NULL DEFAULT 'active', description TEXT, cover_image TEXT, draw_batch TEXT NOT NULL DEFAULT '', abort_reason TEXT NOT NULL DEFAULT '', aborted_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, deleted_at DATETIME );`, `CREATE TABLE threshold_activity_prizes ( id INTEGER PRIMARY KEY AUTOINCREMENT, activity_id INTEGER NOT NULL, reward_type TEXT NOT NULL, reward_ref_id INTEGER NOT NULL, reward_name_snapshot TEXT NOT NULL DEFAULT '', reward_image_snapshot TEXT NOT NULL DEFAULT '', reward_value_snapshot_cents INTEGER NOT NULL DEFAULT 0, cost_snapshot_cents INTEGER NOT NULL DEFAULT 0, quantity INTEGER NOT NULL DEFAULT 0, remaining_quantity INTEGER NOT NULL DEFAULT 0, sort INTEGER NOT NULL DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP );`, `CREATE TABLE threshold_activity_participants ( id INTEGER PRIMARY KEY AUTOINCREMENT, activity_id INTEGER NOT NULL, user_id INTEGER NOT NULL, period_key TEXT NOT NULL, qualification_source TEXT NOT NULL DEFAULT '', paid_amount_snapshot INTEGER NOT NULL DEFAULT 0, effective_invite_count_snapshot INTEGER NOT NULL DEFAULT 0, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE(activity_id, user_id, period_key) );`, `CREATE TABLE threshold_activity_winners ( id INTEGER PRIMARY KEY AUTOINCREMENT, activity_id INTEGER NOT NULL, prize_id INTEGER NOT NULL, reward_type TEXT NOT NULL, reward_ref_id INTEGER NOT NULL, prize_name_snapshot TEXT NOT NULL DEFAULT '', prize_image_snapshot TEXT NOT NULL DEFAULT '', prize_value_snapshot_cents INTEGER NOT NULL DEFAULT 0, user_id INTEGER NOT NULL, grant_record_type TEXT NOT NULL DEFAULT '', grant_record_id INTEGER NOT NULL DEFAULT 0, cost_cents INTEGER NOT NULL DEFAULT 0, draw_batch TEXT NOT NULL DEFAULT '', created_at DATETIME DEFAULT CURRENT_TIMESTAMP, UNIQUE(activity_id, user_id) );`, `CREATE TABLE users ( id INTEGER PRIMARY KEY AUTOINCREMENT, nickname TEXT, avatar TEXT, invite_code TEXT, inviter_id INTEGER NOT NULL DEFAULT 0, status INTEGER NOT NULL DEFAULT 1, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, deleted_at DATETIME );`, `CREATE TABLE user_invites ( id INTEGER PRIMARY KEY AUTOINCREMENT, inviter_id INTEGER NOT NULL, invitee_id INTEGER NOT NULL, invite_code TEXT NOT NULL DEFAULT '', reward_points INTEGER NOT NULL DEFAULT 0, rewarded_at DATETIME, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, deleted_at DATETIME, is_effective BOOLEAN NOT NULL DEFAULT 0, accumulated_amount INTEGER NOT NULL DEFAULT 0 );`, `CREATE TABLE orders ( id INTEGER PRIMARY KEY AUTOINCREMENT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, user_id INTEGER NOT NULL, order_no TEXT NOT NULL, source_type INTEGER NOT NULL DEFAULT 1, total_amount INTEGER NOT NULL DEFAULT 0, discount_amount INTEGER NOT NULL DEFAULT 0, points_amount INTEGER NOT NULL DEFAULT 0, actual_amount INTEGER NOT NULL DEFAULT 0, status INTEGER NOT NULL DEFAULT 1, pay_preorder_id INTEGER NOT NULL DEFAULT 0, paid_at DATETIME, cancelled_at DATETIME, user_address_id INTEGER NOT NULL DEFAULT 0, is_consumed INTEGER NOT NULL DEFAULT 0, points_ledger_id INTEGER NOT NULL DEFAULT 0, coupon_id INTEGER NOT NULL DEFAULT 0, item_card_id INTEGER NOT NULL DEFAULT 0, remark TEXT, ext_order_id TEXT NOT NULL DEFAULT '' );`, `CREATE TABLE products ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price INTEGER NOT NULL, cost_price INTEGER NOT NULL DEFAULT 0, stock INTEGER NOT NULL, images_json TEXT, updated_at DATETIME, deleted_at DATETIME );`, `CREATE TABLE order_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, order_id INTEGER NOT NULL, product_id INTEGER NOT NULL, title TEXT, quantity INTEGER NOT NULL DEFAULT 1, price INTEGER NOT NULL DEFAULT 0, total_amount INTEGER NOT NULL DEFAULT 0, product_images TEXT, status INTEGER NOT NULL DEFAULT 1 );`, `CREATE TABLE user_inventory ( id INTEGER PRIMARY KEY AUTOINCREMENT, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, user_id INTEGER NOT NULL, product_id INTEGER NOT NULL, value_cents INTEGER NOT NULL DEFAULT 0, value_source INTEGER NOT NULL DEFAULT 0, value_snapshot_at DATETIME, order_id INTEGER NOT NULL DEFAULT 0, activity_id INTEGER NOT NULL DEFAULT 0, reward_id INTEGER NOT NULL DEFAULT 0, status INTEGER NOT NULL DEFAULT 1, shipping_no TEXT NOT NULL DEFAULT '', remark TEXT );`, } for _, stmt := range stmts { if err := db.Exec(stmt).Error; err != nil { t.Fatalf("create table failed: %v", err) } } } func mustExec(t *testing.T, db *gorm.DB, sql string, args ...any) { t.Helper() if err := db.Exec(sql, args...).Error; err != nil { t.Fatalf("exec failed: %v, sql=%s", err, sql) } } func mustInsertActivity(t *testing.T, db *gorm.DB, activity Activity) { t.Helper() if activity.CreatedAt.IsZero() { activity.CreatedAt = time.Now() } if activity.UpdatedAt.IsZero() { activity.UpdatedAt = activity.CreatedAt } if err := db.Create(&activity).Error; err != nil { t.Fatalf("insert activity failed: %v", err) } }