From 6f896868626c79f19d7e0dd8f1798c635c5a6d16 Mon Sep 17 00:00:00 2001 From: FragginWagon Date: Thu, 29 Jan 2026 03:57:44 +0000 Subject: [PATCH] =?UTF-8?q?=E2=9C=85=20Add=20unit=20tests=20for=20ActionTo?= =?UTF-8?q?olbar=20component=20in=20gamemaster=20module?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gamemaster/ActionToolbar.test.js | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 code/websites/pokedex.online/tests/unit/components/gamemaster/ActionToolbar.test.js diff --git a/code/websites/pokedex.online/tests/unit/components/gamemaster/ActionToolbar.test.js b/code/websites/pokedex.online/tests/unit/components/gamemaster/ActionToolbar.test.js new file mode 100644 index 0000000..9cc489e --- /dev/null +++ b/code/websites/pokedex.online/tests/unit/components/gamemaster/ActionToolbar.test.js @@ -0,0 +1,101 @@ +/** + * ActionToolbar Component Tests + * Verifies action buttons behavior + */ + +import { describe, it, expect, beforeEach, vi } from 'vitest'; +import { mount } from '@vue/test-utils'; +import { ref } from 'vue'; +import ActionToolbar from '../../../../src/components/gamemaster/ActionToolbar.vue'; +import { useLineSelection } from '../../../../src/composables/useLineSelection.js'; + +vi.mock('../../../../src/composables/useLineSelection.js', () => ({ + useLineSelection: vi.fn() +})); + +const createSelectionMock = overrides => ({ + selectionCount: ref(0), + copySelected: vi.fn(), + copyAll: vi.fn(), + exportSelected: vi.fn(), + exportAll: vi.fn(), + shareUrl: vi.fn(), + ...overrides +}); + +describe('ActionToolbar Component', () => { + let selectionMock; + + beforeEach(() => { + selectionMock = createSelectionMock(); + useLineSelection.mockReturnValue(selectionMock); + }); + + it('renders when file content exists', () => { + const wrapper = mount(ActionToolbar, { + props: { + fileContent: '{"test": true}', + displayLines: [], + selectedFile: 'pokemon' + } + }); + + expect(wrapper.find('.action-bar').exists()).toBe(true); + }); + + it('disables selection-dependent actions when no selection', () => { + const wrapper = mount(ActionToolbar, { + props: { + fileContent: '{"test": true}', + displayLines: [], + selectedFile: 'pokemon' + } + }); + + const buttons = wrapper.findAll('button.btn-action'); + expect(buttons[0].attributes('disabled')).toBeDefined(); + expect(buttons[2].attributes('disabled')).toBeDefined(); + }); + + it('enables selection-dependent actions when selection exists', () => { + selectionMock.selectionCount.value = 3; + + const wrapper = mount(ActionToolbar, { + props: { + fileContent: '{"test": true}', + displayLines: [], + selectedFile: 'pokemon' + } + }); + + const buttons = wrapper.findAll('button.btn-action'); + expect(buttons[0].attributes('disabled')).toBeUndefined(); + expect(buttons[2].attributes('disabled')).toBeUndefined(); + expect(buttons[0].text()).toContain('3 lines'); + }); + + it('triggers action handlers', async () => { + selectionMock.selectionCount.value = 2; + + const wrapper = mount(ActionToolbar, { + props: { + fileContent: '{"test": true}', + displayLines: [], + selectedFile: 'pokemon' + } + }); + + const buttons = wrapper.findAll('button.btn-action'); + await buttons[0].trigger('click'); + await buttons[1].trigger('click'); + await buttons[2].trigger('click'); + await buttons[3].trigger('click'); + await buttons[4].trigger('click'); + + expect(selectionMock.copySelected).toHaveBeenCalled(); + expect(selectionMock.copyAll).toHaveBeenCalled(); + expect(selectionMock.exportSelected).toHaveBeenCalled(); + expect(selectionMock.exportAll).toHaveBeenCalled(); + expect(selectionMock.shareUrl).toHaveBeenCalled(); + }); +});