@mozaic-ds/vue
Version:
Mozaic-Vue is the Vue.js implementation of ADEO Design system
247 lines (204 loc) • 6.61 kB
text/typescript
import { describe, it, expect, vi } from 'vitest';
import { mount } from '@vue/test-utils';
import MTileSelectable from './MTileSelectable.vue';
vi.mock('../checkbox/MCheckbox.vue', () => ({
default: {
name: 'MCheckbox',
props: ['modelValue', 'id', 'name'],
emits: ['update:modelValue'],
template: `
<input
type="checkbox"
:id="id"
:checked="modelValue"
@change="$emit('update:modelValue', !$props.modelValue)"
/>
`,
},
}));
vi.mock('../radio/MRadio.vue', () => ({
default: {
name: 'MRadio',
props: ['modelValue', 'id', 'name'],
emits: ['update:modelValue'],
template: `
<input
type="radio"
:id="id"
:checked="modelValue"
@change="$emit('update:modelValue', true)"
/>
`,
},
}));
describe('MTileSelectable', () => {
it('applies bordered class when bordered is true', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
bordered: true,
},
});
expect(wrapper.classes()).toContain('mc-tile--bordered');
});
it('does not apply bordered class when bordered is false', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
bordered: false,
},
});
expect(wrapper.classes()).not.toContain('mc-tile--bordered');
});
it('applies selected class when modelValue is true', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: true,
},
});
expect(wrapper.classes()).toContain('mc-tile--selected');
});
it('does not apply selected class when modelValue is false', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
},
});
expect(wrapper.classes()).not.toContain('mc-tile--selected');
});
it('applies input left class when inputPosition is left', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
inputPosition: 'left',
},
});
expect(wrapper.classes()).toContain('mc-tile--input-left');
});
it('applies input center class when centered is true', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
centered: true,
},
});
expect(wrapper.classes()).toContain('mc-tile--input-center');
});
it('renders checkbox by default', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
},
});
expect(wrapper.find('input[type="checkbox"]').exists()).toBe(true);
expect(wrapper.find('input[type="radio"]').exists()).toBe(false);
});
it('renders radio when inputType is radio', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
inputType: 'radio',
},
});
expect(wrapper.find('input[type="radio"]').exists()).toBe(true);
expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false);
});
it('emits update:modelValue when checkbox value changes', async () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
},
});
await wrapper.find('input[type="checkbox"]').trigger('change');
expect(wrapper.emitted('update:modelValue')).toBeTruthy();
expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]);
});
it('emits update:modelValue when radio button value changes', async () => {
const wrapper = mount(MTileSelectable, {
props: {
inputType: 'radio',
modelValue: false,
},
});
await wrapper.find('input[type="radio"]').trigger('change');
expect(wrapper.emitted('update:modelValue')).toBeTruthy();
expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]);
});
it('renders header and content when details slot is provided', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
},
slots: {
default: 'Main content',
details: 'Details content',
},
});
expect(wrapper.find('.mc-tile__header').exists()).toBe(true);
expect(wrapper.find('.mc-tile__content').exists()).toBe(true);
expect(wrapper.text()).toContain('Details content');
});
it('does not render content container when details slot is missing', () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
},
});
expect(wrapper.find('.mc-tile__content').exists()).toBe(false);
});
it('emits update:modelValue when card is clicked and clickable is true', async () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
trigger: 'container',
},
});
await wrapper.find('.mc-tile').trigger('click');
expect(wrapper.emitted('update:modelValue')).toBeTruthy();
expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]);
});
it('does not emit update:modelValue when card is clicked but clickable is false', async () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
},
});
await wrapper.find('.mc-tile').trigger('click');
expect(wrapper.emitted('update:modelValue')).toBeFalsy();
});
it('toggles off when card is clicked and already selected with clickable and checkbox', async () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: true,
trigger: 'container',
inputType: 'checkbox',
},
});
await wrapper.find('.mc-tile').trigger('click');
expect(wrapper.emitted('update:modelValue')![0]).toEqual([false]);
});
it('always sets true when card is clicked with clickable and radio', async () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
trigger: 'container',
inputType: 'radio',
},
});
await wrapper.find('.mc-tile').trigger('click');
expect(wrapper.emitted('update:modelValue')![0]).toEqual([true]);
});
it('does not double-toggle when the input itself is clicked with clickable enabled', async () => {
const wrapper = mount(MTileSelectable, {
props: {
modelValue: false,
trigger: 'container',
inputType: 'checkbox',
},
});
const input = wrapper.find('input[type="checkbox"]');
await input.trigger('click');
// Clicking the input itself should not invoke the card click handler
expect(wrapper.emitted('update:modelValue')).toBeFalsy();
});
});