import { describe, it, expect, vi } from 'vitest'; import { createModal } from './create-modal.js'; import type { Theme } from '@penpot/plugin-types'; import type { OpenUIOptions } from './models/open-ui-options.model'; import type { PluginModalElement } from './modal/plugin-modal'; describe('createModal', () => { const modalMock = { setTheme: vi.fn(), style: { setProperty: vi.fn(), getPropertyValue: vi.fn(), }, wrapper: { style: {}, }, setAttribute: vi.fn(), } as unknown as PluginModalElement; const appendChildSpy = vi .spyOn(document.body, 'appendChild') .mockReturnValue(modalMock); const createElementSpy = vi .spyOn(document, 'createElement') .mockReturnValue(modalMock); afterEach(() => { document.body.innerHTML = ''; vi.clearAllMocks(); }); it('should create and configure a modal element', () => { const theme: Theme = 'light'; const options: OpenUIOptions = { width: 400, height: 600 }; const modal = createModal( 'Test Modal', 'https://example.com', theme, options, ); expect(createElementSpy).toHaveBeenCalledWith('plugin-modal'); expect(modal.setTheme).toHaveBeenCalledWith(theme); expect(modal.style.setProperty).toHaveBeenCalledWith( '--modal-block-start', '40px', ); expect(modal.setAttribute).toHaveBeenCalledWith('title', 'Test Modal'); expect(modal.setAttribute).toHaveBeenCalledWith( 'iframe-src', 'https://example.com', ); expect(modal.wrapper.style.width).toEqual('400px'); expect(modal.wrapper.style.height).toEqual('600px'); expect(appendChildSpy).toHaveBeenCalledWith(modal); }); it('should apply default dimensions if options are not provided', () => { const theme: Theme = 'light'; const modal = createModal('Test Modal', 'https://example.com', theme); expect(modal.wrapper.style.width).toEqual('335px'); expect(modal.wrapper.style.height).toEqual('590px'); }); it('should limit modal dimensions to the window size', () => { const theme: Theme = 'light'; const options: OpenUIOptions = { width: 2000, height: 2000 }; window.innerWidth = 1000; window.innerHeight = 800; const modal = createModal( 'Test Modal', 'https://example.com', theme, options, ); const expectedWidth = 960; const expectedHeight = 760; expect(modal.wrapper.style.width).toEqual(`${expectedWidth}px`); expect(modal.wrapper.style.height).toEqual(`${expectedHeight}px`); }); it('should apply minimum dimensions to the modal', () => { const theme: Theme = 'light'; const options: OpenUIOptions = { width: 100, height: 100 }; const modal = createModal( 'Test Modal', 'https://example.com', theme, options, ); expect(modal.wrapper.style.width).toEqual('200px'); expect(modal.wrapper.style.height).toEqual('200px'); }); it('should set allow-clipboard-read attribute when allowClipboardRead is true', () => { const theme: Theme = 'light'; createModal( 'Test Modal', 'https://example.com', theme, undefined, false, true, false, ); expect(modalMock.setAttribute).toHaveBeenCalledWith( 'allow-clipboard-read', 'true', ); expect(modalMock.setAttribute).not.toHaveBeenCalledWith( 'allow-clipboard-write', 'true', ); }); it('should set allow-clipboard-write attribute when allowClipboardWrite is true', () => { const theme: Theme = 'light'; createModal( 'Test Modal', 'https://example.com', theme, undefined, false, false, true, ); expect(modalMock.setAttribute).toHaveBeenCalledWith( 'allow-clipboard-write', 'true', ); expect(modalMock.setAttribute).not.toHaveBeenCalledWith( 'allow-clipboard-read', 'true', ); }); it('should set both clipboard attributes when both are true', () => { const theme: Theme = 'light'; createModal( 'Test Modal', 'https://example.com', theme, undefined, false, true, true, ); expect(modalMock.setAttribute).toHaveBeenCalledWith( 'allow-clipboard-read', 'true', ); expect(modalMock.setAttribute).toHaveBeenCalledWith( 'allow-clipboard-write', 'true', ); }); });