195 lines
6.2 KiB
Go
195 lines
6.2 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"affiliate_dash/internal/model"
|
|
)
|
|
|
|
func TestTokenPackageLink_BuildsUpstreamURL(t *testing.T) {
|
|
db := newRockTestDB(t)
|
|
svc := NewRockService(db, NewRockClient("https://example.com"))
|
|
|
|
packageID := int64(1507)
|
|
token := model.RockToken{
|
|
UpstreamTokenID: "9101",
|
|
RedeemCode: "CODE-LINK",
|
|
Color: model.RockColorBlack,
|
|
Status: model.RockStatusMismatch,
|
|
PackageID: &packageID,
|
|
PackageShareCode: "share-abc",
|
|
}
|
|
if err := db.Create(&token).Error; err != nil {
|
|
t.Fatalf("创建 Token 失败: %v", err)
|
|
}
|
|
|
|
res, err := svc.TokenPackageLink(context.Background(), token.ID)
|
|
if err != nil {
|
|
t.Fatalf("生成包链接失败: %v", err)
|
|
}
|
|
if res.PackageID != 1507 || res.ShareCode != "share-abc" {
|
|
t.Fatalf("包信息不符: %+v", res)
|
|
}
|
|
if res.URL != "https://0666.pro/#/package/share-abc" {
|
|
t.Fatalf("包链接不符: %s", res.URL)
|
|
}
|
|
}
|
|
|
|
func TestTokenPackageLink_RejectsWithoutPackage(t *testing.T) {
|
|
db := newRockTestDB(t)
|
|
svc := NewRockService(db, NewRockClient("https://example.com"))
|
|
|
|
token := model.RockToken{
|
|
UpstreamTokenID: "9102",
|
|
RedeemCode: "CODE-NOPKG",
|
|
Color: model.RockColorBlack,
|
|
Status: model.RockStatusMismatch,
|
|
}
|
|
if err := db.Create(&token).Error; err != nil {
|
|
t.Fatalf("创建 Token 失败: %v", err)
|
|
}
|
|
|
|
if _, err := svc.TokenPackageLink(context.Background(), token.ID); err == nil || !strings.Contains(err.Error(), "没有关联上游打包记录") {
|
|
t.Fatalf("无包 Token 应被拒绝,实际 err=%v", err)
|
|
}
|
|
}
|
|
|
|
func TestTokenPackageLink_RejectsMissingShareCodeWithoutBearer(t *testing.T) {
|
|
db := newRockTestDB(t)
|
|
svc := NewRockService(db, NewRockClient("https://example.com"))
|
|
|
|
packageID := int64(1508)
|
|
token := model.RockToken{
|
|
UpstreamTokenID: "9103",
|
|
RedeemCode: "CODE-NOSHARE",
|
|
Color: model.RockColorBlack,
|
|
Status: model.RockStatusMismatch,
|
|
PackageID: &packageID,
|
|
}
|
|
if err := db.Create(&token).Error; err != nil {
|
|
t.Fatalf("创建 Token 失败: %v", err)
|
|
}
|
|
|
|
if _, err := svc.TokenPackageLink(context.Background(), token.ID); err == nil || !strings.Contains(err.Error(), "无法反查上游包") {
|
|
t.Fatalf("缺少 Bearer Token 时应拒绝反查,实际 err=%v", err)
|
|
}
|
|
}
|
|
|
|
func TestTokenPackageLink_ResolvesAndBackfillsShareCode(t *testing.T) {
|
|
db := newRockTestDB(t)
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
if r.URL.Path != "/api/user/packages" {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"packages": []map[string]interface{}{
|
|
{"id": 1509, "share_code": "share-other"},
|
|
{"id": 1508, "share_code": "share-resolved"},
|
|
},
|
|
"pagination": map[string]interface{}{"page": 1, "pageSize": 100, "total": 2, "totalPages": 1},
|
|
})
|
|
}))
|
|
defer server.Close()
|
|
|
|
svc := NewRockService(db, NewRockClient(server.URL))
|
|
setRockTestBearer(t, svc, "bearer-test")
|
|
|
|
packageID := int64(1508)
|
|
tokens := []model.RockToken{
|
|
{UpstreamTokenID: "9103", RedeemCode: "CODE-NOSHARE", Color: model.RockColorBlack, Status: model.RockStatusMismatch, PackageID: &packageID},
|
|
{UpstreamTokenID: "9104", RedeemCode: "CODE-NOSHARE-2", Color: model.RockColorBlack, Status: model.RockStatusAvailable, PackageID: &packageID},
|
|
}
|
|
for i := range tokens {
|
|
if err := db.Create(&tokens[i]).Error; err != nil {
|
|
t.Fatalf("创建 Token 失败: %v", err)
|
|
}
|
|
}
|
|
|
|
res, err := svc.TokenPackageLink(context.Background(), tokens[0].ID)
|
|
if err != nil {
|
|
t.Fatalf("反查分享码失败: %v", err)
|
|
}
|
|
if res.ShareCode != "share-resolved" || !strings.HasSuffix(res.URL, "/#/package/share-resolved") {
|
|
t.Fatalf("反查结果不符: %+v", res)
|
|
}
|
|
|
|
var saved []model.RockToken
|
|
if err := db.Where("package_id = ?", packageID).Find(&saved).Error; err != nil {
|
|
t.Fatalf("查询 Token 失败: %v", err)
|
|
}
|
|
if len(saved) != len(tokens) {
|
|
t.Fatalf("Token 数量不符: %d", len(saved))
|
|
}
|
|
for _, row := range saved {
|
|
if row.PackageShareCode != "share-resolved" {
|
|
t.Fatalf("同包 Token 未回填: id=%d code=%q", row.ID, row.PackageShareCode)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTokenPackageLink_RejectsWhenUpstreamPackageMissing(t *testing.T) {
|
|
db := newRockTestDB(t)
|
|
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
_ = json.NewEncoder(w).Encode(map[string]interface{}{
|
|
"packages": []map[string]interface{}{},
|
|
"pagination": map[string]interface{}{"page": 1, "pageSize": 100, "total": 0, "totalPages": 1},
|
|
})
|
|
}))
|
|
defer server.Close()
|
|
|
|
svc := NewRockService(db, NewRockClient(server.URL))
|
|
setRockTestBearer(t, svc, "bearer-test")
|
|
|
|
packageID := int64(1599)
|
|
token := model.RockToken{
|
|
UpstreamTokenID: "9105",
|
|
RedeemCode: "CODE-GONE",
|
|
Color: model.RockColorBlack,
|
|
Status: model.RockStatusMismatch,
|
|
PackageID: &packageID,
|
|
}
|
|
if err := db.Create(&token).Error; err != nil {
|
|
t.Fatalf("创建 Token 失败: %v", err)
|
|
}
|
|
|
|
if _, err := svc.TokenPackageLink(context.Background(), token.ID); err == nil || !strings.Contains(err.Error(), "上游未找到") {
|
|
t.Fatalf("上游无该包时应返回明确错误,实际 err=%v", err)
|
|
}
|
|
}
|
|
|
|
func TestImportPackageDetail_StoresPackageShareCode(t *testing.T) {
|
|
db := newRockTestDB(t)
|
|
svc := NewRockService(db, NewRockClient("https://example.com"))
|
|
|
|
var detail RockPackageDetailResponse
|
|
raw := `{
|
|
"package": {"id": 9009, "share_code": "share-import"},
|
|
"tokens": [
|
|
{"id": 39001, "token": "t1", "redeem_code": "c1", "color": "black", "status": "using", "created_at": "2026-10-27 23:31:59"}
|
|
]
|
|
}`
|
|
if err := json.Unmarshal([]byte(raw), &detail); err != nil {
|
|
t.Fatalf("解析包详情失败: %v", err)
|
|
}
|
|
|
|
if _, _, _, err := svc.importPackageDetail(context.Background(), &detail, nil); err != nil {
|
|
t.Fatalf("导入包详情失败: %v", err)
|
|
}
|
|
|
|
var row model.RockToken
|
|
if err := db.Where("upstream_token_id = ?", "39001").First(&row).Error; err != nil {
|
|
t.Fatalf("查询导入 Token 失败: %v", err)
|
|
}
|
|
if row.PackageShareCode != "share-import" {
|
|
t.Fatalf("package_share_code 未写入,实际 %q", row.PackageShareCode)
|
|
}
|
|
}
|