| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- import { flushPromises, mount } from '@vue/test-utils'
- import { beforeEach, expect, it, vi } from 'vitest'
- import HostToolsPanel from '@/components/app/HostToolsPanel.vue'
- import { apiRequest } from '@/api/client'
- vi.mock('@/api/client', () => ({ apiRequest: vi.fn() }))
- const request = vi.mocked(apiRequest)
- const endpoint = '/api/app/admin/desktop-hosts'
- const firstId = '1a111111-1111-4111-8111-111111111111'
- const secondId = '2b222222-2222-4222-8222-222222222222'
- let hosts: { id: string; name: string; displayName: string; enabled: boolean; online: boolean; createdAt: number }[]
- beforeEach(() => {
- request.mockReset()
- hosts = [
- { id: firstId, name: '同名电脑', displayName: '', enabled: true, online: false, createdAt: 1_700_000_000_000 },
- { id: secondId, name: '同名电脑', displayName: '', enabled: true, online: true, createdAt: 1_710_000_000_000 },
- { id: 'disabled-host', name: '已停用电脑', displayName: '', enabled: false, online: false, createdAt: 1 },
- ]
- request.mockImplementation(async (path, options) => {
- if (path === endpoint) return { hosts: structuredClone(hosts), localName: '' } as never
- if (path === '/api/app/settings/host-tools') return { approvalPolicy: 'allow', scriptMachine: true, serverComputer: true, vm: true, cloud: true } as never
- const host = hosts.find(item => path === `${endpoint}/${item.id}/name` || path === `${endpoint}/${item.id}`)
- if (host && options?.method === 'PUT') host.displayName = (options.body as { name: string }).name
- else if (host && options?.method === 'DELETE') host.enabled = false
- else throw new Error(`Unexpected request: ${path}`)
- return { ok: true } as never
- })
- })
- it('distinguishes same-name registrations by status, ID and pairing time without merging them', async () => {
- const wrapper = mount(HostToolsPanel)
- await flushPromises()
- expect(wrapper.findAll('.computer')).toHaveLength(3)
- const first = wrapper.get(`[data-host-id="${firstId}"]`)
- const second = wrapper.get(`[data-host-id="${secondId}"]`)
- expect(first.text()).toContain('未连接')
- expect(second.text()).toContain('已连接')
- expect(first.text()).toContain('编号 1a111111')
- expect(second.text()).toContain('编号 2b222222')
- expect(first.text()).toContain('配对于')
- expect(wrapper.text()).toContain('有同名的配对记录')
- expect(wrapper.text()).not.toContain('已停用电脑')
- expect(wrapper.get('[data-host-id="local"]').find('.remove-host').exists()).toBe(false)
- expect(request.mock.calls.some(([, options]) => options?.method === 'DELETE')).toBe(false)
- wrapper.unmount()
- })
- it('only disables the explicitly confirmed registration, even when names match', async () => {
- const wrapper = mount(HostToolsPanel)
- await flushPromises()
- const first = wrapper.get(`[data-host-id="${firstId}"]`)
- await first.get('.remove-host').trigger('click')
- expect(request.mock.calls.some(([, options]) => options?.method === 'DELETE')).toBe(false)
- await first.get('.remove-confirmation .remove-host').trigger('click')
- await flushPromises()
- expect(request).toHaveBeenCalledWith(`${endpoint}/${firstId}`, { method: 'DELETE' })
- expect(wrapper.find(`[data-host-id="${firstId}"]`).exists()).toBe(false)
- expect(wrapper.find(`[data-host-id="${secondId}"]`).exists()).toBe(true)
- expect(wrapper.text()).toContain('这条配对记录已停用')
- wrapper.unmount()
- })
- it('keeps the record and shows an error when disabling fails', async () => {
- const wrapper = mount(HostToolsPanel)
- await flushPromises()
- request.mockRejectedValueOnce(new Error('服务暂时不可用'))
- const first = wrapper.get(`[data-host-id="${firstId}"]`)
- await first.get('.remove-host').trigger('click')
- await first.get('.remove-confirmation .remove-host').trigger('click')
- await flushPromises()
- expect(wrapper.find(`[data-host-id="${firstId}"]`).exists()).toBe(true)
- expect(wrapper.get('[role="alert"]').text()).toContain('服务暂时不可用')
- wrapper.unmount()
- })
- it('renames by registration ID and preserves another computer’s unsaved name', async () => {
- const wrapper = mount(HostToolsPanel)
- await flushPromises()
- const first = wrapper.get(`[data-host-id="${firstId}"]`)
- const second = wrapper.get(`[data-host-id="${secondId}"]`)
- await first.get('input').setValue('旧电脑')
- await second.get('input').setValue('新电脑')
- await first.get('.name-editor button').trigger('click')
- await flushPromises()
- expect(request).toHaveBeenCalledWith(`${endpoint}/${firstId}/name`, { method: 'PUT', body: { name: '旧电脑' } })
- expect(second.get<HTMLInputElement>('input').element.value).toBe('新电脑')
- hosts[1]!.online = false
- await wrapper.get('.names-heading button').trigger('click')
- await flushPromises()
- expect(second.text()).toContain('未连接')
- expect(second.get<HTMLInputElement>('input').element.value).toBe('新电脑')
- wrapper.unmount()
- })
|