feat: enhance child edit and view components with improved form handling and validation
All checks were successful
Chore App Build and Push Docker Images / build-and-push (push) Successful in 1m4s
All checks were successful
Chore App Build and Push Docker Images / build-and-push (push) Successful in 1m4s
- Added `requireDirty` prop to `EntityEditForm` for dirty state management. - Updated `ChildEditView` to handle initial data loading and image selection more robustly. - Refactored `ChildView` to remove unused reward dialog logic and prevent API calls in child mode. - Improved type definitions for form fields and initial data in `ChildEditView`. - Enhanced error handling in form submissions across components. - Implemented cross-tab logout synchronization on password reset in the auth store. - Added tests for login and entity edit form functionalities to ensure proper behavior. - Introduced global fetch interceptor for handling unauthorized responses. - Documented password reset flow and its implications on session management.
This commit is contained in:
106
frontend/vue-app/src/common/__tests__/backendEvents.spec.ts
Normal file
106
frontend/vue-app/src/common/__tests__/backendEvents.spec.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { mount } from '@vue/test-utils'
|
||||
import { defineComponent, h, toRef } from 'vue'
|
||||
import { useBackendEvents } from '../backendEvents'
|
||||
|
||||
const { emitMock } = vi.hoisted(() => ({
|
||||
emitMock: vi.fn(),
|
||||
}))
|
||||
|
||||
vi.mock('../eventBus', () => ({
|
||||
eventBus: {
|
||||
emit: emitMock,
|
||||
},
|
||||
}))
|
||||
|
||||
class MockEventSource {
|
||||
static instances: MockEventSource[] = []
|
||||
public onmessage: ((event: MessageEvent) => void) | null = null
|
||||
public close = vi.fn(() => {
|
||||
this.closed = true
|
||||
})
|
||||
public closed = false
|
||||
|
||||
constructor(public url: string) {
|
||||
MockEventSource.instances.push(this)
|
||||
}
|
||||
}
|
||||
|
||||
const TestHarness = defineComponent({
|
||||
name: 'BackendEventsHarness',
|
||||
props: {
|
||||
userId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
useBackendEvents(toRef(props, 'userId'))
|
||||
return () => h('div')
|
||||
},
|
||||
})
|
||||
|
||||
describe('useBackendEvents', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
MockEventSource.instances = []
|
||||
vi.stubGlobal('EventSource', MockEventSource)
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.unstubAllGlobals()
|
||||
})
|
||||
|
||||
it('connects when user id becomes available after mount', async () => {
|
||||
const wrapper = mount(TestHarness, { props: { userId: '' } })
|
||||
|
||||
expect(MockEventSource.instances.length).toBe(0)
|
||||
|
||||
await wrapper.setProps({ userId: 'user-1' })
|
||||
|
||||
expect(MockEventSource.instances.length).toBe(1)
|
||||
expect(MockEventSource.instances[0]?.url).toBe('/events?user_id=user-1')
|
||||
})
|
||||
|
||||
it('reconnects when user id changes and closes previous connection', async () => {
|
||||
const wrapper = mount(TestHarness, { props: { userId: 'user-1' } })
|
||||
|
||||
expect(MockEventSource.instances.length).toBe(1)
|
||||
const firstConnection = MockEventSource.instances[0]
|
||||
|
||||
await wrapper.setProps({ userId: 'user-2' })
|
||||
|
||||
expect(firstConnection?.close).toHaveBeenCalledTimes(1)
|
||||
expect(MockEventSource.instances.length).toBe(2)
|
||||
expect(MockEventSource.instances[1]?.url).toBe('/events?user_id=user-2')
|
||||
})
|
||||
|
||||
it('emits parsed backend events on message', async () => {
|
||||
mount(TestHarness, { props: { userId: 'user-1' } })
|
||||
|
||||
const connection = MockEventSource.instances[0]
|
||||
expect(connection).toBeDefined()
|
||||
|
||||
connection?.onmessage?.({
|
||||
data: JSON.stringify({ type: 'profile_updated', payload: { id: 'user-1' } }),
|
||||
} as MessageEvent)
|
||||
|
||||
expect(emitMock).toHaveBeenCalledWith('profile_updated', {
|
||||
type: 'profile_updated',
|
||||
payload: { id: 'user-1' },
|
||||
})
|
||||
expect(emitMock).toHaveBeenCalledWith('sse', {
|
||||
type: 'profile_updated',
|
||||
payload: { id: 'user-1' },
|
||||
})
|
||||
})
|
||||
|
||||
it('closes the event source on unmount', () => {
|
||||
const wrapper = mount(TestHarness, { props: { userId: 'user-1' } })
|
||||
|
||||
const connection = MockEventSource.instances[0]
|
||||
wrapper.unmount()
|
||||
|
||||
expect(connection?.close).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user