diff --git a/ui/src/components/view/VolumesTab.vue b/ui/src/components/view/VolumesTab.vue index 8bb8c0bb88fa..b0a4e799ea4a 100644 --- a/ui/src/components/view/VolumesTab.vue +++ b/ui/src/components/view/VolumesTab.vue @@ -132,7 +132,7 @@ export default { } }, getVolumes () { - getAPI('listVolumes', { listall: true, listsystemvms: true, virtualmachineid: this.vm.id }).then(json => { + getAPI('listVolumes', { listall: true, listsystemvms: true, projectid: '-1', virtualmachineid: this.vm.id }).then(json => { this.volumes = json.listvolumesresponse.volume if (this.volumes) { this.volumes.sort((a, b) => { return a.deviceid - b.deviceid }) diff --git a/ui/tests/unit/components/view/VolumesTab.spec.js b/ui/tests/unit/components/view/VolumesTab.spec.js index 6c333453ffb5..78479b1d1f0a 100644 --- a/ui/tests/unit/components/view/VolumesTab.spec.js +++ b/ui/tests/unit/components/view/VolumesTab.spec.js @@ -15,16 +15,62 @@ // specific language governing permissions and limitations // under the License. +import { createServer } from 'http' import { flushPromises } from '@vue/test-utils' import common from '../../../common' import VolumesTab from '@/components/view/VolumesTab.vue' +import { axios } from '@/utils/request' +import { CURRENT_PROJECT } from '@/store/mutation-types' +import { vueProps } from '@/vue-app' + +jest.mock('@/vue-app', () => ({ + vueProps: { + $localStorage: { + get: jest.fn(() => null) + } + } +})) const router = common.createMockRouter() const i18n = common.createMockI18n('en') +const projectVm = { id: 'vm-1', projectid: 'project-1' } +const accountVm = { id: 'vm-2' } +const systemVm = { id: 'vm-3', systemvmtype: 'secondarystoragevm' } +let requests = [] +const server = createServer((request, response) => { + const params = Object.fromEntries(new URL(request.url, 'http://localhost').searchParams) + requests.push(params) + const vm = [projectVm, accountVm, systemVm].find(vm => vm.id === params.virtualmachineid) + const volume = vm && ( + (params.projectid === '-1' && params.listall === 'true') || + params.projectid === vm.projectid + ) + ? [ + { id: 'data-volume', name: 'Data volume', deviceid: 1 }, + { id: 'root-volume', name: 'Root volume', deviceid: 0 } + ] + : [] + response.setHeader('Content-Type', 'application/json') + response.end(JSON.stringify({ listvolumesresponse: { count: volume.length, volume } })) +}) describe('Components > View > VolumesTab.vue', () => { + beforeAll(async () => { + await new Promise((resolve, reject) => { + server.once('error', reject) + server.listen(0, '127.0.0.1', resolve) + }) + axios.defaults.baseURL = `http://127.0.0.1:${server.address().port}` + axios.defaults.adapter = require('axios/lib/adapters/http') + }) + + afterAll(() => new Promise(resolve => server.close(resolve))) + beforeEach(() => { + requests = [] + jest.clearAllMocks() + vueProps.$localStorage.get.mockReturnValue(null) jest.spyOn(console, 'warn').mockImplementation(() => {}) }) @@ -52,7 +98,58 @@ describe('Components > View > VolumesTab.vue', () => { expect(wrapper.text()).toContain('2.00 GiB') expect(wrapper.text()).not.toContain('2.00 GB') + expect(requests).toHaveLength(0) wrapper.unmount() }) + + it.each([ + ['project instance in Default view', projectVm, null], + ['project instance in its project', projectVm, projectVm.projectid], + ['project instance in another project', projectVm, 'project-2'], + ['account instance in Default view', accountVm, null], + ['account instance in another project', accountVm, 'project-2'], + ['system VM in Default view', systemVm, null], + ['system VM in another project', systemVm, 'project-2'] + ])('shows volume rows for %s', async (name, resource, selectedProjectId) => { + vueProps.$localStorage.get.mockImplementation(key => { + return key === CURRENT_PROJECT && selectedProjectId ? { id: selectedProjectId } : null + }) + let interceptor + const response = new Promise((resolve, reject) => { + interceptor = axios.interceptors.response.use(data => { + resolve(data) + return data + }, error => { + reject(error) + return Promise.reject(error) + }) + }) + const wrapper = common.createFactory(VolumesTab, { + router, + i18n, + props: { resource } + }) + + try { + await response + await flushPromises() + + expect(wrapper.findAll('tbody tr[data-row-key]')).toHaveLength(2) + expect(requests).toEqual([{ + command: 'listVolumes', + response: 'json', + listall: 'true', + listsystemvms: 'true', + projectid: '-1', + virtualmachineid: resource.id + }]) + expect(wrapper.vm.volumes.map(volume => volume.id)).toEqual(['root-volume', 'data-volume']) + expect(wrapper.text()).toContain('Root volume') + expect(wrapper.text()).toContain('Data volume') + } finally { + wrapper.unmount() + axios.interceptors.response.eject(interceptor) + } + }) })