"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require("@testing-library/jest-dom");
const react_1 = __importDefault(require("react"));
const react_core_1 = require("@patternfly/react-core");
const react_icons_1 = require("@patternfly/react-icons");
const react_2 = require("@testing-library/react");
const user_event_1 = __importDefault(require("@testing-library/user-event"));
const SourceDetailsMenuItem_1 = __importDefault(require("../SourceDetailsMenuItem"));
const MessageBar_1 = require("./MessageBar");
const ATTACH_MENU_ITEMS = [
    react_1.default.createElement(react_core_1.DropdownList, { key: "list-1" },
        react_1.default.createElement(react_core_1.DropdownItem, { className: "pf-chatbot-source-details-dropdown-item", value: "auth-operator Pod", id: "0" },
            react_1.default.createElement(SourceDetailsMenuItem_1.default, { icon: react_1.default.createElement("svg", { width: "24", height: "25", viewBox: "0 0 24 25", fill: "none", xmlns: "http://www.w3.org/2000/svg" },
                    react_1.default.createElement("path", { d: "M0 12.5C0 5.87258 5.37258 0.5 12 0.5C18.6274 0.5 24 5.87258 24 12.5C24 19.1274 18.6274 24.5 12 24.5C5.37258 24.5 0 19.1274 0 12.5Z", fill: "currentColor" }),
                    react_1.default.createElement("g", { clipPath: "url(#clip0_3280_27488)" },
                        react_1.default.createElement("path", { d: "M8.25 8.75C8.25 7.92266 8.92266 7.25 9.75 7.25H12C14.0719 7.25 15.75 8.92812 15.75 11C15.75 13.0719 14.0719 14.75 12 14.75H9.75V17C9.75 17.4148 9.41484 17.75 9 17.75C8.58516 17.75 8.25 17.4148 8.25 17V14V8.75ZM9.75 13.25H12C13.2422 13.25 14.25 12.2422 14.25 11C14.25 9.75781 13.2422 8.75 12 8.75H9.75V13.25Z", fill: "white" })),
                    react_1.default.createElement("defs", null,
                        react_1.default.createElement("clipPath", { id: "clip0_3280_27488" },
                            react_1.default.createElement("rect", { width: "7.5", height: "12", fill: "white", transform: "translate(8.25 6.5)" })))), name: "auth-operator", type: "Pod" }))),
    react_1.default.createElement(react_core_1.DropdownGroup, { key: "group2" },
        react_1.default.createElement(react_core_1.DropdownList, null,
            react_1.default.createElement(react_core_1.DropdownItem, { value: "Alerts", id: "1", icon: react_1.default.createElement(react_icons_1.BellIcon, null) }, "Alerts"),
            react_1.default.createElement(react_core_1.DropdownItem, { value: "Events", id: "2", icon: react_1.default.createElement(react_icons_1.CalendarAltIcon, null) }, "Events"),
            react_1.default.createElement(react_core_1.DropdownItem, { value: "Logs", id: "3", icon: react_1.default.createElement(react_icons_1.ClipboardIcon, null) }, "Logs"),
            react_1.default.createElement(react_core_1.DropdownItem, { value: "YAML - Status", id: "4", icon: react_1.default.createElement(react_icons_1.CodeIcon, null) }, "YAML - Status"),
            react_1.default.createElement(react_core_1.DropdownItem, { value: "YAML - All contents", id: "5", icon: react_1.default.createElement(react_icons_1.CodeIcon, null) }, "YAML - All contents")))
];
const originalSpeechRecognition = window.SpeechRecognition;
const mockSpeechRecognition = () => {
    const MockSpeechRecognition = jest.fn().mockImplementation(() => ({
        start: jest.fn(),
        stop: jest.fn()
    }));
    MockSpeechRecognition.prototype = {};
    window.SpeechRecognition = MockSpeechRecognition;
};
describe('Message bar', () => {
    afterAll(() => {
        window.SpeechRecognition = originalSpeechRecognition;
    });
    it('should render correctly', () => {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn }));
        expect(react_2.screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
        expect(react_2.screen.queryByRole('button', { name: 'Send button' })).toBeFalsy();
        expect(react_2.screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
        expect(react_2.screen.getByRole('textbox', { name: /Send a message.../i })).toBeTruthy();
    });
    it('can send via enter key', () => __awaiter(void 0, void 0, void 0, function* () {
        const spy = jest.fn();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: spy }));
        const input = react_2.screen.getByRole('textbox', { name: /Send a message.../i });
        yield user_event_1.default.type(input, 'Hello world');
        expect(input).toHaveTextContent('Hello world');
        yield user_event_1.default.type(input, '[Enter]');
        expect(spy).toHaveBeenCalledTimes(1);
    }));
    it('calls onChange callback appropriately', () => __awaiter(void 0, void 0, void 0, function* () {
        const spy = jest.fn();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, onChange: spy }));
        const input = react_2.screen.getByRole('textbox', { name: /Send a message.../i });
        yield user_event_1.default.type(input, 'A');
        expect(input).toHaveTextContent('A');
        expect(spy).toHaveBeenCalledTimes(1);
        expect(spy).toHaveBeenCalledWith(expect.any(Object), 'A');
    }));
    // Send button
    // --------------------------------------------------------------------------
    it('shows send button when text is input', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn }));
        const input = react_2.screen.getByRole('textbox', { name: /Send a message.../i });
        yield user_event_1.default.type(input, 'Hello world');
        expect(input).toHaveTextContent('Hello world');
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
    }));
    it('can disable send button shown when text is input', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, isSendButtonDisabled: true }));
        const input = react_2.screen.getByRole('textbox', { name: /Send a message.../i });
        yield user_event_1.default.type(input, 'Hello world');
        expect(input).toHaveTextContent('Hello world');
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeDisabled();
    }));
    it('can click send button', () => __awaiter(void 0, void 0, void 0, function* () {
        const spy = jest.fn();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: spy }));
        const input = react_2.screen.getByRole('textbox', { name: /Send a message.../i });
        yield user_event_1.default.type(input, 'Hello world');
        expect(input).toHaveTextContent('Hello world');
        const sendButton = react_2.screen.getByRole('button', { name: 'Send button' });
        expect(sendButton).toBeTruthy();
        yield user_event_1.default.click(sendButton);
        expect(spy).toHaveBeenCalledTimes(1);
    }));
    it('can always show send button', () => {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, alwayShowSendButton: true }));
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeEnabled();
    });
    it('can disable send button if always showing', () => {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, alwayShowSendButton: true, isSendButtonDisabled: true }));
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeDisabled();
    });
    it('can handle buttonProps tooltipContent  appropriately for send', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, alwayShowSendButton: true, buttonProps: { send: { tooltipContent: 'Test' } } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Send button' }));
        expect(react_2.screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
    }));
    it('can handle buttonProps props appropriately for send', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, alwayShowSendButton: true, buttonProps: { send: { props: { 'aria-label': 'Test' } } } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Test' }));
    }));
    // Attach button
    // --------------------------------------------------------------------------
    it('can show attach menu', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, attachMenuProps: {
                isAttachMenuOpen: true,
                setIsAttachMenuOpen: jest.fn(),
                onAttachMenuToggleClick: jest.fn(),
                onAttachMenuInputChange: jest.fn(),
                attachMenuItems: ATTACH_MENU_ITEMS
            } }));
        expect(react_2.screen.getByRole('textbox', { name: /Filter menu items/i })).toBeTruthy();
        expect(react_2.screen.getByRole('menuitem', { name: /auth-operator/i })).toBeTruthy();
        expect(react_2.screen.getByRole('menuitem', { name: /Alerts/i })).toBeTruthy();
        expect(react_2.screen.getByRole('menuitem', { name: /Events/i })).toBeTruthy();
        expect(react_2.screen.getByRole('menuitem', { name: /Logs/i })).toBeTruthy();
        expect(react_2.screen.getByRole('menuitem', { name: /YAML - Status/i })).toBeTruthy();
        expect(react_2.screen.getByRole('menuitem', { name: /YAML - All contents/i })).toBeTruthy();
    }));
    it('can toggle attach menu', () => __awaiter(void 0, void 0, void 0, function* () {
        const attachToggleClickSpy = jest.fn();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, attachMenuProps: {
                isAttachMenuOpen: false,
                setIsAttachMenuOpen: jest.fn(),
                onAttachMenuToggleClick: attachToggleClickSpy,
                onAttachMenuInputChange: jest.fn(),
                attachMenuItems: ATTACH_MENU_ITEMS
            } }));
        expect(react_2.screen.queryByRole('textbox', { name: /Filter menu items/i })).toBeFalsy();
        expect(react_2.screen.queryByRole('menuitem', { name: /auth-operator/i })).toBeFalsy();
        expect(react_2.screen.queryByRole('menuitem', { name: /Alerts/i })).toBeFalsy();
        expect(react_2.screen.queryByRole('menuitem', { name: /Events/i })).toBeFalsy();
        expect(react_2.screen.queryByRole('menuitem', { name: /Logs/i })).toBeFalsy();
        expect(react_2.screen.queryByRole('menuitem', { name: /YAML - Status/i })).toBeFalsy();
        expect(react_2.screen.queryByRole('menuitem', { name: /YAML - All contents/i })).toBeFalsy();
        const attachButton = react_2.screen.getByRole('button', { name: 'Attach button' });
        yield user_event_1.default.click(attachButton);
        expect(attachToggleClickSpy).toHaveBeenCalledTimes(1);
    }));
    it('can hide attach button', () => {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasAttachButton: false }));
        expect(react_2.screen.queryByRole('button', { name: 'Attach button' })).toBeFalsy();
    });
    // Based on this because I had no idea how to do this and was looking around: https://stackoverflow.com/a/75562651
    // See also https://developer.mozilla.org/en-US/docs/Web/API/File/File for what that file variable is doing
    it('can handle handleAttach', () => __awaiter(void 0, void 0, void 0, function* () {
        const spy = jest.fn();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, handleAttach: spy, buttonProps: { attach: { inputTestId: 'input' } } }));
        expect(react_2.screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Attach button' }));
        const file = new File(['test'], 'test.json');
        const input = react_2.screen.getByTestId('input');
        yield user_event_1.default.upload(input, file);
        expect(input.files).toHaveLength(1);
        expect(spy).toHaveBeenCalledTimes(1);
    }));
    it('can handle buttonProps tooltipContent  appropriately for attach', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, buttonProps: { attach: { tooltipContent: 'Test' } } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Attach button' }));
        expect(react_2.screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
    }));
    it('can handle buttonProps props appropriately for attach', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasAttachButton: true, buttonProps: { attach: { props: { 'aria-label': 'Test' } } } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Test' }));
    }));
    // Stop button
    // --------------------------------------------------------------------------
    it('can show stop button', () => {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasStopButton: true, handleStopButton: jest.fn }));
        expect(react_2.screen.getByRole('button', { name: 'Stop button' })).toBeTruthy();
    });
    it('can call handleStopButton', () => __awaiter(void 0, void 0, void 0, function* () {
        const spy = jest.fn();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasStopButton: true, handleStopButton: spy }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Stop button' }));
        expect(spy).toHaveBeenCalledTimes(1);
    }));
    it('can handle buttonProps tooltipContent appropriately for stop', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasStopButton: true, handleStopButton: jest.fn, buttonProps: { stop: { tooltipContent: 'Test' } } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Stop button' }));
        expect(react_2.screen.getByRole('tooltip', { name: 'Test' })).toBeTruthy();
    }));
    it('can handle buttonProps props appropriately for stop', () => __awaiter(void 0, void 0, void 0, function* () {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasStopButton: true, handleStopButton: jest.fn, buttonProps: { stop: { props: { 'aria-label': 'Test' } } } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Test' }));
    }));
    // Microphone button
    // --------------------------------------------------------------------------
    it('can hide microphone button when window.SpeechRecognition is not there', () => {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true }));
        expect(react_2.screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
    });
    it('can show microphone button', () => {
        mockSpeechRecognition();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true }));
        expect(react_2.screen.getByRole('button', { name: 'Microphone button' })).toBeTruthy();
    });
    it('can handle buttonProps appropriately for microphone', () => __awaiter(void 0, void 0, void 0, function* () {
        mockSpeechRecognition();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true, buttonProps: {
                microphone: { tooltipContent: { active: 'Currently listening', inactive: 'Not currently listening' } }
            } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Microphone button' }));
        expect(react_2.screen.getByRole('tooltip', { name: 'Currently listening' })).toBeTruthy();
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Microphone button' }));
        expect(react_2.screen.getByRole('tooltip', { name: 'Not currently listening' })).toBeTruthy();
    }));
    it('can handle buttonProps props appropriately for microphone', () => __awaiter(void 0, void 0, void 0, function* () {
        mockSpeechRecognition();
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, hasMicrophoneButton: true, buttonProps: { microphone: { props: { 'aria-label': 'Test' } } } }));
        yield user_event_1.default.click(react_2.screen.getByRole('button', { name: 'Test' }));
    }));
    it('can be controlled', () => {
        (0, react_2.render)(react_1.default.createElement(MessageBar_1.MessageBar, { onSendMessage: jest.fn, value: "test" }));
        expect(react_2.screen.getByRole('button', { name: 'Attach button' })).toBeTruthy();
        expect(react_2.screen.getByRole('button', { name: 'Send button' })).toBeTruthy();
        expect(react_2.screen.queryByRole('button', { name: 'Microphone button' })).toBeFalsy();
        expect(react_2.screen.getByRole('textbox', { name: /Send a message.../i })).toBeTruthy();
        expect(react_2.screen.getByRole('textbox', { name: /Send a message.../i })).toHaveValue('test');
    });
});
