This project is a palette creator tool that allows users to generate and customize color palettes for their design projects.
at main 123 lines 4.0 kB view raw
1import { mount } from '@vue/test-utils'; 2 3import store from '../store'; 4 5import ColorVariationsPanel from './ColorVariationsPanel.vue'; 6 7// oxlint-disable-next-line max-lines-per-function 8describe('component ColorVariationsPanel', () => { 9 /** @type {import('@vue/test-utils').VueWrapper} */ 10 let wrapper; 11 12 beforeEach(() => { 13 store.state.allColors = [ 14 { 15 hex: '#40a0bf', 16 hsl: 'hsl(200, 50%, 50%)', 17 rgb: 'rgb(64, 160, 191)', 18 type: 'complement', 19 }, 20 { 21 hex: '#4095bf', 22 hsl: 'hsl(210, 50%, 50%)', 23 rgb: 'rgb(64, 149, 191)', 24 type: 'complement', 25 }, 26 { 27 hex: '#408abf', 28 hsl: 'hsl(220, 50%, 50%)', 29 rgb: 'rgb(64, 138, 191)', 30 type: 'mono', 31 }, 32 ]; 33 store.state.copiedColor = ''; 34 store.state.copiedColorIndex = null; 35 36 wrapper = mount(ColorVariationsPanel, { 37 global: { plugins: [store] }, 38 }); 39 }); 40 41 afterEach(() => { 42 wrapper.unmount(); 43 vi.restoreAllMocks(); 44 }); 45 46 it('renders', () => { 47 expect(wrapper.exists()).toBeTruthy(); 48 }); 49 50 it('shows the expanded panel content', () => { 51 expect( 52 wrapper.find('[data-testid="expanded-panel"]').exists(), 53 ).toBeTruthy(); 54 }); 55 56 it('renders a slot for each unique color from the store', () => { 57 const slots = wrapper.findAll('.mini-slot'); 58 59 expect(slots).toHaveLength(store.getters.uniqueColors.length); 60 }); 61 62 it('applies background color to each slot', () => { 63 const slots = wrapper.findAll('.mini-slot'); 64 65 for (const slot of slots) { 66 expect(slot.attributes('style')).toContain('background-color'); 67 } 68 }); 69 70 it('renders the listbox with correct aria attributes', () => { 71 const listbox = wrapper.find('[role="listbox"]'); 72 73 expect(listbox.exists()).toBeTruthy(); 74 expect(listbox.attributes('aria-label')).toBe('Color variations'); 75 }); 76 77 it('dispatches COPY_COLOR when a slot is clicked', async () => { 78 const dispatchSpy = vi.spyOn(store, 'dispatch'); 79 const firstSlot = wrapper.find('[data-testid="mini-slot-0"]'); 80 await firstSlot.trigger('click'); 81 82 expect(dispatchSpy).toHaveBeenCalledWith( 83 'COPY_COLOR', 84 expect.objectContaining({ 85 color: expect.any(String), 86 index: 0, 87 }), 88 ); 89 }); 90 91 it('dispatches CLEAR_COPIED_COLOR when an already-selected slot is clicked', async () => { 92 store.state.copiedColor = 'hsl(200, 50%, 50%)'; 93 store.state.copiedColorIndex = 0; 94 await wrapper.vm.$nextTick(); 95 96 const dispatchSpy = vi.spyOn(store, 'dispatch'); 97 await wrapper.find('[data-testid="mini-slot-0"]').trigger('click'); 98 99 expect(dispatchSpy).toHaveBeenCalledWith('CLEAR_COPIED_COLOR'); 100 }); 101 102 it('marks copied slot with mini-slot-copied class', async () => { 103 store.state.copiedColor = 'hsl(200, 50%, 50%)'; 104 store.state.copiedColorIndex = 0; 105 await wrapper.vm.$nextTick(); 106 const slot1 = wrapper.find('[data-testid="mini-slot-0"]'); 107 const slot2 = wrapper.find('[data-testid="mini-slot-1"]'); 108 109 expect(slot1.classes()).toContain('mini-slot-copied'); 110 expect(slot2.classes()).not.toContain('mini-slot-copied'); 111 }); 112 113 it('sets aria-selected true on the copied slot', async () => { 114 store.state.copiedColor = 'hsl(200, 50%, 50%)'; 115 store.state.copiedColorIndex = 1; 116 await wrapper.vm.$nextTick(); 117 const slot1 = wrapper.find('[data-testid="mini-slot-0"]'); 118 const slot2 = wrapper.find('[data-testid="mini-slot-1"]'); 119 120 expect(slot2.attributes('aria-selected')).toBe('true'); 121 expect(slot1.attributes('aria-selected')).toBe('false'); 122 }); 123});