Refactor and enhance various components and tests
All checks were successful
Chore App Build and Push Docker Images / build-and-push (push) Successful in 1m23s
All checks were successful
Chore App Build and Push Docker Images / build-and-push (push) Successful in 1m23s
- Remove OverrideEditModal.spec.ts test file. - Update ParentPinSetup.vue to handle Enter key for code and PIN inputs. - Modify ChildEditView.vue to add maxlength for age input. - Enhance ChildView.vue with reward confirmation and cancellation dialogs. - Update ParentView.vue to handle pending rewards and confirm edits. - Revise PendingRewardDialog.vue to accept a dynamic message prop. - Expand ChildView.spec.ts to cover reward dialog interactions. - Add tests for ParentView.vue to validate pending reward handling. - Update UserProfile.vue to simplify button styles. - Adjust RewardView.vue to improve delete confirmation handling. - Modify ChildrenListView.vue to clarify child creation instructions. - Refactor EntityEditForm.vue to improve input handling and focus management. - Enhance ItemList.vue to support item selection. - Update LoginButton.vue to focus PIN input on error. - Change ScrollingList.vue empty state color for better visibility. - Remove capture attribute from ImagePicker.vue file input. - Update router/index.ts to redirect logged-in users from auth routes. - Add authGuard.spec.ts to test router authentication logic.
This commit is contained in:
@@ -1,208 +0,0 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { mount, VueWrapper } from '@vue/test-utils'
|
||||
import { nextTick } from 'vue'
|
||||
import OverrideEditModal from '../OverrideEditModal.vue'
|
||||
|
||||
// Mock API functions
|
||||
vi.mock('@/common/api', () => ({
|
||||
setChildOverride: vi.fn(),
|
||||
parseErrorResponse: vi.fn(() => ({ msg: 'Test error', code: 'TEST_ERROR' })),
|
||||
}))
|
||||
|
||||
import { setChildOverride } from '@/common/api'
|
||||
|
||||
global.alert = vi.fn()
|
||||
|
||||
describe('OverrideEditModal', () => {
|
||||
let wrapper: VueWrapper<any>
|
||||
|
||||
const defaultProps = {
|
||||
isOpen: true,
|
||||
childId: 'child-123',
|
||||
entityId: 'task-456',
|
||||
entityType: 'task' as 'task' | 'reward',
|
||||
entityName: 'Test Task',
|
||||
defaultValue: 100,
|
||||
currentOverride: undefined,
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
if (wrapper) {
|
||||
wrapper.unmount()
|
||||
}
|
||||
})
|
||||
|
||||
describe('Modal Display', () => {
|
||||
it('renders when isOpen is true', () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
expect(wrapper.find('.modal-backdrop').exists()).toBe(true)
|
||||
expect(wrapper.text()).toContain('Test Task')
|
||||
})
|
||||
|
||||
it('does not render when isOpen is false', () => {
|
||||
wrapper = mount(OverrideEditModal, { props: { ...defaultProps, isOpen: false } })
|
||||
expect(wrapper.find('.modal-backdrop').exists()).toBe(false)
|
||||
})
|
||||
|
||||
it('displays entity information correctly for tasks', () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
expect(wrapper.text()).toContain('Test Task')
|
||||
expect(wrapper.text()).toContain('New Points')
|
||||
})
|
||||
|
||||
it('displays entity information correctly for rewards', () => {
|
||||
wrapper = mount(OverrideEditModal, {
|
||||
props: { ...defaultProps, entityType: 'reward', entityName: 'Test Reward' },
|
||||
})
|
||||
expect(wrapper.text()).toContain('Test Reward')
|
||||
expect(wrapper.text()).toContain('New Cost')
|
||||
})
|
||||
})
|
||||
|
||||
describe('Input Validation', () => {
|
||||
it('initializes with default value when no override exists', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
await nextTick()
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
expect((input.element as HTMLInputElement).value).toBe('100')
|
||||
})
|
||||
|
||||
it('initializes with current override value when it exists', async () => {
|
||||
wrapper = mount(OverrideEditModal, {
|
||||
props: { ...defaultProps, currentOverride: 150 },
|
||||
})
|
||||
await nextTick()
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
expect((input.element as HTMLInputElement).value).toBe('150')
|
||||
})
|
||||
|
||||
it('validates input within range (0-10000)', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
const saveButton = wrapper.findAll('button').find((btn) => btn.text() === 'Save')
|
||||
|
||||
// Valid value
|
||||
await input.setValue(5000)
|
||||
await nextTick()
|
||||
expect(saveButton?.attributes('disabled')).toBeUndefined()
|
||||
|
||||
// Zero is valid
|
||||
await input.setValue(0)
|
||||
await nextTick()
|
||||
expect(saveButton?.attributes('disabled')).toBeUndefined()
|
||||
|
||||
// Max is valid
|
||||
await input.setValue(10000)
|
||||
await nextTick()
|
||||
expect(saveButton?.attributes('disabled')).toBeUndefined()
|
||||
})
|
||||
|
||||
it('shows error for values outside range', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
|
||||
// Above max
|
||||
await input.setValue(10001)
|
||||
await nextTick()
|
||||
expect(wrapper.text()).toContain('Value must be between 0 and 10000')
|
||||
const saveButton = wrapper.findAll('button').find((btn) => btn.text() === 'Save')
|
||||
expect(saveButton?.attributes('disabled')).toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('User Interactions', () => {
|
||||
it('emits close event when Cancel is clicked', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
const cancelButton = wrapper.findAll('button').find((btn) => btn.text() === 'Cancel')
|
||||
await cancelButton?.trigger('click')
|
||||
expect(wrapper.emitted('close')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('emits close event when clicking backdrop', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
await wrapper.find('.modal-backdrop').trigger('click')
|
||||
expect(wrapper.emitted('close')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('does not close when clicking modal dialog', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
await wrapper.find('.modal-dialog').trigger('click')
|
||||
expect(wrapper.emitted('close')).toBeFalsy()
|
||||
})
|
||||
|
||||
it('calls API and emits events on successful save', async () => {
|
||||
;(setChildOverride as any).mockResolvedValue({ ok: true })
|
||||
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
await input.setValue(250)
|
||||
await nextTick()
|
||||
|
||||
const saveButton = wrapper.findAll('button').find((btn) => btn.text() === 'Save')
|
||||
await saveButton?.trigger('click')
|
||||
await nextTick()
|
||||
|
||||
expect(setChildOverride).toHaveBeenCalledWith('child-123', 'task-456', 'task', 250)
|
||||
expect(wrapper.emitted('saved')).toBeTruthy()
|
||||
expect(wrapper.emitted('close')).toBeTruthy()
|
||||
})
|
||||
|
||||
it('shows alert on API error', async () => {
|
||||
;(setChildOverride as any).mockResolvedValue({ ok: false, status: 400 })
|
||||
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
const saveButton = wrapper.findAll('button').find((btn) => btn.text() === 'Save')
|
||||
await saveButton?.trigger('click')
|
||||
await nextTick()
|
||||
|
||||
expect(global.alert).toHaveBeenCalledWith('Error: Test error')
|
||||
expect(wrapper.emitted('saved')).toBeFalsy()
|
||||
})
|
||||
|
||||
it('does not save when validation fails', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: defaultProps })
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
await input.setValue(20000)
|
||||
await nextTick()
|
||||
|
||||
const saveButton = wrapper.findAll('button').find((btn) => btn.text() === 'Save')
|
||||
await saveButton?.trigger('click')
|
||||
await nextTick()
|
||||
|
||||
expect(setChildOverride).not.toHaveBeenCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('Modal State Updates', () => {
|
||||
it('reinitializes value when modal reopens', async () => {
|
||||
wrapper = mount(OverrideEditModal, { props: { ...defaultProps, isOpen: false } })
|
||||
await nextTick()
|
||||
|
||||
await wrapper.setProps({ isOpen: true })
|
||||
await nextTick()
|
||||
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
expect((input.element as HTMLInputElement).value).toBe('100')
|
||||
})
|
||||
|
||||
it('uses updated currentOverride when modal reopens', async () => {
|
||||
wrapper = mount(OverrideEditModal, {
|
||||
props: { ...defaultProps, isOpen: true, currentOverride: 200 },
|
||||
})
|
||||
await nextTick()
|
||||
|
||||
await wrapper.setProps({ isOpen: false })
|
||||
await nextTick()
|
||||
|
||||
await wrapper.setProps({ isOpen: true, currentOverride: 300 })
|
||||
await nextTick()
|
||||
|
||||
const input = wrapper.find('input[type="number"]')
|
||||
expect((input.element as HTMLInputElement).value).toBe('300')
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user