Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
陈曦
sub2api
Commits
4ebdfcd1
Commit
4ebdfcd1
authored
Apr 21, 2026
by
IanShaw027
Browse files
test(admin): constrain payment visible method sources
parent
0fa47f18
Changes
4
Hide whitespace changes
Inline
Side-by-side
frontend/src/api/__tests__/settings.paymentVisibleMethods.spec.ts
0 → 100644
View file @
4ebdfcd1
import
{
describe
,
expect
,
it
}
from
'
vitest
'
import
{
getPaymentVisibleMethodSourceOptions
,
normalizePaymentVisibleMethodSource
,
}
from
'
@/api/admin/settings
'
describe
(
'
admin settings payment visible method helpers
'
,
()
=>
{
it
(
'
normalizes aliases into canonical source keys per visible method
'
,
()
=>
{
expect
(
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
'
official
'
)).
toBe
(
'
official_alipay
'
)
expect
(
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
'
alipay_direct
'
)).
toBe
(
'
official_alipay
'
)
expect
(
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
'
easypay
'
)).
toBe
(
'
easypay_alipay
'
)
expect
(
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
'
official
'
)).
toBe
(
'
official_wxpay
'
)
expect
(
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
'
wechat
'
)).
toBe
(
'
official_wxpay
'
)
expect
(
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
'
easypay
'
)).
toBe
(
'
easypay_wxpay
'
)
})
it
(
'
rejects unknown or cross-method source values
'
,
()
=>
{
expect
(
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
'
official_wxpay
'
)).
toBe
(
''
)
expect
(
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
'
official_alipay
'
)).
toBe
(
''
)
expect
(
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
'
unknown
'
)).
toBe
(
''
)
expect
(
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
null
)).
toBe
(
''
)
})
it
(
'
exposes method-scoped source options instead of arbitrary strings
'
,
()
=>
{
expect
(
getPaymentVisibleMethodSourceOptions
(
'
alipay
'
)).
toEqual
([
{
value
:
''
,
labelZh
:
'
自动路由
'
,
labelEn
:
'
Automatic routing
'
,
},
{
value
:
'
official_alipay
'
,
labelZh
:
'
支付宝官方
'
,
labelEn
:
'
Official Alipay
'
,
},
{
value
:
'
easypay_alipay
'
,
labelZh
:
'
易支付支付宝
'
,
labelEn
:
'
EasyPay Alipay
'
,
},
])
expect
(
getPaymentVisibleMethodSourceOptions
(
'
wxpay
'
)).
toEqual
([
{
value
:
''
,
labelZh
:
'
自动路由
'
,
labelEn
:
'
Automatic routing
'
,
},
{
value
:
'
official_wxpay
'
,
labelZh
:
'
微信官方
'
,
labelEn
:
'
Official WeChat Pay
'
,
},
{
value
:
'
easypay_wxpay
'
,
labelZh
:
'
易支付微信
'
,
labelEn
:
'
EasyPay WeChat Pay
'
,
},
])
})
})
frontend/src/api/admin/settings.ts
View file @
4ebdfcd1
...
...
@@ -22,10 +22,60 @@ export interface AuthSourceDefaultsValue {
}
export
type
AuthSourceDefaultsState
=
Record
<
AuthSourceType
,
AuthSourceDefaultsValue
>
export
type
PaymentVisibleMethod
=
'
alipay
'
|
'
wxpay
'
export
type
PaymentVisibleMethodSource
=
|
''
|
'
official_alipay
'
|
'
easypay_alipay
'
|
'
official_wxpay
'
|
'
easypay_wxpay
'
export
interface
PaymentVisibleMethodSourceOption
{
value
:
PaymentVisibleMethodSource
labelZh
:
string
labelEn
:
string
}
const
AUTH_SOURCE_TYPES
:
AuthSourceType
[]
=
[
'
email
'
,
'
linuxdo
'
,
'
oidc
'
,
'
wechat
'
]
const
AUTH_SOURCE_DEFAULT_BALANCE
=
0
const
AUTH_SOURCE_DEFAULT_CONCURRENCY
=
5
const
PAYMENT_VISIBLE_METHOD_SOURCE_OPTIONS
:
Record
<
PaymentVisibleMethod
,
PaymentVisibleMethodSourceOption
[]
>
=
{
alipay
:
[
{
value
:
''
,
labelZh
:
'
自动路由
'
,
labelEn
:
'
Automatic routing
'
},
{
value
:
'
official_alipay
'
,
labelZh
:
'
支付宝官方
'
,
labelEn
:
'
Official Alipay
'
},
{
value
:
'
easypay_alipay
'
,
labelZh
:
'
易支付支付宝
'
,
labelEn
:
'
EasyPay Alipay
'
},
],
wxpay
:
[
{
value
:
''
,
labelZh
:
'
自动路由
'
,
labelEn
:
'
Automatic routing
'
},
{
value
:
'
official_wxpay
'
,
labelZh
:
'
微信官方
'
,
labelEn
:
'
Official WeChat Pay
'
},
{
value
:
'
easypay_wxpay
'
,
labelZh
:
'
易支付微信
'
,
labelEn
:
'
EasyPay WeChat Pay
'
},
],
}
const
PAYMENT_VISIBLE_METHOD_SOURCE_ALIASES
:
Record
<
PaymentVisibleMethod
,
Record
<
string
,
PaymentVisibleMethodSource
>
>
=
{
alipay
:
{
official_alipay
:
'
official_alipay
'
,
alipay
:
'
official_alipay
'
,
alipay_direct
:
'
official_alipay
'
,
official
:
'
official_alipay
'
,
easypay_alipay
:
'
easypay_alipay
'
,
easypay
:
'
easypay_alipay
'
,
},
wxpay
:
{
official_wxpay
:
'
official_wxpay
'
,
wxpay
:
'
official_wxpay
'
,
wxpay_direct
:
'
official_wxpay
'
,
wechat
:
'
official_wxpay
'
,
official
:
'
official_wxpay
'
,
easypay_wxpay
:
'
easypay_wxpay
'
,
easypay
:
'
easypay_wxpay
'
,
},
}
export
function
normalizeDefaultSubscriptionSettings
(
subscriptions
:
DefaultSubscriptionSetting
[]
|
null
|
undefined
...
...
@@ -86,6 +136,24 @@ export function appendAuthSourceDefaultsToUpdateRequest(
return
payload
}
export
function
getPaymentVisibleMethodSourceOptions
(
method
:
PaymentVisibleMethod
):
PaymentVisibleMethodSourceOption
[]
{
return
PAYMENT_VISIBLE_METHOD_SOURCE_OPTIONS
[
method
]
}
export
function
normalizePaymentVisibleMethodSource
(
method
:
PaymentVisibleMethod
,
source
:
unknown
):
PaymentVisibleMethodSource
{
if
(
typeof
source
!==
'
string
'
)
return
''
const
normalized
=
source
.
trim
().
toLowerCase
()
if
(
!
normalized
)
return
''
return
PAYMENT_VISIBLE_METHOD_SOURCE_ALIASES
[
method
][
normalized
]
??
''
}
/**
* System settings interface
*/
...
...
frontend/src/views/admin/SettingsView.vue
View file @
4ebdfcd1
...
...
@@ -2717,20 +2717,19 @@
<
div
class
=
"
mt-4
"
>
<
label
class
=
"
input-label
"
>
{{
localText
(
'
来源
键
'
,
'
S
ource
key
'
)
}}
{{
localText
(
'
支付
来源
'
,
'
Payment s
ource
'
)
}}
<
/label
>
<
input
:
value
=
"
getPaymentVisibleMethodSource(visibleMethod.key)
"
@
input
=
"
setPaymentVisibleMethodSource(visibleMethod.key, ($event.target as HTMLInputElement).value)
"
type
=
"
text
"
class
=
"
input
"
<
Select
:
model
-
value
=
"
getPaymentVisibleMethodSource(visibleMethod.key)
"
:
options
=
"
getPaymentVisibleMethodSourceSelectOptions(visibleMethod.key)
"
@
update
:
model
-
value
=
"
setPaymentVisibleMethodSource(visibleMethod.key, $event)
"
:
placeholder
=
"
visibleMethod.key
"
/>
<
p
class
=
"
mt-1.5 text-xs text-gray-400
"
>
{{
localText
(
'
留空表示
由后端使用默认来源;可填 easypay、alipay、wxpay 等来源标识
。
'
,
'
Leave blank
to let the backend decide. Typ
ical
values are easypay, alipay, or wxpay
.
'
'
留空表示
自动路由;仅允许当前系统支持的官方或易支付来源
。
'
,
'
Leave blank
for automatic routing. Only supported off
ic
i
al
or EasyPay sources are allowed
.
'
)
}}
<
/p
>
...
...
@@ -3117,11 +3116,14 @@ import { adminAPI } from '@/api'
import
{
appendAuthSourceDefaultsToUpdateRequest
,
buildAuthSourceDefaultsState
,
getPaymentVisibleMethodSourceOptions
,
normalizePaymentVisibleMethodSource
,
normalizeDefaultSubscriptionSettings
,
}
from
'
@/api/admin/settings
'
import
type
{
AuthSourceDefaultsState
,
AuthSourceType
,
PaymentVisibleMethod
,
SystemSettings
,
UpdateSettingsRequest
,
DefaultSubscriptionSetting
,
...
...
@@ -3429,12 +3431,23 @@ function getPaymentVisibleMethodSource(method: 'alipay' | 'wxpay'): string {
:
form
.
payment_visible_method_wxpay_source
}
function
setPaymentVisibleMethodSource
(
method
:
'
alipay
'
|
'
wxpay
'
,
source
:
string
)
{
function
getPaymentVisibleMethodSourceSelectOptions
(
method
:
PaymentVisibleMethod
)
{
return
getPaymentVisibleMethodSourceOptions
(
method
).
map
((
option
)
=>
({
value
:
option
.
value
,
label
:
localText
(
option
.
labelZh
,
option
.
labelEn
),
}
))
}
function
setPaymentVisibleMethodSource
(
method
:
'
alipay
'
|
'
wxpay
'
,
source
:
string
|
number
|
boolean
|
null
)
{
const
normalized
=
normalizePaymentVisibleMethodSource
(
method
,
source
)
if
(
method
===
'
alipay
'
)
{
form
.
payment_visible_method_alipay_source
=
source
form
.
payment_visible_method_alipay_source
=
normalized
return
}
form
.
payment_visible_method_wxpay_source
=
source
form
.
payment_visible_method_wxpay_source
=
normalized
}
// Proxies for web search emulation ProxySelector
...
...
@@ -3805,6 +3818,14 @@ async function loadSettings() {
Object
.
assign
(
authSourceDefaults
,
buildAuthSourceDefaultsState
(
settings
))
form
.
backend_mode_enabled
=
settings
.
backend_mode_enabled
form
.
default_subscriptions
=
normalizeDefaultSubscriptionSettings
(
settings
.
default_subscriptions
)
form
.
payment_visible_method_alipay_source
=
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
settings
.
payment_visible_method_alipay_source
)
form
.
payment_visible_method_wxpay_source
=
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
settings
.
payment_visible_method_wxpay_source
)
registrationEmailSuffixWhitelistTags
.
value
=
normalizeRegistrationEmailSuffixDomains
(
settings
.
registration_email_suffix_whitelist
)
...
...
@@ -4070,8 +4091,14 @@ async function saveSettings() {
payment_cancel_rate_limit_window
:
Number
(
form
.
payment_cancel_rate_limit_window
)
||
1
,
payment_cancel_rate_limit_unit
:
form
.
payment_cancel_rate_limit_unit
,
payment_cancel_rate_limit_window_mode
:
form
.
payment_cancel_rate_limit_window_mode
,
payment_visible_method_alipay_source
:
form
.
payment_visible_method_alipay_source
,
payment_visible_method_wxpay_source
:
form
.
payment_visible_method_wxpay_source
,
payment_visible_method_alipay_source
:
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
form
.
payment_visible_method_alipay_source
),
payment_visible_method_wxpay_source
:
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
form
.
payment_visible_method_wxpay_source
),
payment_visible_method_alipay_enabled
:
form
.
payment_visible_method_alipay_enabled
,
payment_visible_method_wxpay_enabled
:
form
.
payment_visible_method_wxpay_enabled
,
openai_advanced_scheduler_enabled
:
form
.
openai_advanced_scheduler_enabled
,
...
...
@@ -4092,6 +4119,14 @@ async function saveSettings() {
}
}
Object
.
assign
(
authSourceDefaults
,
buildAuthSourceDefaultsState
(
updated
))
form
.
payment_visible_method_alipay_source
=
normalizePaymentVisibleMethodSource
(
'
alipay
'
,
updated
.
payment_visible_method_alipay_source
)
form
.
payment_visible_method_wxpay_source
=
normalizePaymentVisibleMethodSource
(
'
wxpay
'
,
updated
.
payment_visible_method_wxpay_source
)
registrationEmailSuffixWhitelistTags
.
value
=
normalizeRegistrationEmailSuffixDomains
(
updated
.
registration_email_suffix_whitelist
)
...
...
frontend/src/views/admin/__tests__/SettingsView.spec.ts
0 → 100644
View file @
4ebdfcd1
import
{
beforeEach
,
describe
,
expect
,
it
,
vi
}
from
'
vitest
'
import
{
defineComponent
,
h
,
ref
}
from
'
vue
'
import
{
flushPromises
,
mount
}
from
'
@vue/test-utils
'
import
SettingsView
from
'
../SettingsView.vue
'
const
{
getSettings
,
updateSettings
,
getWebSearchEmulationConfig
,
updateWebSearchEmulationConfig
,
getAdminApiKey
,
getOverloadCooldownSettings
,
getStreamTimeoutSettings
,
getRectifierSettings
,
getBetaPolicySettings
,
getGroups
,
listProxies
,
getProviders
,
fetchPublicSettings
,
adminSettingsFetch
,
showError
,
showSuccess
,
}
=
vi
.
hoisted
(()
=>
({
getSettings
:
vi
.
fn
(),
updateSettings
:
vi
.
fn
(),
getWebSearchEmulationConfig
:
vi
.
fn
(),
updateWebSearchEmulationConfig
:
vi
.
fn
(),
getAdminApiKey
:
vi
.
fn
(),
getOverloadCooldownSettings
:
vi
.
fn
(),
getStreamTimeoutSettings
:
vi
.
fn
(),
getRectifierSettings
:
vi
.
fn
(),
getBetaPolicySettings
:
vi
.
fn
(),
getGroups
:
vi
.
fn
(),
listProxies
:
vi
.
fn
(),
getProviders
:
vi
.
fn
(),
fetchPublicSettings
:
vi
.
fn
(),
adminSettingsFetch
:
vi
.
fn
(),
showError
:
vi
.
fn
(),
showSuccess
:
vi
.
fn
(),
}))
vi
.
mock
(
'
@/api
'
,
()
=>
({
adminAPI
:
{
settings
:
{
getSettings
,
updateSettings
,
getWebSearchEmulationConfig
,
updateWebSearchEmulationConfig
,
getAdminApiKey
,
getOverloadCooldownSettings
,
getStreamTimeoutSettings
,
getRectifierSettings
,
getBetaPolicySettings
,
},
groups
:
{
getAll
:
getGroups
,
},
proxies
:
{
list
:
listProxies
,
},
payment
:
{
getProviders
,
},
},
}))
vi
.
mock
(
'
@/stores
'
,
()
=>
({
useAppStore
:
()
=>
({
showError
,
showSuccess
,
showWarning
:
vi
.
fn
(),
showInfo
:
vi
.
fn
(),
fetchPublicSettings
,
}),
}))
vi
.
mock
(
'
@/stores/adminSettings
'
,
()
=>
({
useAdminSettingsStore
:
()
=>
({
fetch
:
adminSettingsFetch
,
}),
}))
vi
.
mock
(
'
@/composables/useClipboard
'
,
()
=>
({
useClipboard
:
()
=>
({
copyToClipboard
:
vi
.
fn
(),
}),
}))
vi
.
mock
(
'
@/utils/apiError
'
,
()
=>
({
extractApiErrorMessage
:
()
=>
'
error
'
,
}))
vi
.
mock
(
'
vue-i18n
'
,
async
()
=>
{
const
actual
=
await
vi
.
importActual
<
typeof
import
(
'
vue-i18n
'
)
>
(
'
vue-i18n
'
)
return
{
...
actual
,
useI18n
:
()
=>
({
t
:
(
key
:
string
)
=>
key
,
locale
:
ref
(
'
zh-CN
'
),
}),
}
})
const
AppLayoutStub
=
{
template
:
'
<div><slot /></div>
'
}
const
ToggleStub
=
defineComponent
({
props
:
{
modelValue
:
{
type
:
Boolean
,
default
:
false
,
},
},
emits
:
[
'
update:modelValue
'
],
setup
(
props
,
{
emit
})
{
return
()
=>
h
(
'
input
'
,
{
class
:
'
toggle-stub
'
,
type
:
'
checkbox
'
,
checked
:
props
.
modelValue
,
onChange
:
(
event
:
Event
)
=>
{
emit
(
'
update:modelValue
'
,
(
event
.
target
as
HTMLInputElement
).
checked
)
},
})
},
})
const
SelectStub
=
defineComponent
({
props
:
{
modelValue
:
{
type
:
[
String
,
Number
,
Boolean
,
null
],
default
:
''
,
},
options
:
{
type
:
Array
,
default
:
()
=>
[],
},
placeholder
:
{
type
:
String
,
default
:
''
,
},
},
emits
:
[
'
update:modelValue
'
,
'
change
'
],
setup
(
props
,
{
emit
})
{
const
onChange
=
(
event
:
Event
)
=>
{
const
target
=
event
.
target
as
HTMLSelectElement
emit
(
'
update:modelValue
'
,
target
.
value
)
const
option
=
(
props
.
options
as
Array
<
Record
<
string
,
unknown
>>
).
find
(
(
item
)
=>
String
(
item
.
value
??
''
)
===
target
.
value
)
??
null
emit
(
'
change
'
,
target
.
value
,
option
)
}
return
()
=>
h
(
'
select
'
,
{
class
:
'
select-stub
'
,
value
:
props
.
modelValue
??
''
,
'
data-placeholder
'
:
props
.
placeholder
,
onChange
,
},
(
props
.
options
as
Array
<
Record
<
string
,
unknown
>>
).
map
((
option
)
=>
h
(
'
option
'
,
{
key
:
`
${
String
(
option
.
value
??
''
)}
:
${
String
(
option
.
label
??
''
)}
`
,
value
:
option
.
value
as
string
,
},
String
(
option
.
label
??
''
)
)
)
)
},
})
const
baseSettingsResponse
=
{
registration_enabled
:
true
,
email_verify_enabled
:
false
,
registration_email_suffix_whitelist
:
[],
promo_code_enabled
:
true
,
invitation_code_enabled
:
false
,
password_reset_enabled
:
false
,
totp_enabled
:
false
,
totp_encryption_key_configured
:
false
,
default_balance
:
0
,
default_concurrency
:
1
,
default_subscriptions
:
[],
site_name
:
'
Sub2API
'
,
site_logo
:
''
,
site_subtitle
:
''
,
api_base_url
:
''
,
contact_info
:
''
,
doc_url
:
''
,
home_content
:
''
,
hide_ccs_import_button
:
false
,
table_default_page_size
:
20
,
table_page_size_options
:
[
10
,
20
,
50
,
100
],
backend_mode_enabled
:
false
,
custom_menu_items
:
[],
custom_endpoints
:
[],
frontend_url
:
''
,
smtp_host
:
''
,
smtp_port
:
587
,
smtp_username
:
''
,
smtp_password_configured
:
false
,
smtp_from_email
:
''
,
smtp_from_name
:
''
,
smtp_use_tls
:
true
,
turnstile_enabled
:
false
,
turnstile_site_key
:
''
,
turnstile_secret_key_configured
:
false
,
linuxdo_connect_enabled
:
false
,
linuxdo_connect_client_id
:
''
,
linuxdo_connect_client_secret_configured
:
false
,
linuxdo_connect_redirect_url
:
''
,
oidc_connect_enabled
:
false
,
oidc_connect_provider_name
:
'
OIDC
'
,
oidc_connect_client_id
:
''
,
oidc_connect_client_secret_configured
:
false
,
oidc_connect_issuer_url
:
''
,
oidc_connect_discovery_url
:
''
,
oidc_connect_authorize_url
:
''
,
oidc_connect_token_url
:
''
,
oidc_connect_userinfo_url
:
''
,
oidc_connect_jwks_url
:
''
,
oidc_connect_scopes
:
'
openid email profile
'
,
oidc_connect_redirect_url
:
''
,
oidc_connect_frontend_redirect_url
:
'
/auth/oidc/callback
'
,
oidc_connect_token_auth_method
:
'
client_secret_post
'
,
oidc_connect_use_pkce
:
true
,
oidc_connect_validate_id_token
:
true
,
oidc_connect_allowed_signing_algs
:
'
RS256,ES256,PS256
'
,
oidc_connect_clock_skew_seconds
:
120
,
oidc_connect_require_email_verified
:
false
,
oidc_connect_userinfo_email_path
:
''
,
oidc_connect_userinfo_id_path
:
''
,
oidc_connect_userinfo_username_path
:
''
,
enable_model_fallback
:
false
,
fallback_model_anthropic
:
''
,
fallback_model_openai
:
''
,
fallback_model_gemini
:
''
,
fallback_model_antigravity
:
''
,
enable_identity_patch
:
false
,
identity_patch_prompt
:
''
,
ops_monitoring_enabled
:
false
,
ops_realtime_monitoring_enabled
:
false
,
ops_query_mode_default
:
'
auto
'
,
ops_metrics_interval_seconds
:
60
,
min_claude_code_version
:
''
,
max_claude_code_version
:
''
,
allow_ungrouped_key_scheduling
:
false
,
enable_fingerprint_unification
:
true
,
enable_metadata_passthrough
:
false
,
enable_cch_signing
:
false
,
payment_enabled
:
true
,
payment_min_amount
:
1
,
payment_max_amount
:
10000
,
payment_daily_limit
:
50000
,
payment_order_timeout_minutes
:
30
,
payment_max_pending_orders
:
3
,
payment_enabled_types
:
[],
payment_balance_disabled
:
false
,
payment_balance_recharge_multiplier
:
1
,
payment_recharge_fee_rate
:
0
,
payment_load_balance_strategy
:
'
round-robin
'
,
payment_product_name_prefix
:
''
,
payment_product_name_suffix
:
''
,
payment_help_image_url
:
''
,
payment_help_text
:
''
,
payment_cancel_rate_limit_enabled
:
false
,
payment_cancel_rate_limit_max
:
10
,
payment_cancel_rate_limit_window
:
1
,
payment_cancel_rate_limit_unit
:
'
day
'
,
payment_cancel_rate_limit_window_mode
:
'
rolling
'
,
payment_visible_method_alipay_source
:
'
alipay_direct
'
,
payment_visible_method_wxpay_source
:
'
invalid-source
'
,
payment_visible_method_alipay_enabled
:
true
,
payment_visible_method_wxpay_enabled
:
true
,
openai_advanced_scheduler_enabled
:
false
,
balance_low_notify_enabled
:
false
,
balance_low_notify_threshold
:
0
,
balance_low_notify_recharge_url
:
''
,
account_quota_notify_enabled
:
false
,
account_quota_notify_emails
:
[],
}
function
mountView
()
{
return
mount
(
SettingsView
,
{
global
:
{
stubs
:
{
AppLayout
:
AppLayoutStub
,
Select
:
SelectStub
,
Toggle
:
ToggleStub
,
Icon
:
true
,
ConfirmDialog
:
true
,
PaymentProviderList
:
true
,
PaymentProviderDialog
:
true
,
GroupBadge
:
true
,
GroupOptionItem
:
true
,
ProxySelector
:
true
,
ImageUpload
:
true
,
BackupSettings
:
true
,
},
},
})
}
async
function
openPaymentTab
(
wrapper
:
ReturnType
<
typeof
mountView
>
)
{
const
paymentTabButton
=
wrapper
.
findAll
(
'
button
'
)
.
find
((
node
)
=>
node
.
text
().
includes
(
'
admin.settings.tabs.payment
'
))
expect
(
paymentTabButton
).
toBeDefined
()
await
paymentTabButton
?.
trigger
(
'
click
'
)
await
flushPromises
()
}
describe
(
'
admin SettingsView payment visible method controls
'
,
()
=>
{
beforeEach
(()
=>
{
getSettings
.
mockReset
()
updateSettings
.
mockReset
()
getWebSearchEmulationConfig
.
mockReset
()
updateWebSearchEmulationConfig
.
mockReset
()
getAdminApiKey
.
mockReset
()
getOverloadCooldownSettings
.
mockReset
()
getStreamTimeoutSettings
.
mockReset
()
getRectifierSettings
.
mockReset
()
getBetaPolicySettings
.
mockReset
()
getGroups
.
mockReset
()
listProxies
.
mockReset
()
getProviders
.
mockReset
()
fetchPublicSettings
.
mockReset
()
adminSettingsFetch
.
mockReset
()
showError
.
mockReset
()
showSuccess
.
mockReset
()
getSettings
.
mockResolvedValue
({
...
baseSettingsResponse
})
updateSettings
.
mockImplementation
(
async
(
payload
)
=>
({
...
baseSettingsResponse
,
...
payload
,
}))
getWebSearchEmulationConfig
.
mockResolvedValue
({
enabled
:
false
,
providers
:
[],
})
updateWebSearchEmulationConfig
.
mockResolvedValue
({
enabled
:
false
,
providers
:
[],
})
getAdminApiKey
.
mockResolvedValue
({
exists
:
false
,
masked_key
:
''
,
})
getOverloadCooldownSettings
.
mockResolvedValue
({
enabled
:
true
,
cooldown_minutes
:
10
,
})
getStreamTimeoutSettings
.
mockResolvedValue
({
enabled
:
true
,
action
:
'
temp_unsched
'
,
temp_unsched_minutes
:
5
,
threshold_count
:
3
,
threshold_window_minutes
:
10
,
})
getRectifierSettings
.
mockResolvedValue
({
enabled
:
true
,
thinking_signature_enabled
:
true
,
thinking_budget_enabled
:
true
,
apikey_signature_enabled
:
false
,
apikey_signature_patterns
:
[],
})
getBetaPolicySettings
.
mockResolvedValue
({
rules
:
[],
})
getGroups
.
mockResolvedValue
([])
listProxies
.
mockResolvedValue
({
items
:
[],
})
getProviders
.
mockResolvedValue
({
data
:
[],
})
fetchPublicSettings
.
mockResolvedValue
(
undefined
)
adminSettingsFetch
.
mockResolvedValue
(
undefined
)
})
it
(
'
loads canonical source options and normalizes existing values
'
,
async
()
=>
{
const
wrapper
=
mountView
()
await
flushPromises
()
await
openPaymentTab
(
wrapper
)
const
paymentSourceSelects
=
wrapper
.
findAll
(
'
select.select-stub
'
)
.
filter
((
node
)
=>
[
'
alipay
'
,
'
wxpay
'
].
includes
(
node
.
attributes
(
'
data-placeholder
'
)))
expect
(
paymentSourceSelects
).
toHaveLength
(
2
)
const
alipaySelect
=
paymentSourceSelects
.
find
(
(
node
)
=>
node
.
attributes
(
'
data-placeholder
'
)
===
'
alipay
'
)
const
wxpaySelect
=
paymentSourceSelects
.
find
(
(
node
)
=>
node
.
attributes
(
'
data-placeholder
'
)
===
'
wxpay
'
)
expect
(
alipaySelect
?.
element
.
value
).
toBe
(
'
official_alipay
'
)
expect
(
alipaySelect
?.
findAll
(
'
option
'
).
map
((
option
)
=>
option
.
element
.
value
)).
toEqual
([
''
,
'
official_alipay
'
,
'
easypay_alipay
'
,
])
expect
(
wxpaySelect
?.
element
.
value
).
toBe
(
''
)
expect
(
wxpaySelect
?.
findAll
(
'
option
'
).
map
((
option
)
=>
option
.
element
.
value
)).
toEqual
([
''
,
'
official_wxpay
'
,
'
easypay_wxpay
'
,
])
})
it
(
'
saves canonical source keys selected from the dropdowns
'
,
async
()
=>
{
const
wrapper
=
mountView
()
await
flushPromises
()
await
openPaymentTab
(
wrapper
)
const
paymentSourceSelects
=
wrapper
.
findAll
(
'
select.select-stub
'
)
.
filter
((
node
)
=>
[
'
alipay
'
,
'
wxpay
'
].
includes
(
node
.
attributes
(
'
data-placeholder
'
)))
const
alipaySelect
=
paymentSourceSelects
.
find
(
(
node
)
=>
node
.
attributes
(
'
data-placeholder
'
)
===
'
alipay
'
)
const
wxpaySelect
=
paymentSourceSelects
.
find
(
(
node
)
=>
node
.
attributes
(
'
data-placeholder
'
)
===
'
wxpay
'
)
await
alipaySelect
?.
setValue
(
'
easypay_alipay
'
)
await
wxpaySelect
?.
setValue
(
'
official_wxpay
'
)
await
wrapper
.
find
(
'
form
'
).
trigger
(
'
submit.prevent
'
)
await
flushPromises
()
expect
(
updateSettings
).
toHaveBeenCalledTimes
(
1
)
expect
(
updateSettings
).
toHaveBeenCalledWith
(
expect
.
objectContaining
({
payment_visible_method_alipay_source
:
'
easypay_alipay
'
,
payment_visible_method_wxpay_source
:
'
official_wxpay
'
,
payment_visible_method_alipay_enabled
:
true
,
payment_visible_method_wxpay_enabled
:
true
,
})
)
})
})
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment