Skip to content

Commit dc61527

Browse files
committed
script preview unit tests
1 parent 2dc27fe commit dc61527

1 file changed

Lines changed: 177 additions & 0 deletions

File tree

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import { mount } from '@vue/test-utils'
2+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
3+
4+
import ScriptPreview from '@/components/ScriptPreview.vue'
5+
6+
const { mockOpen, mockOnChange } = vi.hoisted(() => ({
7+
mockOpen: vi.fn(),
8+
mockOnChange: vi.fn(),
9+
}))
10+
11+
vi.mock('@vueuse/core', async (importOriginal) => {
12+
const vueuse = await importOriginal<typeof import('@vueuse/core')>()
13+
return {
14+
...vueuse,
15+
useFileDialog: () => ({
16+
open: mockOpen,
17+
onChange: mockOnChange,
18+
}),
19+
}
20+
})
21+
22+
describe('ScriptPreview', () => {
23+
const defaultProps = {
24+
highlightedScriptHtml: '<span class="MOCK">mOCk</span>',
25+
isLoading: false,
26+
showCopySuccess: false,
27+
}
28+
29+
beforeEach(() => {
30+
vi.clearAllMocks()
31+
vi.spyOn(window, 'confirm').mockImplementation(() => true)
32+
})
33+
34+
afterEach(() => {
35+
vi.restoreAllMocks()
36+
})
37+
38+
it('renders script html', () => {
39+
const wrapper = mount(ScriptPreview, { props: defaultProps })
40+
expect(wrapper.html()).toContain(defaultProps.highlightedScriptHtml)
41+
})
42+
43+
describe('copy button', () => {
44+
it('emits copyPermalink', async () => {
45+
const wrapper = mount(ScriptPreview, { props: defaultProps })
46+
47+
const copyButton = wrapper.findAll('button').find((b) => b.text().includes('Permalink'))
48+
expect(copyButton).not.toBeFalsy()
49+
expect(copyButton?.classes()).toContain('btn-info')
50+
51+
await copyButton?.trigger('click')
52+
53+
expect(wrapper.emitted('copyPermalink')).toBeTruthy()
54+
})
55+
56+
it('shows copy success text when showCopySuccess is true', () => {
57+
const wrapper = mount(ScriptPreview, {
58+
props: { ...defaultProps, showCopySuccess: true },
59+
})
60+
61+
const copyButton = wrapper.findAll('button').find((b) => b.text().includes('Copied!'))
62+
expect(copyButton).not.toBeFalsy()
63+
expect(copyButton?.classes()).toContain('btn-success')
64+
})
65+
})
66+
67+
describe('download button', () => {
68+
it('emits download', async () => {
69+
const wrapper = mount(ScriptPreview, { props: defaultProps })
70+
71+
const downloadButton = wrapper.findAll('button').find((b) => b.text().includes('Download'))
72+
expect(downloadButton).not.toBeFalsy()
73+
74+
await downloadButton?.trigger('click')
75+
76+
expect(wrapper.emitted('download')).toBeTruthy()
77+
})
78+
79+
it('disables the download button when loading', () => {
80+
const wrapper = mount(ScriptPreview, {
81+
props: { ...defaultProps, isLoading: true },
82+
})
83+
84+
const downloadButton = wrapper.findAll('button').find((b) => b.text().includes('Download'))
85+
expect(downloadButton).not.toBeFalsy()
86+
expect(downloadButton?.attributes()).toHaveProperty('disabled')
87+
})
88+
})
89+
90+
describe('import button', () => {
91+
it('opens file picker when import script clicked', async () => {
92+
const wrapper = mount(ScriptPreview, { props: defaultProps })
93+
94+
const importButton = wrapper.findAll('button').find((b) => b.text().includes('Import Script'))
95+
expect(importButton).not.toBeFalsy()
96+
await importButton?.trigger('click')
97+
98+
expect(mockOpen).toHaveBeenCalledOnce()
99+
})
100+
101+
it('emits importScript with file', () => {
102+
const wrapper = mount(ScriptPreview, { props: defaultProps })
103+
104+
const callback = mockOnChange.mock.calls[0][0]
105+
const file = new File(['echo mock'], 'fun.sh')
106+
107+
callback([file])
108+
109+
expect(window.confirm).toHaveBeenCalledWith(
110+
'Importing a script will overwrite all of your current config. Are you sure?',
111+
)
112+
expect(wrapper.emitted('importScript')).toBeTruthy()
113+
expect(wrapper.emitted('importScript')?.[0]).toEqual([file])
114+
})
115+
116+
it('doesnt emit importScript if confirm is cancelled', () => {
117+
vi.spyOn(window, 'confirm').mockImplementation(() => false)
118+
119+
const wrapper = mount(ScriptPreview, { props: defaultProps })
120+
const callback = mockOnChange.mock.calls[0][0]
121+
122+
callback([new File([''], 'cool.sh')])
123+
124+
expect(window.confirm).toHaveBeenCalled()
125+
expect(wrapper.emitted('importScript')).toBeUndefined()
126+
})
127+
128+
it('does nothing when no files are given', () => {
129+
const wrapper = mount(ScriptPreview, { props: defaultProps })
130+
const callback = mockOnChange.mock.calls[0][0]
131+
132+
callback([])
133+
callback(null)
134+
135+
expect(window.confirm).not.toHaveBeenCalled()
136+
expect(wrapper.emitted('importScript')).toBeUndefined()
137+
})
138+
})
139+
140+
describe('validation errors', () => {
141+
it('has no error content when no errors are present', () => {
142+
const wrapper = mount(ScriptPreview, {
143+
props: { ...defaultProps, validationErrors: {} },
144+
})
145+
146+
expect(wrapper.find('.alert-error').exists()).toBe(false)
147+
148+
const downloadButton = wrapper.findAll('button').find((b) => b.text().includes('Download'))
149+
expect(downloadButton!.attributes()).not.toHaveProperty('disabled')
150+
})
151+
152+
it('shows errors and disables download button properly', () => {
153+
const wrapper = mount(ScriptPreview, {
154+
props: {
155+
...defaultProps,
156+
validationErrors: {
157+
one: 'evil error',
158+
two: 'bad error',
159+
},
160+
},
161+
})
162+
163+
const errors = wrapper.findAll('.alert-error')
164+
expect(errors).toHaveLength(2)
165+
expect(errors[0].text()).toContain('Configuration Error: evil error')
166+
expect(errors[1].text()).toContain('Configuration Error: bad error')
167+
168+
const downloadButton = wrapper.findAll('button').find((b) => b.text().includes('Download'))
169+
expect(downloadButton!.attributes()).toHaveProperty('disabled')
170+
171+
const downloadTooltip = wrapper.findAll('.tooltip').find((t) => t.html().includes('Download'))
172+
expect(downloadTooltip!.attributes('data-tip')).toBe(
173+
'Fix configuration errors to download script',
174+
)
175+
})
176+
})
177+
})

0 commit comments

Comments
 (0)