Skip to content

Commit 5c84da8

Browse files
test(vue3): add FileStatusList coverage
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 931661c commit 5c84da8

1 file changed

Lines changed: 168 additions & 0 deletions

File tree

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 LibreCode coop and 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+
9+
import FileStatusList from '../../components/FileStatusList.vue'
10+
11+
const axiosGetMock = vi.fn()
12+
13+
vi.mock('@nextcloud/l10n', () => ({
14+
t: vi.fn((_app: string, text: string) => text),
15+
n: vi.fn((_app: string, singular: string, plural: string, count: number) => (count === 1 ? singular : plural)),
16+
}))
17+
18+
vi.mock('@nextcloud/files', () => ({
19+
formatFileSize: vi.fn((size: number) => `${size}B`),
20+
}))
21+
22+
vi.mock('@nextcloud/moment', () => ({
23+
default: vi.fn((value: string) => ({
24+
calendar: vi.fn(() => `calendar:${value}`),
25+
})),
26+
}))
27+
28+
vi.mock('@nextcloud/axios', () => ({
29+
default: {
30+
get: vi.fn((...args: unknown[]) => axiosGetMock(...args)),
31+
},
32+
}))
33+
34+
vi.mock('@nextcloud/router', () => ({
35+
generateOcsUrl: vi.fn((path: string) => `/ocs/v2.php${path}`),
36+
}))
37+
38+
vi.mock('../../utils/fileStatus.js', () => ({
39+
getStatusLabel: vi.fn((status: number) => `status:${status}`),
40+
getStatusIcon: vi.fn((status: number) => `icon:${status}`),
41+
}))
42+
43+
vi.mock('../../constants.js', () => ({
44+
FILE_STATUS: {
45+
NOT_LIBRESIGN_FILE: 0,
46+
DRAFT: 0,
47+
ABLE_TO_SIGN: 1,
48+
PARTIAL_SIGNED: 2,
49+
SIGNED: 3,
50+
DELETED: 4,
51+
SIGNING_IN_PROGRESS: 5,
52+
},
53+
}))
54+
55+
vi.mock('@nextcloud/vue/components/NcEmptyContent', () => ({
56+
default: {
57+
name: 'NcEmptyContent',
58+
props: ['name'],
59+
template: '<div class="nc-empty-content-stub">{{ name }}</div>',
60+
},
61+
}))
62+
63+
vi.mock('@nextcloud/vue/components/NcIconSvgWrapper', () => ({
64+
default: {
65+
name: 'NcIconSvgWrapper',
66+
template: '<i class="nc-icon-svg-wrapper-stub" />',
67+
},
68+
}))
69+
70+
describe('FileStatusList.vue', () => {
71+
const createWrapper = (props: { fileIds?: number[]; updateInterval?: number } = {}) => mount(FileStatusList, {
72+
props: {
73+
fileIds: [],
74+
updateInterval: 2000,
75+
...props,
76+
},
77+
})
78+
79+
beforeEach(() => {
80+
vi.useRealTimers()
81+
axiosGetMock.mockReset()
82+
axiosGetMock.mockResolvedValue({
83+
data: {
84+
ocs: {
85+
data: {
86+
data: [],
87+
},
88+
},
89+
},
90+
})
91+
})
92+
93+
it('renders the empty state when there are no files to show', () => {
94+
const wrapper = createWrapper()
95+
96+
expect(wrapper.find('.empty-state').exists()).toBe(true)
97+
expect(wrapper.find('.nc-empty-content-stub').text()).toBe('No files to sign')
98+
})
99+
100+
it('loads the requested files and emits files-updated', async () => {
101+
axiosGetMock.mockResolvedValueOnce({
102+
data: {
103+
ocs: {
104+
data: {
105+
data: [
106+
{ id: 1, uuid: 'a', name: 'contract-a.pdf', size: 100, status: 1 },
107+
{ id: 2, uuid: 'b', name: 'contract-b.pdf', size: 250, status: 3 },
108+
],
109+
},
110+
},
111+
},
112+
})
113+
114+
const wrapper = createWrapper({ fileIds: [2, 1] })
115+
await wrapper.vm.loadFiles()
116+
117+
expect(axiosGetMock).toHaveBeenCalledWith('/ocs/v2.php/apps/libresign/api/v1/file/list', { timeout: 10000 })
118+
expect(wrapper.vm.files.map((file: { id: number }) => file.id)).toEqual([2, 1])
119+
expect(wrapper.emitted('files-updated')?.at(-1)?.[0]).toEqual(wrapper.vm.files)
120+
})
121+
122+
it('emits file-signed only for newly signed files', async () => {
123+
axiosGetMock.mockResolvedValue({
124+
data: {
125+
ocs: {
126+
data: {
127+
data: [
128+
{ id: 1, uuid: 'a', name: 'contract-a.pdf', size: 100, status: 3 },
129+
],
130+
},
131+
},
132+
},
133+
})
134+
135+
const wrapper = createWrapper({ fileIds: [1] })
136+
await wrapper.vm.loadFiles()
137+
await wrapper.vm.loadFiles()
138+
139+
expect(wrapper.emitted('file-signed')).toHaveLength(1)
140+
expect(wrapper.emitted('file-signed')?.[0]?.[0]).toMatchObject({ id: 1, status: 3 })
141+
})
142+
143+
it('starts and stops polling with the configured interval', async () => {
144+
vi.useFakeTimers()
145+
axiosGetMock.mockResolvedValue({
146+
data: {
147+
ocs: {
148+
data: {
149+
data: [{ id: 1, uuid: 'a', name: 'contract-a.pdf', size: 100, status: 0 }],
150+
},
151+
},
152+
},
153+
})
154+
155+
const wrapper = createWrapper({ fileIds: [1], updateInterval: 1500 })
156+
const loadFilesSpy = vi.spyOn(wrapper.vm, 'loadFiles')
157+
158+
wrapper.vm.startUpdatePolling()
159+
vi.advanceTimersByTime(1500)
160+
161+
expect(loadFilesSpy).toHaveBeenCalled()
162+
expect(wrapper.vm.updatePollingInterval).toBeTruthy()
163+
164+
wrapper.vm.stopUpdatePolling()
165+
166+
expect(wrapper.vm.updatePollingInterval).toBeNull()
167+
})
168+
})

0 commit comments

Comments
 (0)