fix: update ParentView tests to use mount options and improve mock implementations
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m18s
All checks were successful
Chore App Build, Test, and Push Docker Images / build-and-push (push) Successful in 3m18s
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { mount, VueWrapper } from '@vue/test-utils'
|
||||
import { nextTick } from 'vue'
|
||||
import { nextTick, defineComponent } from 'vue'
|
||||
import ParentView from '../ParentView.vue'
|
||||
import { eventBus } from '@/common/eventBus'
|
||||
|
||||
@@ -8,6 +8,7 @@ import { eventBus } from '@/common/eventBus'
|
||||
vi.mock('vue-router', () => ({
|
||||
useRoute: vi.fn(() => ({
|
||||
params: { id: 'child-123' },
|
||||
query: {},
|
||||
})),
|
||||
useRouter: vi.fn(() => ({
|
||||
push: vi.fn(),
|
||||
@@ -17,6 +18,15 @@ vi.mock('vue-router', () => ({
|
||||
vi.mock('@/common/api', () => ({
|
||||
setChildOverride: vi.fn(),
|
||||
parseErrorResponse: vi.fn(() => ({ msg: 'Test error', code: 'TEST_ERROR' })),
|
||||
extendChoreTime: vi.fn(),
|
||||
approveChore: vi.fn(),
|
||||
rejectChore: vi.fn(),
|
||||
resetChore: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('@/common/imageCache', () => ({
|
||||
getCachedImageUrl: vi.fn(() => Promise.resolve('/mock-image.png')),
|
||||
revokeAllImageUrls: vi.fn(),
|
||||
}))
|
||||
|
||||
global.fetch = vi.fn()
|
||||
@@ -24,6 +34,51 @@ global.alert = vi.fn()
|
||||
|
||||
import { setChildOverride, parseErrorResponse } from '@/common/api'
|
||||
|
||||
// Stub for ScrollingList that exposes the same interface
|
||||
const ScrollingListStub = defineComponent({
|
||||
name: 'ScrollingList',
|
||||
props: [
|
||||
'title',
|
||||
'fetchBaseUrl',
|
||||
'ids',
|
||||
'itemKey',
|
||||
'imageField',
|
||||
'imageFields',
|
||||
'enableEdit',
|
||||
'childId',
|
||||
'readyItemId',
|
||||
'isParentAuthenticated',
|
||||
'filterFn',
|
||||
'sortFn',
|
||||
'getItemClass',
|
||||
],
|
||||
emits: ['trigger-item', 'edit-item', 'item-ready'],
|
||||
setup(_, { expose }) {
|
||||
const refresh = vi.fn()
|
||||
const scrollToItem = vi.fn()
|
||||
const centerItem = vi.fn()
|
||||
expose({ refresh, items: [], centerItem, scrollToItem })
|
||||
return { refresh, scrollToItem, centerItem }
|
||||
},
|
||||
template: '<div class="scrolling-list-stub"><slot /></div>',
|
||||
})
|
||||
|
||||
const mountOptions = {
|
||||
global: {
|
||||
stubs: {
|
||||
ScrollingList: ScrollingListStub,
|
||||
ChildDetailCard: { template: '<div class="child-detail-stub" />' },
|
||||
StatusMessage: { template: '<div class="status-stub" />' },
|
||||
ModalDialog: { template: '<div class="modal-stub"><slot /></div>' },
|
||||
ScheduleModal: { template: '<div class="schedule-stub" />' },
|
||||
PendingRewardDialog: { template: '<div class="pending-reward-stub" />' },
|
||||
TaskConfirmDialog: { template: '<div class="task-confirm-stub" />' },
|
||||
RewardConfirmDialog: { template: '<div class="reward-confirm-stub" />' },
|
||||
ChoreApproveDialog: { template: '<div class="chore-approve-stub" />' },
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
describe('ParentView', () => {
|
||||
let wrapper: VueWrapper<any>
|
||||
|
||||
@@ -91,7 +146,7 @@ describe('ParentView', () => {
|
||||
|
||||
describe('Component Mounting', () => {
|
||||
it('loads and displays child data on mount', async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
|
||||
@@ -100,7 +155,7 @@ describe('ParentView', () => {
|
||||
|
||||
it('registers SSE event listeners on mount', async () => {
|
||||
const onSpy = vi.spyOn(eventBus, 'on')
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
|
||||
expect(onSpy).toHaveBeenCalledWith('child_task_triggered', expect.any(Function))
|
||||
@@ -111,7 +166,7 @@ describe('ParentView', () => {
|
||||
|
||||
it('unregisters SSE event listeners on unmount', async () => {
|
||||
const offSpy = vi.spyOn(eventBus, 'off')
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
|
||||
wrapper.unmount()
|
||||
@@ -123,7 +178,7 @@ describe('ParentView', () => {
|
||||
|
||||
describe('Override Modal', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
})
|
||||
@@ -184,7 +239,7 @@ describe('ParentView', () => {
|
||||
|
||||
describe('Save Override', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
})
|
||||
@@ -229,7 +284,7 @@ describe('ParentView', () => {
|
||||
|
||||
describe('SSE Event Handlers', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
})
|
||||
@@ -248,13 +303,15 @@ describe('ParentView', () => {
|
||||
})
|
||||
|
||||
it('handles child_override_set event and refreshes appropriate lists', async () => {
|
||||
const mockChoreRefresh = vi.fn()
|
||||
const mockPenaltyRefresh = vi.fn()
|
||||
const mockRewardRefresh = vi.fn()
|
||||
const mockChoreRefresh = vi.fn().mockResolvedValue(undefined)
|
||||
const mockPenaltyRefresh = vi.fn().mockResolvedValue(undefined)
|
||||
const mockRewardRefresh = vi.fn().mockResolvedValue(undefined)
|
||||
const mockKindnessRefresh = vi.fn().mockResolvedValue(undefined)
|
||||
|
||||
wrapper.vm.childChoreListRef = { refresh: mockChoreRefresh }
|
||||
wrapper.vm.childPenaltyListRef = { refresh: mockPenaltyRefresh }
|
||||
wrapper.vm.childRewardListRef = { refresh: mockRewardRefresh }
|
||||
wrapper.vm.childChoreListRef = { refresh: mockChoreRefresh, scrollToItem: vi.fn() }
|
||||
wrapper.vm.childKindnessListRef = { refresh: mockKindnessRefresh, scrollToItem: vi.fn() }
|
||||
wrapper.vm.childPenaltyListRef = { refresh: mockPenaltyRefresh, scrollToItem: vi.fn() }
|
||||
wrapper.vm.childRewardListRef = { refresh: mockRewardRefresh, scrollToItem: vi.fn() }
|
||||
|
||||
// Test task override
|
||||
wrapper.vm.handleOverrideSet({
|
||||
@@ -318,7 +375,7 @@ describe('ParentView', () => {
|
||||
|
||||
describe('Ready Item State Management', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
})
|
||||
@@ -339,7 +396,7 @@ describe('ParentView', () => {
|
||||
|
||||
describe('Penalty Display', () => {
|
||||
it('displays penalty values as negative in template', async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
|
||||
// The template should show -custom_value or -points for penalties
|
||||
@@ -361,7 +418,7 @@ describe('ParentView', () => {
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
})
|
||||
@@ -453,7 +510,7 @@ describe('ParentView', () => {
|
||||
|
||||
describe('Chore Card Selection (selectedChoreId)', () => {
|
||||
beforeEach(async () => {
|
||||
wrapper = mount(ParentView)
|
||||
wrapper = mount(ParentView, mountOptions)
|
||||
await nextTick()
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
})
|
||||
|
||||
@@ -89,13 +89,6 @@ async function refresh() {
|
||||
loading.value = false
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
refresh,
|
||||
items,
|
||||
centerItem,
|
||||
scrollToItem,
|
||||
})
|
||||
|
||||
const scrollToItem = async (itemId: string) => {
|
||||
await nextTick()
|
||||
const card = itemRefs.value[itemId]
|
||||
@@ -123,6 +116,13 @@ const centerItem = async (itemId: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
refresh,
|
||||
items,
|
||||
centerItem,
|
||||
scrollToItem,
|
||||
})
|
||||
|
||||
const handleClicked = async (item: any) => {
|
||||
await nextTick()
|
||||
const wrapper = scrollWrapper.value
|
||||
|
||||
Reference in New Issue
Block a user