feat(server): 到账通知四接缝(邀请注册/首充/TG/购买开通)——与发放同事务零孤儿
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
package reward
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/wangjia/pangolin/server/internal/notices"
|
||||
)
|
||||
|
||||
// failingGranter 总是拒绝发放,用于验证「发放失败 → 通知(与本事务其余写入)一并回滚」。
|
||||
type failingGranter struct{}
|
||||
|
||||
func (failingGranter) GrantRewardTx(ctx context.Context, tx *sql.Tx, userID int64, days int, source, auditAction, ref string) (int64, time.Time, error) {
|
||||
return 0, time.Time{}, fmt.Errorf("boom")
|
||||
}
|
||||
|
||||
func TestOnRegister_InsertsRewardNotices(t *testing.T) {
|
||||
db := openDB(t)
|
||||
seedU(t, db, 1, "inviter")
|
||||
seedU(t, db, 2, "invitee")
|
||||
s := newSvc(t, db)
|
||||
s.SetNoticer(notices.NewStore(db))
|
||||
code, _ := s.EnsureCode(context.Background(), 1)
|
||||
s.OnRegister(context.Background(), 2, code, "dev-2")
|
||||
var n int
|
||||
db.QueryRow(`SELECT COUNT(*) FROM notices WHERE type='reward' AND user_id IN (1,2)`).Scan(&n)
|
||||
if n != 2 {
|
||||
t.Fatalf("注册段应双方各一条到账通知, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestClaimTelegram_NoticeRollsBackWithGrantFailure(t *testing.T) {
|
||||
db := openDB(t)
|
||||
seedU(t, db, 1, "u1")
|
||||
s := NewService(db, NewStore(db), failingGranter{}, Config{TgDays: 3}, time.Now)
|
||||
s.SetTelegram("bot", "@ch", "tok", "sec")
|
||||
s.SetMemberChecker(fakeChecker{member: true})
|
||||
s.SetNoticer(notices.NewStore(db))
|
||||
|
||||
if _, err := s.ClaimTelegram(context.Background(), 1, "tg-1"); err == nil {
|
||||
t.Fatalf("expected grant failure error, got nil")
|
||||
}
|
||||
var n int
|
||||
db.QueryRow(`SELECT COUNT(*) FROM notices`).Scan(&n)
|
||||
if n != 0 {
|
||||
t.Fatalf("grant 失败应整事务回滚,notices should be 0, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOnFirstPaidTx_InsertsRewardNotices(t *testing.T) {
|
||||
db := openDB(t)
|
||||
seedU(t, db, 1, "inviter")
|
||||
seedU(t, db, 2, "invitee")
|
||||
s := newSvc(t, db)
|
||||
s.SetNoticer(notices.NewStore(db))
|
||||
code, _ := s.EnsureCode(context.Background(), 1)
|
||||
s.OnRegister(context.Background(), 2, code, "dev-2")
|
||||
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := s.OnFirstPaidTx(context.Background(), tx, 2, time.Now().UTC()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := tx.Commit(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var n int
|
||||
db.QueryRow(`SELECT COUNT(*) FROM notices WHERE type='reward' AND user_id IN (1,2)`).Scan(&n)
|
||||
// 注册段 2 条 + 首充段 2 条 = 4 条
|
||||
if n != 4 {
|
||||
t.Fatalf("注册+首充共应 4 条到账通知, got %d", n)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user