import { flushPromises, mount } from '@vue/test-utils' import { createPinia } from 'pinia' import { describe, expect, it, vi } from 'vitest' import Cloud from '../Cloud.vue' import { rpcClient } from '@/api/rpc-client' vi.mock('vue-router', () => ({ useRouter: () => ({ push: vi.fn() }), RouterLink: { name: 'RouterLink', props: ['to'], template: '' }, })) vi.mock('@/stores/app', () => ({ useAppStore: () => ({ packages: {} }), })) vi.mock('@/api/rpc-client', () => ({ rpcClient: { federationListNodes: vi.fn(), }, })) function deferred() { let resolve!: (value: T) => void let reject!: (reason?: unknown) => void const promise = new Promise((res, rej) => { resolve = res reject = rej }) return { promise, resolve, reject } } function makePeer() { return { did: 'did:key:peer', pubkey: 'peer', onion: 'peer.onion', name: 'Peer Alpha', trust_level: 'trusted', added_at: '2026-06-10T10:00:00Z', } } describe('Cloud peer list', () => { it('keeps peer nodes visible while refresh is pending or fails', async () => { vi.mocked(rpcClient.federationListNodes).mockResolvedValueOnce({ nodes: [makePeer()] }) const wrapper = mount(Cloud, { global: { plugins: [createPinia()] } }) await flushPromises() expect(wrapper.text()).toContain('Peer Alpha') expect(wrapper.text()).not.toContain('No peers yet') const pending = deferred<{ nodes: [] }>() vi.mocked(rpcClient.federationListNodes).mockReturnValueOnce(pending.promise) const refresh = (wrapper.vm as unknown as { loadPeers: () => Promise }).loadPeers() await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Peer Alpha') expect(wrapper.text()).toContain('Refreshing peer nodes...') expect(wrapper.text()).not.toContain('No peers yet') pending.reject(new Error('offline')) await refresh await flushPromises() expect(wrapper.text()).toContain('Peer Alpha') expect(wrapper.text()).toContain('offline') expect(wrapper.text()).not.toContain('Refreshing peer nodes...') expect(wrapper.text()).not.toContain('No peers yet') }) })