feat: 通过加密会话和冲突设置连接桌面 Sync
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
// @vitest-environment happy-dom
|
||||
import { flushPromises, mount } from '@vue/test-utils'
|
||||
import { afterEach, expect, it, vi } from 'vitest'
|
||||
import { hostInvoke } from '@/services/platform/desktop'
|
||||
import SyncSettings from './SyncSettings.vue'
|
||||
vi.mock('@/services/platform/desktop', () => ({ hostInvoke: vi.fn() }))
|
||||
const confirm = vi.hoisted(() => vi.fn())
|
||||
vi.mock('@/composables/useActionDialog', () => ({ useActionDialog: () => ({ actionDialog: null, resolveAction: vi.fn(), askConfirm: confirm }) }))
|
||||
afterEach(() => { vi.useRealTimers(); vi.resetAllMocks() })
|
||||
const empty = () => ({ vault_id: 'local', binding: null, paused: false, pending: 0, conflicts: [], credential_state: 'unbound', running: false, error: null, retry_in: null })
|
||||
it('clears login password, explicitly opts into HTTP and stops polling on unmount', async () => {
|
||||
vi.useFakeTimers()
|
||||
vi.mocked(hostInvoke).mockImplementation(async command => command === 'sync_status' ? empty() : command === 'sync_login' ? { endpoint: 'http://test.example:18080/', account: 'test' } : { items: [] })
|
||||
const wrapper = mount(SyncSettings); await flushPromises()
|
||||
await wrapper.get('input[type=url]').setValue('http://test.example:18080')
|
||||
await wrapper.get('input[autocomplete=username]').setValue('test')
|
||||
await wrapper.get('input[type=password]').setValue('private-fixture')
|
||||
await wrapper.get('input[type=checkbox]').setValue(true)
|
||||
await wrapper.get('form').trigger('submit'); await flushPromises()
|
||||
expect(hostInvoke).toHaveBeenCalledWith('sync_login', { request: { endpoint: 'http://test.example:18080', account: 'test', password: 'private-fixture', device_name: 'OpenNexus Desktop', allow_test_http: true } })
|
||||
expect((wrapper.get('input[type=password]').element as HTMLInputElement).value).toBe('')
|
||||
expect(wrapper.text()).not.toContain('private-fixture')
|
||||
wrapper.unmount(); const count = vi.mocked(hostInvoke).mock.calls.length
|
||||
await vi.advanceTimersByTimeAsync(6000); expect(hostInvoke).toHaveBeenCalledTimes(count)
|
||||
})
|
||||
it('cancels destructive choices and binds accepted conflict decisions to their snapshot', async () => {
|
||||
const state = { ...empty(), binding: { id: 'binding', endpoint: 'https://test.example/', account: 'test', remote_vault: 'remote', cursor: 7 }, credential_state: 'ready', conflicts: [{ sequence: 7, local_path: 'note.md', local_hash: 'original-hash', remote: { path: 'note.md', operation: 'put' } }] }
|
||||
vi.mocked(hostInvoke).mockResolvedValue(state)
|
||||
const wrapper = mount(SyncSettings); await flushPromises()
|
||||
const button = wrapper.findAll('button').find(button => button.text() === '采用远端')!
|
||||
confirm.mockResolvedValue(false); await button.trigger('click'); await flushPromises()
|
||||
expect(vi.mocked(hostInvoke).mock.calls.some(([command]) => command === 'sync_resolve')).toBe(false)
|
||||
confirm.mockResolvedValue(true); await button.trigger('click'); await flushPromises()
|
||||
expect(hostInvoke).toHaveBeenCalledWith('sync_resolve', { bindingId: 'binding', sequence: 7, choice: 'remote', destination: '', expected: 'original-hash' })
|
||||
expect(wrapper.get('input[type=url]').attributes('disabled')).toBeDefined()
|
||||
wrapper.unmount()
|
||||
})
|
||||
Reference in New Issue
Block a user