feat: share reviewed website archives and repair companion setup flows

This commit is contained in:
archipelago
2026-10-08 12:18:45 -04:00
parent 08bffdb43d
commit e5d77916d4
17 changed files with 394 additions and 20 deletions
@@ -0,0 +1,29 @@
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import SearchableAppSelect from '../SearchableAppSelect.vue'
const options = [{ id: 'homeassistant', name: 'Home Assistant' }, { id: 'immich', name: 'Immich' }]
describe('searchable app picker', () => {
it('renders actual touchable options, filters them and selects only an offered app', async () => {
const wrapper = mount(SearchableAppSelect, { props: { modelValue: '', options } })
await wrapper.get('button').trigger('click')
expect(wrapper.findAll('[role="option"]')).toHaveLength(2)
await wrapper.get('input').setValue('imm')
expect(wrapper.findAll('[role="option"]')).toHaveLength(1)
await wrapper.get('[role="option"]').trigger('click')
expect(wrapper.emitted('update:modelValue')).toEqual([['immich']])
expect(wrapper.find('[role="listbox"]').exists()).toBe(false)
})
it('supports keyboard choice and escape without selecting arbitrary search text', async () => {
const wrapper = mount(SearchableAppSelect, { props: { modelValue: '', options } })
await wrapper.get('button').trigger('keydown', { key: 'ArrowDown' })
await wrapper.get('input').setValue('home')
await wrapper.get('input').trigger('keydown', { key: 'Enter' })
expect(wrapper.emitted('update:modelValue')).toEqual([['homeassistant']])
await wrapper.get('button').trigger('click')
await wrapper.get('input').setValue('unknown')
await wrapper.get('input').trigger('keydown', { key: 'Enter' })
expect(wrapper.emitted('update:modelValue')).toHaveLength(1)
await wrapper.get('input').trigger('keydown', { key: 'Escape' })
expect(wrapper.find('[role="listbox"]').exists()).toBe(false)
})
})
@@ -0,0 +1,26 @@
import { mount } from '@vue/test-utils'
import { describe, expect, it } from 'vitest'
import WebsiteArchiveSharing from '../WebsiteArchiveSharing.vue'
describe('archived website sharing consent', () => {
it('requires fresh approval after the reviewed snapshot changes', async () => {
const wrapper = mount(WebsiteArchiveSharing, { props: { publication: { html: '<h1>Reviewed</h1>' }, archive: { sha256: 'a'.repeat(64), size: 17 } } })
expect(wrapper.get('button').attributes('disabled')).toBeDefined()
expect(wrapper.get('iframe').attributes('sandbox')).toBe('')
expect(wrapper.get('iframe').attributes('srcdoc')).toContain('<h1>Reviewed</h1>')
await wrapper.get('input').setValue(true)
await wrapper.get('button').trigger('click')
expect(wrapper.emitted('change')).toEqual([[true]])
await wrapper.setProps({ publication: { html: '<h1>Different</h1>' } })
expect(wrapper.get('button').attributes('disabled')).toBeDefined()
expect(wrapper.emitted('change')).toHaveLength(1)
})
it('keeps removal available without new approval and exposes only the selected hash', async () => {
const hash = 'a'.repeat(64)
const wrapper = mount(WebsiteArchiveSharing, { props: { publication: { html: 'public', public_archive: hash }, address: 'https://example.com/' } })
expect(wrapper.text()).toContain('https://example.com/'+hash)
expect(wrapper.find('input').exists()).toBe(false)
await wrapper.get('button').trigger('click')
expect(wrapper.emitted('change')).toEqual([[false]])
})
})