@furystack/shades-common-components
Version:
Common UI components for FuryStack Shades
195 lines • 9.97 kB
JavaScript
import { createComponent, flushUpdates } from '@furystack/shades';
import { describe, expect, it, vi } from 'vitest';
import { Pagination } from './pagination.js';
describe('Pagination', () => {
it('should be defined', () => {
expect(Pagination).toBeDefined();
expect(typeof Pagination).toBe('function');
});
it('should create a pagination element with required props', () => {
const onPageChange = vi.fn();
const el = (createComponent(Pagination, { count: 10, page: 1, onPageChange: onPageChange }));
expect(el).toBeDefined();
expect(el.tagName?.toLowerCase()).toBe('shade-pagination');
});
it('should set props correctly', () => {
const onPageChange = vi.fn();
const el = (createComponent(Pagination, { count: 10, page: 3, onPageChange: onPageChange, siblingCount: 2, boundaryCount: 1, disabled: true, size: "small", color: "primary" }));
const props = el.props;
expect(props.count).toBe(10);
expect(props.page).toBe(3);
expect(props.siblingCount).toBe(2);
expect(props.boundaryCount).toBe(1);
expect(props.disabled).toBe(true);
expect(props.size).toBe('small');
expect(props.color).toBe('primary');
});
it('should render page buttons for small page counts', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
// Should have prev + 5 page buttons + next = 7 buttons
const items = pagination.querySelectorAll('.pagination-item');
expect(items.length).toBe(7); // prev + 5 pages + next
});
it('should render ellipsis for large page counts', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 20, page: 10, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const ellipses = pagination.querySelectorAll('.pagination-ellipsis');
expect(ellipses.length).toBe(2);
});
it('should mark current page as selected', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const selected = pagination.querySelector('[data-selected]');
expect(selected).not.toBeNull();
expect(selected.textContent).toBe('3');
});
it('should set data-disabled on prev button when on first page', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const prevButton = pagination.querySelector('.pagination-item');
expect(prevButton.hasAttribute('data-disabled')).toBe(true);
});
it('should set data-disabled on next button when on last page', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 5, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const items = pagination.querySelectorAll('.pagination-item');
const nextButton = items[items.length - 1];
expect(nextButton.hasAttribute('data-disabled')).toBe(true);
});
it('should call onPageChange with the correct page when a page button is clicked', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
// Click page 3 (index: prev=0, page1=1, page2=2, page3=3)
const items = pagination.querySelectorAll('.pagination-item');
items[3].click();
expect(onPageChange).toHaveBeenCalledWith(3);
});
it('should call onPageChange with page-1 when prev button is clicked', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const prevButton = pagination.querySelector('.pagination-item');
prevButton.click();
expect(onPageChange).toHaveBeenCalledWith(2);
});
it('should call onPageChange with page+1 when next button is clicked', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const items = pagination.querySelectorAll('.pagination-item');
const nextButton = items[items.length - 1];
nextButton.click();
expect(onPageChange).toHaveBeenCalledWith(4);
});
it('should not call onPageChange when clicking the currently selected page', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 3, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const selected = pagination.querySelector('[data-selected]');
selected.click();
expect(onPageChange).not.toHaveBeenCalled();
});
it('should set data-size attribute when size is provided', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange, size: "small" })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
expect(pagination.getAttribute('data-size')).toBe('small');
});
it('should set data-disabled on host when disabled', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange, disabled: true })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
expect(pagination.hasAttribute('data-disabled')).toBe(true);
});
it('should set CSS custom properties for palette color', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange, color: "primary" })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
expect(pagination.style.getPropertyValue('--pagination-color-main')).toBe('var(--shades-theme-palette-primary-main)');
});
it('should set default CSS custom properties when no color prop', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 5, page: 1, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
expect(pagination.style.getPropertyValue('--pagination-color-main')).toBe('var(--shades-theme-text-primary)');
});
it('should render only left ellipsis when near the end', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 20, page: 19, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const ellipses = pagination.querySelectorAll('.pagination-ellipsis');
expect(ellipses.length).toBe(1);
});
it('should render only right ellipsis when near the start', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 20, page: 2, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const ellipses = pagination.querySelectorAll('.pagination-ellipsis');
expect(ellipses.length).toBe(1);
});
it('should render all pages without ellipsis for count equal to total display slots', async () => {
const onPageChange = vi.fn();
const el = (createComponent("div", null,
createComponent(Pagination, { count: 7, page: 4, onPageChange: onPageChange })));
const pagination = el.firstElementChild;
pagination.updateComponent();
await flushUpdates();
const ellipses = pagination.querySelectorAll('.pagination-ellipsis');
expect(ellipses.length).toBe(0);
const items = pagination.querySelectorAll('.pagination-item');
expect(items.length).toBe(9); // prev + 7 pages + next
});
});
//# sourceMappingURL=pagination.spec.js.map