import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount, flushPromises } from '@vue/test-utils' import { setActivePinia, createPinia } from 'pinia' // useRouter().push 를 캡처 const { pushMock } = vi.hoisted(() => ({ pushMock: vi.fn() })) vi.mock('vue-router', () => ({ useRouter: () => ({ push: pushMock }) })) vi.mock('@/api/authApi', () => ({ authApi: { login: vi.fn(), signupEnabled: vi.fn(() => Promise.resolve({ enabled: true })), }, })) vi.mock('@capacitor/preferences', () => ({ Preferences: { set: vi.fn(() => Promise.resolve()), get: vi.fn(() => Promise.resolve({ value: null })), remove: vi.fn(() => Promise.resolve()), }, })) import { authApi } from '@/api/authApi' import { useUiStore } from '@/stores/ui' import LoginModal from '@/components/LoginModal.vue' function mountOpen() { const ui = useUiStore() return { ui, wrapper: mount(LoginModal, { global: { stubs: { teleport: true } } }) } } async function submitLogin(wrapper) { await wrapper.find('input[autocomplete="username"]').setValue('u1') await wrapper.find('input[autocomplete="current-password"]').setValue('pw') await wrapper.find('form').trigger('submit') await flushPromises() } describe('LoginModal 로그인 플로우', () => { beforeEach(() => { setActivePinia(createPinia()) localStorage.clear() authApi.login.mockResolvedValue({ token: 'tok', member: { id: 1, loginId: 'u1', name: 'N' } }) }) it('redirect 없으면 로그인 후 대시보드(/)로 이동', async () => { const { ui, wrapper } = mountOpen() ui.openLogin('') await wrapper.vm.$nextTick() await submitLogin(wrapper) expect(authApi.login).toHaveBeenCalledWith({ loginId: 'u1', password: 'pw', rememberMe: true }) expect(pushMock).toHaveBeenCalledWith('/') expect(ui.loginOpen).toBe(false) }) it('redirect 있으면 보존된 목적지로 이동', async () => { const { ui, wrapper } = mountOpen() ui.openLogin('/account/wallets') await wrapper.vm.$nextTick() await submitLogin(wrapper) expect(pushMock).toHaveBeenCalledWith('/account/wallets') }) it('로그인 실패 시 에러 표시 + 이동 없음', async () => { authApi.login.mockRejectedValueOnce({ response: { data: { message: '아이디 또는 비밀번호가 올바르지 않습니다.' } } }) const { ui, wrapper } = mountOpen() ui.openLogin('') await wrapper.vm.$nextTick() await submitLogin(wrapper) expect(pushMock).not.toHaveBeenCalled() expect(ui.loginOpen).toBe(true) expect(wrapper.text()).toContain('아이디 또는 비밀번호가 올바르지 않습니다.') }) })