/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you 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.
*/
/**
* Components using the @osd/i18n module require access to the intl context.
* This is not available when mounting single components in Enzyme.
* These helper functions aim to address that and wrap a valid,
* intl context around them.
*/
import { I18nProvider, InjectedIntl, intlShape, __IntlProvider } from '@osd/i18n/react';
import { mount, ReactWrapper, render, shallow } from 'enzyme';
import React, { ReactElement, ValidationMap } from 'react';
import { IntlProvider } from 'react-intl';
// Use fake component to extract `intl` property to use in tests.
const { intl } = (mount(
).find('IntlProvider') as ReactWrapper<{}, {}, __IntlProvider>)
.instance()
.getChildContext();
function getOptions(context = {}, childContextTypes: ValidationMap = {}, props = {}) {
return {
context: {
...context,
intl,
},
childContextTypes: {
...childContextTypes,
intl: intlShape,
},
...props,
};
}
/**
* When using @osd/i18n `injectI18n` on components, props.intl is required.
*/
export function nodeWithIntlProp(
node: ReactElement
): ReactElement {
return React.cloneElement(node, { intl });
}
/**
* Creates the wrapped IntlProvider instance
*
* @param node The React element or cheerio wrapper
* @return The wrapped IntlProvider instance
*/
export function wrapWithIntl(node: ReactElement) {
return {node};
}
/**
* Creates the wrapper instance using shallow with provided intl object into context
*
* @param node The React element or cheerio wrapper
* @param options properties to pass into shallow wrapper
* @return The wrapper instance around the rendered output with intl object in context
*/
export function shallowWithIntl(
node: ReactElement,
{
context,
childContextTypes,
...props
}: {
context?: any;
childContextTypes?: ValidationMap;
} = {}
) {
const options = getOptions(context, childContextTypes, props);
return shallow(nodeWithIntlProp(node), options);
}
/**
* Creates the wrapper instance using mount with provided intl object into context
*
* @param node The React element or cheerio wrapper
* @param options properties to pass into mount wrapper
* @return The wrapper instance around the rendered output with intl object in context
*/
export function mountWithIntl(
node: ReactElement,
{
context,
childContextTypes,
...props
}: {
context?: any;
childContextTypes?: ValidationMap;
} = {}
) {
const options = getOptions(context, childContextTypes, props);
return mount(nodeWithIntlProp(node), options);
}
/**
* Creates the wrapper instance using render with provided intl object into context
*
* @param node The React element or cheerio wrapper
* @param options properties to pass into render wrapper
* @return The wrapper instance around the rendered output with intl object in context
*/
export function renderWithIntl(
node: ReactElement,
{
context,
childContextTypes,
...props
}: {
context?: any;
childContextTypes?: ValidationMap;
} = {}
) {
const options = getOptions(context, childContextTypes, props);
return render(nodeWithIntlProp(node), options);
}
export const nextTick = () => new Promise((res) => process.nextTick(res));
export function shallowWithI18nProvider(child: ReactElement) {
const wrapped = shallow({child});
const name = typeof child.type === 'string' ? child.type : child.type.name;
return wrapped.find(name).dive();
}
export function mountWithI18nProvider(child: ReactElement) {
const wrapped = mount({child});
const name = typeof child.type === 'string' ? child.type : child.type.name;
return wrapped.find(name);
}