Files
pangolin/server/internal/codes/service_sqlite_test.go
T
wangjia e128c96d22 feat(server): CreateBatch/生成器切换到 codes 库(Mint 单事务全成或全无)(#codes-lib)
Store 挂库 store(NewStore 内部构造 libcodes.Store,签名不变);
generator.go 三函数委托 libcodes,ErrDuplicate 别名同一哨兵;
Service.CreateBatch 走 libcodes.Mint(签名不变)。openMigratedSQLite
挪到共享 sqlite_helper_test.go,backfill_test.go/service_sqlite_test.go
共用。Store.CreateBatch/CreateCode/CodeExistsByHash 原样保留供
webhook.go(Task 6 改用新原语,Task 7 删除)。
2026-07-10 14:24:18 +08:00

58 lines
2.0 KiB
Go

package codes_test
import (
"context"
"testing"
"time"
"github.com/wangjia/pangolin/server/internal/codes"
)
// TestCreateBatchViaLib verifies CreateBatch mints codes through the shared
// codes library (Mint): codes land in the lib's new `codes` table (no
// plaintext persisted), the batch's entitlement is a duration payload, and
// unknown plans are still rejected up front (old behaviour, service.go:336-339).
func TestCreateBatchViaLib(t *testing.T) {
ctx := context.Background()
db := openMigratedSQLite(t)
store := codes.NewStore(db)
svc := codes.NewService(store, nil, 5, time.Hour) // rdb=nil: cmd/codegen's real usage
res, err := svc.CreateBatch(ctx, codes.BatchRequest{
PlanCode: codes.PlanPro, DurationDays: 30, Count: 5,
Channel: codes.ChannelManual, Note: "t", CreatedBy: "admin:1",
})
if err != nil {
t.Fatalf("CreateBatch: %v", err)
}
if len(res.Codes) != 5 || res.BatchID == 0 {
t.Fatalf("res = %+v", res)
}
// 码落在库的新表里,明文不落库,权益为 duration payload。
var cnt int
if err := db.QueryRow(`SELECT COUNT(*) FROM codes WHERE batch_id=?`, res.BatchID).Scan(&cnt); err != nil || cnt != 5 {
t.Fatalf("new codes rows = %d (err=%v), want 5", cnt, err)
}
var kind, payload string
if err := db.QueryRow(`SELECT entitlement_kind, entitlement_payload FROM codes_batches WHERE id=?`, res.BatchID).Scan(&kind, &payload); err != nil {
t.Fatalf("batch: %v", err)
}
if kind != "duration" || payload != `{"plan":"pro","days":30}` {
t.Fatalf("kind=%q payload=%s", kind, payload)
}
for _, plain := range res.Codes {
var n int
if err := db.QueryRow(`SELECT COUNT(*) FROM codes WHERE code_hash=?`, codes.Hash(plain)).Scan(&n); err != nil || n != 1 {
t.Fatalf("hash lookup for %q: n=%d err=%v", plain, n, err)
}
}
// 未知 plan 仍报错(旧行为 service.go:336-339)。
if _, err := svc.CreateBatch(ctx, codes.BatchRequest{
PlanCode: "nope", DurationDays: 30, Count: 1, Channel: codes.ChannelManual, CreatedBy: "x",
}); err == nil {
t.Fatal("unknown plan should error")
}
}