import React from 'react';
import { render } from '@testing-library/react';
import { NormalizedCacheObject } from 'apollo-cache-inmemory';
import ApolloClient from 'apollo-client';
import { omit } from 'lodash';
import * as apollo from 'src/apollo';
import { WorkstationConfig, WorkstationIdentity } from 'src/types';
import { LocalizationManager } from 'src/utils';
import Datadog from 'src/utils/datadog';
import { Wrapper } from '../wrapper';

describe('Wrapper', () => {
    const identity = {
        locale: 'de',
        features: {},
        user: {
            identity: {
                localization: 'fr',
            },
        },
    } as unknown as WorkstationIdentity;

    const config = {
        brand: 'awal',
        cdnUrl: 'cdn-url',
    } as WorkstationConfig;

    const mockClient = {} as ApolloClient<NormalizedCacheObject>;

    beforeEach(() => {
        jest.spyOn(apollo, 'default').mockReturnValue(mockClient);
        jest.spyOn(Datadog, 'persistConfig').mockImplementation();
    });

    afterEach(() => {
        LocalizationManager.setCurrentLocale('en');
        jest.clearAllMocks();
    });

    test('sets locale from workstation identity', async () => {
        const setLocaleSpy = jest.spyOn(
            LocalizationManager,
            'setCurrentLocale'
        );

        render(<Wrapper loading={false} data={{ identity, config }} />);

        expect(setLocaleSpy).toHaveBeenCalledWith(
            identity.user.identity?.localization
        );

        expect(window.ORCHARD_LOCALE).toEqual(
            identity.user.identity?.localization
        );
    });

    test('fallbacks to locale from identity', async () => {
        const setLocaleSpy = jest.spyOn(
            LocalizationManager,
            'setCurrentLocale'
        );

        render(
            <Wrapper
                loading={false}
                data={{
                    identity: omit(identity, 'user'),
                    config,
                }}
            />
        );

        expect(setLocaleSpy).toHaveBeenCalledWith(identity.locale);
        expect(window.ORCHARD_LOCALE).toEqual(identity.locale);
    });

    test('sets branded favicon', async () => {
        const link = document.createElement('link');
        link.setAttribute('rel', 'shortcut icon');
        link.setAttribute('href', 'favicon.ico');
        document.head.appendChild(link);

        render(<Wrapper loading={false} data={{ identity, config }} />);

        expect(link.getAttribute('href')).toEqual(
            'cdn-url/assets/awal/icons/workstation_app.svg'
        );
    });

    test('calls Datadog.persistConfig', () => {
        render(<Wrapper loading={false} data={{ identity, config }} />);

        expect(Datadog.persistConfig).toHaveBeenCalledTimes(1);
        expect(Datadog.persistConfig).toHaveBeenCalledWith(config);
    });

    test('creates apollo client once', () => {
        const { rerender } = render(
            <Wrapper loading={false} data={{ identity, config }} />
        );

        rerender(<Wrapper loading={false} data={{ identity, config }} />);

        expect(apollo.default).toHaveBeenCalledTimes(1);
    });
});
