fix(ci): align auth and payment verification tests

This commit is contained in:
IanShaw027
2026-04-22 02:32:53 +08:00
parent 6d51834a95
commit b13e34f831
21 changed files with 335 additions and 339 deletions

View File

@@ -2,7 +2,6 @@ package service
import (
"context"
"database/sql"
"encoding/json"
"errors"
"fmt"
@@ -20,8 +19,6 @@ import (
"github.com/Wei-Shaw/sub2api/internal/pkg/logger"
"github.com/Wei-Shaw/sub2api/internal/pkg/pagination"
"github.com/Wei-Shaw/sub2api/internal/util/httputil"
entsql "entgo.io/ent/dialect/sql"
)
// AdminService interface defines admin management operations
@@ -999,17 +996,6 @@ func (s *adminServiceImpl) BindUserAuthIdentity(ctx context.Context, userID int6
return buildAdminBoundAuthIdentity(identity, channel), nil
}
func (s *adminServiceImpl) adminSQLDB() (*sql.DB, error) {
if s == nil || s.entClient == nil {
return nil, infraerrors.ServiceUnavailable("ADMIN_SQL_NOT_READY", "admin sql access is not ready")
}
driver, ok := s.entClient.Driver().(*entsql.Driver)
if !ok || driver.DB() == nil {
return nil, infraerrors.ServiceUnavailable("ADMIN_SQL_NOT_READY", "admin sql access is not ready")
}
return driver.DB(), nil
}
func normalizeAdminBindChannelInput(input *AdminBindAuthIdentityChannelInput) *AdminBindAuthIdentityChannelInput {
if input == nil {
return nil

View File

@@ -11,8 +11,8 @@ import (
dbent "github.com/Wei-Shaw/sub2api/ent"
"github.com/Wei-Shaw/sub2api/ent/identityadoptiondecision"
dbpredicate "github.com/Wei-Shaw/sub2api/ent/predicate"
"github.com/Wei-Shaw/sub2api/ent/pendingauthsession"
dbpredicate "github.com/Wei-Shaw/sub2api/ent/predicate"
infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors"
entsql "entgo.io/ent/dialect/sql"

View File

@@ -679,13 +679,6 @@ func (s *AuthService) LoginOrRegisterOAuthWithTokenPair(ctx context.Context, ema
return tokenPair, user, nil
}
func (s *AuthService) assignDefaultSubscriptions(ctx context.Context, userID int64) {
if s.settingService == nil {
return
}
s.assignSubscriptions(ctx, userID, s.settingService.GetDefaultSubscriptions(ctx), "auto assigned by default user subscriptions setting")
}
func (s *AuthService) assignSubscriptions(ctx context.Context, userID int64, items []DefaultSubscriptionSetting, notes string) {
if s.settingService == nil || s.defaultSubAssigner == nil || userID <= 0 {
return
@@ -863,7 +856,7 @@ func (s *AuthService) hasProviderGrantRecord(
if err != nil {
return false, err
}
defer rows.Close()
defer func() { _ = rows.Close() }()
return rows.Next(), rows.Err()
}
@@ -917,7 +910,7 @@ func (s *AuthService) ensureEmailAuthIdentity(ctx context.Context, user *User, s
DoNothing().
Exec(ctx); err != nil {
if isSQLNoRowsError(err) {
err = nil
return nil, false
}
}
if err != nil {

View File

@@ -53,40 +53,6 @@ func pcApplyEnabledVisibleMethodInstances(typeInstances map[string][]*dbent.Paym
return filtered
}
func pcApplyVisibleMethodRouting(typeInstances map[string][]*dbent.PaymentProviderInstance, vals map[string]string, available map[string]bool) map[string][]*dbent.PaymentProviderInstance {
if len(typeInstances) == 0 {
return typeInstances
}
filtered := make(map[string][]*dbent.PaymentProviderInstance, len(typeInstances))
for paymentType, instances := range typeInstances {
visibleMethod := NormalizeVisibleMethod(paymentType)
switch visibleMethod {
case payment.TypeAlipay, payment.TypeWxpay:
if !visibleMethodShouldBeExposed(visibleMethod, vals, available) {
continue
}
targetProviderKey, ok := VisibleMethodProviderKeyForSource(visibleMethod, vals[visibleMethodSourceSettingKey(visibleMethod)])
if !ok {
continue
}
matching := make([]*dbent.PaymentProviderInstance, 0, len(instances))
for _, inst := range instances {
if inst.ProviderKey == targetProviderKey {
matching = append(matching, inst)
}
}
if len(matching) == 0 {
continue
}
filtered[paymentType] = matching
default:
filtered[paymentType] = instances
}
}
return filtered
}
// GetMethodLimits returns per-payment-type limits from enabled provider instances.
func (s *PaymentConfigService) GetMethodLimits(ctx context.Context, types []string) ([]MethodLimits, error) {
instances, err := s.entClient.PaymentProviderInstance.Query().

View File

@@ -210,9 +210,15 @@ func TestCreateProviderInstanceRejectsConflictingVisibleMethodEnablement(t *test
}
_, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
ProviderKey: "easypay",
Name: "EasyPay Alipay",
Config: map[string]string{"pid": "1001"},
ProviderKey: "easypay",
Name: "EasyPay Alipay",
Config: map[string]string{
"pid": "1001",
"pkey": "pkey-1001",
"apiBase": "https://pay.example.com",
"notifyUrl": "https://merchant.example.com/notify",
"returnUrl": "https://merchant.example.com/return",
},
SupportedTypes: []string{"alipay"},
Enabled: true,
})
@@ -240,9 +246,15 @@ func TestUpdateProviderInstanceRejectsEnablingConflictingVisibleMethodProvider(t
}
existing, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
ProviderKey: "easypay",
Name: "EasyPay WeChat",
Config: map[string]string{"pid": "2001"},
ProviderKey: "easypay",
Name: "EasyPay WeChat",
Config: map[string]string{
"pid": "2001",
"pkey": "pkey-2001",
"apiBase": "https://pay.example.com",
"notifyUrl": "https://merchant.example.com/notify",
"returnUrl": "https://merchant.example.com/return",
},
SupportedTypes: []string{"wxpay"},
Enabled: true,
})
@@ -276,9 +288,15 @@ func TestUpdateProviderInstancePersistsEnabledAndSupportedTypes(t *testing.T) {
}
instance, err := svc.CreateProviderInstance(ctx, CreateProviderInstanceRequest{
ProviderKey: "easypay",
Name: "EasyPay",
Config: map[string]string{"pid": "3001"},
ProviderKey: "easypay",
Name: "EasyPay",
Config: map[string]string{
"pid": "3001",
"pkey": "pkey-3001",
"apiBase": "https://pay.example.com",
"notifyUrl": "https://merchant.example.com/notify",
"returnUrl": "https://merchant.example.com/return",
},
SupportedTypes: []string{"alipay"},
Enabled: false,
})

View File

@@ -23,8 +23,6 @@ const (
PaymentSourceHostedRedirect = "hosted_redirect"
PaymentSourceWechatInAppResume = "wechat_in_app_resume"
paymentResumeFallbackSigningKey = "sub2api-payment-resume"
SettingPaymentVisibleMethodAlipaySource = "payment_visible_method_alipay_source"
SettingPaymentVisibleMethodWxpaySource = "payment_visible_method_wxpay_source"
SettingPaymentVisibleMethodAlipayEnabled = "payment_visible_method_alipay_enabled"

View File

@@ -413,7 +413,7 @@ func mustCreateFallbackSignedToken(t *testing.T, claims any) string {
t.Fatalf("marshal claims: %v", err)
}
encodedPayload := base64.RawURLEncoding.EncodeToString(payload)
mac := hmac.New(sha256.New, []byte(paymentResumeFallbackSigningKey))
mac := hmac.New(sha256.New, []byte("sub2api-payment-resume"))
_, _ = mac.Write([]byte(encodedPayload))
signature := base64.RawURLEncoding.EncodeToString(mac.Sum(nil))
return encodedPayload + "." + signature

View File

@@ -4,7 +4,11 @@ package service
import (
"context"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"encoding/json"
"encoding/pem"
"strconv"
"testing"
"time"
@@ -52,6 +56,28 @@ func newWebhookProviderTestLoadBalancer(client *dbent.Client) payment.LoadBalanc
return payment.NewDefaultLoadBalancer(client, []byte(webhookProviderTestEncryptionKey))
}
func encryptValidWebhookWxpayConfig(t *testing.T, suffix string) string {
t.Helper()
key, err := rsa.GenerateKey(rand.Reader, 2048)
require.NoError(t, err)
privDER, err := x509.MarshalPKCS8PrivateKey(key)
require.NoError(t, err)
pubDER, err := x509.MarshalPKIXPublicKey(&key.PublicKey)
require.NoError(t, err)
return encryptWebhookProviderConfig(t, map[string]string{
"appId": "wx-app-" + suffix,
"mchId": "mch-" + suffix,
"privateKey": string(pem.EncodeToMemory(&pem.Block{Type: "PRIVATE KEY", Bytes: privDER})),
"apiV3Key": webhookProviderTestEncryptionKey,
"publicKey": string(pem.EncodeToMemory(&pem.Block{Type: "PUBLIC KEY", Bytes: pubDER})),
"publicKeyId": "public-key-id-" + suffix,
"certSerial": "cert-serial-" + suffix,
})
}
func TestGetOrderProviderInstanceResolvesUniqueLegacyProviderKey(t *testing.T) {
ctx := context.Background()
client := newPaymentConfigServiceTestClient(t)
@@ -275,24 +301,8 @@ func TestGetOrderProviderInstanceRejectsMissingSnapshotInstanceWithoutLegacyFall
func TestGetWebhookProviderRejectsAmbiguousRegistryFallback(t *testing.T) {
ctx := context.Background()
client := newPaymentConfigServiceTestClient(t)
wxpayConfigA := encryptWebhookProviderConfig(t, map[string]string{
"appId": "wx-app-a",
"mchId": "mch-a",
"privateKey": "private-key-a",
"apiV3Key": webhookProviderTestEncryptionKey,
"publicKey": "public-key-a",
"publicKeyId": "public-key-id-a",
"certSerial": "cert-serial-a",
})
wxpayConfigB := encryptWebhookProviderConfig(t, map[string]string{
"appId": "wx-app-b",
"mchId": "mch-b",
"privateKey": "private-key-b",
"apiV3Key": webhookProviderTestEncryptionKey,
"publicKey": "public-key-b",
"publicKeyId": "public-key-id-b",
"certSerial": "cert-serial-b",
})
wxpayConfigA := encryptValidWebhookWxpayConfig(t, "a")
wxpayConfigB := encryptValidWebhookWxpayConfig(t, "b")
_, err := client.PaymentProviderInstance.Create().
SetProviderKey(payment.TypeWxpay).
SetName("wxpay-a").
@@ -442,24 +452,8 @@ func TestGetWebhookProviderUsesProviderSnapshotBeforeWxpayFallback(t *testing.T)
Save(ctx)
require.NoError(t, err)
wxpayConfigA := encryptWebhookProviderConfig(t, map[string]string{
"appId": "wx-app-snapshot-a",
"mchId": "mch-snapshot-a",
"privateKey": "private-key-snapshot-a",
"apiV3Key": webhookProviderTestEncryptionKey,
"publicKey": "public-key-snapshot-a",
"publicKeyId": "public-key-id-snapshot-a",
"certSerial": "cert-serial-snapshot-a",
})
wxpayConfigB := encryptWebhookProviderConfig(t, map[string]string{
"appId": "wx-app-snapshot-b",
"mchId": "mch-snapshot-b",
"privateKey": "private-key-snapshot-b",
"apiV3Key": webhookProviderTestEncryptionKey,
"publicKey": "public-key-snapshot-b",
"publicKeyId": "public-key-id-snapshot-b",
"certSerial": "cert-serial-snapshot-b",
})
wxpayConfigA := encryptValidWebhookWxpayConfig(t, "snapshot-a")
wxpayConfigB := encryptValidWebhookWxpayConfig(t, "snapshot-b")
instA, err := client.PaymentProviderInstance.Create().
SetProviderKey(payment.TypeWxpay).
SetName("wxpay-snapshot-a").

View File

@@ -183,10 +183,6 @@ type UpsertUserAvatarInput struct {
SHA256 string
}
type userAuthIdentityReader interface {
ListUserAuthIdentities(ctx context.Context, userID int64) ([]UserAuthIdentityRecord, error)
}
type userProfileIdentityTxRunner interface {
WithUserProfileIdentityTx(ctx context.Context, fn func(txCtx context.Context) error) error
}
@@ -812,17 +808,6 @@ func maskOpaqueIdentity(value string) string {
}
}
func cloneAnyMap(values map[string]any) map[string]any {
if len(values) == 0 {
return map[string]any{}
}
cloned := make(map[string]any, len(values))
for key, value := range values {
cloned[key] = value
}
return cloned
}
// ChangePassword 修改密码
// Security: Increments TokenVersion to invalidate all existing JWT tokens
func (s *UserService) ChangePassword(ctx context.Context, userID int64, req ChangePasswordRequest) error {