import React from 'react';
import { render, screen } from '@testing-library/react';
import { VARIANT_CONTROL, VARIANT_ENABLED } from 'src/constants/permissions';
import IdentityContext from 'src/context';
import { IdentityManager } from 'src/utils';
import IdentityProvider from '../identity-provider';
import type { FeatureFlagDictionary } from '@orchard/frontend-identity';
import type { WorkstationUser } from 'src/types';

describe('<IdentityProvider>', () => {
    const TEST_FF1 = 'TEST_FF1';
    const TEST_FF2 = 'TEST_FF2';

    const user: WorkstationUser = {
        accountName: 'timmy',
    };

    const defaultProps = {
        user,
        featureFlags: {
            [TEST_FF1]: VARIANT_ENABLED,
            [TEST_FF2]: VARIANT_CONTROL,
        } as FeatureFlagDictionary,
    };

    // Consumer reads identity from IdentityContext
    const Consumer = () => {
        const { identity } = React.useContext(IdentityContext);
        return <div>{identity?.accountName ?? ''}</div>;
    };

    const renderComponent = (props: Partial<typeof defaultProps> = {}) =>
        render(
            <IdentityProvider {...defaultProps} {...props}>
                <Consumer />
            </IdentityProvider>
        );

    afterEach(() => {
        IdentityManager.instance.identity = undefined;
    });

    test('provides context to children', () => {
        renderComponent();
        expect(screen.getByText(user.accountName!)).toBeInTheDocument();
    });

    test('sets identity in IdentityManager', () => {
        renderComponent();
        expect(IdentityManager.instance.identity).toMatchObject(user);
    });

    test('sets featureFlags in IdentityManager', () => {
        renderComponent();
        expect(IdentityManager.instance.hasFeatureFlag(TEST_FF1)).toEqual(true);
        expect(IdentityManager.instance.hasFeatureFlag(TEST_FF2)).toEqual(
            false
        );
    });

    describe('on empty identity', () => {
        const emptyProps: Partial<typeof defaultProps>[] = [
            { user: undefined },
            { user: {} },
        ];

        test('provides anonymous identity in context', () => {
            emptyProps.forEach(props => {
                const { unmount, container } = renderComponent(props);
                expect(container.textContent).toBe('');
                unmount();
            });
        });
    });
});
