import React from 'react';
import { render } from '@testing-library/react';
import { Identity } from '@theorchard/suite-identity';
import { MemoryRouter } from 'react-router-dom';
import * as appContext from '../../../app/appContext';
import { AppContext } from '../../../types';
import { clearRoutes, registerModuleRoute } from '../../../utils';
import { RouteLink } from '../routeLink';

describe('ModuleLink', () => {
    const page1 = () => <>home</>;
    const page2 = () => <>admin</>;

    const route1 = { id: 'home', path: '/home', page: page1 };
    const route2 = {
        id: 'admin',
        path: '/admin',
        page: page2,
        roles: ['admin'],
    };

    beforeEach(() => {
        clearRoutes();

        registerModuleRoute('one', route1);
        registerModuleRoute('two', route2);
    });

    const renderLink = (routeId: string, identity: Identity) => {
        vi.spyOn(appContext, 'useAppContext').mockReturnValue({
            config: {},
            graphqlClient: {},
            authClient: {},
            identity,
        } as AppContext);

        return render(
            <MemoryRouter>
                <RouteLink routeId={routeId}>link text</RouteLink>
            </MemoryRouter>
        );
    };

    test('renders a link', () => {
        const { getByText } = renderLink('home', {} as Identity);

        const element = getByText('link text');

        expect(element).toBeInTheDocument();
        expect(element).toHaveAttribute('href', '/home');
    });

    describe('user has access to route', () => {
        test('renders the link', () => {
            const { getByText } = renderLink('admin', {
                roles: ['admin'],
            } as Identity);

            const element = getByText('link text');

            expect(element).toBeInTheDocument();
            expect(element).toHaveAttribute('href', '/admin');
        });
    });

    describe('user does not have access to route', () => {
        test('does not render the link', () => {
            const { queryByText } = renderLink('admin', {
                roles: ['view'],
            } as Identity);

            const element = queryByText('link text');

            expect(element).toBeNull();
        });
    });

    describe('route does not exist', () => {
        test('does not render the link', () => {
            const { queryByText } = renderLink('bull', {
                roles: ['view'],
            } as Identity);

            const element = queryByText('link text');

            expect(element).toBeNull();
        });
    });
});
