Web app: new entities (Image, RenderedAsset, SharedImage, Token, DeviceImageHistory), enums, repositories, controllers, message handlers, migrations, tests, frontend upload/library/sticker UI, Vue components. Firmware: EPD background screen binaries + gen scripts, setup_bg header. Infra: ddev config, test bundle, gitignore coverage dir. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import DevicePicker from '@/components/DevicePicker.vue'
|
||||
import type { Device } from '@/types'
|
||||
|
||||
// Stub child components DevicePicker wraps
|
||||
vi.mock('@/components/BaseBottomSheet.vue', () => ({
|
||||
default: {
|
||||
name: 'BaseBottomSheet',
|
||||
template: '<div class="bottom-sheet-stub"><slot /></div>',
|
||||
props: ['modelValue', 'label'],
|
||||
emits: ['update:modelValue'],
|
||||
},
|
||||
}))
|
||||
vi.mock('@/components/BaseButton.vue', () => ({
|
||||
default: {
|
||||
name: 'BaseButton',
|
||||
template: '<button :disabled="disabled" @click="$emit(\'click\')"><slot /></button>',
|
||||
props: ['variant', 'disabled'],
|
||||
emits: ['click'],
|
||||
},
|
||||
}))
|
||||
|
||||
const makeDevice = (overrides: Partial<Device> = {}): Device => ({
|
||||
id: 1,
|
||||
mac: 'AA:BB:CC:DD:EE:FF',
|
||||
name: 'Living Room',
|
||||
orientation: 'landscape',
|
||||
rotationIntervalMinutes: 60,
|
||||
wakeHour: null,
|
||||
timezone: 'America/Chicago',
|
||||
uniquenessWindow: 30,
|
||||
linkedAt: '2026-01-01T00:00:00Z',
|
||||
lastSeenAt: null,
|
||||
lockedImageId: null,
|
||||
...overrides,
|
||||
})
|
||||
|
||||
describe('DevicePicker', () => {
|
||||
const devices = [
|
||||
makeDevice({ id: 1, name: 'Living Room' }),
|
||||
makeDevice({ id: 2, name: 'Bedroom' }),
|
||||
]
|
||||
|
||||
function mountPicker(selected: number[] = []) {
|
||||
return mount(DevicePicker, {
|
||||
props: {
|
||||
modelValue: true,
|
||||
devices,
|
||||
selected,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// DP-01: Selecting a device emits update:selected with the device added
|
||||
it('checking a device emits update:selected with device id added', async () => {
|
||||
const wrapper = mountPicker([])
|
||||
|
||||
const checkboxes = wrapper.findAll('input[type="checkbox"]')
|
||||
// Click the first checkbox (Living Room, id=1)
|
||||
await checkboxes[0].trigger('change')
|
||||
|
||||
const emitted = wrapper.emitted('update:selected')
|
||||
expect(emitted).toBeTruthy()
|
||||
expect(emitted![0][0]).toEqual([1])
|
||||
})
|
||||
|
||||
// DP-02: Deselecting a device emits update:selected with device id removed
|
||||
it('unchecking a device emits update:selected with device id removed', async () => {
|
||||
// Start with both selected
|
||||
const wrapper = mountPicker([1, 2])
|
||||
|
||||
const checkboxes = wrapper.findAll('input[type="checkbox"]')
|
||||
// Click the first checkbox (Living Room, id=1) — it's currently checked, so this deselects
|
||||
await checkboxes[0].trigger('change')
|
||||
|
||||
const emitted = wrapper.emitted('update:selected')
|
||||
expect(emitted).toBeTruthy()
|
||||
// Should emit [2] — Living Room removed
|
||||
expect(emitted![0][0]).toEqual([2])
|
||||
})
|
||||
|
||||
// DP-03: Checkboxes reflect the selected prop
|
||||
it('checkboxes are checked for ids in selected prop', async () => {
|
||||
const wrapper = mountPicker([2])
|
||||
|
||||
const checkboxes = wrapper.findAll('input[type="checkbox"]')
|
||||
expect((checkboxes[0].element as HTMLInputElement).checked).toBe(false) // id=1 not selected
|
||||
expect((checkboxes[1].element as HTMLInputElement).checked).toBe(true) // id=2 selected
|
||||
})
|
||||
|
||||
// DP-04: Confirm button disabled when nothing selected
|
||||
it('confirm button is disabled when selected is empty', async () => {
|
||||
const wrapper = mountPicker([])
|
||||
const btn = wrapper.find('button')
|
||||
expect((btn.element as HTMLButtonElement).disabled).toBe(true)
|
||||
})
|
||||
|
||||
// DP-05: Confirm button enabled when at least one device selected
|
||||
it('confirm button is enabled when a device is selected', async () => {
|
||||
const wrapper = mountPicker([1])
|
||||
const btn = wrapper.find('button')
|
||||
expect((btn.element as HTMLButtonElement).disabled).toBe(false)
|
||||
})
|
||||
|
||||
// DP-06: Device names are rendered
|
||||
it('renders all device names', () => {
|
||||
const wrapper = mountPicker([])
|
||||
expect(wrapper.text()).toContain('Living Room')
|
||||
expect(wrapper.text()).toContain('Bedroom')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user