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
a6b919eb
Commit
a6b919eb
authored
Apr 21, 2026
by
IanShaw027
Browse files
frontend: normalize auth oauth i18n and error toasts
parent
4c21320d
Changes
25
Show whitespace changes
Inline
Side-by-side
frontend/src/views/auth/__tests__/LinuxDoCallbackView.spec.ts
View file @
a6b919eb
...
...
@@ -31,7 +31,12 @@ vi.mock('vue-i18n', async () => {
return
{
...
actual
,
useI18n
:
()
=>
({
t
:
(
key
:
string
)
=>
key
t
:
(
key
:
string
,
params
?:
Record
<
string
,
string
>
)
=>
{
if
(
key
===
'
auth.oauthFlow.totpHint
'
)
{
return
`verify
${
params
?.
account
??
''
}
`
.
trim
()
}
return
key
}
})
}
})
...
...
@@ -498,6 +503,34 @@ describe('LinuxDoCallbackView', () => {
)
})
it
(
'
shows create-account failures through toast without inline error text
'
,
async
()
=>
{
exchangePendingOAuthCompletion
.
mockResolvedValue
({
error
:
'
email_required
'
,
redirect
:
'
/welcome
'
})
apiClientPost
.
mockRejectedValue
(
new
Error
(
'
create failed
'
))
const
wrapper
=
mount
(
LinuxDoCallbackView
,
{
global
:
{
stubs
:
{
AuthLayout
:
{
template
:
'
<div><slot /></div>
'
},
Icon
:
true
,
RouterLink
:
{
template
:
'
<a><slot /></a>
'
},
transition
:
false
}
}
})
await
flushPromises
()
await
wrapper
.
get
(
'
[data-testid="linuxdo-create-account-email"]
'
).
setValue
(
'
new@example.com
'
)
await
wrapper
.
get
(
'
[data-testid="linuxdo-create-account-password"]
'
).
setValue
(
'
secret-123
'
)
await
wrapper
.
get
(
'
[data-testid="linuxdo-create-account-submit"]
'
).
trigger
(
'
click
'
)
await
flushPromises
()
expect
(
showError
).
toHaveBeenCalledWith
(
'
create failed
'
)
expect
(
wrapper
.
text
()).
not
.
toContain
(
'
create failed
'
)
})
it
(
'
sends a verify code for pending oauth account creation
'
,
async
()
=>
{
exchangePendingOAuthCompletion
.
mockResolvedValue
({
error
:
'
email_required
'
,
...
...
frontend/src/views/auth/__tests__/OAuthCallbackView.spec.ts
0 → 100644
View file @
a6b919eb
import
{
mount
}
from
'
@vue/test-utils
'
import
{
beforeEach
,
describe
,
expect
,
it
,
vi
}
from
'
vitest
'
import
OAuthCallbackView
from
'
@/views/auth/OAuthCallbackView.vue
'
const
{
routeState
,
showErrorMock
,
copyToClipboardMock
}
=
vi
.
hoisted
(()
=>
({
routeState
:
{
query
:
{}
as
Record
<
string
,
unknown
>
,
},
showErrorMock
:
vi
.
fn
(),
copyToClipboardMock
:
vi
.
fn
(),
}))
vi
.
mock
(
'
vue-router
'
,
()
=>
({
useRoute
:
()
=>
routeState
,
}))
vi
.
mock
(
'
vue-i18n
'
,
()
=>
({
useI18n
:
()
=>
({
t
:
(
key
:
string
)
=>
key
,
}),
}))
vi
.
mock
(
'
@/stores
'
,
()
=>
({
useAppStore
:
()
=>
({
showError
:
(...
args
:
any
[])
=>
showErrorMock
(...
args
),
}),
}))
vi
.
mock
(
'
@/composables/useClipboard
'
,
()
=>
({
useClipboard
:
()
=>
({
copyToClipboard
:
(...
args
:
any
[])
=>
copyToClipboardMock
(...
args
),
}),
}))
describe
(
'
OAuthCallbackView
'
,
()
=>
{
beforeEach
(()
=>
{
routeState
.
query
=
{}
showErrorMock
.
mockReset
()
copyToClipboardMock
.
mockReset
()
})
it
(
'
renders localized callback copy actions
'
,
()
=>
{
routeState
.
query
=
{
code
:
'
oauth-code
'
,
state
:
'
oauth-state
'
,
}
const
wrapper
=
mount
(
OAuthCallbackView
)
expect
(
wrapper
.
text
()).
toContain
(
'
auth.oauth.callbackTitle
'
)
expect
(
wrapper
.
text
()).
toContain
(
'
auth.oauth.callbackHint
'
)
expect
(
wrapper
.
text
()).
toContain
(
'
common.copy
'
)
expect
(
wrapper
.
find
(
'
input[value="oauth-code"]
'
).
exists
()).
toBe
(
true
)
expect
(
wrapper
.
find
(
'
input[value="oauth-state"]
'
).
exists
()).
toBe
(
true
)
})
it
(
'
sends callback errors to toast instead of rendering inline red text
'
,
()
=>
{
routeState
.
query
=
{
error
:
'
oauth failed
'
,
}
const
wrapper
=
mount
(
OAuthCallbackView
)
expect
(
showErrorMock
).
toHaveBeenCalledWith
(
'
oauth failed
'
)
expect
(
wrapper
.
text
()).
not
.
toContain
(
'
oauth failed
'
)
expect
(
wrapper
.
find
(
'
.bg-red-50
'
).
exists
()).
toBe
(
false
)
})
})
frontend/src/views/auth/__tests__/OidcCallbackView.spec.ts
View file @
a6b919eb
...
...
@@ -32,6 +32,9 @@ vi.mock('vue-i18n', async () => {
...
actual
,
useI18n
:
()
=>
({
t
:
(
key
:
string
,
params
?:
Record
<
string
,
string
>
)
=>
{
if
(
key
===
'
auth.oauthFlow.totpHint
'
)
{
return
`verify
${
params
?.
account
??
''
}
`
.
trim
()
}
if
(
!
params
?.
providerName
)
{
return
key
}
...
...
@@ -477,6 +480,34 @@ describe('OidcCallbackView', () => {
)
})
it
(
'
shows create-account failures through toast without inline error text
'
,
async
()
=>
{
exchangePendingOAuthCompletion
.
mockResolvedValue
({
error
:
'
email_required
'
,
redirect
:
'
/welcome
'
})
apiClientPost
.
mockRejectedValue
(
new
Error
(
'
create failed
'
))
const
wrapper
=
mount
(
OidcCallbackView
,
{
global
:
{
stubs
:
{
AuthLayout
:
{
template
:
'
<div><slot /></div>
'
},
Icon
:
true
,
RouterLink
:
{
template
:
'
<a><slot /></a>
'
},
transition
:
false
}
}
})
await
flushPromises
()
await
wrapper
.
get
(
'
[data-testid="oidc-create-account-email"]
'
).
setValue
(
'
new@example.com
'
)
await
wrapper
.
get
(
'
[data-testid="oidc-create-account-password"]
'
).
setValue
(
'
secret-123
'
)
await
wrapper
.
get
(
'
[data-testid="oidc-create-account-submit"]
'
).
trigger
(
'
click
'
)
await
flushPromises
()
expect
(
showError
).
toHaveBeenCalledWith
(
'
create failed
'
)
expect
(
wrapper
.
text
()).
not
.
toContain
(
'
create failed
'
)
})
it
(
'
sends a verify code for pending oauth account creation
'
,
async
()
=>
{
exchangePendingOAuthCompletion
.
mockResolvedValue
({
error
:
'
email_required
'
,
...
...
frontend/src/views/auth/__tests__/WechatCallbackView.spec.ts
View file @
a6b919eb
...
...
@@ -71,6 +71,9 @@ vi.mock('vue-i18n', () => ({
}),
useI18n
:
()
=>
({
t
:
(
key
:
string
,
params
?:
Record
<
string
,
string
>
)
=>
{
if
(
key
===
'
auth.oauthFlow.totpHint
'
)
{
return
`verify
${
params
?.
account
??
''
}
`
.
trim
()
}
if
(
key
===
'
auth.oidc.callbackTitle
'
)
{
return
`Signing you in with
${
params
?.
providerName
??
''
}
`
.
trim
()
}
...
...
@@ -695,6 +698,34 @@ describe('WechatCallbackView', () => {
)
})
it
(
'
shows create-account failures through toast without inline error text
'
,
async
()
=>
{
exchangePendingOAuthCompletionMock
.
mockResolvedValue
({
error
:
'
email_required
'
,
redirect
:
'
/welcome
'
,
})
apiClientPostMock
.
mockRejectedValue
(
new
Error
(
'
create failed
'
))
const
wrapper
=
mount
(
WechatCallbackView
,
{
global
:
{
stubs
:
{
AuthLayout
:
{
template
:
'
<div><slot /></div>
'
},
Icon
:
true
,
RouterLink
:
{
template
:
'
<a><slot /></a>
'
},
transition
:
false
,
},
},
})
await
flushPromises
()
await
wrapper
.
get
(
'
[data-testid="wechat-create-account-email"]
'
).
setValue
(
'
new@example.com
'
)
await
wrapper
.
get
(
'
[data-testid="wechat-create-account-password"]
'
).
setValue
(
'
secret-123
'
)
await
wrapper
.
get
(
'
[data-testid="wechat-create-account-submit"]
'
).
trigger
(
'
click
'
)
await
flushPromises
()
expect
(
showErrorMock
).
toHaveBeenCalledWith
(
'
create failed
'
)
expect
(
wrapper
.
text
()).
not
.
toContain
(
'
create failed
'
)
})
it
(
'
sends a verify code for pending oauth account creation
'
,
async
()
=>
{
exchangePendingOAuthCompletionMock
.
mockResolvedValue
({
error
:
'
email_required
'
,
...
...
frontend/src/views/auth/__tests__/WechatPaymentCallbackView.spec.ts
View file @
a6b919eb
...
...
@@ -2,7 +2,7 @@ import { flushPromises, mount } from '@vue/test-utils'
import
{
beforeEach
,
describe
,
expect
,
it
,
vi
}
from
'
vitest
'
import
WechatPaymentCallbackView
from
'
@/views/auth/WechatPaymentCallbackView.vue
'
const
{
replaceMock
,
routeState
,
locationState
}
=
vi
.
hoisted
(()
=>
({
const
{
replaceMock
,
routeState
,
locationState
,
showErrorMock
}
=
vi
.
hoisted
(()
=>
({
replaceMock
:
vi
.
fn
(),
routeState
:
{
query
:
{}
as
Record
<
string
,
unknown
>
,
...
...
@@ -16,6 +16,7 @@ const { replaceMock, routeState, locationState } = vi.hoisted(() => ({
origin
:
'
http://localhost
'
,
}
as
Location
&
{
origin
:
string
},
},
showErrorMock
:
vi
.
fn
(),
}))
vi
.
mock
(
'
vue-router
'
,
()
=>
({
...
...
@@ -27,14 +28,27 @@ vi.mock('vue-router', () => ({
vi
.
mock
(
'
vue-i18n
'
,
()
=>
({
useI18n
:
()
=>
({
t
:
(
key
:
string
)
=>
key
,
t
:
(
key
:
string
)
=>
{
if
(
key
===
'
auth.wechatPayment.callbackTitle
'
)
return
'
正在恢复微信支付
'
if
(
key
===
'
auth.wechatPayment.callbackProcessing
'
)
return
'
正在恢复微信支付...
'
if
(
key
===
'
auth.wechatPayment.backToPayment
'
)
return
'
返回支付页
'
if
(
key
===
'
auth.wechatPayment.callbackMissingResumeToken
'
)
return
'
微信支付回调缺少恢复令牌。
'
return
key
},
locale
:
{
value
:
'
zh-CN
'
},
}),
}))
vi
.
mock
(
'
@/stores
'
,
()
=>
({
useAppStore
:
()
=>
({
showError
:
(...
args
:
any
[])
=>
showErrorMock
(...
args
),
}),
}))
describe
(
'
WechatPaymentCallbackView
'
,
()
=>
{
beforeEach
(()
=>
{
replaceMock
.
mockReset
()
showErrorMock
.
mockReset
()
routeState
.
query
=
{}
locationState
.
current
=
{
href
:
'
http://localhost/auth/wechat/payment/callback
'
,
...
...
@@ -72,6 +86,8 @@ describe('WechatPaymentCallbackView', () => {
await
flushPromises
()
expect
(
replaceMock
).
not
.
toHaveBeenCalled
()
expect
(
showErrorMock
).
toHaveBeenCalledWith
(
'
微信支付回调缺少恢复令牌。
'
)
expect
(
wrapper
.
text
()).
toContain
(
'
微信支付回调缺少恢复令牌。
'
)
expect
(
wrapper
.
find
(
'
.bg-red-50
'
).
exists
()).
toBe
(
false
)
})
})
Prev
1
2
Next
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