test(12): close Nyquist validation gap

This commit is contained in:
curo1305
2026-06-22 06:44:33 +02:00
parent e64980af5f
commit 692600c755
2 changed files with 124 additions and 14 deletions
@@ -0,0 +1,92 @@
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
vi.mock('../../../api/client.js', () => ({
getConnectionConfig: vi.fn(),
connectWebDav: vi.fn(),
updateWebDavCredentials: vi.fn(),
}))
import * as api from '../../../api/client.js'
import CloudCredentialModal from '../CloudCredentialModal.vue'
const nextcloudProvider = { key: 'nextcloud', label: 'Nextcloud' }
const global = { stubs: { AppIcon: true } }
async function openModal(props = {}) {
const wrapper = mount(CloudCredentialModal, {
props: {
show: false,
provider: nextcloudProvider,
existing: null,
...props,
},
global,
})
await wrapper.setProps({ show: true })
await flushPromises()
return wrapper
}
beforeEach(() => {
vi.clearAllMocks()
api.getConnectionConfig.mockResolvedValue({
connection_username: 'alice',
server_url: 'https://cloud.example.com/remote.php/dav/files/alice/',
})
api.connectWebDav.mockResolvedValue({ id: 'new-connection-id' })
api.updateWebDavCredentials.mockResolvedValue({ id: 'connection-id' })
})
describe('CloudCredentialModal connection lifecycle', () => {
it('creates a new Nextcloud connection and constructs its WebDAV URL', async () => {
const wrapper = await openModal()
await wrapper.find('input[type="url"]').setValue('https://cloud.example.com')
await wrapper.find('input[type="text"]').setValue('alice@example.com')
await wrapper.find('input[type="password"]').setValue('app-password')
await wrapper.find('form').trigger('submit')
await flushPromises()
expect(api.connectWebDav).toHaveBeenCalledWith(
'nextcloud',
'https://cloud.example.com/remote.php/dav/files/alice%40example.com/',
'alice@example.com',
'app-password',
)
expect(api.updateWebDavCredentials).not.toHaveBeenCalled()
expect(wrapper.emitted('connected')).toHaveLength(1)
expect(wrapper.emitted('close')).toHaveLength(1)
})
it('updates the selected connection ID and omits a blank replacement password', async () => {
const wrapper = await openModal({ existing: { id: 'connection-id' } })
expect(api.getConnectionConfig).toHaveBeenCalledWith('connection-id')
expect(wrapper.find('input[type="text"]').element.value).toBe('alice')
await wrapper.find('form').trigger('submit')
await flushPromises()
expect(api.updateWebDavCredentials).toHaveBeenCalledWith('connection-id', {
serverUrl: 'https://cloud.example.com/remote.php/dav/files/alice/',
username: 'alice',
password: undefined,
})
expect(api.connectWebDav).not.toHaveBeenCalled()
})
it('shows an actionable API validation message without closing', async () => {
api.connectWebDav.mockRejectedValueOnce(new Error('server_url: URL must use HTTPS'))
const wrapper = await openModal()
await wrapper.find('input[type="url"]').setValue('http://cloud.example.com')
await wrapper.find('input[type="text"]').setValue('alice')
await wrapper.find('input[type="password"]').setValue('secret')
await wrapper.find('form').trigger('submit')
await flushPromises()
expect(wrapper.text()).toContain('server_url: URL must use HTTPS')
expect(wrapper.emitted('connected')).toBeUndefined()
expect(wrapper.emitted('close')).toBeUndefined()
})
})