/*
 * 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.
 *
 * 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.
 */
import React, { ReactChild } from 'react';
import { mount } from 'enzyme';
import { OuiContext } from '../context';
import { OuiI18n, useOuiI18n } from './i18n';
/* eslint-disable local/i18n */
describe('OuiI18n', () => {
  describe('default rendering', () => {
    describe('rendering to dom', () => {
      it('renders a basic string to the dom', () => {
        const component = mount(
          
        );
        expect(component).toMatchSnapshot();
      });
      it('renders a string with placeholders to the dom', () => {
        const component = mount(
          
        );
        expect(component).toMatchSnapshot();
      });
      it('calls a function and renders the result to the dom', () => {
        const values = { type: 'callback', special: 'values' };
        const renderCallback = jest.fn(
          ({ type, special }) => `This is a ${type} with ${special}.`
        );
        const component = mount(
          
        );
        expect(component).toMatchSnapshot();
        expect(renderCallback).toHaveBeenCalledWith(values);
      });
      it('renders when value is null', () => {
        const component = mount(
          
        );
        expect(component).toMatchSnapshot();
      });
    });
    describe('render prop with single token', () => {
      it('renders render prop result to the dom', () => {
        const component = mount(
          
            {(result: ReactChild) => `A nifty thing: ${result}`}
          
        );
        expect(component).toMatchSnapshot();
      });
      it('renders render prop result with placeholders to the dom', () => {
        const component = mount(
          
            {(result: ReactChild) => `Here's something cool: ${result}`}
          
        );
        expect(component).toMatchSnapshot();
      });
      it('calls a function and renders render prop result to the dom', () => {
        const values = { type: 'callback', special: 'values' };
        const renderCallback = jest.fn(
          ({ type, special }) => `This is a ${type} with ${special}.`
        );
        const component = mount(
          
            {(result: string) => `Here's something neat: ${result}`}
          
        );
        expect(component).toMatchSnapshot();
        expect(renderCallback).toHaveBeenCalledWith(values);
      });
    });
    describe('render prop with multiple tokens', () => {
      it('renders render prop result to the dom', () => {
        const component = mount(
          
            {([one, two]: ReactChild[]) => (
              
                {one} {two}
              
            )}
          
        );
        expect(component).toMatchSnapshot();
      });
    });
  });
  describe('reading values from context', () => {
    describe('rendering to dom', () => {
      it('renders a mapped basic string to the dom', () => {
        const component = mount(
          
            
          
        );
        expect(component).toMatchSnapshot();
      });
      it('renders a mapped string with placeholders to the dom', () => {
        const component = mount(
          
            
          
        );
        expect(component).toMatchSnapshot();
      });
      it('calls a mapped function and renders the result to the dom', () => {
        const values = { type: 'callback', special: 'values' };
        const renderCallback = jest.fn(
          ({ type, special }) => `This is a mapped ${type} with ${special}.`
        );
        const component = mount(
          
             ''} values={values} />
          
        );
        expect(component).toMatchSnapshot();
        expect(renderCallback).toHaveBeenCalledWith(values);
      });
    });
    describe('render prop with single token', () => {
      it('renders mapped render prop result to the dom', () => {
        const component = mount(
          
            
              {(result: ReactChild) => `A nifty thing: ${result}`}
            
          
        );
        expect(component).toMatchSnapshot();
      });
      it('renders mapped render prop result with placeholders to the dom', () => {
        const component = mount(
          
            
              {(result: ReactChild) => `Here's something cool: ${result}`}
            
          
        );
        expect(component).toMatchSnapshot();
      });
      it('calls a mapped function and renders render prop result to the dom', () => {
        const values = { type: 'callback', special: 'values' };
        const renderCallback = jest.fn(
          ({ type, special }) => `This is a ${type} with ${special}.`
        );
        const component = mount(
          
            
              {(result: ReactChild) => `Here's something neat: ${result}`}
            
          
        );
        expect(component).toMatchSnapshot();
        expect(renderCallback).toHaveBeenCalledWith(values);
      });
    });
    describe('render prop with multiple tokens', () => {
      it('renders mapped render prop result to the dom', () => {
        const component = mount(
          
            
              {([one, two]: ReactChild[]) => (
                
                  {one} {two}
                
              )}
            
          
        );
        expect(component).toMatchSnapshot();
      });
    });
    describe('mappingFunc', () => {
      it('calls the mapping function with the source string', () => {
        const component = mount(
           value.toUpperCase(),
            }}>
            
              {(one: string) => {one}
}
            
          
        );
        expect(component).toMatchSnapshot();
      });
    });
  });
  describe('useOuiI18n', () => {
    describe('unmapped', () => {
      it('handles single token without values', () => {
        const Component = () => {
          const value = useOuiI18n('token', 'placeholder');
          return 
{value}
;
        };
        const component = mount();
        expect(component).toMatchSnapshot();
      });
      it('handles single token with values', () => {
        const Component = () => {
          const value = useOuiI18n('myToken', 'first {first}, then {second}', {
            first: 'apples',
            second: 'aardvarks',
          });
          return {value}
;
        };
        const component = mount();
        expect(component).toMatchSnapshot();
      });
      it('handles multiple tokens', () => {
        const Component = () => {
          const [first, second] = useOuiI18n(
            ['test1', 'test2'],
            ['the first placeholder', 'the second placeholder']
          );
          return (
            
              {first}
              {second}
            
          );
        };
        const component = mount();
        expect(component).toMatchSnapshot();
      });
      it('calls a function and renders the result to the dom', () => {
        const values = { type: 'callback', special: 'values' };
        const renderCallback = jest.fn(({ type, special }) => (
          
            This is a {type} with {special}.
          
        ));
        const Component = () => (
          {useOuiI18n('test', renderCallback, values)}
        );
        const component = mount();
        expect(component).toMatchSnapshot();
        expect(renderCallback).toHaveBeenCalledWith(values);
      });
    });
  });
  describe('mapped tokens', () => {
    it('handles single token without values', () => {
      const Component = () => {
        const value = useOuiI18n('token', 'placeholder');
        return {value}
;
      };
      const component = mount(
        
          
        
      );
      expect(component).toMatchSnapshot();
    });
    it('handles single token with values', () => {
      const Component = () => {
        const value = useOuiI18n('myToken', 'first {first}, then {second}', {
          first: 'apples',
          second: 'aardvarks',
        });
        return {value}
;
      };
      const component = mount(
        
          
        
      );
      expect(component).toMatchSnapshot();
    });
    it('handles multiple tokens', () => {
      const Component = () => {
        const [first, second] = useOuiI18n(
          ['test1', 'test2'],
          ['the first placeholder', 'the second placeholder']
        );
        return (
          
            {first}
            {second}
          
        );
      };
      const component = mount(
        
          
        
      );
      expect(component).toMatchSnapshot();
    });
    describe('mappingFunc', () => {
      it('calls the mapping function with the source string', () => {
        const Component = () => {
          const value = useOuiI18n('test1', 'placeholder');
          return {value}
;
        };
        const component = mount(
           value.toUpperCase(),
            }}>
            
          
        );
        expect(component).toMatchSnapshot();
      });
    });
  });
});