import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' import { mount, VueWrapper } from '@vue/test-utils' import { nextTick } from 'vue' import LoginButton from '../shared/LoginButton.vue' // Mock dependencies vi.mock('vue-router', () => ({ useRouter: vi.fn(() => ({ push: vi.fn() })), })) vi.mock('../../stores/auth', () => ({ authenticateParent: vi.fn(), isParentAuthenticated: { value: false }, isParentPersistent: { value: false }, logoutParent: vi.fn(), logoutUser: vi.fn(), })) vi.mock('@/common/imageCache', () => ({ getCachedImageUrl: vi.fn(), getCachedImageBlob: vi.fn(), })) vi.mock('@/common/eventBus', () => ({ eventBus: { on: vi.fn(), off: vi.fn(), emit: vi.fn(), }, })) import { eventBus } from '@/common/eventBus' describe('LoginButton', () => { let wrapper: VueWrapper let mockFetch: any beforeEach(() => { vi.clearAllMocks() mockFetch = vi.fn() vi.stubGlobal('fetch', mockFetch) }) afterEach(() => { if (wrapper) { wrapper.unmount() } vi.unstubAllGlobals() }) describe('Event Listeners', () => { it('registers event listeners on mount', () => { mockFetch.mockResolvedValue({ ok: true, json: () => Promise.resolve({ first_name: '', last_name: '', email: '', image_id: null }), }) wrapper = mount(LoginButton) expect(eventBus.on).toHaveBeenCalledWith('open-login', expect.any(Function)) expect(eventBus.on).toHaveBeenCalledWith('profile_updated', expect.any(Function)) }) it('unregisters event listeners on unmount', () => { mockFetch.mockResolvedValue({ ok: true, json: () => Promise.resolve({ first_name: '', last_name: '', email: '', image_id: null }), }) wrapper = mount(LoginButton) wrapper.unmount() expect(eventBus.off).toHaveBeenCalledWith('open-login', expect.any(Function)) expect(eventBus.off).toHaveBeenCalledWith('profile_updated', expect.any(Function)) }) it('refetches profile when profile_updated event is received', async () => { mockFetch .mockResolvedValueOnce({ ok: true, json: () => Promise.resolve({ first_name: '', last_name: '', email: '', image_id: null }), }) .mockResolvedValueOnce({ ok: true, json: () => Promise.resolve({ first_name: 'Updated', last_name: 'User', email: 'updated@example.com', image_id: 'new-image-id', }), }) wrapper = mount(LoginButton) // Get the profile_updated callback const profileUpdatedCall = eventBus.on.mock.calls.find( (call) => call[0] === 'profile_updated', ) const profileUpdatedCallback = profileUpdatedCall[1] // Call the callback await profileUpdatedCallback() // Check that fetch was called for profile expect(mockFetch).toHaveBeenCalledWith('/api/user/profile', { credentials: 'include' }) }) }) })