diff --git a/code/websites/pokedex.online/tests/unit/components/challonge/ApiVersionSelector.test.js b/code/websites/pokedex.online/tests/unit/components/challonge/ApiVersionSelector.test.js new file mode 100644 index 0000000..9567703 --- /dev/null +++ b/code/websites/pokedex.online/tests/unit/components/challonge/ApiVersionSelector.test.js @@ -0,0 +1,131 @@ +/** + * ApiVersionSelector Component Tests + */ + +import { describe, it, expect } from 'vitest'; +import { mount } from '@vue/test-utils'; +import ApiVersionSelector from '../../../../src/components/challonge/ApiVersionSelector.vue'; + +describe('ApiVersionSelector', () => { + it('renders with default v2.1 selected', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1' } + }); + + expect(wrapper.find('input[value="v2.1"]').element.checked).toBe(true); + expect(wrapper.text()).toContain('Using API v2.1'); + }); + + it('renders with v1 selected', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v1' } + }); + + expect(wrapper.find('input[value="v1"]').element.checked).toBe(true); + expect(wrapper.text()).toContain('Using API v1'); + }); + + it('emits update:modelValue when version changes', async () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1' } + }); + + const v1Radio = wrapper.findAll('input[type="radio"]')[0]; + await v1Radio.setValue(true); + + expect(wrapper.emitted('update:modelValue')).toBeTruthy(); + expect(wrapper.emitted('update:modelValue')[0]).toEqual(['v1']); + }); + + it('shows per-page selector for v2.1', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', showPerPage: true } + }); + + expect(wrapper.text()).toContain('Results per page'); + expect(wrapper.find('.select-input').exists()).toBe(true); + }); + + it('hides per-page selector for v1', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v1', showPerPage: true } + }); + + expect(wrapper.text()).not.toContain('Results per page'); + }); + + it('shows scope selector for v2.1', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', showScope: true } + }); + + expect(wrapper.text()).toContain('Tournament scope'); + }); + + it('hides scope selector for v1', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v1', showScope: true } + }); + + expect(wrapper.text()).not.toContain('Tournament scope'); + }); + + it('emits update:perPage when per-page changes', async () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', perPage: 100, showPerPage: true } + }); + + const select = wrapper.findAll('select')[0]; + await select.setValue('25'); + + expect(wrapper.emitted('update:perPage')).toBeTruthy(); + expect(wrapper.emitted('update:perPage')[0]).toEqual([25]); + }); + + it('emits update:scope when scope changes', async () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', scope: 'user', showScope: true } + }); + + const select = wrapper.findAll('select')[1]; + await select.setValue('app'); + + expect(wrapper.emitted('update:scope')).toBeTruthy(); + expect(wrapper.emitted('update:scope')[0]).toEqual(['app']); + }); + + it('shows USER scope info badge', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', scope: 'user', showScope: true } + }); + + expect(wrapper.text()).toContain('USER scope'); + expect(wrapper.find('.info-badge').exists()).toBe(true); + expect(wrapper.find('.info-badge.warning').exists()).toBe(false); + }); + + it('shows APPLICATION scope warning badge', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', scope: 'app', showScope: true } + }); + + expect(wrapper.text()).toContain('APPLICATION scope'); + expect(wrapper.find('.info-badge.warning').exists()).toBe(true); + }); + + it('can hide per-page selector', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', showPerPage: false } + }); + + expect(wrapper.text()).not.toContain('Results per page'); + }); + + it('can hide scope selector', () => { + const wrapper = mount(ApiVersionSelector, { + props: { modelValue: 'v2.1', showScope: false } + }); + + expect(wrapper.text()).not.toContain('Tournament scope'); + }); +});