141 lines
5.7 KiB
TypeScript
141 lines
5.7 KiB
TypeScript
import { mount } from '@vue/test-utils';
|
|
import VCard from './VCard.vue';
|
|
import VIcon from './VIcon.vue'; // VCard uses VIcon
|
|
import { describe, it, expect, vi } from 'vitest';
|
|
|
|
// Mock VIcon to simplify testing VCard in isolation,
|
|
// especially if VIcon itself has complex rendering or external dependencies.
|
|
// vi.mock('./VIcon.vue', ()_ => ({
|
|
// name: 'VIcon',
|
|
// props: ['name', 'size'],
|
|
// template: '<i :class="`mock-icon icon-${name}`"></i>',
|
|
// }));
|
|
// For now, let's allow it to render as its props are simple.
|
|
|
|
describe('VCard.vue', () => {
|
|
// Default variant tests
|
|
describe('Default Variant', () => {
|
|
it('renders headerTitle when provided and no header slot', () => {
|
|
const headerText = 'My Card Header';
|
|
const wrapper = mount(VCard, { props: { headerTitle: headerText } });
|
|
const header = wrapper.find('.card-header');
|
|
expect(header.exists()).toBe(true);
|
|
expect(header.find('.card-header-title').text()).toBe(headerText);
|
|
});
|
|
|
|
it('renders header slot content instead of headerTitle', () => {
|
|
const slotContent = '<div class="custom-header">Custom Header</div>';
|
|
const wrapper = mount(VCard, {
|
|
props: { headerTitle: 'Ignored Title' },
|
|
slots: { header: slotContent },
|
|
});
|
|
const header = wrapper.find('.card-header');
|
|
expect(header.exists()).toBe(true);
|
|
expect(header.find('.custom-header').exists()).toBe(true);
|
|
expect(header.text()).toContain('Custom Header');
|
|
expect(header.find('.card-header-title').exists()).toBe(false);
|
|
});
|
|
|
|
it('does not render .card-header if no headerTitle and no header slot', () => {
|
|
const wrapper = mount(VCard, { slots: { default: '<p>Body</p>' } });
|
|
expect(wrapper.find('.card-header').exists()).toBe(false);
|
|
});
|
|
|
|
it('renders default slot content in .card-body', () => {
|
|
const bodyContent = '<p>Main card content here.</p>';
|
|
const wrapper = mount(VCard, { slots: { default: bodyContent } });
|
|
const body = wrapper.find('.card-body');
|
|
expect(body.exists()).toBe(true);
|
|
expect(body.html()).toContain(bodyContent);
|
|
});
|
|
|
|
it('renders footer slot content in .card-footer', () => {
|
|
const footerContent = '<span>Card Footer Text</span>';
|
|
const wrapper = mount(VCard, { slots: { footer: footerContent } });
|
|
const footer = wrapper.find('.card-footer');
|
|
expect(footer.exists()).toBe(true);
|
|
expect(footer.html()).toContain(footerContent);
|
|
});
|
|
|
|
it('does not render .card-footer if no footer slot', () => {
|
|
const wrapper = mount(VCard, { slots: { default: '<p>Body</p>' } });
|
|
expect(wrapper.find('.card-footer').exists()).toBe(false);
|
|
});
|
|
|
|
it('applies .card class by default', () => {
|
|
const wrapper = mount(VCard);
|
|
expect(wrapper.classes()).toContain('card');
|
|
expect(wrapper.classes()).not.toContain('empty-state-card');
|
|
});
|
|
});
|
|
|
|
// Empty state variant tests
|
|
describe('Empty State Variant', () => {
|
|
const emptyStateProps = {
|
|
variant: 'empty-state' as const,
|
|
emptyIcon: 'alert',
|
|
emptyTitle: 'Nothing to Show',
|
|
emptyMessage: 'There is no data available at this moment.',
|
|
};
|
|
|
|
it('applies .card and .empty-state-card classes', () => {
|
|
const wrapper = mount(VCard, { props: emptyStateProps });
|
|
expect(wrapper.classes()).toContain('card');
|
|
expect(wrapper.classes()).toContain('empty-state-card');
|
|
});
|
|
|
|
it('renders empty state icon, title, and message', () => {
|
|
const wrapper = mount(VCard, {
|
|
props: emptyStateProps,
|
|
global: { components: { VIcon } } // Ensure VIcon is available
|
|
});
|
|
const icon = wrapper.findComponent(VIcon); // Or find by class if not using findComponent
|
|
expect(icon.exists()).toBe(true);
|
|
expect(icon.props('name')).toBe(emptyStateProps.emptyIcon);
|
|
|
|
expect(wrapper.find('.empty-state-title').text()).toBe(emptyStateProps.emptyTitle);
|
|
expect(wrapper.find('.empty-state-message').text()).toBe(emptyStateProps.emptyMessage);
|
|
});
|
|
|
|
it('does not render icon, title, message if props not provided', () => {
|
|
const wrapper = mount(VCard, {
|
|
props: { variant: 'empty-state' as const },
|
|
global: { components: { VIcon } }
|
|
});
|
|
expect(wrapper.findComponent(VIcon).exists()).toBe(false); // Or check for .empty-state-icon
|
|
expect(wrapper.find('.empty-state-title').exists()).toBe(false);
|
|
expect(wrapper.find('.empty-state-message').exists()).toBe(false);
|
|
});
|
|
|
|
it('renders empty-actions slot content', () => {
|
|
const actionsContent = '<button>Add Item</button>';
|
|
const wrapper = mount(VCard, {
|
|
props: emptyStateProps,
|
|
slots: { 'empty-actions': actionsContent },
|
|
});
|
|
const actionsContainer = wrapper.find('.empty-state-actions');
|
|
expect(actionsContainer.exists()).toBe(true);
|
|
expect(actionsContainer.html()).toContain(actionsContent);
|
|
});
|
|
|
|
it('does not render .empty-state-actions if slot is not provided', () => {
|
|
const wrapper = mount(VCard, { props: emptyStateProps });
|
|
expect(wrapper.find('.empty-state-actions').exists()).toBe(false);
|
|
});
|
|
|
|
it('does not render standard header, body (main slot), or footer in empty state', () => {
|
|
const wrapper = mount(VCard, {
|
|
props: { ...emptyStateProps, headerTitle: 'Should not show' },
|
|
slots: {
|
|
default: '<p>Standard body</p>',
|
|
footer: '<span>Standard footer</span>',
|
|
},
|
|
});
|
|
expect(wrapper.find('.card-header').exists()).toBe(false);
|
|
// The .card-body is used by empty-state-content, so check for specific standard content
|
|
expect(wrapper.text()).not.toContain('Standard body');
|
|
expect(wrapper.find('.card-footer').exists()).toBe(false);
|
|
});
|
|
});
|
|
});
|