From eb383c4c9f6fed96f0fb957718f4a3b851cdc5c1 Mon Sep 17 00:00:00 2001
From: Jonas Braathen <jbr@uio.no>
Date: Wed, 12 Jul 2023 21:21:53 +0200
Subject: [PATCH] Replace the mock of react-i18next with a configured i18next
 provider

---
 frontend/src/test-utils.tsx | 95 +++++++++----------------------------
 1 file changed, 23 insertions(+), 72 deletions(-)

diff --git a/frontend/src/test-utils.tsx b/frontend/src/test-utils.tsx
index fa873902..78d06443 100644
--- a/frontend/src/test-utils.tsx
+++ b/frontend/src/test-utils.tsx
@@ -1,12 +1,32 @@
-import React from 'react'
-import { render } from '@testing-library/react'
 import { ThemeProvider } from '@mui/material/styles'
+import { render } from '@testing-library/react'
+import React from 'react'
+import { I18nextProvider, initReactI18next } from 'react-i18next'
+import i18n from 'i18next'
 
 import { defaultTheme } from 'themes'
 
+i18n.use(initReactI18next).init({
+  lng: 'en',
+  fallbackLng: 'en',
+
+  ns: ['translationsNS'],
+  defaultNS: 'translationsNS',
+
+  debug: false,
+
+  interpolation: {
+    escapeValue: false,
+  },
+
+  resources: { en: { translationsNS: {} } },
+})
+
 // Providers used in test rendering
 const AllTheProviders = ({ children }: any) => (
-  <ThemeProvider theme={defaultTheme}> {children} </ThemeProvider>
+  <I18nextProvider i18n={i18n}>
+    <ThemeProvider theme={defaultTheme}> {children} </ThemeProvider>
+  </I18nextProvider>
 )
 
 // Custom testing-library/react renderer using our providers.
@@ -18,72 +38,3 @@ export * from '@testing-library/react'
 
 // override render method
 export { customRender as render }
-
-// The reason for this complex mock of react-i18next is to make the Trans-component work when running tests
-jest.mock('react-i18next', (): object => {
-  // Need to require React at this level as well to avoid getting an error
-  // when running the tests saying that the module factory is not allowed
-  // to reference out-of-scope variables
-  // eslint-disable-next-line @typescript-eslint/no-shadow,global-require
-  const React = require('react')
-
-  const hasChildren = (node: any): boolean =>
-    node && (node.children || (node.props && node.props.children))
-
-  const getChildrenFromProps = (node: any): any =>
-    node.props && node.props.children ? node.props.children : null
-
-  const getChildren = (node: any): any =>
-    node && node.children ? node.children : getChildrenFromProps(node)
-
-  const renderNodes = (reactNodes: any): any => {
-    if (typeof reactNodes === 'string') {
-      return reactNodes
-    }
-
-    return Object.keys(reactNodes).map((key, i) => {
-      const child = reactNodes[key]
-
-      if (typeof child === 'string') {
-        return child
-      }
-
-      if (hasChildren(child)) {
-        const inner = renderNodes(getChildren(child))
-        // eslint-disable-next-line react/no-array-index-key
-        return React.cloneElement(child, { ...child.props, key: i }, inner)
-      }
-
-      const isElement = React.isValidElement(child)
-      if (typeof child === 'object' && !isElement) {
-        return Object.keys(child).reduce(
-          (str, childKey) => `${str}${child[childKey]}`,
-          ''
-        )
-      }
-
-      return child
-    })
-  }
-
-  const useMock: any = [(k: any) => k, {}]
-  // Mock react-i18next module to return a translation that just returns the key
-  useMock.t = (k: any) => k
-  useMock.i18n = {
-    // Return "en" as the selected language if the code asks for it
-    language: 'en',
-    changeLanguage: () => new Promise(() => {}),
-  }
-
-  return {
-    withTranslation:
-      () =>
-      (Component: any): any =>
-      (props: any): any =>
-        <Component t={(k: any): any => k} {...props} />,
-    Trans: ({ children }: any) => renderNodes(children),
-    Translation: ({ children }: any) =>
-      children((k: any): any => k, { i18n: {} }),
-    useTranslation: () => useMock,
-  }
-})
-- 
GitLab