128 lines
5.1 KiB
TypeScript
128 lines
5.1 KiB
TypeScript
import { mount } from '@vue/test-utils';
|
|
import VAlert from './VAlert.vue';
|
|
import VIcon from './VIcon.vue'; // VAlert uses VIcon
|
|
import { nextTick } from 'vue';
|
|
|
|
// Mock VIcon
|
|
vi.mock('./VIcon.vue', () => ({
|
|
name: 'VIcon',
|
|
props: ['name'],
|
|
template: '<i :class="`mock-icon icon-${name}`"></i>',
|
|
}));
|
|
|
|
describe('VAlert.vue', () => {
|
|
it('renders message prop when no default slot', () => {
|
|
const messageText = 'This is a test alert.';
|
|
const wrapper = mount(VAlert, { props: { message: messageText } });
|
|
expect(wrapper.find('.alert-content').text()).toBe(messageText);
|
|
});
|
|
|
|
it('renders default slot content instead of message prop', () => {
|
|
const slotContent = '<strong>Custom Alert Content</strong>';
|
|
const wrapper = mount(VAlert, {
|
|
props: { message: 'Ignored message' },
|
|
slots: { default: slotContent },
|
|
});
|
|
expect(wrapper.find('.alert-content').html()).toContain(slotContent);
|
|
});
|
|
|
|
it('applies correct class based on type prop', () => {
|
|
const wrapperInfo = mount(VAlert, { props: { type: 'info' } });
|
|
expect(wrapperInfo.classes()).toContain('alert-info');
|
|
|
|
const wrapperSuccess = mount(VAlert, { props: { type: 'success' } });
|
|
expect(wrapperSuccess.classes()).toContain('alert-success');
|
|
|
|
const wrapperWarning = mount(VAlert, { props: { type: 'warning' } });
|
|
expect(wrapperWarning.classes()).toContain('alert-warning');
|
|
|
|
const wrapperError = mount(VAlert, { props: { type: 'error' } });
|
|
expect(wrapperError.classes()).toContain('alert-error');
|
|
});
|
|
|
|
it('shows close button and emits events when closable is true', async () => {
|
|
const wrapper = mount(VAlert, { props: { closable: true, modelValue: true } });
|
|
const closeButton = wrapper.find('.alert-close-btn');
|
|
expect(closeButton.exists()).toBe(true);
|
|
|
|
await closeButton.trigger('click');
|
|
expect(wrapper.emitted()['update:modelValue']).toBeTruthy();
|
|
expect(wrapper.emitted()['update:modelValue'][0]).toEqual([false]);
|
|
expect(wrapper.emitted()['close']).toBeTruthy();
|
|
|
|
// Check if alert is hidden after internalModelValue updates (due to transition)
|
|
await nextTick(); // Allow internalModelValue to update and transition to start
|
|
// Depending on how transition is handled, the element might still be in DOM but display:none
|
|
// or completely removed. VAlert uses v-if, so it should be removed.
|
|
// Forcing internalModelValue directly for test simplicity if needed, or wait for transition.
|
|
// wrapper.vm.internalModelValue = false; // If directly manipulating for test
|
|
// await nextTick();
|
|
expect(wrapper.find('.alert').exists()).toBe(false); // After click and model update, it should be gone
|
|
});
|
|
|
|
it('does not show close button when closable is false (default)', () => {
|
|
const wrapper = mount(VAlert);
|
|
expect(wrapper.find('.alert-close-btn').exists()).toBe(false);
|
|
});
|
|
|
|
it('displays icon by default and uses type-specific default icons', () => {
|
|
const wrapperSuccess = mount(VAlert, { props: { type: 'success' } });
|
|
expect(wrapperSuccess.find('.alert-icon').exists()).toBe(true);
|
|
expect(wrapperSuccess.find('.icon-check-circle').exists()).toBe(true); // Mocked VIcon class
|
|
|
|
const wrapperError = mount(VAlert, { props: { type: 'error' } });
|
|
expect(wrapperError.find('.icon-alert-octagon').exists()).toBe(true);
|
|
});
|
|
|
|
it('displays custom icon when icon prop is provided', () => {
|
|
const customIconName = 'custom-bell';
|
|
const wrapper = mount(VAlert, { props: { icon: customIconName } });
|
|
expect(wrapper.find('.alert-icon').exists()).toBe(true);
|
|
expect(wrapper.find(`.icon-${customIconName}`).exists()).toBe(true);
|
|
});
|
|
|
|
it('does not display icon when showIcon is false', () => {
|
|
const wrapper = mount(VAlert, { props: { showIcon: false } });
|
|
expect(wrapper.find('.alert-icon').exists()).toBe(false);
|
|
});
|
|
|
|
it('renders actions slot content', () => {
|
|
const actionsContent = '<button>Retry</button>';
|
|
const wrapper = mount(VAlert, {
|
|
slots: { actions: actionsContent },
|
|
});
|
|
const actionsDiv = wrapper.find('.alert-actions');
|
|
expect(actionsDiv.exists()).toBe(true);
|
|
expect(actionsDiv.html()).toContain(actionsContent);
|
|
});
|
|
|
|
it('does not render .alert-actions if slot is not provided', () => {
|
|
const wrapper = mount(VAlert);
|
|
expect(wrapper.find('.alert-actions').exists()).toBe(false);
|
|
});
|
|
|
|
it('is visible by default (modelValue true)', () => {
|
|
const wrapper = mount(VAlert);
|
|
expect(wrapper.find('.alert').exists()).toBe(true);
|
|
});
|
|
|
|
it('is hidden when modelValue is initially false', () => {
|
|
const wrapper = mount(VAlert, { props: { modelValue: false } });
|
|
expect(wrapper.find('.alert').exists()).toBe(false);
|
|
});
|
|
|
|
it('updates visibility when modelValue prop changes', async () => {
|
|
const wrapper = mount(VAlert, { props: { modelValue: true } });
|
|
expect(wrapper.find('.alert').exists()).toBe(true);
|
|
|
|
await wrapper.setProps({ modelValue: false });
|
|
// Wait for transition if any, or internalModelValue update
|
|
await nextTick();
|
|
expect(wrapper.find('.alert').exists()).toBe(false);
|
|
|
|
await wrapper.setProps({ modelValue: true });
|
|
await nextTick();
|
|
expect(wrapper.find('.alert').exists()).toBe(true);
|
|
});
|
|
});
|