@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
177 lines • 8.23 kB
JavaScript
import { createComponent } from '@furystack/shades';
import { flushUpdates } from '@furystack/shades';
import { describe, expect, it, vi } from 'vitest';
import { Alert } from './alert.js';
describe('Alert', () => {
it('should be defined', () => {
expect(Alert).toBeDefined();
expect(typeof Alert).toBe('function');
});
it('should create an alert element with default props', () => {
const el = (createComponent(Alert, null, "Test message"));
expect(el).toBeDefined();
expect(el.tagName?.toLowerCase()).toBe('shade-alert');
});
it('should set severity to info by default', async () => {
const el = (createComponent("div", null,
createComponent(Alert, null, "Info message")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
expect(alert.getAttribute('data-severity')).toBe('info');
});
it('should set data-severity attribute for each severity', async () => {
const severities = ['error', 'warning', 'info', 'success'];
for (const severity of severities) {
const el = (createComponent("div", null,
createComponent(Alert, { severity: severity }, "Message")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
expect(alert.getAttribute('data-severity')).toBe(severity);
}
});
it('should set data-variant attribute when variant is provided', async () => {
const variants = ['filled', 'outlined', 'standard'];
for (const variant of variants) {
const el = (createComponent("div", null,
createComponent(Alert, { variant: variant }, "Message")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
expect(alert.getAttribute('data-variant')).toBe(variant);
}
});
it('should not set data-variant attribute when variant is not provided', async () => {
const el = (createComponent("div", null,
createComponent(Alert, null, "Message")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
expect(alert.hasAttribute('data-variant')).toBe(false);
});
it('should set role="alert" on the element', async () => {
const el = (createComponent("div", null,
createComponent(Alert, null, "Message")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
expect(alert.getAttribute('role')).toBe('alert');
});
it('should render a title when title prop is provided', async () => {
const el = (createComponent("div", null,
createComponent(Alert, { title: "Error Title", severity: "error" }, "Details here")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const titleEl = alert.querySelector('.alert-title');
expect(titleEl).not.toBeNull();
expect(titleEl?.textContent).toBe('Error Title');
});
it('should not render a title when title prop is not provided', async () => {
const el = (createComponent("div", null,
createComponent(Alert, { severity: "info" }, "Just a message")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const titleEl = alert.querySelector('.alert-title');
expect(titleEl).toBeNull();
});
it('should render a close button when onClose is provided', async () => {
const onClose = vi.fn();
const el = (createComponent("div", null,
createComponent(Alert, { onClose: onClose }, "Closeable")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const closeBtn = alert.querySelector('.alert-close');
expect(closeBtn).not.toBeNull();
});
it('should not render a close button when onClose is not provided', async () => {
const el = (createComponent("div", null,
createComponent(Alert, null, "Not closeable")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const closeBtn = alert.querySelector('.alert-close');
expect(closeBtn).toBeNull();
});
it('should call onClose when close button is clicked', async () => {
const onClose = vi.fn();
const el = (createComponent("div", null,
createComponent(Alert, { onClose: onClose }, "Closeable")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const closeBtn = alert.querySelector('.alert-close');
closeBtn.click();
expect(onClose).toHaveBeenCalledOnce();
});
it('should stop propagation when close button is clicked', async () => {
const onClose = vi.fn();
const onAlertClick = vi.fn();
const el = (createComponent("div", null,
createComponent(Alert, { onClose: onClose, onclick: onAlertClick }, "Closeable")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const closeBtn = alert.querySelector('.alert-close');
closeBtn.click();
expect(onClose).toHaveBeenCalledOnce();
expect(onAlertClick).not.toHaveBeenCalled();
});
it('should render the default icon for the severity', async () => {
const el = (createComponent("div", null,
createComponent(Alert, { severity: "error" }, "Error")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const iconEl = alert.querySelector('.alert-icon');
expect(iconEl).not.toBeNull();
expect(iconEl?.querySelector('shade-icon')).not.toBeNull();
});
it('should render a custom icon when icon prop is provided', async () => {
const el = (createComponent("div", null,
createComponent(Alert, { severity: "error", icon: "\uD83D\uDD25" }, "Error")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const iconEl = alert.querySelector('.alert-icon');
expect(iconEl).not.toBeNull();
expect(iconEl?.textContent).toBe('🔥');
});
it('should set CSS custom properties for severity color', async () => {
const el = (createComponent("div", null,
createComponent(Alert, { severity: "error" }, "Error")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
expect(alert.style.getPropertyValue('--alert-color-main')).toBe('var(--shades-theme-palette-error-main)');
});
it('should set CSS custom properties for success severity', async () => {
const el = (createComponent("div", null,
createComponent(Alert, { severity: "success" }, "Success")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
expect(alert.style.getPropertyValue('--alert-color-main')).toBe('var(--shades-theme-palette-success-main)');
});
it('should render children in the message area', async () => {
const el = (createComponent("div", null,
createComponent(Alert, null, "Alert message content")));
const alert = el.firstElementChild;
alert.updateComponent();
await flushUpdates();
const messageEl = alert.querySelector('.alert-message');
expect(messageEl).not.toBeNull();
});
it('should set props correctly', () => {
const el = (createComponent(Alert, { severity: "warning", variant: "filled", title: "Warning Title", icon: "\u26A1" }, "Warning content"));
const props = el.props;
expect(props.severity).toBe('warning');
expect(props.variant).toBe('filled');
expect(props.title).toBe('Warning Title');
expect(props.icon).toBe('⚡');
});
});
//# sourceMappingURL=alert.spec.js.map