Skip to content

Commit 4f4d078

Browse files
committed
Fix project scoped network filtering
1 parent 7ea1dca commit 4f4d078

3 files changed

Lines changed: 174 additions & 1 deletion

File tree

ui/src/views/compute/wizard/MultiNetworkSelection.vue

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ export default {
107107
type: String,
108108
default: ''
109109
},
110+
projectid: {
111+
type: String,
112+
default: ''
113+
},
110114
selectionEnabled: {
111115
type: Boolean,
112116
default: true
@@ -194,6 +198,9 @@ export default {
194198
zoneId () {
195199
this.fetchNetworks()
196200
},
201+
projectid () {
202+
this.fetchNetworks()
203+
},
197204
account () {
198205
clearTimeout(this.accountNetworkUpdateTimer)
199206
this.accountNetworkUpdateTimer = setTimeout(() => {
@@ -217,7 +224,9 @@ export default {
217224
zoneid: this.zoneId,
218225
listall: true
219226
}
220-
if (this.domainid && this.account) {
227+
if (this.projectid) {
228+
params.projectid = this.projectid
229+
} else if (this.domainid && this.account) {
221230
params.domainid = this.domainid
222231
params.account = this.account
223232
}

ui/src/views/tools/ImportUnmanagedInstance.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@
369369
:zoneId="cluster.zoneid"
370370
:domainid="form.domainid"
371371
:account="form.account"
372+
:projectid="form.projectid"
372373
:selectionEnabled="false"
373374
:filterUnimplementedNetworks="true"
374375
:hypervisor="this.cluster.hypervisortype"
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
import { flushPromises } from '@vue/test-utils'
19+
20+
import mockAxios from '../../../mock/mockAxios'
21+
import common from '../../../common'
22+
import MultiNetworkSelection from '@/views/compute/wizard/MultiNetworkSelection'
23+
24+
jest.mock('axios', () => mockAxios)
25+
jest.mock('@/vue-app', () => ({
26+
vueProps: {
27+
$localStorage: {
28+
set: jest.fn(),
29+
get: jest.fn(() => null)
30+
}
31+
}
32+
}))
33+
34+
let router
35+
let i18n
36+
let store
37+
let wrapper
38+
39+
const factory = (opts = {}) => {
40+
return common.createFactory(MultiNetworkSelection, {
41+
router,
42+
i18n,
43+
store,
44+
props: opts.props || {},
45+
data: opts.data || {}
46+
})
47+
}
48+
49+
describe('Components > Compute > MultiNetworkSelection.vue', () => {
50+
beforeEach(() => {
51+
jest.clearAllMocks()
52+
53+
router = common.createMockRouter({})
54+
i18n = common.createMockI18n('en', {})
55+
store = common.createMockStore()
56+
57+
mockAxios.mockResolvedValue({
58+
listnetworksresponse: {
59+
count: 0,
60+
network: []
61+
}
62+
})
63+
})
64+
65+
afterEach(() => {
66+
if (wrapper) {
67+
wrapper.unmount()
68+
wrapper = null
69+
}
70+
})
71+
72+
describe('fetchNetworks()', () => {
73+
it('API should be called with projectid when project scope is selected', async () => {
74+
wrapper = factory({
75+
props: {
76+
items: [],
77+
zoneId: 'zone-1',
78+
domainid: 'domain-1',
79+
account: 'account-1',
80+
projectid: 'project-1'
81+
}
82+
})
83+
84+
await wrapper.vm.fetchNetworks()
85+
await flushPromises()
86+
87+
expect(mockAxios).toHaveBeenLastCalledWith(
88+
expect.objectContaining({
89+
url: '/',
90+
method: 'GET',
91+
params: expect.objectContaining({
92+
command: 'listNetworks',
93+
zoneid: 'zone-1',
94+
listall: true,
95+
projectid: 'project-1'
96+
})
97+
})
98+
)
99+
100+
const request = mockAxios.mock.calls[mockAxios.mock.calls.length - 1][0]
101+
102+
expect(request.params).not.toHaveProperty('account')
103+
expect(request.params).not.toHaveProperty('domainid')
104+
})
105+
106+
it('API should be called with domainid and account when project scope is not selected', async () => {
107+
wrapper = factory({
108+
props: {
109+
items: [],
110+
zoneId: 'zone-1',
111+
domainid: 'domain-1',
112+
account: 'account-1',
113+
projectid: ''
114+
}
115+
})
116+
117+
await wrapper.vm.fetchNetworks()
118+
await flushPromises()
119+
120+
expect(mockAxios).toHaveBeenLastCalledWith(
121+
expect.objectContaining({
122+
url: '/',
123+
method: 'GET',
124+
params: expect.objectContaining({
125+
command: 'listNetworks',
126+
zoneid: 'zone-1',
127+
listall: true,
128+
domainid: 'domain-1',
129+
account: 'account-1'
130+
})
131+
})
132+
)
133+
134+
const request = mockAxios.mock.calls[mockAxios.mock.calls.length - 1][0]
135+
136+
expect(request.params).not.toHaveProperty('projectid')
137+
})
138+
})
139+
140+
describe('projectid watcher', () => {
141+
it('should refresh networks when project changes', async () => {
142+
wrapper = factory({
143+
props: {
144+
items: [],
145+
zoneId: 'zone-1',
146+
projectid: 'project-1'
147+
}
148+
})
149+
150+
await flushPromises()
151+
152+
mockAxios.mockClear()
153+
154+
await wrapper.setProps({
155+
projectid: 'project-2'
156+
})
157+
158+
await flushPromises()
159+
160+
expect(mockAxios).toHaveBeenCalled()
161+
})
162+
})
163+
})

0 commit comments

Comments
 (0)