import { render } from '@testing-library/react';
import { FC } from 'react';
import { useMFEMetadataContext } from '../../contexts/mfe-metadata-context';
import { MfeStyleRegistry } from '../mfe-style-registry';
import { withCssInjector } from '../with-css-injector';
jest.mock('../../contexts/mfe-metadata-context');
jest.mock('../../globals', () => ({
// eslint-disable-next-line @typescript-eslint/naming-convention
WEB_COMPONENT_NAME: 'test-mfe',
}));
jest.mock('../mfe-style-registry');
describe(`[web-components] ${withCssInjector.name}`, () => {
const innerTestId = 'inner';
const innerLabel = 'foo';
const InnerComponent: FC<{ label: string }> = ({ label }) => (
{label}
);
const WrappedComponent = withCssInjector(InnerComponent);
let registry: jest.Mocked;
let shadowRoot: ShadowRoot;
let portalShadowRoot: ShadowRoot;
beforeEach(() => {
jest.clearAllMocks();
delete globalThis.__mfeSelfHosted__;
registry = {
observeRoot: jest.fn(),
unobserveRoot: jest.fn(),
} as unknown as jest.Mocked;
jest.mocked(MfeStyleRegistry.for).mockReturnValue(registry);
shadowRoot = document.createElement('div').attachShadow({ mode: 'open' });
portalShadowRoot = document.createElement('span').attachShadow({ mode: 'open' });
jest.mocked(useMFEMetadataContext).mockImplementation(() => ({
shadowRoot,
portalShadowRoot,
}));
});
const subject = () => render();
test('renders the wrapped component with its props', () => {
const { getByTestId } = subject();
expect(getByTestId(innerTestId).textContent).toBe(innerLabel);
});
test('retrieves the registry for the component', () => {
subject();
expect(MfeStyleRegistry.for).toHaveBeenCalledWith('test-mfe');
});
test('observes shadow root', () => {
subject();
expect(registry.observeRoot).toHaveBeenCalledWith(shadowRoot);
});
test('observes portal shadow root', () => {
subject();
expect(registry.observeRoot).toHaveBeenCalledWith(portalShadowRoot);
});
describe('when self-hosted', () => {
beforeEach(() => {
globalThis.__mfeSelfHosted__ = true;
});
test('observes document', () => {
subject();
expect(registry.observeRoot).toHaveBeenCalledWith(document);
});
test('unobserves document on unmount', () => {
const { unmount } = subject();
unmount();
expect(registry.unobserveRoot).toHaveBeenCalledWith(document);
});
});
describe('when unmounted', () => {
test('unobserves shadow root', () => {
const { unmount } = subject();
unmount();
expect(registry.unobserveRoot).toHaveBeenCalledWith(shadowRoot);
});
test('unobserves portal shadow root', () => {
const { unmount } = subject();
unmount();
expect(registry.unobserveRoot).toHaveBeenCalledWith(portalShadowRoot);
});
});
describe('in production', () => {
const originalEnv = process.env.NODE_ENV;
beforeEach(() => {
process.env.NODE_ENV = 'production';
});
afterEach(() => {
process.env.NODE_ENV = originalEnv;
});
test('returns Component directly', () => {
expect.assertions(1);
jest.isolateModules(() => {
const { withCssInjector: freshWithCssInjector } = require('../with-css-injector');
const Dummy: FC = () => ;
expect(freshWithCssInjector(Dummy)).toBe(Dummy);
});
});
});
});