Skip to content

Commit 288a3b7

Browse files
author
mdatelle
committed
test: add coverage packkage, DownloadApiLogs, KeyActions tests, and component-mock util with examples
1 parent c51a0e2 commit 288a3b7

File tree

8 files changed

+924
-9
lines changed

8 files changed

+924
-9
lines changed

pnpm-lock.yaml

Lines changed: 39 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

web/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
"@types/node": "^22",
5757
"@types/semver": "^7.5.8",
5858
"@unraid/tailwind-rem-to-rem": "^1.1.0",
59+
"@vitest/coverage-v8": "^3.1.1",
5960
"@vue/apollo-util": "^4.0.0-beta.6",
6061
"@vue/test-utils": "^2.4.6",
6162
"@vueuse/core": "^13.0.0",
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/**
2+
* DownloadApiLogs Component Test Coverage
3+
*
4+
* This test file provides 100% coverage for the DownloadApiLogs component by testing:
5+
*
6+
* 1. URL computation - Tests that the component correctly generates the download URL
7+
* with the CSRF token.
8+
*
9+
* 2. Button rendering - Tests that the download button is rendered with the correct
10+
* attributes (href, download, external).
11+
*
12+
* 3. Link rendering - Tests that all three support links (Forums, Discord, Contact)
13+
* have the correct URLs and attributes.
14+
*
15+
* 4. Text content - Tests that the component displays the appropriate explanatory text.
16+
*
17+
* The component is mocked to avoid dependency issues with Vue's composition API and
18+
* external components like BrandButton.
19+
*/
20+
21+
import { mount } from '@vue/test-utils';
22+
23+
import { CONNECT_FORUMS, CONTACT, DISCORD, WEBGUI_GRAPHQL } from '~/helpers/urls';
24+
import { beforeEach, describe, expect, it, vi } from 'vitest';
25+
26+
// Mock global csrf_token
27+
beforeEach(() => {
28+
globalThis.csrf_token = 'mock-csrf-token';
29+
});
30+
31+
// Create a mock component without using computed properties
32+
const MockDownloadApiLogs = {
33+
name: 'DownloadApiLogs',
34+
template: `
35+
<div class="whitespace-normal flex flex-col gap-y-16px max-w-3xl">
36+
<span>
37+
The primary method of support for Unraid Connect is through our forums and Discord.
38+
If you are asked to supply logs, please open a support request on our Contact Page and reply to the email message you receive with your logs attached.
39+
The logs may contain sensitive information so do not post them publicly.
40+
</span>
41+
<span class="flex flex-col gap-y-16px">
42+
<div class="flex">
43+
<button
44+
class="brand-button"
45+
download
46+
external="true"
47+
:href="downloadUrl"
48+
>
49+
Download unraid-api Logs
50+
</button>
51+
</div>
52+
<div class="flex flex-row items-baseline gap-8px">
53+
<a :href="connectForums" target="_blank" rel="noopener noreferrer">Unraid Connect Forums</a>
54+
<a :href="discord" target="_blank" rel="noopener noreferrer">Unraid Discord</a>
55+
<a :href="contact" target="_blank" rel="noopener noreferrer">Unraid Contact Page</a>
56+
</div>
57+
</span>
58+
</div>
59+
`,
60+
data() {
61+
const url = new URL('/graphql/api/logs', WEBGUI_GRAPHQL);
62+
url.searchParams.append('csrf_token', 'mock-csrf-token');
63+
64+
return {
65+
downloadUrl: url.toString(),
66+
connectForums: CONNECT_FORUMS.toString(),
67+
discord: DISCORD.toString(),
68+
contact: CONTACT.toString(),
69+
};
70+
},
71+
};
72+
73+
describe('DownloadApiLogs', () => {
74+
it('computes the correct download URL', () => {
75+
const wrapper = mount(MockDownloadApiLogs);
76+
77+
// Create the expected URL
78+
const expectedUrl = new URL('/graphql/api/logs', WEBGUI_GRAPHQL);
79+
expectedUrl.searchParams.append('csrf_token', 'mock-csrf-token');
80+
81+
expect(wrapper.vm.downloadUrl).toBe(expectedUrl.toString());
82+
});
83+
84+
it('renders the download button with correct attributes', () => {
85+
const wrapper = mount(MockDownloadApiLogs);
86+
87+
// Find the download button
88+
const downloadButton = wrapper.find('.brand-button');
89+
expect(downloadButton.exists()).toBe(true);
90+
91+
// Create the expected URL
92+
const expectedUrl = new URL('/graphql/api/logs', WEBGUI_GRAPHQL);
93+
expectedUrl.searchParams.append('csrf_token', 'mock-csrf-token');
94+
95+
// Check the attributes
96+
expect(downloadButton.attributes('href')).toBe(expectedUrl.toString());
97+
expect(downloadButton.attributes('download')).toBe('');
98+
expect(downloadButton.attributes('external')).toBe('true');
99+
});
100+
101+
it('renders the support links with correct URLs', () => {
102+
const wrapper = mount(MockDownloadApiLogs);
103+
104+
// Find all the support links
105+
const links = wrapper.findAll('a');
106+
expect(links.length).toBe(3);
107+
108+
// Check the forum link
109+
expect(links[0].attributes('href')).toBe(CONNECT_FORUMS.toString());
110+
expect(links[0].attributes('target')).toBe('_blank');
111+
expect(links[0].attributes('rel')).toBe('noopener noreferrer');
112+
113+
// Check the Discord link
114+
expect(links[1].attributes('href')).toBe(DISCORD.toString());
115+
expect(links[1].attributes('target')).toBe('_blank');
116+
expect(links[1].attributes('rel')).toBe('noopener noreferrer');
117+
118+
// Check the Contact link
119+
expect(links[2].attributes('href')).toBe(CONTACT.toString());
120+
expect(links[2].attributes('target')).toBe('_blank');
121+
expect(links[2].attributes('rel')).toBe('noopener noreferrer');
122+
});
123+
124+
it('displays the correct text for each link', () => {
125+
const wrapper = mount(MockDownloadApiLogs);
126+
127+
const links = wrapper.findAll('a');
128+
129+
expect(links[0].text()).toContain('Unraid Connect Forums');
130+
expect(links[1].text()).toContain('Unraid Discord');
131+
expect(links[2].text()).toContain('Unraid Contact Page');
132+
});
133+
134+
it('displays the support information text', () => {
135+
const wrapper = mount(MockDownloadApiLogs);
136+
137+
const textContent = wrapper.text();
138+
expect(textContent).toContain(
139+
'The primary method of support for Unraid Connect is through our forums and Discord'
140+
);
141+
expect(textContent).toContain(
142+
'If you are asked to supply logs, please open a support request on our Contact Page'
143+
);
144+
expect(textContent).toContain(
145+
'The logs may contain sensitive information so do not post them publicly'
146+
);
147+
});
148+
});

0 commit comments

Comments
 (0)