mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-07 01:47:47 +08:00
fix(frontend): recover login redirect navigation
This commit is contained in:
@@ -265,6 +265,7 @@ import { oauthApi, type OAuthProviderInfo } from '@/api/oauth'
|
||||
import { getClientDeviceId } from '@/utils/deviceId'
|
||||
import { getApiUrl } from '@/utils/url'
|
||||
import { getOAuthIcon } from '@/utils/oauth-icons'
|
||||
import { navigateAfterLogin } from '@/features/auth/utils/loginRedirect'
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
@@ -361,15 +362,7 @@ async function handleLogin(event?: Event) {
|
||||
if (success) {
|
||||
const targetPath = consumeStoredRedirectPath() ?? (authStore.canAccessAdmin ? '/admin/dashboard' : '/dashboard')
|
||||
|
||||
try {
|
||||
const navigationFailure = await router.push(targetPath)
|
||||
if (navigationFailure) {
|
||||
throw navigationFailure
|
||||
}
|
||||
} catch {
|
||||
showError('登录成功,但跳转失败,请刷新页面或手动进入控制台')
|
||||
return
|
||||
}
|
||||
await navigateAfterLogin(router, targetPath)
|
||||
|
||||
showSuccess('登录成功,正在跳转...')
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import { createApp, defineComponent, h, nextTick, type App } from 'vue'
|
||||
import { createMemoryHistory, createRouter } from 'vue-router'
|
||||
|
||||
import LoginDialog from '../LoginDialog.vue'
|
||||
|
||||
@@ -29,12 +30,16 @@ const oauthApiMocks = vi.hoisted(() => ({
|
||||
getProviders: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('vue-router', () => ({
|
||||
useRoute: () => routeMock,
|
||||
useRouter: () => ({
|
||||
push: routerPushMock,
|
||||
}),
|
||||
}))
|
||||
vi.mock('vue-router', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('vue-router')>()
|
||||
return {
|
||||
...actual,
|
||||
useRoute: () => routeMock,
|
||||
useRouter: () => ({
|
||||
push: routerPushMock,
|
||||
}),
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/stores/auth', () => ({
|
||||
useAuthStore: () => authStoreMock,
|
||||
@@ -156,6 +161,21 @@ async function settle() {
|
||||
}
|
||||
}
|
||||
|
||||
async function createDuplicatedNavigationFailure(path: string) {
|
||||
const router = createRouter({
|
||||
history: createMemoryHistory(),
|
||||
routes: [
|
||||
{
|
||||
path,
|
||||
component: defineComponent({ setup: () => () => null }),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
await router.push(path)
|
||||
return router.push(path)
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
authStoreMock.loading = false
|
||||
authStoreMock.error = ''
|
||||
@@ -242,4 +262,26 @@ describe('LoginDialog password manager contract', () => {
|
||||
expect(sessionStorage.getItem('redirectPath')).toBeNull()
|
||||
expect(toastMocks.success).toHaveBeenCalledWith('登录成功,正在跳转...')
|
||||
})
|
||||
|
||||
it('treats duplicated router navigation after successful auth as a completed login', async () => {
|
||||
authStoreMock.login.mockResolvedValue(true)
|
||||
routerPushMock.mockResolvedValue(await createDuplicatedNavigationFailure('/dashboard'))
|
||||
const root = mountLoginDialog()
|
||||
await settle()
|
||||
|
||||
const form = root.querySelector('form')
|
||||
const username = root.querySelector<HTMLInputElement>('input[name="username"]')
|
||||
const password = root.querySelector<HTMLInputElement>('input[name="password"]')
|
||||
|
||||
username!.value = '[email protected]'
|
||||
password!.value = 'secret-from-manager'
|
||||
form!.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }))
|
||||
await settle()
|
||||
|
||||
expect(authStoreMock.login).toHaveBeenCalledWith('[email protected]', 'secret-from-manager', 'local')
|
||||
expect(routerPushMock).toHaveBeenCalledWith('/dashboard')
|
||||
expect(toastMocks.error).not.toHaveBeenCalled()
|
||||
expect(toastMocks.success).toHaveBeenCalledWith('登录成功,正在跳转...')
|
||||
expect(root.querySelector('[data-testid="dialog"]')).toBeNull()
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user