Skip to content

Commit 58c7ba6

Browse files
committed
tests(front): cover UserView
1 parent c3ce08e commit 58c7ba6

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import { describe, test, expect, beforeEach, vi } from 'vitest'
2+
import { mount } from '@vue/test-utils'
3+
import { RouterLink } from 'vue-router'
4+
import UserView from '@/views/UserView.vue'
5+
import { init_plugins, getMockClusterDataPoller } from '../lib/common'
6+
import { useRuntimeStore } from '@/stores/runtime'
7+
import type { ClusterAssociation } from '@/composables/GatewayAPI'
8+
import associations from '../assets/associations.json'
9+
import ErrorAlert from '@/components/ErrorAlert.vue'
10+
import InfoAlert from '@/components/InfoAlert.vue'
11+
import LoadingSpinner from '@/components/LoadingSpinner.vue'
12+
import AccountBreadcrumb from '@/components/accounts/AccountBreadcrumb.vue'
13+
14+
const mockClusterDataPoller = getMockClusterDataPoller<ClusterAssociation[]>()
15+
16+
vi.mock('@/composables/DataPoller', () => ({
17+
useClusterDataPoller: () => mockClusterDataPoller
18+
}))
19+
20+
describe('UserView.vue', () => {
21+
beforeEach(() => {
22+
init_plugins()
23+
useRuntimeStore().availableClusters = [
24+
{
25+
name: 'foo',
26+
permissions: { roles: [], actions: [] },
27+
racksdb: true,
28+
infrastructure: 'foo',
29+
metrics: true,
30+
cache: true
31+
}
32+
]
33+
mockClusterDataPoller.data.value = undefined
34+
mockClusterDataPoller.unable.value = false
35+
mockClusterDataPoller.loaded.value = false
36+
})
37+
38+
test('displays user details', () => {
39+
mockClusterDataPoller.loaded.value = true
40+
mockClusterDataPoller.data.value = associations as ClusterAssociation[]
41+
42+
const wrapper = mount(UserView, {
43+
props: {
44+
cluster: 'foo',
45+
user: 'root'
46+
}
47+
})
48+
49+
// Back to accounts button
50+
const buttons = wrapper.findAll('button')
51+
const backButton = buttons.find((btn) => btn.text().includes('Back to accounts'))
52+
expect(backButton).toBeDefined()
53+
54+
// User heading
55+
const userHeading = wrapper.get('div#user-heading')
56+
expect(userHeading.text()).toContain('User root')
57+
58+
// root is associated with root account only
59+
expect(userHeading.text()).toContain('1')
60+
expect(userHeading.text()).toContain('account associated')
61+
62+
// View jobs link
63+
const viewJobsLink = userHeading.getComponent(RouterLink)
64+
expect(viewJobsLink.props('to')).toEqual({
65+
name: 'jobs',
66+
params: { cluster: 'foo' },
67+
query: { users: 'root' }
68+
})
69+
70+
// User associations table
71+
const userAssociationsTable = wrapper.get('table')
72+
73+
// Column headers
74+
const columnHeaders = userAssociationsTable.get('thead').findAll('th')
75+
expect(columnHeaders[0].text()).toBe('Account')
76+
expect(columnHeaders[1].text()).toBe('Job limits')
77+
expect(columnHeaders[2].text()).toBe('Resource limits')
78+
expect(columnHeaders[3].text()).toBe('Time limits')
79+
expect(columnHeaders[4].text()).toBe('QOS')
80+
expect(userAssociationsTable.findAll('tbody tr').length).toBeGreaterThan(0)
81+
82+
// Check presence of breadcrumbs
83+
const breadcrumbs = userAssociationsTable.findAllComponents(AccountBreadcrumb)
84+
expect(breadcrumbs.length).toBeGreaterThan(0)
85+
})
86+
87+
test('shows loading spinner when data is not loaded', () => {
88+
mockClusterDataPoller.loaded.value = false
89+
90+
const wrapper = mount(UserView, {
91+
props: {
92+
cluster: 'foo',
93+
user: 'root'
94+
}
95+
})
96+
97+
expect(wrapper.findComponent(LoadingSpinner).exists()).toBe(true)
98+
expect(wrapper.text()).toContain('Loading user details...')
99+
})
100+
101+
test('shows error alert when unable to retrieve associations', () => {
102+
mockClusterDataPoller.unable.value = true
103+
mockClusterDataPoller.loaded.value = true
104+
105+
const wrapper = mount(UserView, {
106+
props: {
107+
cluster: 'foo',
108+
user: 'root'
109+
}
110+
})
111+
112+
const errorAlert = wrapper.findComponent(ErrorAlert)
113+
expect(errorAlert.exists()).toBe(true)
114+
expect(errorAlert.text()).toContain('Unable to retrieve associations for cluster')
115+
expect(errorAlert.text()).toContain('foo')
116+
})
117+
118+
test('shows info alert when user has no associations', () => {
119+
mockClusterDataPoller.loaded.value = true
120+
mockClusterDataPoller.data.value = []
121+
122+
const wrapper = mount(UserView, {
123+
props: {
124+
cluster: 'foo',
125+
user: 'nonexistent'
126+
}
127+
})
128+
129+
const infoAlert = wrapper.findComponent(InfoAlert)
130+
expect(infoAlert.exists()).toBe(true)
131+
expect(infoAlert.text()).toContain('User nonexistent has no associations on this cluster')
132+
})
133+
})

0 commit comments

Comments
 (0)