import React from 'react';
import { renderHook } from '@testing-library/react-hooks';
import { render } from '@testing-library/react';
import { UserIdentityContext, User } from 'src/types';
import { useIdentity, IdentityContext, useUser, withUser } from '../identity';

describe('useIdentity', () => {

    describe('without identity in context', () => {
        test('throws exception', () => {
            const { result } = renderHook(() => useIdentity());
            expect(result.error).toBeDefined();
        });
    });

    describe('with identity in context', () => {
        test('returns context', () => {
            const context = { user: {}, client: {} } as UserIdentityContext;
            const { result } = renderHook(() => useIdentity(), {
                wrapper: ({ children }) => (
                    <IdentityContext.Provider value={context}>
                        {children}
                    </IdentityContext.Provider>
                )
            });
            expect(result.current).toEqual(context);
        });
    });
});

describe('useUser', () => {

    describe('without identity in context', () => {
        test('returns undefined', () => {
            const { result } = renderHook(() => useUser());
            expect(result.current).toBeUndefined();
        });
    });

    describe('with identity in context', () => {
        test('returns user', () => {
            const context = { user: { name: 'test' } } as UserIdentityContext;
            const { result } = renderHook(() => useUser(), {
                wrapper: ({ children }) => (
                    <IdentityContext.Provider value={context}>
                        {children}
                    </IdentityContext.Provider>
                )
            });
            expect(result.current).toEqual(context.user);
        });
    });
});


describe('withUser', () => {

    interface TestProps {
        user: User;
    }

    const context = { user: { name: 'USER NAME' } } as UserIdentityContext;
    const unknown = 'UNDEFINED';
    const TestComponent: React.FC<TestProps> = ({ user }) => (
        <div>{(user && user.name) || unknown}</div>
    );
    const TestConsumer = withUser(TestComponent);

    describe('without identity in context', () => {
        test('renders children with undefined user prop', () => {
            const { getByText } = render(<TestConsumer />);
            expect(getByText(unknown)).toBeVisible();
        });
    });

    describe('with identity in context', () => {
        test('renders children with user prop', () => {
            const { getByText } = render(<TestConsumer />, {
                wrapper: ({ children }) => (
                    <IdentityContext.Provider value={context}>
                        {children}
                    </IdentityContext.Provider>
                )
            });
            expect(getByText(context.user.name || unknown)).toBeVisible();
        });
    });
});
