mitlist/fe/src/components/valerie/VProgressBar.spec.ts

94 lines
4.0 KiB
TypeScript

import { mount } from '@vue/test-utils';
import VProgressBar from './VProgressBar.vue';
import { describe, it, expect } from 'vitest';
describe('VProgressBar.vue', () => {
it('calculates percentage and sets width style correctly', () => {
const wrapper = mount(VProgressBar, { props: { value: 50, max: 100 } });
const bar = wrapper.find('.progress-bar');
expect(bar.attributes('style')).toContain('width: 50%;');
});
it('calculates percentage correctly with different max values', () => {
const wrapper = mount(VProgressBar, { props: { value: 10, max: 20 } }); // 50%
expect(wrapper.find('.progress-bar').attributes('style')).toContain('width: 50%;');
});
it('caps percentage at 100% if value exceeds max', () => {
const wrapper = mount(VProgressBar, { props: { value: 150, max: 100 } });
expect(wrapper.find('.progress-bar').attributes('style')).toContain('width: 100%;');
});
it('caps percentage at 0% if value is negative', () => {
const wrapper = mount(VProgressBar, { props: { value: -50, max: 100 } });
expect(wrapper.find('.progress-bar').attributes('style')).toContain('width: 0%;');
});
it('handles max value of 0 or less by setting width to 0%', () => {
const wrapperZeroMax = mount(VProgressBar, { props: { value: 50, max: 0 } });
expect(wrapperZeroMax.find('.progress-bar').attributes('style')).toContain('width: 0%;');
const wrapperNegativeMax = mount(VProgressBar, { props: { value: 50, max: -10 } });
expect(wrapperNegativeMax.find('.progress-bar').attributes('style')).toContain('width: 0%;');
});
it('shows progress text by default', () => {
const wrapper = mount(VProgressBar, { props: { value: 30 } });
expect(wrapper.find('.progress-text').exists()).toBe(true);
expect(wrapper.find('.progress-text').text()).toBe('30%');
});
it('hides progress text when showText is false', () => {
const wrapper = mount(VProgressBar, { props: { value: 30, showText: false } });
expect(wrapper.find('.progress-text').exists()).toBe(false);
});
it('displays custom valueText when provided', () => {
const customText = 'Step 1 of 3';
const wrapper = mount(VProgressBar, {
props: { value: 33, valueText: customText },
});
expect(wrapper.find('.progress-text').text()).toBe(customText);
});
it('displays percentage with zero decimal places by default', () => {
const wrapper = mount(VProgressBar, { props: { value: 33.333, max: 100 } });
expect(wrapper.find('.progress-text').text()).toBe('33%'); // toFixed(0)
});
it('applies "striped" class by default', () => {
const wrapper = mount(VProgressBar, { props: { value: 50 } });
expect(wrapper.find('.progress-bar').classes()).toContain('striped');
});
it('does not apply "striped" class when striped prop is false', () => {
const wrapper = mount(VProgressBar, { props: { value: 50, striped: false } });
expect(wrapper.find('.progress-bar').classes()).not.toContain('striped');
});
it('sets ARIA attributes correctly', () => {
const labelText = 'Upload progress';
const wrapper = mount(VProgressBar, {
props: { value: 60, max: 100, label: labelText },
});
const container = wrapper.find('.progress-container');
expect(container.attributes('role')).toBe('progressbar');
expect(container.attributes('aria-valuenow')).toBe('60');
expect(container.attributes('aria-valuemin')).toBe('0');
expect(container.attributes('aria-valuemax')).toBe('100');
expect(container.attributes('aria-label')).toBe(labelText);
});
it('sets default ARIA label if label prop is not provided', () => {
const wrapper = mount(VProgressBar, { props: { value: 10 } });
expect(wrapper.find('.progress-container').attributes('aria-label')).toBe('Progress indicator');
});
it('has .progress-container and .progress-bar classes', () => {
const wrapper = mount(VProgressBar, { props: { value: 10 } });
expect(wrapper.find('.progress-container').exists()).toBe(true);
expect(wrapper.find('.progress-bar').exists()).toBe(true);
});
});