Skip to content

Commit 7d55d26

Browse files
test(FileListFilterChips): add component tests
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 36b4b86 commit 7d55d26

1 file changed

Lines changed: 159 additions & 0 deletions

File tree

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 LibreCode coop and LibreCode contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { beforeEach, describe, expect, it, vi } from 'vitest'
7+
import { mount } from '@vue/test-utils'
8+
import { setActivePinia } from 'pinia'
9+
import { createTestingPinia } from '@pinia/testing'
10+
11+
import FileListFilterChips from '../../../../views/FilesList/FileListFilter/FileListFilterChips.vue'
12+
import { useFiltersStore } from '../../../../store/filters.js'
13+
14+
vi.mock('@nextcloud/l10n', () => ({
15+
t: vi.fn((_app: string, text: string) => text),
16+
}))
17+
18+
vi.mock('@nextcloud/logger', () => ({
19+
getLogger: vi.fn(() => ({
20+
error: vi.fn(),
21+
warn: vi.fn(),
22+
info: vi.fn(),
23+
debug: vi.fn(),
24+
})),
25+
getLoggerBuilder: vi.fn(() => ({
26+
setApp: vi.fn().mockReturnThis(),
27+
detectUser: vi.fn().mockReturnThis(),
28+
build: vi.fn(() => ({
29+
error: vi.fn(),
30+
warn: vi.fn(),
31+
info: vi.fn(),
32+
debug: vi.fn(),
33+
})),
34+
})),
35+
}))
36+
37+
vi.mock('@nextcloud/axios', () => ({
38+
default: { get: vi.fn(), post: vi.fn(), put: vi.fn(), delete: vi.fn(), patch: vi.fn() },
39+
}))
40+
41+
vi.mock('@nextcloud/router', () => ({
42+
generateOcsUrl: vi.fn((path: string) => `/ocs/v2.php${path}`),
43+
}))
44+
45+
vi.mock('@nextcloud/initial-state', () => ({
46+
loadState: vi.fn((_app: string, _key: string, defaultValue: unknown) => defaultValue),
47+
}))
48+
49+
vi.mock('@nextcloud/event-bus', () => ({
50+
emit: vi.fn(),
51+
subscribe: vi.fn(),
52+
}))
53+
54+
vi.mock('@nextcloud/vue/components/NcAvatar', () => ({
55+
default: {
56+
name: 'NcAvatar',
57+
props: ['user', 'size', 'disableMenu', 'verboseStatus'],
58+
template: '<span class="nc-avatar-stub" :data-user="user" />',
59+
},
60+
}))
61+
62+
vi.mock('@nextcloud/vue/components/NcChip', () => ({
63+
default: {
64+
name: 'NcChip',
65+
props: ['text', 'iconSvg', 'ariaLabelClose'],
66+
emits: ['close'],
67+
template: '<span class="nc-chip-stub" :data-text="text" @click.stop><slot name="icon" /><button class="nc-chip-close" @click="$emit(\'close\')" /></span>',
68+
},
69+
}))
70+
71+
describe('FileListFilterChips.vue', () => {
72+
beforeEach(() => {
73+
setActivePinia(createTestingPinia({ createSpy: vi.fn }))
74+
})
75+
76+
function mountComponent() {
77+
return mount(FileListFilterChips)
78+
}
79+
80+
it('renders nothing when there are no active chips', () => {
81+
const wrapper = mountComponent()
82+
expect(wrapper.find('ul').exists()).toBe(false)
83+
})
84+
85+
it('renders a chip for each active chip in the store', async () => {
86+
const filtersStore = useFiltersStore()
87+
filtersStore.$patch({
88+
chips: {
89+
status: [
90+
{ id: 1, text: 'Signed', onclick: () => {} },
91+
{ id: 2, text: 'Ready to sign', onclick: () => {} },
92+
],
93+
},
94+
})
95+
96+
const wrapper = mountComponent()
97+
const chips = wrapper.findAll('.nc-chip-stub')
98+
expect(chips).toHaveLength(2)
99+
})
100+
101+
it('passes the chip text to NcChip', async () => {
102+
const filtersStore = useFiltersStore()
103+
filtersStore.$patch({
104+
chips: {
105+
modified: [{ id: 'today', text: 'Today', onclick: () => {} }],
106+
},
107+
})
108+
109+
const wrapper = mountComponent()
110+
const chip = wrapper.find('.nc-chip-stub')
111+
expect(chip.attributes('data-text')).toBe('Today')
112+
})
113+
114+
it('renders chips from multiple filter categories combined', async () => {
115+
const filtersStore = useFiltersStore()
116+
filtersStore.$patch({
117+
chips: {
118+
status: [{ id: 1, text: 'Signed', onclick: () => {} }],
119+
modified: [{ id: 'today', text: 'Today', onclick: () => {} }],
120+
},
121+
})
122+
123+
const wrapper = mountComponent()
124+
expect(wrapper.findAll('.nc-chip-stub')).toHaveLength(2)
125+
})
126+
127+
it('reactively shows chips when store updates after mount', async () => {
128+
const filtersStore = useFiltersStore()
129+
const wrapper = mountComponent()
130+
131+
// Initially empty — no ul rendered
132+
expect(wrapper.find('ul').exists()).toBe(false)
133+
134+
// Add a chip
135+
filtersStore.$patch({
136+
chips: { status: [{ id: 1, text: 'Signed', onclick: () => {} }] },
137+
})
138+
await wrapper.vm.$nextTick()
139+
140+
expect(wrapper.find('ul').exists()).toBe(true)
141+
expect(wrapper.findAll('.nc-chip-stub')).toHaveLength(1)
142+
})
143+
144+
it('reactively hides chips when store becomes empty after mount', async () => {
145+
const filtersStore = useFiltersStore()
146+
filtersStore.$patch({
147+
chips: { status: [{ id: 1, text: 'Signed', onclick: () => {} }] },
148+
})
149+
150+
const wrapper = mountComponent()
151+
expect(wrapper.find('ul').exists()).toBe(true)
152+
153+
// Clear chips — use callback to replace (not merge) the chips object
154+
filtersStore.$patch((state: typeof filtersStore.$state) => { state.chips = {} })
155+
await wrapper.vm.$nextTick()
156+
157+
expect(wrapper.find('ul').exists()).toBe(false)
158+
})
159+
})

0 commit comments

Comments
 (0)