diff options
author | Philippe Perrin <philippe.perrin@sonarsource.com> | 2022-01-28 17:39:50 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-03-29 20:03:37 +0000 |
commit | b345bbc09eb8e0bd04951e1db88f56666f5f4c6a (patch) | |
tree | d61378aa709f81a1c6a9729b6c792e404700dfcf /server/sonar-web/src/main/js/helpers | |
parent | c1ea1e9df27db899c07948ce50e6aa9cceab348a (diff) | |
download | sonarqube-b345bbc09eb8e0bd04951e1db88f56666f5f4c6a.tar.gz sonarqube-b345bbc09eb8e0bd04951e1db88f56666f5f4c6a.zip |
SONAR-15938 Improve code sharing with the license extension
Diffstat (limited to 'server/sonar-web/src/main/js/helpers')
9 files changed, 406 insertions, 218 deletions
diff --git a/server/sonar-web/src/main/js/helpers/__tests__/error-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/error-test.ts new file mode 100644 index 00000000000..ca6f81a60e9 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/__tests__/error-test.ts @@ -0,0 +1,94 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import getStore from '../../app/utils/getStore'; +import { throwGlobalError } from '../error'; + +beforeAll(() => { + jest.useFakeTimers(); +}); + +afterAll(() => { + jest.runOnlyPendingTimers(); + jest.useRealTimers(); +}); + +it('should put the error message in the store', async () => { + const response = new Response(); + response.json = jest.fn().mockResolvedValue({ errors: [{ msg: 'error 1' }] }); + + // We need to catch because throwGlobalError rethrows after displaying the message + await throwGlobalError(response) + .then(() => { + throw new Error('Should throw'); + }) + .catch(() => {}); + + expect(getStore().getState().globalMessages[0]).toMatchObject({ + level: 'ERROR', + message: 'error 1' + }); +}); + +it('should put a default error messsage in the store', async () => { + const response = new Response(); + response.json = jest.fn().mockResolvedValue({}); + + // We need to catch because throwGlobalError rethrows after displaying the message + await throwGlobalError(response) + .then(() => { + throw new Error('Should throw'); + }) + .catch(() => {}); + + expect(getStore().getState().globalMessages[0]).toMatchObject({ + level: 'ERROR', + message: 'default_error_message' + }); +}); + +it('should handle weird response types', () => { + const response = { weird: 'response type' }; + + return throwGlobalError(response) + .then(() => { + throw new Error('Should throw'); + }) + .catch(error => { + expect(error).toBe(response); + }); +}); + +it('should unwrap response if necessary', async () => { + const response = new Response(); + response.json = jest.fn().mockResolvedValue({}); + + /* eslint-disable-next-line no-console */ + console.warn = jest.fn(); + + // We need to catch because throwGlobalError rethrows after displaying the message + await throwGlobalError({ response }) + .then(() => { + throw new Error('Should throw'); + }) + .catch(() => {}); + + /* eslint-disable-next-line no-console */ + expect(console.warn).toHaveBeenCalled(); +}); diff --git a/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts index 58d2f94461d..346d097dce8 100644 --- a/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts +++ b/server/sonar-web/src/main/js/helpers/__tests__/l10n-test.ts @@ -17,84 +17,51 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { fetchL10nBundle } from '../../api/l10n'; +import { Dict } from '../../types/types'; import { getLocalizedCategoryMetricName, getLocalizedMetricDomain, getLocalizedMetricName, - getMessages, getShortMonthName, getShortWeekDayName, getWeekDayName, hasMessage, - loadL10nBundle, - resetMessages, translate, translateWithParameters } from '../l10n'; -import { get } from '../storage'; +import { getMessages } from '../l10nBundle'; -beforeEach(() => { - jest.clearAllMocks(); - jest.spyOn(window.navigator, 'languages', 'get').mockReturnValue(['de']); -}); +const MSG = 'my_message'; -jest.mock('../../api/l10n', () => ({ - fetchL10nBundle: jest - .fn() - .mockResolvedValue({ effectiveLocale: 'de', messages: { test_message: 'test' } }) -})); +jest.unmock('../l10n'); -jest.mock('../../helpers/storage', () => ({ - get: jest.fn(), - save: jest.fn() +jest.mock('../l10nBundle', () => ({ + getMessages: jest.fn().mockReturnValue({}) })); -describe('#loadL10nBundle', () => { - it('should fetch bundle without any timestamp', async () => { - await loadL10nBundle(); - - expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined }); - }); - - it('should ftech bundle without local storage timestamp if locales are different', async () => { - const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } }; - (get as jest.Mock).mockReturnValueOnce(JSON.stringify(cachedBundle)); - - await loadL10nBundle(); - - expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined }); - }); - - it('should fetch bundle with cached bundle timestamp and browser locale', async () => { - const cachedBundle = { timestamp: 'timestamp', locale: 'de', messages: { cache: 'cache' } }; - (get as jest.Mock).mockReturnValueOnce(JSON.stringify(cachedBundle)); +const resetMessages = (messages: Dict<string>) => + (getMessages as jest.Mock).mockReturnValue(messages); - await loadL10nBundle(); +beforeEach(() => { + resetMessages({}); +}); - expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: cachedBundle.timestamp }); +describe('hasMessage', () => { + it('should return that the message exists', () => { + resetMessages({ + foo: 'foo', + 'foo.bar': 'foobar' + }); + expect(hasMessage('foo')).toBe(true); + expect(hasMessage('foo', 'bar')).toBe(true); }); - it('should fallback to cached bundle if the server respond with 304', async () => { - const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } }; - (fetchL10nBundle as jest.Mock).mockRejectedValueOnce({ status: 304 }); - (get as jest.Mock).mockReturnValueOnce(JSON.stringify(cachedBundle)); - - const bundle = await loadL10nBundle(); - - expect(bundle).toEqual( - expect.objectContaining({ locale: cachedBundle.locale, messages: cachedBundle.messages }) - ); + it('should return that the message is missing', () => { + expect(hasMessage('foo')).toBe(false); + expect(hasMessage('foo', 'bar')).toBe(false); }); }); -const originalMessages = getMessages(); -const MSG = 'my_message'; - -afterEach(() => { - resetMessages(originalMessages); -}); - describe('translate', () => { it('should translate simple message', () => { resetMessages({ my_key: MSG }); @@ -153,19 +120,6 @@ describe('translateWithParameters', () => { }); }); -describe('hasMessage', () => { - it('should return that the message exists', () => { - resetMessages({ foo: 'Foo', 'foo.bar': 'Foo Bar' }); - expect(hasMessage('foo')).toBe(true); - expect(hasMessage('foo', 'bar')).toBe(true); - }); - - it('should return that the message is missing', () => { - expect(hasMessage('foo')).toBe(false); - expect(hasMessage('foo', 'bar')).toBe(false); - }); -}); - describe('getLocalizedMetricName', () => { const metric = { key: 'new_code', name: 'new_code_metric_name' }; diff --git a/server/sonar-web/src/main/js/helpers/__tests__/l10nBundle-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/l10nBundle-test.ts new file mode 100644 index 00000000000..58c1e603b51 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/__tests__/l10nBundle-test.ts @@ -0,0 +1,71 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { fetchL10nBundle } from '../../api/l10n'; +import { loadL10nBundle } from '../l10nBundle'; + +beforeEach(() => { + jest.clearAllMocks(); + jest.spyOn(window.navigator, 'languages', 'get').mockReturnValue(['de']); +}); + +jest.mock('../../api/l10n', () => ({ + fetchL10nBundle: jest.fn().mockResolvedValue({ + effectiveLocale: 'de', + messages: { foo: 'Foo', 'foo.bar': 'Foo Bar' } + }) +})); + +describe('#loadL10nBundle', () => { + it('should fetch bundle without any timestamp', async () => { + await loadL10nBundle(); + + expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined }); + }); + + it('should ftech bundle without local storage timestamp if locales are different', async () => { + const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } }; + ((window as unknown) as any).sonarQubeL10nBundle = cachedBundle; + + await loadL10nBundle(); + + expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: undefined }); + }); + + it('should fetch bundle with cached bundle timestamp and browser locale', async () => { + const cachedBundle = { timestamp: 'timestamp', locale: 'de', messages: { cache: 'cache' } }; + ((window as unknown) as any).sonarQubeL10nBundle = cachedBundle; + + await loadL10nBundle(); + + expect(fetchL10nBundle).toHaveBeenCalledWith({ locale: 'de', ts: cachedBundle.timestamp }); + }); + + it('should fallback to cached bundle if the server respond with 304', async () => { + const cachedBundle = { timestamp: 'timestamp', locale: 'fr', messages: { cache: 'cache' } }; + (fetchL10nBundle as jest.Mock).mockRejectedValueOnce({ status: 304 }); + ((window as unknown) as any).sonarQubeL10nBundle = cachedBundle; + + const bundle = await loadL10nBundle(); + + expect(bundle).toEqual( + expect.objectContaining({ locale: cachedBundle.locale, messages: cachedBundle.messages }) + ); + }); +}); diff --git a/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts b/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts index 04a0bfa2ffa..3a301c9b9b6 100644 --- a/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts +++ b/server/sonar-web/src/main/js/helpers/__tests__/measures-test.ts @@ -17,7 +17,9 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { resetMessages } from '../l10n'; + +import { Dict } from '../../types/types'; +import { getMessages } from '../l10nBundle'; import { enhanceConditionWithMeasure, formatMeasure, @@ -27,6 +29,36 @@ import { import { mockQualityGateStatusCondition } from '../mocks/quality-gates'; import { mockMeasureEnhanced, mockMetric } from '../testMocks'; +jest.unmock('../l10n'); + +jest.mock('../l10nBundle', () => ({ + getCurrentLocale: jest.fn().mockReturnValue('us'), + getMessages: jest.fn().mockReturnValue({}) +})); + +const resetMessages = (messages: Dict<string>) => + (getMessages as jest.Mock).mockReturnValue(messages); + +beforeAll(() => { + resetMessages({ + 'work_duration.x_days': '{0}d', + 'work_duration.x_hours': '{0}h', + 'work_duration.x_minutes': '{0}min', + 'work_duration.about': '~ {0}', + 'metric.level.ERROR': 'Error', + 'metric.level.WARN': 'Warning', + 'metric.level.OK': 'Ok', + 'short_number_suffix.g': 'G', + 'short_number_suffix.k': 'k', + 'short_number_suffix.m': 'M' + }); +}); + +const HOURS_IN_DAY = 8; +const ONE_MINUTE = 1; +const ONE_HOUR = ONE_MINUTE * 60; +const ONE_DAY = HOURS_IN_DAY * ONE_HOUR; + describe('enhanceConditionWithMeasure', () => { it('should correctly map enhance conditions with measure data', () => { const measures = [ @@ -71,30 +103,6 @@ describe('isPeriodBestValue', () => { }); }); -const HOURS_IN_DAY = 8; -const ONE_MINUTE = 1; -const ONE_HOUR = ONE_MINUTE * 60; -const ONE_DAY = HOURS_IN_DAY * ONE_HOUR; - -beforeAll(() => { - resetMessages({ - 'work_duration.x_days': '{0}d', - 'work_duration.x_hours': '{0}h', - 'work_duration.x_minutes': '{0}min', - 'work_duration.about': '~ {0}', - 'metric.level.ERROR': 'Error', - 'metric.level.WARN': 'Warning', - 'metric.level.OK': 'Ok', - 'short_number_suffix.g': 'G', - 'short_number_suffix.k': 'k', - 'short_number_suffix.m': 'M' - }); -}); - -afterAll(() => { - resetMessages({}); -}); - describe('#formatMeasure()', () => { it('should format INT', () => { expect(formatMeasure(0, 'INT')).toBe('0'); diff --git a/server/sonar-web/src/main/js/helpers/error.ts b/server/sonar-web/src/main/js/helpers/error.ts new file mode 100644 index 00000000000..78f2fa12d9a --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/error.ts @@ -0,0 +1,45 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import getStore from '../app/utils/getStore'; +import { addGlobalErrorMessage } from '../store/globalMessages'; +import { parseError } from './request'; + +export function throwGlobalError(param: Response | any): Promise<Response | any> { + const store = getStore(); + + if (param.response instanceof Response) { + /* eslint-disable-next-line no-console */ + console.warn('DEPRECATED: response should not be wrapped, pass it directly.'); + param = param.response; + } + + if (param instanceof Response) { + return parseError(param) + .then( + message => { + store.dispatch(addGlobalErrorMessage(message)); + }, + () => {} + ) + .then(() => Promise.reject(param)); + } + + return Promise.reject(param); +} diff --git a/server/sonar-web/src/main/js/helpers/l10n.ts b/server/sonar-web/src/main/js/helpers/l10n.ts index 9b8fafa258e..149955f2844 100644 --- a/server/sonar-web/src/main/js/helpers/l10n.ts +++ b/server/sonar-web/src/main/js/helpers/l10n.ts @@ -17,22 +17,13 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { fetchL10nBundle } from '../api/l10n'; -import { L10nBundle, L10nBundleRequestParams } from '../types/l10n'; -import { Dict } from '../types/types'; -import { toNotSoISOString } from './dates'; -import { get as loadFromLocalStorage, save as saveInLocalStorage } from './storage'; -export type Messages = Dict<string>; +import { getMessages } from './l10nBundle'; -export const DEFAULT_LOCALE = 'en'; -export const DEFAULT_MESSAGES = { - // eslint-disable-next-line camelcase - default_error_message: 'The request cannot be processed. Try again later.' -}; - -let allMessages: Messages = {}; -let locale: string | undefined; +export function hasMessage(...keys: string[]): boolean { + const messageKey = keys.join('.'); + return getMessages()[messageKey] != null; +} export function translate(...keys: string[]): string { const messageKey = keys.join('.'); @@ -61,23 +52,6 @@ export function translateWithParameters( return `${messageKey}.${parameters.join('.')}`; } -export function hasMessage(...keys: string[]): boolean { - const messageKey = keys.join('.'); - return getMessages()[messageKey] != null; -} - -export function getMessages() { - if (typeof allMessages === 'undefined') { - logWarning('L10n messages are not initialized. Use default messages.'); - return DEFAULT_MESSAGES; - } - return allMessages; -} - -export function resetMessages(newMessages: Messages) { - allMessages = newMessages; -} - export function getLocalizedMetricName( metric: { key: string; name?: string }, short = false @@ -101,14 +75,6 @@ export function getLocalizedMetricDomain(domainName: string) { return hasMessage(bundleKey) ? translate(bundleKey) : domainName; } -export function getCurrentLocale() { - return locale; -} - -export function resetCurrentLocale(newLocale: string) { - locale = newLocale; -} - export function getShortMonthName(index: number) { const months = [ 'Jan', @@ -136,88 +102,3 @@ export function getShortWeekDayName(index: number) { const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; return weekdays[index] ? translate(weekdays[index]) : ''; } - -const L10N_BUNDLE_LS_KEY = 'l10n.bundle'; - -export async function loadL10nBundle() { - const bundle = await getLatestL10nBundle().catch(() => ({ - locale: DEFAULT_LOCALE, - messages: {} - })); - - resetCurrentLocale(bundle.locale); - resetMessages(bundle.messages); - - return bundle; -} - -export async function getLatestL10nBundle() { - const browserLocale = getPreferredLanguage(); - const cachedBundle = loadL10nBundleFromLocalStorage(); - - const params: L10nBundleRequestParams = {}; - - if (browserLocale) { - params.locale = browserLocale; - - if ( - cachedBundle.locale && - browserLocale.startsWith(cachedBundle.locale) && - cachedBundle.timestamp && - cachedBundle.messages - ) { - params.ts = cachedBundle.timestamp; - } - } - - const { effectiveLocale, messages } = await fetchL10nBundle(params).catch(response => { - if (response && response.status === 304) { - return { - effectiveLocale: cachedBundle.locale || browserLocale || DEFAULT_LOCALE, - messages: cachedBundle.messages ?? {} - }; - } - throw new Error(`Unexpected status code: ${response.status}`); - }); - - const bundle = { - timestamp: toNotSoISOString(new Date()), - locale: effectiveLocale, - messages - }; - - saveL10nBundleToLocalStorage(bundle); - - return bundle; -} - -export function getCurrentL10nBundle() { - return loadL10nBundleFromLocalStorage(); -} - -function getPreferredLanguage() { - return window.navigator.languages ? window.navigator.languages[0] : window.navigator.language; -} - -function loadL10nBundleFromLocalStorage() { - let bundle: L10nBundle; - - try { - bundle = JSON.parse(loadFromLocalStorage(L10N_BUNDLE_LS_KEY) ?? '{}'); - } catch { - bundle = {}; - } - - return bundle; -} - -function saveL10nBundleToLocalStorage(bundle: L10nBundle) { - saveInLocalStorage(L10N_BUNDLE_LS_KEY, JSON.stringify(bundle)); -} - -function logWarning(message: string) { - if (process.env.NODE_ENV !== 'production') { - // eslint-disable-next-line no-console - console.warn(message); - } -} diff --git a/server/sonar-web/src/main/js/helpers/l10nBundle.ts b/server/sonar-web/src/main/js/helpers/l10nBundle.ts new file mode 100644 index 00000000000..fc1a4414d57 --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/l10nBundle.ts @@ -0,0 +1,93 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { fetchL10nBundle } from '../api/l10n'; +import { L10nBundle, L10nBundleRequestParams } from '../types/l10nBundle'; +import { toNotSoISOString } from './dates'; + +const DEFAULT_LOCALE = 'en'; +const DEFAULT_MESSAGES = { + // eslint-disable-next-line camelcase + default_error_message: 'The request cannot be processed. Try again later.' +}; + +export function getMessages() { + return getL10nBundleFromCache().messages ?? DEFAULT_MESSAGES; +} + +export function getCurrentLocale() { + return getL10nBundleFromCache().locale; +} + +export function getCurrentL10nBundle() { + return getL10nBundleFromCache(); +} + +export async function loadL10nBundle() { + const browserLocale = getPreferredLanguage(); + const cachedBundle = getL10nBundleFromCache(); + + const params: L10nBundleRequestParams = {}; + + if (browserLocale) { + params.locale = browserLocale; + + if ( + cachedBundle.locale && + browserLocale.startsWith(cachedBundle.locale) && + cachedBundle.timestamp && + cachedBundle.messages + ) { + params.ts = cachedBundle.timestamp; + } + } + + const { effectiveLocale, messages } = await fetchL10nBundle(params).catch(response => { + if (response && response.status === 304) { + return { + effectiveLocale: cachedBundle.locale || browserLocale || DEFAULT_LOCALE, + messages: cachedBundle.messages ?? {} + }; + } + throw new Error(`Unexpected status code: ${response.status}`); + }); + + const bundle = { + timestamp: toNotSoISOString(new Date()), + locale: effectiveLocale, + messages + }; + + persistL10nBundleInCache(bundle); + + return bundle; +} + +function getPreferredLanguage() { + return window.navigator.languages ? window.navigator.languages[0] : window.navigator.language; +} + +function getL10nBundleFromCache() { + return ((window as unknown) as any).sonarQubeL10nBundle ?? {}; +} + +function persistL10nBundleInCache(bundle: L10nBundle) { + ((window as unknown) as any).sonarQubeL10nBundle = bundle; +} diff --git a/server/sonar-web/src/main/js/helpers/measures.ts b/server/sonar-web/src/main/js/helpers/measures.ts index cedf304914a..31aca41f983 100644 --- a/server/sonar-web/src/main/js/helpers/measures.ts +++ b/server/sonar-web/src/main/js/helpers/measures.ts @@ -23,7 +23,8 @@ import { QualityGateStatusConditionEnhanced } from '../types/quality-gates'; import { Dict, Measure, MeasureEnhanced, Metric } from '../types/types'; -import { getCurrentLocale, translate, translateWithParameters } from './l10n'; +import { translate, translateWithParameters } from './l10n'; +import { getCurrentLocale } from './l10nBundle'; import { isDefined } from './types'; export function enhanceMeasuresWithMetrics( diff --git a/server/sonar-web/src/main/js/helpers/mocks/editions.ts b/server/sonar-web/src/main/js/helpers/mocks/editions.ts new file mode 100644 index 00000000000..58fb0b759cb --- /dev/null +++ b/server/sonar-web/src/main/js/helpers/mocks/editions.ts @@ -0,0 +1,41 @@ +/* + * SonarQube + * Copyright (C) 2009-2022 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { License } from '../../types/editions'; + +export function mockLicense(override?: Partial<License>) { + return { + contactEmail: 'contact@sonarsource.com', + edition: 'Developer Edition', + expiresAt: '2018-05-18', + isExpired: false, + isValidEdition: true, + isValidServerId: true, + isOfficialDistribution: true, + isSupported: false, + loc: 120085, + maxLoc: 500000, + plugins: ['Branches', 'PLI language'], + remainingLocThreshold: 490000, + serverId: 'AU-TpxcA-iU5OvuD2FL0', + type: 'production', + ...override + }; +} |