mirror of https://github.com/rancher/dashboard.git
Merge pull request #10435 from richard-cox/optimise-branding-apps-fetch
Fetch only specific csp adapter helm apps... instead of all helm apps
This commit is contained in:
commit
fd92fbe93c
|
|
@ -0,0 +1,170 @@
|
|||
import { mount } from '@vue/test-utils';
|
||||
import { CATALOG, MANAGEMENT } from '@shell/config/types';
|
||||
import Brand from '@shell/mixins/brand';
|
||||
|
||||
describe('brandMixin', () => {
|
||||
const createWrapper = (vaiOn = false) => {
|
||||
const Component = {
|
||||
template: '<div></div>',
|
||||
mixins: [Brand],
|
||||
};
|
||||
|
||||
const data = {
|
||||
apps: null, haveAppsAndSettings: null, canPaginate: false
|
||||
};
|
||||
|
||||
const store = {
|
||||
dispatch: (action, ...args) => {
|
||||
switch (action) {
|
||||
case 'management/findAll':
|
||||
if (args[0] === MANAGEMENT.SETTING) {
|
||||
return [];
|
||||
}
|
||||
if (args[0] === CATALOG.APP) {
|
||||
return [];
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
'auth/loggedIn': () => true,
|
||||
'auth/fromHeader': () => false,
|
||||
'management/byId': () => undefined,
|
||||
'management/canList': () => () => true,
|
||||
'management/schemaFor': (type: string) => {
|
||||
switch (type) {
|
||||
case MANAGEMENT.SETTING:
|
||||
return { linkFor: () => undefined };
|
||||
}
|
||||
},
|
||||
'management/generation': () => undefined,
|
||||
'management/paginationEnabled': () => vaiOn,
|
||||
'management/all': (type: string) => {
|
||||
switch (type) {
|
||||
case MANAGEMENT.SETTING:
|
||||
return [];
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
const wrapper = mount(
|
||||
Component,
|
||||
{
|
||||
data: () => data,
|
||||
global: { mocks: { $store: store } }
|
||||
});
|
||||
const spyManagementFindAll = jest.spyOn(store, 'dispatch');
|
||||
|
||||
return {
|
||||
wrapper,
|
||||
store,
|
||||
spyManagementFindAll,
|
||||
};
|
||||
};
|
||||
|
||||
describe('should make correct requests', () => {
|
||||
it('vai off', async() => {
|
||||
const { wrapper, spyManagementFindAll } = createWrapper(false);
|
||||
|
||||
// NOTE - wrapper.vm.$options.fetch() doesn't work
|
||||
await wrapper.vm.$options.fetch.apply(wrapper.vm);
|
||||
|
||||
// wrapper.vm.$nextTick();
|
||||
expect(spyManagementFindAll).toHaveBeenNthCalledWith(1, 'management/findAll', {
|
||||
type: MANAGEMENT.SETTING,
|
||||
opt: {
|
||||
load: 'multi', redirectUnauthorized: false, url: `/v1/${ MANAGEMENT.SETTING }s`
|
||||
}
|
||||
});
|
||||
expect(spyManagementFindAll).toHaveBeenNthCalledWith(2, 'management/findAll', { type: CATALOG.APP });
|
||||
});
|
||||
|
||||
it('vai on', async() => {
|
||||
const { wrapper, spyManagementFindAll } = createWrapper(true);
|
||||
|
||||
// NOTE - wrapper.vm.$options.fetch() doesn't work
|
||||
await wrapper.vm.$options.fetch.apply(wrapper.vm);
|
||||
|
||||
expect(spyManagementFindAll).toHaveBeenNthCalledWith(1, 'management/findAll', {
|
||||
type: MANAGEMENT.SETTING,
|
||||
opt: {
|
||||
load: 'multi', url: `/v1/${ MANAGEMENT.SETTING }s`, redirectUnauthorized: false
|
||||
}
|
||||
});
|
||||
expect(spyManagementFindAll).toHaveBeenNthCalledWith(2, 'management/findPage', {
|
||||
type: CATALOG.APP,
|
||||
opt: {
|
||||
pagination: {
|
||||
filters: [{
|
||||
equals: true,
|
||||
fields: [{
|
||||
equals: true, exact: true, field: 'metadata.name', value: 'rancher-csp-adapter'
|
||||
}, {
|
||||
equals: true, exact: true, field: 'metadata.name', value: 'rancher-csp-billing-adapter'
|
||||
}],
|
||||
param: 'filter'
|
||||
}],
|
||||
labelSelector: undefined,
|
||||
page: null,
|
||||
pageSize: null,
|
||||
projectsOrNamespaces: [],
|
||||
sort: []
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('cspAdapter', () => {
|
||||
it('should have correct csp values (off)', async() => {
|
||||
const { wrapper, store } = createWrapper();
|
||||
|
||||
const spyManagementFindAll = jest.spyOn(store, 'dispatch').mockImplementation((_, options) => {
|
||||
const { type } = options as any;
|
||||
|
||||
if (type === MANAGEMENT.SETTING) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
if (type === CATALOG.APP) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
return Promise.reject(new Error('reason'));
|
||||
});
|
||||
|
||||
// NOTE - wrapper.vm.$options.fetch() doesn't work
|
||||
await wrapper.vm.$options.fetch.apply(wrapper.vm, []);
|
||||
|
||||
expect(spyManagementFindAll).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(wrapper.vm.canCalcCspAdapter).toBeTruthy();
|
||||
expect(wrapper.vm.cspAdapter).toBeFalsy();
|
||||
});
|
||||
|
||||
it.each(['rancher-csp-adapter', 'rancher-csp-billing-adapter'])('should have correct csp values (on - %p )', async(chartName) => {
|
||||
const { wrapper, store } = createWrapper();
|
||||
|
||||
const spyManagementFindAll = jest.spyOn(store, 'dispatch').mockImplementation((_, options) => {
|
||||
const { type } = options as any;
|
||||
|
||||
if (type === MANAGEMENT.SETTING) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
if (type === CATALOG.APP) {
|
||||
return Promise.resolve([{ metadata: { name: chartName } }]);
|
||||
}
|
||||
|
||||
return Promise.reject(new Error('reason'));
|
||||
});
|
||||
|
||||
// NOTE - wrapper.vm.$options.fetch() doesn't work
|
||||
await wrapper.vm.$options.fetch.apply(wrapper.vm, []);
|
||||
|
||||
expect(spyManagementFindAll).toHaveBeenCalledTimes(2);
|
||||
|
||||
expect(wrapper.vm.canCalcCspAdapter).toBeTruthy();
|
||||
expect(wrapper.vm.cspAdapter).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,31 +1,28 @@
|
|||
import { mapGetters } from 'vuex';
|
||||
import { CATALOG, MANAGEMENT } from '@shell/config/types';
|
||||
import { MANAGEMENT } from '@shell/config/types';
|
||||
import { SETTING } from '@shell/config/settings';
|
||||
import { createCssVars } from '@shell/utils/color';
|
||||
import { setTitle } from '@shell/config/private-label';
|
||||
import { setFavIcon, haveSetFavIcon } from '@shell/utils/favicon';
|
||||
|
||||
const cspAdaptorApp = ['rancher-csp-adapter', 'rancher-csp-billing-adapter'];
|
||||
|
||||
export const hasCspAdapter = (apps) => {
|
||||
return apps?.find((a) => cspAdaptorApp.includes(a.metadata?.name));
|
||||
};
|
||||
import { allHash } from '@shell/utils/promise';
|
||||
import { fetchInitialSettings } from '@shell/utils/settings';
|
||||
import CspAdapterUtils from '@shell/utils/cspAdaptor';
|
||||
|
||||
export default {
|
||||
async fetch() {
|
||||
// For the login page, the schemas won't be loaded - we don't need the apps in this case
|
||||
try {
|
||||
if (this.$store.getters['management/canList'](CATALOG.APP)) {
|
||||
this.apps = await this.$store.dispatch('management/findAll', { type: CATALOG.APP });
|
||||
}
|
||||
} catch (e) {}
|
||||
|
||||
const res = await allHash({
|
||||
// Ensure we read the settings even when we are not authenticated
|
||||
try {
|
||||
globalSettings: fetchInitialSettings(this.$store),
|
||||
apps: CspAdapterUtils.fetchCspAdaptorApp(this.$store),
|
||||
});
|
||||
|
||||
// The favicon is implicitly dependent on the initial settings having already been fetched
|
||||
if (!haveSetFavIcon()) {
|
||||
setFavIcon(this.$store);
|
||||
}
|
||||
|
||||
this.apps = res.apps;
|
||||
} catch (e) { }
|
||||
|
||||
// Setting this up front will remove `computed` churn, and we only care that we've initialised them
|
||||
|
|
@ -33,7 +30,9 @@ export default {
|
|||
},
|
||||
|
||||
data() {
|
||||
return { apps: null, haveAppsAndSettings: null };
|
||||
return {
|
||||
apps: null, haveAppsAndSettings: null, canPaginate: false
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
|
@ -87,7 +86,7 @@ export default {
|
|||
// Note! this used to be `findBy(this.app)` however for that case we lost reactivity on the collection
|
||||
// (computed fires before fetch, fetch happens and update apps, computed would not fire again - even with vue.set)
|
||||
// So use `.find` in method instead
|
||||
return hasCspAdapter(this.apps);
|
||||
return CspAdapterUtils.hasCspAdapter({ $store: this.$store, apps: this.apps });
|
||||
},
|
||||
|
||||
canCalcCspAdapter() {
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
import BannerGraphic from '@shell/components/BannerGraphic';
|
||||
import IndentedPanel from '@shell/components/IndentedPanel';
|
||||
import CommunityLinks from '@shell/components/CommunityLinks';
|
||||
import { CATALOG, MANAGEMENT } from '@shell/config/types';
|
||||
import { MANAGEMENT } from '@shell/config/types';
|
||||
import { getVendor } from '@shell/config/private-label';
|
||||
import { SETTING } from '@shell/config/settings';
|
||||
import { addParam } from '@shell/utils/url';
|
||||
import { isRancherPrime } from '@shell/config/version';
|
||||
import { hasCspAdapter } from '@shell/mixins/brand';
|
||||
import TabTitle from '@shell/components/TabTitle';
|
||||
import CspAdapterUtils from '@shell/utils/cspAdaptor';
|
||||
|
||||
export default {
|
||||
|
||||
|
|
@ -42,9 +42,7 @@ export default {
|
|||
return setting;
|
||||
};
|
||||
|
||||
if ( this.$store.getters['management/canList'](CATALOG.APP) ) {
|
||||
this.apps = await this.$store.dispatch('management/findAll', { type: CATALOG.APP });
|
||||
}
|
||||
this.apps = await CspAdapterUtils.fetchCspAdaptorApp(this.$store);
|
||||
this.brandSetting = await fetchOrCreateSetting(SETTING.BRAND, '');
|
||||
this.serverUrlSetting = await fetchOrCreateSetting(SETTING.SERVER_URL, '');
|
||||
this.uiIssuesSetting = await this.$store.dispatch('management/find', { type: MANAGEMENT.SETTING, id: SETTING.ISSUES });
|
||||
|
|
@ -75,7 +73,7 @@ export default {
|
|||
|
||||
computed: {
|
||||
cspAdapter() {
|
||||
return hasCspAdapter(this.apps);
|
||||
return CspAdapterUtils.hasCspAdapter({ $store: this.$store, apps: this.apps });
|
||||
},
|
||||
|
||||
hasSupport() {
|
||||
|
|
|
|||
|
|
@ -667,19 +667,19 @@ export const PAGINATION_SETTINGS_STORE_DEFAULTS: PaginationSettingsStore = {
|
|||
}
|
||||
}
|
||||
},
|
||||
// Disabled due to https://github.com/rancher/dashboard/issues/14493
|
||||
// management: {
|
||||
// resources: {
|
||||
// enableAll: false,
|
||||
// enableSome: {
|
||||
// enabled: [
|
||||
// { resource: CAPI.RANCHER_CLUSTER, context: ['home', 'side-bar'] },
|
||||
// { resource: MANAGEMENT.CLUSTER, context: ['side-bar'] },
|
||||
// ],
|
||||
// generic: false,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
management: {
|
||||
resources: {
|
||||
enableAll: false,
|
||||
enableSome: {
|
||||
enabled: [
|
||||
// { resource: CAPI.RANCHER_CLUSTER, context: ['home', 'side-bar'] }, // Disabled due to https://github.com/rancher/dashboard/issues/14493
|
||||
// { resource: MANAGEMENT.CLUSTER, context: ['side-bar'] }, // Disabled due to https://github.com/rancher/dashboard/issues/14493
|
||||
{ resource: CATALOG.APP, context: ['branding'] },
|
||||
],
|
||||
generic: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default new StevePaginationUtils();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
// For testing these could be changed to something like...
|
||||
|
||||
import { CATALOG } from '@shell/config/types';
|
||||
import { FilterArgs, PaginationFilterField, PaginationParamFilter } from '@shell/types/store/pagination.types';
|
||||
import { VuexStore } from '@shell/types/store/vuex';
|
||||
|
||||
const CSP_ADAPTER_APPS = ['rancher-csp-adapter', 'rancher-csp-billing-adapter'];
|
||||
// For testing above line could be replaced with below line...
|
||||
// const cspAdaptorApp = ['rancher-webhooka', 'rancher-webhook'];
|
||||
|
||||
/**
|
||||
* Helpers in order to
|
||||
*/
|
||||
class CspAdapterUtils {
|
||||
static canPagination($store: VuexStore): boolean {
|
||||
return $store.getters[`management/paginationEnabled`]({ id: CATALOG.APP, context: 'branding' });
|
||||
}
|
||||
|
||||
static fetchCspAdaptorApp($store: VuexStore): Promise<any> {
|
||||
// For the login page, the schemas won't be loaded - we don't need the apps in this case
|
||||
if ($store.getters['management/canList'](CATALOG.APP)) {
|
||||
if (CspAdapterUtils.canPagination($store)) {
|
||||
// Restrict the amount of apps we need to fetch
|
||||
return $store.dispatch('management/findPage', {
|
||||
type: CATALOG.APP,
|
||||
opt: { // Of type ActionFindPageArgs
|
||||
pagination: new FilterArgs({
|
||||
filters: PaginationParamFilter.createMultipleFields(CSP_ADAPTER_APPS.map(
|
||||
(t) => new PaginationFilterField({
|
||||
field: 'metadata.name',
|
||||
value: t,
|
||||
})
|
||||
)),
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return $store.dispatch('management/findAll', { type: CATALOG.APP });
|
||||
}
|
||||
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
static hasCspAdapter({ $store, apps }: { $store: VuexStore, apps: any[]}): Object {
|
||||
// In theory this should contain the filtered apps when pagination is on, and all apps when off. Keep filtering though in both cases just in case
|
||||
return apps?.find((a) => CSP_ADAPTER_APPS.includes(a.metadata?.name));
|
||||
}
|
||||
}
|
||||
|
||||
export default CspAdapterUtils;
|
||||
Loading…
Reference in New Issue