Skip to content

Commit

Permalink
(refactor) Load styleguide config asynchronously in PageHeader (#1133)
Browse files Browse the repository at this point in the history
* (refactor) Load styleguide config asynchronously in PageHeader

This PR refactors the PageHeader component to load the styleguide config
asynchronously via the getConfig function. This fixes an issue where the useConfig hook usage would result in the consuming
component failing to render in the test environment when running tests. I'm not sure why this only happens in the test environment,
but it's likely related to the way the styleguide config is loaded in the test environment. It's also possible that the better approach here would be
to refactor the useConfig stub to make it more flexible, but this PR fixes the issue for now. Functionality should be unchanged.

FWIW, the [other use](https://github.com/openmrs/openmrs-esm-patient-management/blob/main/packages/esm-patient-registration-app/src/patient-registration/form-manager.ts#L139-L140) of the styleguide config in the Patient Management app loads the config asynchronously via the getConfig function,
so this PR is consistent with that approach.

* Review feedback
  • Loading branch information
denniskigen authored Sep 2, 2024
1 parent c8abf51 commit fa6bfd2
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @module @category UI */
import React from 'react';
import React, { useEffect, useState } from 'react';
import classNames from 'classnames';
import { useConfig } from '@openmrs/esm-react-utils';
import { getConfig } from '@openmrs/esm-config';
import { type StyleguideConfigObject } from '../config-schema';
import styles from './page-header.module.scss';

Expand Down Expand Up @@ -87,10 +87,13 @@ export const PageHeader: React.FC<PageHeaderProps> = (props) => {
* ```
*/
export const PageHeaderContent: React.FC<PageHeaderContentProps> = ({ title, illustration, className }) => {
const config = useConfig<StyleguideConfigObject>({
// Do not remove this property. See https://github.com/openmrs/openmrs-esm-core/pull/1125#issuecomment-2313230513 for more context.
externalModuleName: '@openmrs/esm-styleguide',
});
const [config, setConfig] = useState<StyleguideConfigObject | null>(null);

useEffect(() => {
getConfig('@openmrs/esm-styleguide').then((fetchedConfig: StyleguideConfigObject) => {
setConfig(fetchedConfig);
});
}, []);

return (
<div className={classNames(styles.pageHeaderContent, className)}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { getConfig } from '@openmrs/esm-config';
import { PageHeaderContent } from './page-header.component';

const mockedGetConfig = jest.mocked(getConfig);

jest.mock('@openmrs/esm-config', () => ({
getConfig: jest.fn(),
}));

describe('PageHeaderContent', () => {
const mockIllustration = <svg data-testid="mock-illustration" />;

it('renders title and illustration', async () => {
mockedGetConfig.mockResolvedValue({});

render(<PageHeaderContent title="Test Title" illustration={mockIllustration} />);

await screen.findByText(/test title/i);
expect(screen.getByTestId('mock-illustration')).toBeInTheDocument();
});

it('renders implementation name when provided in config', async () => {
mockedGetConfig.mockResolvedValue({ implementationName: 'Test Clinic' });

render(<PageHeaderContent title="Test Title" illustration={mockIllustration} />);

await screen.findByText('Test Clinic');
});

it('does not render implementation name when not provided in config', async () => {
mockedGetConfig.mockResolvedValue({});

render(<PageHeaderContent title="Test Title" illustration={mockIllustration} />);

await screen.findByText(/test title/i);
expect(screen.queryByText('Test Clinic')).not.toBeInTheDocument();
});

it('applies custom className when provided', async () => {
mockedGetConfig.mockResolvedValue({});

const { container } = render(
<PageHeaderContent title="Test Title" illustration={mockIllustration} className="custom-class" />,
);

await screen.findByText(/test title/i);
expect(container.firstChild).toHaveClass('custom-class');
});

it('calls getConfig with correct module name', async () => {
mockedGetConfig.mockResolvedValue({});

render(<PageHeaderContent title="Test Title" illustration={mockIllustration} />);

await screen.findByText(/test title/i);
expect(getConfig).toHaveBeenCalledWith('@openmrs/esm-styleguide');
});
});

0 comments on commit fa6bfd2

Please sign in to comment.