Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(tests) O3-4097 Add tests for rendering a dummy schema #13

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 14 additions & 26 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,22 @@
/**
* @returns {Promise<import('jest').Config>}
*/
const path = require('path');

/** @type {import('jest').Config} */
module.exports = {
collectCoverageFrom: [
'**/src/**/*.component.tsx',
'!**/node_modules/**',
'!**/vendor/**',
'!**/src/**/*.test.*',
'!**/src/declarations.d.ts',
'!**/e2e/**',
],
clearMocks: true,
transform: {
'^.+\\.tsx?$': ['@swc/jest'],
},
transformIgnorePatterns: ['/node_modules/(?!@openmrs)'],
moduleNameMapper: {
'@openmrs/esm-framework': '@openmrs/esm-framework/mock',
'@openmrs/esm-utils': '@openmrs/esm-framework/mock',
'\\.(s?css)$': 'identity-obj-proxy',
'^lodash-es/(.*)$': 'lodash/$1',
'lodash-es': 'lodash',
'^dexie$': require.resolve('dexie'),
'^@testing-library/jest-dom/extend-expect$': '@testing-library/jest-dom',
},
moduleNameMapper: {
'^@carbon/icons-react/es/(.*)$': '@carbon/icons-react/lib/$1',
'^carbon-components-react/es/(.*)$': 'carbon-components-react/lib/$1',
'@openmrs/esm-framework': '@openmrs/esm-framework/mock',
'\\.(s?css)$': 'identity-obj-proxy',
'^lodash-es/(.*)$': 'lodash/$1',
'lodash-es': 'lodash',
'^dexie$': '<rootDir>/node_modules/dexie',
'^react-i18next$': '<rootDir>/__mocks__/react-i18next.js',
'ace-builds': '<rootDir>/node_modules/ace-builds',
},
setupFilesAfterEnv: ['<rootDir>/src/setup-tests.ts'],
testPathIgnorePatterns: [path.resolve(__dirname, 'e2e')],
testEnvironment: 'jsdom',
testEnvironmentOptions: {
url: 'http://localhost/',
},
testPathIgnorePatterns: ['<rootDir>/e2e'],
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"dotenv": "^16.4.5",
"file-loader": "^6.2.0",
"fuzzy": "^0.1.3",
"globy": "^0.1.8",
"lodash-es": "^4.17.21",
"react-ace": "^11.0.1",
"sass": "^1.67.0",
Expand All @@ -75,7 +76,7 @@
"@swc/core": "^1.5.7",
"@swc/jest": "^0.2.36",
"@testing-library/dom": "^9.3.4",
"@testing-library/jest-dom": "^6.6.1",
"@testing-library/jest-dom": "^6.6.2",
"@testing-library/react": "^14.3.1",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.12",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import { useTranslation } from 'react-i18next';
import ConfigureDashboardModal from './add-columns-modal.component';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
import { useTranslation } from 'react-i18next';
import { showSnackbar } from '@openmrs/esm-framework';
import PackageModal from './add-package-modal.component';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
import { useTranslation } from 'react-i18next';
import { showSnackbar } from '@openmrs/esm-framework';
import NewSubMenuModal from './add-submenu-modal.component';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import ConfigureDashboardModal from './configure-dashboard-modal.component';
import { showSnackbar } from '@openmrs/esm-framework';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
import DeleteConfigDetailModal from './delete-config-detail-modal.component';
import { WidgetTypes } from '../../types';
import userEvent from '@testing-library/user-event';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import React from 'react';
import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import { I18nextProvider } from 'react-i18next';
import i18n from 'i18next';
import '@testing-library/jest-dom';
import EditTabDefinitionModal from './edit-tab-definition-modal';
import userEvent from '@testing-library/user-event';

const renderWithI18n = (ui: React.ReactElement) => {
return render(<I18nextProvider i18n={i18n}>{ui}</I18nextProvider>);
};

describe('EditTabDefinitionModal', () => {
const mockOnSave = jest.fn();
const mockOnCancel = jest.fn();
Expand All @@ -20,7 +14,7 @@ describe('EditTabDefinitionModal', () => {
});

it('renders with initial values', () => {
const { getByLabelText } = renderWithI18n(
const { getByLabelText } = render(
<EditTabDefinitionModal tabDefinition={tabDefinition} onSave={mockOnSave} onCancel={mockOnCancel} />,
);

Expand All @@ -30,7 +24,7 @@ describe('EditTabDefinitionModal', () => {

it('calls onSave with updated values', async () => {
const user = userEvent.setup();
const { getByLabelText, getByText } = renderWithI18n(
const { getByLabelText, getByText } = render(
<EditTabDefinitionModal tabDefinition={tabDefinition} onSave={mockOnSave} onCancel={mockOnCancel} />,
);

Expand All @@ -51,7 +45,7 @@ describe('EditTabDefinitionModal', () => {

it('calls onCancel when cancel button is clicked', async () => {
const user = userEvent.setup();
const { getByText } = renderWithI18n(
const { getByText } = render(
<EditTabDefinitionModal tabDefinition={tabDefinition} onSave={mockOnSave} onCancel={mockOnCancel} />,
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import '@testing-library/jest-dom';
import { showModal, showSnackbar } from '@openmrs/esm-framework';
import InteractiveBuilder from './interactive-builder.component';
import { v4 as uuidv4 } from 'uuid';
Expand Down
54 changes: 54 additions & 0 deletions src/components/view-editor/view-editor.component.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import { ContentPackagesEditorContent } from './view-editor.component';
import userEvent from '@testing-library/user-event';

jest.mock('react-i18next', () => ({
useTranslation: () => ({
t: (key) => key,
}),
}));

beforeEach(() => {
localStorage.clear();
});

describe('ContentPackagesEditorContent', () => {
it('renders correctly and allows inputting dummy schema', async () => {
render(
<MemoryRouter initialEntries={['/clinical-views-builder/new']}>
<ContentPackagesEditorContent t={(key) => key} />
</MemoryRouter>,
);

expect(screen.getByText('schemaEditor')).toBeInTheDocument();
const importSchemaButtons = screen.queryAllByText(/importSchema/i);
expect(importSchemaButtons.length).toBeGreaterThan(0);
expect(screen.getByText(/inputDummySchema/i)).toBeInTheDocument();

await userEvent.click(screen.getByText(/inputDummySchema/i));

expect(screen.getByText(/interactiveBuilderInfo/i)).toBeInTheDocument();
expect(screen.getByText(/Package One/i)).toBeInTheDocument();
expect(screen.getByText(/clinicalViewMenus/i)).toBeInTheDocument();
expect(screen.getByText(/First Menu/i)).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', { name: /First Menu/i }));
expect(screen.getByText(/menuSlot\s*:\s*first-menu-slot/i)).toBeInTheDocument();
const firstHelperText = screen.getAllByText(/helperTextForAddDasboards/i)[0];
expect(firstHelperText).toBeInTheDocument();

const firstConfigureButton = screen.getAllByRole('button', { name: /configureDashboard/i })[0];
expect(firstConfigureButton).toBeInTheDocument();
expect(screen.getByText(/Second Menu/i)).toBeInTheDocument();

await userEvent.click(screen.getByRole('button', { name: /Second Menu/i }));
expect(screen.getByText(/menuSlot\s*:\s*second-menu-slot/i)).toBeInTheDocument();
const secondHelperText = screen.getAllByText(/helperTextForAddDasboards/i)[1];
expect(secondHelperText).toBeInTheDocument();

const secondConfigureButton = screen.getAllByRole('button', { name: /configureDashboard/i })[1];
expect(secondConfigureButton).toBeInTheDocument();
expect(screen.getByRole('button', { name: /addClinicalViewSubMenu/i })).toBeInTheDocument();
});
});
8 changes: 4 additions & 4 deletions src/components/view-editor/view-editor.component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface TranslationFnProps {
t: TFunction;
}

const ContentPackagesEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
export const ContentPackagesEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
const [isMaximized, setIsMaximized] = useState(false);

const [schema, setSchema] = useState<Schema>();
Expand Down Expand Up @@ -295,7 +295,7 @@ const ContentPackagesEditorContent: React.FC<TranslationFnProps> = ({ t }) => {
);
};

function BackButton({ t }: TranslationFnProps) {
export function BackButton({ t }: TranslationFnProps) {
return (
<div className={styles.backButton}>
<ConfigurableLink to={window.getOpenmrsSpaBase() + 'clinical-views-builder'}>
Expand All @@ -311,7 +311,7 @@ function BackButton({ t }: TranslationFnProps) {
);
}

function ClinicalViewsEditor() {
const ClinicalViewsEditor: React.FC = () => {
const { t } = useTranslation();

return (
Expand All @@ -321,6 +321,6 @@ function ClinicalViewsEditor() {
<ContentPackagesEditorContent t={t} />
</>
);
}
};

export default ClinicalViewsEditor;
8 changes: 8 additions & 0 deletions src/setup-tests.ts
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
import '@testing-library/jest-dom';

window.URL.createObjectURL = jest.fn();
window.openmrsBase = '/openmrs';
window.spaBase = '/spa';
window.getOpenmrsSpaBase = () => '/openmrs/spa/';

// https://github.com/jsdom/jsdom/issues/1695
window.HTMLElement.prototype.scrollIntoView = function () {};
30 changes: 30 additions & 0 deletions src/test-helpers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { SWRConfig } from 'swr';
import { type RenderOptions, render, screen, waitForElementToBeRemoved } from '@testing-library/react';

// This component wraps whatever component is passed to it with an SWRConfig context which provides a global configuration for all SWR hooks.
const swrWrapper = ({ children }: { children: React.ReactNode }) => {
return (
<SWRConfig
value={{
// Sets the `dedupingInterval` to 0 - we don't need to dedupe requests in our test environment.
dedupingInterval: 0,
// Returns a new Map object, effectively wrapping our application with an empty cache provider. This is useful for resetting the SWR cache between test cases.
provider: () => new Map(),
}}
>
{children}
</SWRConfig>
);
};

// Render the provided component within the wrapper we created above
export const renderWithSwr = (ui: React.ReactElement, options?: RenderOptions) =>
render(ui, { wrapper: swrWrapper, ...options });

// Helper function that waits for a loading state to disappear from the screen
export function waitForLoadingToFinish() {
return waitForElementToBeRemoved(() => [...screen.queryAllByRole('progressbar')], {
timeout: 4000,
});
}
11 changes: 10 additions & 1 deletion webpack.config.js
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
module.exports = require('openmrs/default-webpack-config');
const config = (module.exports = require('openmrs/default-webpack-config'));
config.scriptRuleConfig.exclude = /(node_modules(?![/\\]@(?:openmrs|ohri)))/;
config.overrides.resolve = {
extensions: ['.tsx', '.ts', '.jsx', '.js', '.scss', '.json'],
alias: {
'@openmrs/esm-framework': '@openmrs/esm-framework/src/internal',
'@openmrs/esm-form-engine-lib': '@openmrs/esm-form-engine-lib/src/index',
},
};
module.exports = config;
28 changes: 23 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3127,7 +3127,7 @@ __metadata:
"@swc/core": "npm:^1.5.7"
"@swc/jest": "npm:^0.2.36"
"@testing-library/dom": "npm:^9.3.4"
"@testing-library/jest-dom": "npm:^6.6.1"
"@testing-library/jest-dom": "npm:^6.6.2"
"@testing-library/react": "npm:^14.3.1"
"@testing-library/user-event": "npm:^14.5.2"
"@types/jest": "npm:^29.5.12"
Expand All @@ -3148,6 +3148,7 @@ __metadata:
eslint-plugin-testing-library: "npm:^6.2.2"
file-loader: "npm:^6.2.0"
fuzzy: "npm:^0.1.3"
globy: "npm:^0.1.8"
husky: "npm:^8.0.3"
i18next: "npm:^23.11.4"
i18next-parser: "npm:^9.0.2"
Expand Down Expand Up @@ -5722,9 +5723,9 @@ __metadata:
languageName: node
linkType: hard

"@testing-library/jest-dom@npm:^6.6.1":
version: 6.6.1
resolution: "@testing-library/jest-dom@npm:6.6.1"
"@testing-library/jest-dom@npm:^6.6.2":
version: 6.6.2
resolution: "@testing-library/jest-dom@npm:6.6.2"
dependencies:
"@adobe/css-tools": "npm:^4.4.0"
aria-query: "npm:^5.0.0"
Expand All @@ -5733,7 +5734,7 @@ __metadata:
dom-accessibility-api: "npm:^0.6.3"
lodash: "npm:^4.17.21"
redent: "npm:^3.0.0"
checksum: 10/006357d7547cc50624564a1b0e9986d0f0252365a6e5ac1c7c989032159c47226adfbd9a9ac17eef236738e9597541d344176176b5c3ed0e06e8f4b33387e135
checksum: 10/c5f1ac369e685ea7c17eff190f2e9996e6e54615a3048c3c00cbbbec48f94c557d348ba935a7e8170efbbb109c035785952f6e46d0c03edb18e9a8cc55f8f118
languageName: node
linkType: hard

Expand Down Expand Up @@ -11489,6 +11490,16 @@ __metadata:
languageName: node
linkType: hard

"globy@npm:^0.1.8":
version: 0.1.8
resolution: "globy@npm:0.1.8"
dependencies:
nan: "npm:^1.2.0"
node-gyp: "npm:latest"
checksum: 10/83c3217aa066ad9d9299413b575f6400534271f4a750aa6365cb5cda122757a70fbe5883fa65c337adc14937e4d541142f8b64d077cc35b3608e215a2d6758e6
languageName: node
linkType: hard

"gopd@npm:^1.0.1":
version: 1.0.1
resolution: "gopd@npm:1.0.1"
Expand Down Expand Up @@ -14392,6 +14403,13 @@ __metadata:
languageName: node
linkType: hard

"nan@npm:^1.2.0":
version: 1.9.0
resolution: "nan@npm:1.9.0"
checksum: 10/2a52437a19e6d63da98264011352719cfcec139d41f4d59f6f1a6ecb19110f9eac6527c51fa9186c9d61ec608572be5107b5a84ccf0ba166f4289e5763ab70a3
languageName: node
linkType: hard

"nanoid@npm:^3.3.7":
version: 3.3.7
resolution: "nanoid@npm:3.3.7"
Expand Down
Loading