import { describe, expect, jest, test, } from '@jest/globals'; import { fireEvent, render, waitFor } from '@testing-library/react'; import * as React from 'react'; import Bubble from '../src/Bubble'; import { BubbleType } from '../src/types'; import { askString, deleteAttribute, deleteElement } from '../src/Util'; describe('Bubble component', () => { test('attribute asker bubble renders properly', () => { const docSpec = { elements: { root: { attributes: { attribute: { asker: askString, }, }, }, }, }; const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('attribute menu bubble renders properly', async () => { const docSpec = { elements: { root: { attributes: { attribute: { menu: [{ action: deleteAttribute, caption: 'Delete this attribute', }], }, }, }, }, }; const setXml = jest.fn(); const showBubble = jest.fn(); const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('Click attribute action should modify xml and close bubble', async () => { const docSpec = { elements: { root: { attributes: { attribute: { menu: [{ action: deleteAttribute, caption: 'Delete this attribute', }], }, }, }, }, }; const setXml = jest.fn(); const showBubble = jest.fn(); const { getByText } = render( , ); fireEvent.click(getByText('Delete this attribute')); await waitFor(() => expect(setXml).toHaveBeenCalledWith({ root: { '#name': 'root', '$': {}, }, })); expect(showBubble).toHaveBeenCalledWith({ show: false, }); }); test('element bubble renders properly', async () => { const setXml = jest.fn(); const showBubble = jest.fn(); const docSpec = { elements: { element: { menu: [{ action: deleteElement, caption: 'Delete', }], }, }, }; const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('Click element action should modify xml and close bubble', async () => { const setXml = jest.fn(); const showBubble = jest.fn(); const docSpec = { elements: { element: { menu: [{ action: deleteElement, caption: 'Delete', }], }, }, }; const { getByText } = render( , ); fireEvent.click(getByText('Delete')); await waitFor(() => expect(setXml).toHaveBeenCalledWith({ root: { '#name': 'root', '$$': [], }, })); expect(showBubble).toHaveBeenCalledWith({ show: false, }); }); test('element bubble without menu renders properly', () => { const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('text bubble renders properly', () => { const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('bubble should not render if id is invalid', () => { const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('should not render if "show" is false', () => { const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('captions should be correctly formatted', () => { const docSpec = { elements: { element: { menu: [{ action: deleteElement, caption: '', icon: 'icon.png', }, { action: deleteElement, caption: '@key="value"', }, { action: deleteElement, caption: '@key', }, { action: deleteElement, caption: '@key=""', }, { action: deleteElement, caption: '@"value"', }], }, }, }; const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('menu item should be hidden if hideIf() returns true', () => { const docSpec = { elements: { element: { menu: [{ action: deleteElement, caption: 'Delete this ', hideIf: () => true, }], }, }, }; const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('attribute menu bubble should be empty', async () => { const { container } = render( , ); expect(container).toMatchSnapshot(); }); test('attribute asker bubble should be empty', () => { const { container } = render( , ); expect(container).toMatchSnapshot(); }); });