test(10-13): regression tests for all 6 UAT gaps
- keyboard.test.js: Gap 4 test — matched.find(r => r.instances?.default) resolves to FileManagerView - TreeItem.test.js: Gap 1 tests — animate-pulse present, 'Loading' text absent during shimmer state - StorageBrowser.showSearch.test.js: Gap 2 tests — showSearch true for local+cloud at root - All 219 tests pass (8 new, 211 existing)
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { createPinia, setActivePinia } from 'pinia'
|
||||
import StorageBrowser from '../StorageBrowser.vue'
|
||||
|
||||
const globalStubs = {
|
||||
BreadcrumbBar: true,
|
||||
SearchBar: true,
|
||||
SortControls: true,
|
||||
DropZone: true,
|
||||
UploadProgress: true,
|
||||
TopicBadge: true,
|
||||
AppIcon: true,
|
||||
EmptyState: true,
|
||||
}
|
||||
|
||||
function mountBrowser(mode, breadcrumb = []) {
|
||||
setActivePinia(createPinia())
|
||||
return mount(StorageBrowser, {
|
||||
props: {
|
||||
mode,
|
||||
breadcrumb,
|
||||
documents: [],
|
||||
folders: [],
|
||||
files: [],
|
||||
topicColorFn: () => '#000',
|
||||
loading: false,
|
||||
},
|
||||
global: { stubs: globalStubs },
|
||||
})
|
||||
}
|
||||
|
||||
describe('Gap 2: showSearch visible at root for local and cloud modes', () => {
|
||||
it("mode='local', breadcrumb=[] → showSearch is true (root-level local)", () => {
|
||||
const w = mountBrowser('local', [])
|
||||
expect(w.vm.showSearch).toBe(true)
|
||||
})
|
||||
|
||||
it("mode='local', breadcrumb=[{name:'Folder'}] → showSearch is true (non-root local)", () => {
|
||||
const w = mountBrowser('local', [{ name: 'Folder' }])
|
||||
expect(w.vm.showSearch).toBe(true)
|
||||
})
|
||||
|
||||
it("mode='cloud', breadcrumb=[] → showSearch is true (cloud root)", () => {
|
||||
const w = mountBrowser('cloud', [])
|
||||
expect(w.vm.showSearch).toBe(true)
|
||||
})
|
||||
|
||||
it("mode='shared' → showSearch is false", () => {
|
||||
const w = mountBrowser('shared', [])
|
||||
expect(w.vm.showSearch).toBe(false)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,68 @@
|
||||
import { describe, it, expect, vi } from 'vitest'
|
||||
import { mount, flushPromises } from '@vue/test-utils'
|
||||
import { nextTick } from 'vue'
|
||||
import TreeItem from '../TreeItem.vue'
|
||||
|
||||
vi.mock('../AppIcon.vue', () => ({ default: { template: '<span/>' } }))
|
||||
|
||||
function mountItem(overrides = {}) {
|
||||
return mount(TreeItem, {
|
||||
props: {
|
||||
label: 'Test',
|
||||
loadChildren: vi.fn().mockResolvedValue([]),
|
||||
expandable: true,
|
||||
...overrides,
|
||||
},
|
||||
global: { stubs: { RouterLink: true } },
|
||||
})
|
||||
}
|
||||
|
||||
describe('Gap 1: sidebar shimmer rows', () => {
|
||||
it('renders animate-pulse elements when loading=true (expanded via refresh)', async () => {
|
||||
// First expand the item (so expanded=true, childrenLoaded=true)
|
||||
let resolveFn1
|
||||
const loadChildren = vi.fn()
|
||||
.mockReturnValueOnce(Promise.resolve([])) // first load resolves immediately
|
||||
.mockReturnValue(new Promise(resolve => { resolveFn1 = resolve })) // refresh never resolves
|
||||
const w = mountItem({ loadChildren })
|
||||
// Expand by awaiting toggleExpand — sets expanded=true after load completes
|
||||
const setupState = w.vm.$.setupState
|
||||
await setupState.toggleExpand()
|
||||
await flushPromises()
|
||||
// Now call refresh() without awaiting — it calls load() which sets loading=true while expanded stays true
|
||||
setupState.refresh() // NOT awaited — loading=true while promise is pending
|
||||
await nextTick() // let Vue update the DOM
|
||||
const pulseEls = w.findAll('.animate-pulse')
|
||||
expect(pulseEls.length).toBeGreaterThanOrEqual(2)
|
||||
// Cleanup
|
||||
if (resolveFn1) resolveFn1([])
|
||||
await flushPromises()
|
||||
})
|
||||
|
||||
it('does not render "Loading" text when loading=true (expanded via refresh)', async () => {
|
||||
let resolveFn1
|
||||
const loadChildren = vi.fn()
|
||||
.mockReturnValueOnce(Promise.resolve([]))
|
||||
.mockReturnValue(new Promise(resolve => { resolveFn1 = resolve }))
|
||||
const w = mountItem({ loadChildren })
|
||||
const setupState = w.vm.$.setupState
|
||||
await setupState.toggleExpand()
|
||||
await flushPromises()
|
||||
setupState.refresh()
|
||||
await nextTick()
|
||||
expect(w.text()).not.toContain('Loading')
|
||||
if (resolveFn1) resolveFn1([])
|
||||
await flushPromises()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Gap 1 regression: non-loading branches unchanged', () => {
|
||||
it('shows Empty text when loadChildren resolves to [] and item is expanded', async () => {
|
||||
const w = mountItem({ loadChildren: vi.fn().mockResolvedValue([]) })
|
||||
const toggleExpand = w.vm.$.setupState.toggleExpand
|
||||
await toggleExpand()
|
||||
await flushPromises()
|
||||
await nextTick()
|
||||
expect(w.text()).toContain('Empty')
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user