]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-17362 Add getValue and refactor use of getValues for settings
authorMathieu Suen <mathieu.suen@sonarsource.com>
Fri, 23 Sep 2022 08:01:48 +0000 (10:01 +0200)
committersonartech <sonartech@sonarsource.com>
Tue, 27 Sep 2022 20:03:17 +0000 (20:03 +0000)
20 files changed:
server/sonar-web/src/main/js/api/mocks/AuditLogsServiceMock.ts
server/sonar-web/src/main/js/api/mocks/AuthenticationServiceMock.ts
server/sonar-web/src/main/js/api/settings.ts
server/sonar-web/src/main/js/app/components/SystemAnnouncement.tsx
server/sonar-web/src/main/js/apps/audit-logs/components/AuditApp.tsx
server/sonar-web/src/main/js/apps/audit-logs/components/__tests__/AuditApp-test.tsx
server/sonar-web/src/main/js/apps/marketplace/App.tsx
server/sonar-web/src/main/js/apps/marketplace/__tests__/App-test.tsx
server/sonar-web/src/main/js/apps/projectBranches/components/LifetimeInformation.tsx
server/sonar-web/src/main/js/apps/projectBranches/components/__tests__/LifetimeInformation-test.tsx
server/sonar-web/src/main/js/apps/projectsManagement/ProjectManagementApp.tsx
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ProjectManagementApp-it.tsx
server/sonar-web/src/main/js/apps/projectsManagement/__tests__/ProjectManagementApp-test.tsx
server/sonar-web/src/main/js/apps/settings/components/CategoryDefinitionsList.tsx
server/sonar-web/src/main/js/apps/settings/components/Definition.tsx
server/sonar-web/src/main/js/apps/settings/components/__tests__/CategoryDefinitionsList-test.tsx
server/sonar-web/src/main/js/apps/settings/components/__tests__/Definition-test.tsx
server/sonar-web/src/main/js/apps/settings/components/authentication/SamlAuthentication.tsx
server/sonar-web/src/main/js/components/tutorials/TutorialSelection.tsx
server/sonar-web/src/main/js/components/tutorials/__tests__/TutorialSelection-test.tsx

index 10f6f36fdc0284264942e34a2faa82ac63f168cd..8d52440034d5213d6c9d4f67e73cb96ec62bc946 100644 (file)
 import { cloneDeep } from 'lodash';
 import { HousekeepingPolicy } from '../../apps/audit-logs/utils';
 import { SettingValue } from '../../types/settings';
-import { getValues } from '../settings';
+import { getValue } from '../settings';
 
 export default class AuditLogsServiceMock {
-  settingValue: SettingValue[];
-  defaultValues: SettingValue[] = [{ key: 'test', value: HousekeepingPolicy.Weekly }];
+  settingValue: SettingValue;
+  defaultValues: SettingValue = { key: 'test', value: HousekeepingPolicy.Weekly };
 
   constructor() {
     this.settingValue = cloneDeep(this.defaultValues);
-    (getValues as jest.Mock).mockImplementation(this.getValuesHandler);
+    (getValue as jest.Mock).mockImplementation(this.getValuesHandler);
   }
 
   getValuesHandler = () => {
index 17dda673074c7975ca189cb266dba1e7c70f5e4e..c5a5287e6c25eb49a0eb0945cec75d522130b770 100644 (file)
@@ -41,9 +41,7 @@ export default class AuthenticationServiceMock {
 
   getValuesHandler = (data: { keys: string; component?: string } & BranchParameters) => {
     if (data.keys) {
-      return Promise.resolve(
-        this.settingValues.filter(set => data.keys.split(',').includes(set.key))
-      );
+      return Promise.resolve(this.settingValues.filter(set => data.keys.includes(set.key)));
     }
     return Promise.resolve(this.settingValues);
   };
index c00cc81078b745570f16046e72f2ba43e771214e..6fd866a2a302663bd111e425386452092eb40ca7 100644 (file)
@@ -36,10 +36,19 @@ export function getDefinitions(component?: string): Promise<ExtendedSettingDefin
   );
 }
 
+export function getValue(
+  data: { key: string; component?: string } & BranchParameters
+): Promise<SettingValue> {
+  return getValues({ keys: [data.key], component: data.component }).then(([result]) => result);
+}
+
 export function getValues(
-  data: { keys: string; component?: string } & BranchParameters
+  data: { keys: string[]; component?: string } & BranchParameters
 ): Promise<SettingValue[]> {
-  return getJSON('/api/settings/values', data).then((r: SettingValueResponse) => [
+  return getJSON('/api/settings/values', {
+    keys: data.keys.join(','),
+    component: data.component
+  }).then((r: SettingValueResponse) => [
     ...r.settings,
     ...r.setSecuredSettings.map(key => ({ key }))
   ]);
index 65e630c76dc16f27d5badc99c0305b227772ca1a..dd0abf833ea68d8b21bfb90366e5127bbc337353 100644 (file)
@@ -44,7 +44,7 @@ export default class SystemAnnouncement extends React.PureComponent<{}, State> {
 
   getSettings = async () => {
     const values: SettingValue[] = await getValues({
-      keys: [GlobalSettingKeys.DisplaySystemMessage, GlobalSettingKeys.SystemMessage].join(',')
+      keys: [GlobalSettingKeys.DisplaySystemMessage, GlobalSettingKeys.SystemMessage]
     });
     const settings = keyBy(values, 'key');
 
index 30790038dc88a7ce0fcab09d11a7f46dabf98cfb..7582b963c922d97517fdd7f8c33949437916bfa4 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import { getValues } from '../../../api/settings';
+import { getValue } from '../../../api/settings';
 import withAdminPagesOutletContext from '../../../app/components/admin/withAdminPagesOutletContext';
 import { AdminPageExtension } from '../../../types/extension';
 import { SettingsKey } from '../../../types/settings';
@@ -62,11 +62,11 @@ export class AuditApp extends React.PureComponent<Props, State> {
   }
 
   fetchHouseKeepingPolicy = async () => {
-    const results = await getValues({ keys: SettingsKey.AuditHouseKeeping });
+    const result = await getValue({ key: SettingsKey.AuditHouseKeeping });
 
     this.setState({
       housekeepingPolicy:
-        (results[0]?.value as HousekeepingPolicy | undefined) ?? HousekeepingPolicy.Monthly
+        (result?.value as HousekeepingPolicy | undefined) ?? HousekeepingPolicy.Monthly
     });
   };
 
index 5d519095633075477cc001460ded69afeb5b1487..21ffca857b0aae01cc3484293a5093f86dbc8bae 100644 (file)
@@ -20,7 +20,7 @@
 import { subDays } from 'date-fns';
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import { getValues } from '../../../../api/settings';
+import { getValue } from '../../../../api/settings';
 import { waitAndUpdate } from '../../../../helpers/testUtils';
 import { AdminPageExtension } from '../../../../types/extension';
 import { HousekeepingPolicy, RangeOption } from '../../utils';
@@ -28,7 +28,7 @@ import { AuditApp } from '../AuditApp';
 import AuditAppRenderer from '../AuditAppRenderer';
 
 jest.mock('../../../../api/settings', () => ({
-  getValues: jest.fn().mockResolvedValue([])
+  getValue: jest.fn().mockResolvedValue({})
 }));
 
 beforeEach(() => {
@@ -44,11 +44,11 @@ it('should do nothing if governance is not available', async () => {
   await waitAndUpdate(wrapper);
 
   expect(wrapper.type()).toBeNull();
-  expect(getValues).not.toBeCalled();
+  expect(getValue).not.toBeCalled();
 });
 
 it('should handle housekeeping policy', async () => {
-  (getValues as jest.Mock).mockResolvedValueOnce([{ value: HousekeepingPolicy.Weekly }]);
+  (getValue as jest.Mock).mockResolvedValueOnce({ value: HousekeepingPolicy.Weekly });
 
   const wrapper = shallowRender();
 
@@ -92,12 +92,12 @@ it('should handle update to admin pages', async () => {
   await waitAndUpdate(wrapper);
 
   expect(wrapper.type()).toBeNull();
-  expect(getValues).not.toBeCalled();
+  expect(getValue).not.toBeCalled();
 
   wrapper.setProps({ adminPages: [{ key: AdminPageExtension.GovernanceConsole, name: 'name' }] });
   await waitAndUpdate(wrapper);
 
-  expect(getValues).toBeCalled();
+  expect(getValue).toBeCalled();
 });
 
 function shallowRender(props: Partial<AuditApp['props']> = {}) {
index 2ce22d60b0ab818ed449ffad5d613a88b71d9b29..60d03b5b190762ca9912343a60cfe764e1342ab0 100644 (file)
@@ -27,7 +27,7 @@ import {
   getInstalledPluginsWithUpdates,
   getPluginUpdates
 } from '../../api/plugins';
-import { getValues, setSimpleSettingValue } from '../../api/settings';
+import { getValue, setSimpleSettingValue } from '../../api/settings';
 import Link from '../../components/common/Link';
 import Suggestions from '../../components/embed-docs-modal/Suggestions';
 import { Location, Router, withRouter } from '../../components/hoc/withRouter';
@@ -111,14 +111,12 @@ export class App extends React.PureComponent<Props, State> {
   };
 
   fetchRiskConsent = async () => {
-    const result = await getValues({ keys: SettingsKey.PluginRiskConsent });
+    const consent = await getValue({ key: SettingsKey.PluginRiskConsent });
 
-    if (!result || result.length < 1) {
+    if (consent === undefined) {
       return;
     }
 
-    const [consent] = result;
-
     this.setState({ riskConsent: consent.value as RiskConsent | undefined });
   };
 
index eb6876198a8ec3f6875668331bb16e0c9487bacf..3f70f9d36766dad3fe6a6014aa9bc7b8f5fcf249 100644 (file)
@@ -25,7 +25,7 @@ import {
   getInstalledPluginsWithUpdates,
   getPluginUpdates
 } from '../../../api/plugins';
-import { getValues, setSimpleSettingValue } from '../../../api/settings';
+import { getValue, setSimpleSettingValue } from '../../../api/settings';
 import { mockLocation, mockRouter } from '../../../helpers/testMocks';
 import { waitAndUpdate } from '../../../helpers/testUtils';
 import { EditionKey } from '../../../types/editions';
@@ -45,7 +45,7 @@ jest.mock('../../../api/plugins', () => {
 });
 
 jest.mock('../../../api/settings', () => ({
-  getValues: jest.fn().mockResolvedValue([]),
+  getValue: jest.fn().mockResolvedValue({}),
   setSimpleSettingValue: jest.fn().mockResolvedValue(true)
 }));
 
@@ -65,21 +65,21 @@ it('should render correctly', async () => {
 });
 
 it('should handle accepting the risk', async () => {
-  (getValues as jest.Mock)
-    .mockResolvedValueOnce([{ value: RiskConsent.NotAccepted }])
-    .mockResolvedValueOnce([{ value: RiskConsent.Accepted }]);
+  (getValue as jest.Mock)
+    .mockResolvedValueOnce({ value: RiskConsent.NotAccepted })
+    .mockResolvedValueOnce({ value: RiskConsent.Accepted });
 
   const wrapper = shallowRender();
 
   await waitAndUpdate(wrapper);
-  expect(getValues).toBeCalledWith({ keys: SettingsKey.PluginRiskConsent });
+  expect(getValue).toBeCalledWith({ key: SettingsKey.PluginRiskConsent });
 
   wrapper.instance().acknowledgeRisk();
 
   await new Promise(setImmediate);
 
   expect(setSimpleSettingValue).toBeCalled();
-  expect(getValues).toBeCalledWith({ keys: SettingsKey.PluginRiskConsent });
+  expect(getValue).toBeCalledWith({ key: SettingsKey.PluginRiskConsent });
   expect(wrapper.state().riskConsent).toBe(RiskConsent.Accepted);
 });
 
index aabaf35c73067ab8af95cc9237e13afb53ef4a21..a6a0de260a47ae611a31857b5e6b03f9e446b88e 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import { getValues } from '../../../api/settings';
+import { getValue } from '../../../api/settings';
 import withAppStateContext from '../../../app/components/app-state/withAppStateContext';
 import { AppState } from '../../../types/appstate';
 import { SettingsKey } from '../../../types/settings';
@@ -47,12 +47,12 @@ export class LifetimeInformation extends React.PureComponent<Props, State> {
   }
 
   fetchBranchAndPullRequestLifetimeSetting() {
-    getValues({ keys: SettingsKey.DaysBeforeDeletingInactiveBranchesAndPRs }).then(
+    getValue({ key: SettingsKey.DaysBeforeDeletingInactiveBranchesAndPRs }).then(
       settings => {
         if (this.mounted) {
           this.setState({
             loading: false,
-            branchAndPullRequestLifeTimeInDays: settings.length > 0 ? settings[0].value : undefined
+            branchAndPullRequestLifeTimeInDays: settings?.value
           });
         }
       },
index f34d9e24983df1d12b7eacc4a2ed85c511075a64..17d4bd8d3ad655d90b8081f5ec5fd07c814aa3d6 100644 (file)
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import { getValues } from '../../../../api/settings';
+import { getValue } from '../../../../api/settings';
 import { mockAppState } from '../../../../helpers/testMocks';
 import { waitAndUpdate } from '../../../../helpers/testUtils';
 import { SettingsKey } from '../../../../types/settings';
 import { LifetimeInformation } from '../LifetimeInformation';
 
 jest.mock('../../../../api/settings', () => ({
-  getValues: jest.fn().mockResolvedValue([{ value: '45' }])
+  getValue: jest.fn().mockResolvedValue({ value: '45' })
 }));
 
 it('should render correctly', async () => {
@@ -35,8 +35,8 @@ it('should render correctly', async () => {
 
   await waitAndUpdate(wrapper);
 
-  expect(getValues).toHaveBeenCalledWith({
-    keys: SettingsKey.DaysBeforeDeletingInactiveBranchesAndPRs
+  expect(getValue).toHaveBeenCalledWith({
+    key: SettingsKey.DaysBeforeDeletingInactiveBranchesAndPRs
   });
   expect(wrapper).toMatchSnapshot('after_fetching_data');
 });
index 020448c3f73ec8b923296d4879cf69c4b0fd9ac8..c333b03605826921245a12b1e1364cc7f4fc8410 100644 (file)
@@ -22,7 +22,7 @@ import * as React from 'react';
 import { Helmet } from 'react-helmet-async';
 import { getComponents, Project } from '../../api/components';
 import { changeProjectDefaultVisibility } from '../../api/permissions';
-import { getValues } from '../../api/settings';
+import { getValue } from '../../api/settings';
 import withCurrentUserContext from '../../app/components/current-user/withCurrentUserContext';
 import ListFooter from '../../components/controls/ListFooter';
 import Suggestions from '../../components/embed-docs-modal/Suggestions';
@@ -90,10 +90,10 @@ export class ProjectManagementApp extends React.PureComponent<Props, State> {
   }
 
   fetchDefaultProjectVisibility = async () => {
-    const results = await getValues({ keys: SettingsKey.DefaultProjectVisibility });
+    const results = await getValue({ key: SettingsKey.DefaultProjectVisibility });
 
-    if (this.mounted && results.length > 0 && results[0].value) {
-      this.setState({ defaultProjectVisibility: results[0].value as Visibility });
+    if (this.mounted && results?.value !== undefined) {
+      this.setState({ defaultProjectVisibility: results.value as Visibility });
     }
   };
 
index 7c7aa6f02bd42f684938992ad71dd6ce4a84d4b3..0c39eeebfc654d8b1593be7de039d5989b9de43b 100644 (file)
@@ -36,7 +36,7 @@ jest.mock('../../../api/components', () => ({
 }));
 
 jest.mock('../../../api/settings', () => ({
-  getValues: jest.fn().mockResolvedValue([{ value: 'public' }])
+  getValue: jest.fn().mockResolvedValue({ value: 'public' })
 }));
 
 const components = mockComponents(11);
index 086e4b53644c0139bc6e791b0226f2df68551e6d..acde118094344829d4722e4b335a9b49be4611d2 100644 (file)
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme';
 import * as React from 'react';
 import { getComponents } from '../../../api/components';
 import { changeProjectDefaultVisibility } from '../../../api/permissions';
-import { getValues } from '../../../api/settings';
+import { getValue } from '../../../api/settings';
 import { mockLoggedInUser } from '../../../helpers/testMocks';
 import { waitAndUpdate } from '../../../helpers/testUtils';
 import { ProjectManagementApp, Props } from '../ProjectManagementApp';
@@ -41,7 +41,7 @@ jest.mock('../../../api/permissions', () => ({
 }));
 
 jest.mock('../../../api/settings', () => ({
-  getValues: jest.fn().mockResolvedValue([{ value: 'public' }])
+  getValue: jest.fn().mockResolvedValue({ value: 'public' })
 }));
 
 const defaultSearchParameters = {
@@ -58,7 +58,7 @@ it('fetches all projects on mount', async () => {
   const wrapper = shallowRender();
   await waitAndUpdate(wrapper);
   expect(getComponents).lastCalledWith({ ...defaultSearchParameters, qualifiers: 'TRK' });
-  expect(getValues).toBeCalled();
+  expect(getValue).toBeCalled();
   expect(wrapper.state().defaultProjectVisibility).toBe('public');
 });
 
index 683fd3404c048cb2132006ff68475af857078a54..107183e40b75d1fb4dc098633ce4b1c8b86ef9c2 100644 (file)
@@ -67,7 +67,7 @@ export default class CategoryDefinitionsList extends React.PureComponent<Props,
       definition => definition.category.toLowerCase() === category.toLowerCase()
     );
 
-    const keys = categoryDefinitions.map(definition => definition.key).join(',');
+    const keys = categoryDefinitions.map(definition => definition.key);
 
     const values: SettingValue[] = await getValues({
       keys,
index 34e1dcc04bb87410b2ee46629a395f49f694af5e..1bf9c91506deef4aed72219a0c2d68bb2d046ccd 100644 (file)
@@ -18,7 +18,7 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import * as React from 'react';
-import { getValues, resetSettingValue, setSettingValue } from '../../../api/settings';
+import { getValue, resetSettingValue, setSettingValue } from '../../../api/settings';
 import { translate, translateWithParameters } from '../../../helpers/l10n';
 import { parseError } from '../../../helpers/request';
 import { ExtendedSettingDefinition, SettingType, SettingValue } from '../../../types/settings';
@@ -78,8 +78,7 @@ export default class Definition extends React.PureComponent<Props, State> {
 
     try {
       await resetSettingValue({ keys: definition.key, component: component?.key });
-      const result = await getValues({ keys: definition.key, component: component?.key });
-      const settingValue = result[0];
+      const settingValue = await getValue({ key: definition.key, component: component?.key });
 
       this.setState({
         changedValue: undefined,
@@ -164,8 +163,7 @@ export default class Definition extends React.PureComponent<Props, State> {
 
       try {
         await setSettingValue(definition, changedValue, component?.key);
-        const result = await getValues({ keys: definition.key, component: component?.key });
-        const settingValue = result[0];
+        const settingValue = await getValue({ key: definition.key, component: component?.key });
 
         this.setState({
           changedValue: undefined,
index 1a2c7b5660b512b105435a53cd0b7df741613110..105a5569df4c513120865aad12dbf379ec936612 100644 (file)
@@ -45,7 +45,7 @@ it('should load settings values', async () => {
 
   await waitAndUpdate(wrapper);
 
-  expect(getValues).toBeCalledWith({ keys: 'yes,yesagain', component: undefined });
+  expect(getValues).toBeCalledWith({ keys: ['yes', 'yesagain'], component: undefined });
 
   expect(wrapper.state().settings).toEqual([
     { definition: definitions[0], settingValue: settings[0] },
@@ -63,13 +63,13 @@ it('should reload on category change', async () => {
 
   await waitAndUpdate(wrapper);
 
-  expect(getValues).toBeCalledWith({ keys: 'yes,yesagain', component: 'comp-key' });
+  expect(getValues).toBeCalledWith({ keys: ['yes', 'yesagain'], component: 'comp-key' });
 
   wrapper.setProps({ category: 'other' });
 
   await waitAndUpdate(wrapper);
 
-  expect(getValues).toBeCalledWith({ keys: 'nope', component: 'comp-key' });
+  expect(getValues).toBeCalledWith({ keys: ['nope'], component: 'comp-key' });
 });
 
 function shallowRender(props: Partial<CategoryDefinitionsList['props']> = {}) {
index f877ba5dfb406e4dd3b62965f78833e8579bd147..65af2b65543d2766dac47e1d01a6a46d025f2ceb 100644 (file)
  */
 import { shallow } from 'enzyme';
 import * as React from 'react';
-import { getValues, resetSettingValue, setSettingValue } from '../../../../api/settings';
+import { getValue, resetSettingValue, setSettingValue } from '../../../../api/settings';
 import { mockDefinition, mockSettingValue } from '../../../../helpers/mocks/settings';
 import { waitAndUpdate } from '../../../../helpers/testUtils';
 import { SettingType } from '../../../../types/settings';
 import Definition from '../Definition';
 
 jest.mock('../../../../api/settings', () => ({
-  getValues: jest.fn().mockResolvedValue([]),
+  getValue: jest.fn().mockResolvedValue({}),
   resetSettingValue: jest.fn().mockResolvedValue(undefined),
   setSettingValue: jest.fn().mockResolvedValue(undefined)
 }));
@@ -120,7 +120,7 @@ describe('handleSave', () => {
 
   it('should save and update setting value', async () => {
     const settingValue = mockSettingValue();
-    (getValues as jest.Mock).mockResolvedValueOnce([settingValue]);
+    (getValue as jest.Mock).mockResolvedValueOnce(settingValue);
     const definition = mockDefinition();
     const wrapper = shallowRender({ definition });
 
@@ -133,7 +133,7 @@ describe('handleSave', () => {
     await waitAndUpdate(wrapper);
 
     expect(setSettingValue).toBeCalledWith(definition, 'new value', undefined);
-    expect(getValues).toBeCalledWith({ keys: definition.key, component: undefined });
+    expect(getValue).toBeCalledWith({ key: definition.key, component: undefined });
     expect(wrapper.state().changedValue).toBeUndefined();
     expect(wrapper.state().loading).toBe(false);
     expect(wrapper.state().success).toBe(true);
@@ -146,7 +146,7 @@ describe('handleSave', () => {
 
 it('should reset and update setting value', async () => {
   const settingValue = mockSettingValue();
-  (getValues as jest.Mock).mockResolvedValueOnce([settingValue]);
+  (getValue as jest.Mock).mockResolvedValueOnce(settingValue);
   const definition = mockDefinition();
   const wrapper = shallowRender({ definition });
 
@@ -157,7 +157,7 @@ it('should reset and update setting value', async () => {
   await waitAndUpdate(wrapper);
 
   expect(resetSettingValue).toBeCalledWith({ keys: definition.key, component: undefined });
-  expect(getValues).toBeCalledWith({ keys: definition.key, component: undefined });
+  expect(getValue).toBeCalledWith({ key: definition.key, component: undefined });
   expect(wrapper.state().changedValue).toBeUndefined();
   expect(wrapper.state().loading).toBe(false);
   expect(wrapper.state().success).toBe(true);
index f6070383c109b9db30bc86b8407afb36baf4148e..1196ed4309c941fd91863850faad3c0eec8cd709 100644 (file)
@@ -86,7 +86,7 @@ class SamlAuthentication extends React.PureComponent<
 
   componentDidMount() {
     const { definitions } = this.props;
-    const keys = definitions.map(definition => definition.key).join(',');
+    const keys = definitions.map(definition => definition.key);
     // Added setTimeout to make sure the component gets updated before scrolling
     setTimeout(() => {
       if (location.hash) {
@@ -134,7 +134,7 @@ class SamlAuthentication extends React.PureComponent<
     });
   };
 
-  async loadSettingValues(keys: string) {
+  async loadSettingValues(keys: string[]) {
     const { settingValue, securedFieldsSubmitted } = this.state;
     const values = await getValues({
       keys
@@ -212,7 +212,7 @@ class SamlAuthentication extends React.PureComponent<
       }
       this.setState({ success: dirtyFields.length !== dataWithError.length });
     });
-    await this.loadSettingValues(dirtyFields.join(','));
+    await this.loadSettingValues(dirtyFields);
     this.setState({ submitting: false, dirtyFields: [] });
   };
 
index ae972acfd0ef9d13b71d7fe3a0191e33b3b1cd39..9888924b8e9e1b3f6c6a4c3f3256f69fdc2aec7e 100644 (file)
@@ -20,7 +20,7 @@
 import * as React from 'react';
 import { getAlmSettingsNoCatch } from '../../api/alm-settings';
 import { getScannableProjects } from '../../api/components';
-import { getValues } from '../../api/settings';
+import { getValue } from '../../api/settings';
 import { getHostUrl } from '../../helpers/urls';
 import { hasGlobalPermission } from '../../helpers/users';
 import { AlmSettingsInstance, ProjectAlmBindingResponse } from '../../types/alm-settings';
@@ -102,8 +102,8 @@ export class TutorialSelection extends React.PureComponent<Props, State> {
   };
 
   fetchBaseUrl = async () => {
-    const settings = await getValues({ keys: SettingsKey.ServerBaseUrl }).catch(() => undefined);
-    const baseUrl = settings && settings.find(s => s.key === SettingsKey.ServerBaseUrl)?.value;
+    const setting = await getValue({ key: SettingsKey.ServerBaseUrl }).catch(() => undefined);
+    const baseUrl = setting?.value;
     if (baseUrl && baseUrl.length > 0 && this.mounted) {
       this.setState({ baseUrl });
     }
index 5cbf3a11a69454cae9e6bb6bc178e67acb8fd026..7dd92e43fd81888b834734da4e4f86c1b15a43e6 100644 (file)
@@ -21,7 +21,7 @@ import { shallow } from 'enzyme';
 import * as React from 'react';
 import { getAlmSettingsNoCatch } from '../../../api/alm-settings';
 import { getScannableProjects } from '../../../api/components';
-import { getValues } from '../../../api/settings';
+import { getValue } from '../../../api/settings';
 import {
   mockAlmSettingsInstance,
   mockProjectBitbucketBindingResponse
@@ -44,7 +44,7 @@ jest.mock('../../../api/alm-settings', () => ({
 }));
 
 jest.mock('../../../api/settings', () => ({
-  getValues: jest.fn().mockResolvedValue([])
+  getValue: jest.fn().mockResolvedValue({})
 }));
 
 jest.mock('../../../api/components', () => ({
@@ -90,14 +90,14 @@ it('should handle selection', () => {
 });
 
 it('should fetch the correct baseUrl', async () => {
-  (getValues as jest.Mock)
-    .mockResolvedValueOnce([{ key: SettingsKey.ServerBaseUrl, value: '' }])
-    .mockResolvedValueOnce([{ key: SettingsKey.ServerBaseUrl, value: 'http://sq.example.com' }])
+  (getValue as jest.Mock)
+    .mockResolvedValueOnce({ key: SettingsKey.ServerBaseUrl, value: '' })
+    .mockResolvedValueOnce({ key: SettingsKey.ServerBaseUrl, value: 'http://sq.example.com' })
     .mockRejectedValueOnce(null);
 
   let wrapper = shallowRender();
 
-  expect(getValues).toBeCalled();
+  expect(getValue).toBeCalled();
   expect(getHostUrl).toBeCalled();
 
   // No baseURL, fallback to the URL in the browser.