import React from 'react';
import { render, screen } from '@testing-library/react';
import ResourceLauncher from './ResourceLauncher';
import { PluginLaunchModeType } from '../types';

import { mockPlugin, mockSourceWithPlugin, mockResource } from '../__mocks__/MockModels';

describe('ResourceLauncher', () => {
    const RenderResourceLauncher = jest.fn().mockReturnValue(<div>Resource Launcher UI</div>);
    const defaultPlugin = mockPlugin({
        renderResourceLauncher: () => {
            return RenderResourceLauncher;
        },
    });

    it('should render <li> for each provided source', () => {
        const sources = [mockSourceWithPlugin({ plugin: defaultPlugin }), mockSourceWithPlugin({ id: '2', plugin: defaultPlugin })];
        const onSourceSelect = jest.fn();
        render(<ResourceLauncher sources={sources} onSourceSelect={onSourceSelect} />);

        expect(screen.getByLabelText('sources list')).toBeInTheDocument();
        expect(screen.getByLabelText('sources list').children.length).toEqual(2);
        expect(screen.queryAllByText('Resource Launcher UI').length).toEqual(2);
    });

    it('should render the divider only for source items except the last one', () => {
        const sources = [
            mockSourceWithPlugin({ plugin: defaultPlugin }),
            mockSourceWithPlugin({ id: '2', plugin: defaultPlugin }),
            mockSourceWithPlugin({ id: '3', plugin: defaultPlugin }),
        ];
        const onSourceSelect = jest.fn();
        const { container } = render(<ResourceLauncher sources={sources} onSourceSelect={onSourceSelect} />);

        const dividerContainers = container.querySelectorAll('div.pt-3.pb-3');
        // With 3 sources, there should be 2 dividers (in the first two <li>s)
        expect(dividerContainers.length).toEqual(sources.length - 1);
    });

    it('onSourceSelect query', async () => {
        const sources = [mockSourceWithPlugin({ plugin: defaultPlugin })];
        const onSourceSelect = jest.fn();
        render(<ResourceLauncher sources={sources} onSourceSelect={onSourceSelect} />);

        // Get the first plugin function launcher components called props
        const { onSearch } = (RenderResourceLauncher as jest.Mock).mock.calls[0][0];

        // Invoke the onSearch handler
        onSearch('test');
        expect(onSourceSelect).toHaveBeenCalledWith(sources[0], { type: PluginLaunchModeType.Search, args: { query: 'test' } });
    });

    it('onSourceSelect browse', async () => {
        const sources = [mockSourceWithPlugin({ plugin: defaultPlugin })];
        const onSourceSelect = jest.fn();
        render(<ResourceLauncher sources={sources} onSourceSelect={onSourceSelect} />);

        // Get the first plugin function launcher components called props
        const { onBrowse } = (RenderResourceLauncher as jest.Mock).mock.calls[0][0];

        // Invoke the onBrowse handler
        onBrowse();
        expect(onSourceSelect).toHaveBeenCalledWith(sources[0], { type: PluginLaunchModeType.Browse, args: { browseTo: undefined } });
    });

    it('onSourceSelect browseTo', async () => {
        const sources = [mockSourceWithPlugin({ plugin: defaultPlugin })];
        const onSourceSelect = jest.fn();
        render(<ResourceLauncher sources={sources} onSourceSelect={onSourceSelect} />);

        // Get the first plugin function launcher components called props
        const { onBrowse } = (RenderResourceLauncher as jest.Mock).mock.calls[0][0];

        // Invoke the onBrowse handler
        const browseTo = mockResource();
        onBrowse(browseTo);
        expect(onSourceSelect).toHaveBeenCalledWith(sources[0], { type: PluginLaunchModeType.Browse, args: { browseTo } });
    });
});
