From a7c01da53070d180b5877b078aae5dc566dbf0f4 Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Thu, 14 Sep 2023 21:11:50 +0200 Subject: [PATCH] test-utils: add built-in TranslationApi mock Signed-off-by: Patrik Oldsberg --- packages/test-utils/package.json | 1 + .../apis/TranslationApi/MockTranslationApi.ts | 84 +++++++++++++++++++ .../testUtils/apis/TranslationApi/index.ts | 17 ++++ .../test-utils/src/testUtils/apis/index.ts | 1 + packages/test-utils/src/testUtils/mockApis.ts | 9 +- yarn.lock | 1 + 6 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 packages/test-utils/src/testUtils/apis/TranslationApi/MockTranslationApi.ts create mode 100644 packages/test-utils/src/testUtils/apis/TranslationApi/index.ts diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index ccfbb30a20..5a291d605d 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -61,6 +61,7 @@ "@testing-library/user-event": "^14.0.0", "@types/react": "^16.13.1 || ^17.0.0", "cross-fetch": "^3.1.5", + "i18next": "^22.4.15", "zen-observable": "^0.10.0" }, "peerDependencies": { diff --git a/packages/test-utils/src/testUtils/apis/TranslationApi/MockTranslationApi.ts b/packages/test-utils/src/testUtils/apis/TranslationApi/MockTranslationApi.ts new file mode 100644 index 0000000000..19b4f08479 --- /dev/null +++ b/packages/test-utils/src/testUtils/apis/TranslationApi/MockTranslationApi.ts @@ -0,0 +1,84 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { + TranslationApi, + TranslationRef, + TranslationSnapshot, +} from '@backstage/core-plugin-api/alpha'; +import { createInstance as createI18n, type i18n as I18n } from 'i18next'; +import ObservableImpl from 'zen-observable'; + +import { Observable } from '@backstage/types'; +// Internal import to avoid code duplication, this will lead to duplication in build output +// eslint-disable-next-line @backstage/no-relative-monorepo-imports +import { toInternalTranslationRef } from '../../../../../core-plugin-api/src/translation/TranslationRef'; + +const DEFAULT_LANGUAGE = 'en'; + +/** @alpha */ +export class MockTranslationApi implements TranslationApi { + static create() { + const i18n = createI18n({ + fallbackLng: DEFAULT_LANGUAGE, + supportedLngs: [DEFAULT_LANGUAGE], + interpolation: { + escapeValue: false, + }, + ns: [], + defaultNS: false, + fallbackNS: false, + }); + + i18n.init(); + + return new MockTranslationApi(i18n); + } + + #i18n: I18n; + + private constructor(i18n: I18n) { + this.#i18n = i18n; + } + + getTranslation( + translationRef: TranslationRef, + ): TranslationSnapshot { + const internalRef = toInternalTranslationRef(translationRef); + + const t = this.#i18n.getFixedT(null, internalRef.id); + const defaultMessages = internalRef.getDefaultMessages() as TMessages; + + return { + ready: true, + t: (key, options) => { + return t(key as string, { + ...options, + defaultValue: defaultMessages[key], + }); + }, + }; + } + + translation$(): Observable< + TranslationSnapshot + > { + // No need to implement, getTranslation will always return a ready snapshot + return new ObservableImpl>(_subscriber => { + return () => {}; + }); + } +} diff --git a/packages/test-utils/src/testUtils/apis/TranslationApi/index.ts b/packages/test-utils/src/testUtils/apis/TranslationApi/index.ts new file mode 100644 index 0000000000..2c10347545 --- /dev/null +++ b/packages/test-utils/src/testUtils/apis/TranslationApi/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright 2023 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export { MockTranslationApi } from './MockTranslationApi'; diff --git a/packages/test-utils/src/testUtils/apis/index.ts b/packages/test-utils/src/testUtils/apis/index.ts index e122a4b432..ac56bd6e18 100644 --- a/packages/test-utils/src/testUtils/apis/index.ts +++ b/packages/test-utils/src/testUtils/apis/index.ts @@ -20,3 +20,4 @@ export * from './ErrorApi'; export * from './FetchApi'; export * from './PermissionApi'; export * from './StorageApi'; +export * from './TranslationApi'; diff --git a/packages/test-utils/src/testUtils/mockApis.ts b/packages/test-utils/src/testUtils/mockApis.ts index 0fbfdf5967..9f3b62907c 100644 --- a/packages/test-utils/src/testUtils/mockApis.ts +++ b/packages/test-utils/src/testUtils/mockApis.ts @@ -20,10 +20,17 @@ import { fetchApiRef, storageApiRef, } from '@backstage/core-plugin-api'; -import { MockErrorApi, MockFetchApi, MockStorageApi } from './apis'; +import { translationApiRef } from '@backstage/core-plugin-api/alpha'; +import { + MockErrorApi, + MockFetchApi, + MockStorageApi, + MockTranslationApi, +} from './apis'; export const mockApis = [ createApiFactory(errorApiRef, new MockErrorApi()), createApiFactory(fetchApiRef, new MockFetchApi()), createApiFactory(storageApiRef, MockStorageApi.create()), + createApiFactory(translationApiRef, MockTranslationApi.create()), ]; diff --git a/yarn.lock b/yarn.lock index 567e440ab2..2a037184fa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10063,6 +10063,7 @@ __metadata: "@testing-library/user-event": ^14.0.0 "@types/react": ^16.13.1 || ^17.0.0 cross-fetch: ^3.1.5 + i18next: ^22.4.15 msw: ^1.0.0 zen-observable: ^0.10.0 peerDependencies: