more tests

This commit is contained in:
Ulf Gebhardt 2026-04-04 03:30:56 +02:00
parent b7a6eea72b
commit 3a21c36d02
Signed by: ulfgebhardt
GPG Key ID: DA6B843E748679C9
2 changed files with 317 additions and 0 deletions

View File

@ -201,6 +201,50 @@ describe('AddChatRoomByUserSearch.vue', () => {
})
})
describe('apollo searchChatTargets config', () => {
it('query returns the searchChatTargets query', () => {
wrapper = Wrapper()
const apolloConfig = wrapper.vm.$options.apollo.searchChatTargets
expect(apolloConfig.query.call(wrapper.vm)).toBeDefined()
})
it('variables returns query and limit', () => {
wrapper = Wrapper()
wrapper.vm.query = 'test'
const apolloConfig = wrapper.vm.$options.apollo.searchChatTargets
expect(apolloConfig.variables.call(wrapper.vm)).toEqual({ query: 'test', limit: 10 })
})
it('skip returns true when search is not started', () => {
wrapper = Wrapper()
wrapper.vm.query = 'ab'
const apolloConfig = wrapper.vm.$options.apollo.searchChatTargets
expect(apolloConfig.skip.call(wrapper.vm)).toBe(true)
})
it('skip returns false when search is started', () => {
wrapper = Wrapper()
wrapper.vm.query = 'abc'
const apolloConfig = wrapper.vm.$options.apollo.searchChatTargets
expect(apolloConfig.skip.call(wrapper.vm)).toBe(false)
})
it('update normalizes results with groupName fallback', () => {
wrapper = Wrapper()
const apolloConfig = wrapper.vm.$options.apollo.searchChatTargets
apolloConfig.update.call(wrapper.vm, {
searchChatTargets: [
{ id: '1', name: 'User', __typename: 'User' },
{ id: '2', groupName: 'Group', __typename: 'Group' },
],
})
expect(wrapper.vm.results).toEqual([
{ id: '1', name: 'User', __typename: 'User' },
{ id: '2', name: 'Group', groupName: 'Group', __typename: 'Group' },
])
})
})
describe('beforeDestroy', () => {
it('clears blur timeout', () => {
jest.useFakeTimers()

View File

@ -1017,4 +1017,277 @@ describe('Chat.vue', () => {
})
})
})
describe('currentLocaleIso watcher', () => {
it('reformats message dates when locale changes', async () => {
wrapper = Wrapper()
wrapper.vm.messages = [mockMessage({ _rawDate: '2026-06-15T14:30:00Z' })]
mocks.$i18n.locale = () => 'de'
wrapper.vm.$options.watch.currentLocaleIso.call(wrapper.vm)
expect(wrapper.vm.messages[0].timestamp).toBeDefined()
})
})
describe('expandChatLink', () => {
it('returns chat route with no query when no room selected', () => {
wrapper = Wrapper()
expect(wrapper.vm.expandChatLink).toEqual({ name: 'chat' })
})
it('returns groupId query for group rooms', () => {
wrapper = Wrapper()
wrapper.vm.selectedRoom = mockRoom({
isGroupRoom: true,
groupProfile: { id: 'g1' },
users: [{ id: 'current-user' }],
})
expect(wrapper.vm.expandChatLink).toEqual({ name: 'chat', query: { groupId: 'g1' } })
})
it('returns userId query for DM rooms', () => {
wrapper = Wrapper()
wrapper.vm.selectedRoom = mockRoom()
expect(wrapper.vm.expandChatLink).toEqual({ name: 'chat', query: { userId: 'other-user' } })
})
})
describe('roomHeaderLink', () => {
it('returns null when no other user found in DM', () => {
wrapper = Wrapper()
wrapper.vm.selectedRoom = mockRoom({ users: [{ id: 'current-user', name: 'Me' }] })
expect(wrapper.vm.roomHeaderLink).toBeNull()
})
})
describe('buildLastMessage', () => {
it('returns file name for non-audio files', () => {
wrapper = Wrapper()
const result = wrapper.vm.buildLastMessage({
content: '',
files: [{ name: 'photo', type: 'image/jpeg' }],
})
expect(result.content).toBe('\uD83D\uDCCE photo')
})
it('returns empty for audio files', () => {
wrapper = Wrapper()
const result = wrapper.vm.buildLastMessage({
content: '',
files: [{ name: 'audio', type: 'audio/mpeg' }],
})
expect(result.content).toBe('')
})
})
describe('searchRooms', () => {
it('fetches rooms with search term', async () => {
wrapper = Wrapper()
mocks.$apollo.query.mockResolvedValue({ data: { Room: [] } })
await wrapper.vm.searchRooms({ value: 'test' })
expect(wrapper.vm.roomSearch).toBe('test')
})
it('clears search and resets cursor', async () => {
wrapper = Wrapper()
wrapper.vm.roomSearch = 'old'
mocks.$apollo.query.mockResolvedValue({ data: { Room: [mockRoom()] } })
await wrapper.vm.searchRooms({ value: '' })
expect(wrapper.vm.roomSearch).toBe('')
expect(wrapper.vm.roomCursor).toBeDefined()
})
it('increments generation to handle concurrent searches', async () => {
wrapper = Wrapper()
mocks.$apollo.query.mockResolvedValue({ data: { Room: [] } })
await wrapper.vm.searchRooms({ value: 'a' })
expect(wrapper.vm.roomSearchGeneration).toBe(1)
await wrapper.vm.searchRooms({ value: 'ab' })
expect(wrapper.vm.roomSearchGeneration).toBe(2)
})
it('sets roomObserverDirty when roomsLoaded was true', async () => {
wrapper = Wrapper()
wrapper.vm.roomsLoaded = true
mocks.$apollo.query.mockResolvedValue({ data: { Room: [] } })
await wrapper.vm.searchRooms({ value: 'x' })
// roomObserverDirty was set, roomsLoaded is true (< pageSize), so no reinit
expect(wrapper.vm.roomObserverDirty).toBe(true)
})
})
describe('fetchMoreRooms', () => {
it('delegates to fetchRooms with current search', () => {
wrapper = Wrapper()
wrapper.vm.fetchRooms = jest.fn()
wrapper.vm.roomSearch = 'test'
wrapper.vm.fetchMoreRooms()
expect(wrapper.vm.fetchRooms).toHaveBeenCalledWith({ search: 'test' })
})
})
describe('fetchRooms replace mode', () => {
it('replaces rooms instead of appending', async () => {
wrapper = Wrapper()
wrapper.vm.rooms = [mockRoom({ id: 'old', roomId: 'old' })]
mocks.$apollo.query.mockResolvedValue({ data: { Room: [mockRoom({ id: 'new', roomId: 'new' })] } })
await wrapper.vm.fetchRooms({ replace: true })
expect(wrapper.vm.rooms).toHaveLength(1)
expect(wrapper.vm.rooms[0].id).toBe('new')
})
it('selects first room in singleRoom mode', async () => {
wrapper = Wrapper({ singleRoom: true })
mocks.$apollo.query.mockResolvedValue({ data: { Room: [mockRoom()] } })
await wrapper.vm.fetchRooms({})
expect(wrapper.vm.activeRoomId).toBe('room-1')
})
it('fetches by room id', async () => {
wrapper = Wrapper()
mocks.$apollo.query.mockResolvedValue({ data: { Room: [mockRoom()] } })
await wrapper.vm.fetchRooms({ room: { id: 'room-1' } })
expect(mocks.$apollo.query).toHaveBeenCalledWith(
expect.objectContaining({ variables: expect.objectContaining({ id: 'room-1' }) }),
)
})
})
describe('fetchMessages edge cases', () => {
it('skips when room has no roomId', async () => {
wrapper = Wrapper()
await wrapper.vm.fetchMessages({ room: {} })
expect(wrapper.vm.activeRoomId).toBeNull()
})
it('blocks external room auto-select', async () => {
wrapper = Wrapper()
wrapper.vm.selectedRoom = mockRoom({ id: 'current', roomId: 'current' })
wrapper.vm.activeRoomId = 'current'
wrapper.vm._externalRoomIds = new Set(['ext-room'])
await wrapper.vm.fetchMessages({ room: { id: 'ext', roomId: 'ext-room' } })
expect(wrapper.vm.activeRoomId).toBe('current')
})
it('handles virtual rooms with early return', async () => {
wrapper = Wrapper()
wrapper.vm.selectedRoom = null
await wrapper.vm.fetchMessages({ room: { id: 'temp-123', roomId: 'temp-123' } })
// Virtual rooms toggle messagesLoaded and return early
expect(wrapper.vm.selectedRoom).toEqual({ id: 'temp-123', roomId: 'temp-123' })
})
it('handles fetch error', async () => {
wrapper = Wrapper()
mocks.$apollo.query.mockRejectedValue(new Error('Network error'))
await wrapper.vm.fetchMessages({ room: mockRoom(), options: {} })
expect(mocks.$toast.error).toHaveBeenCalledWith('Network error')
expect(wrapper.vm.messages).toEqual([])
})
})
describe('chatMessageAdded with new room', () => {
it('returns early when server returns empty rooms', async () => {
wrapper = Wrapper()
wrapper.vm.rooms = []
mocks.$apollo.query.mockResolvedValue({ data: { Room: [] } })
await subscriptionHandlers.chatMessageAdded.next({
data: { chatMessageAdded: mockMessage({ room: { id: 'unknown' } }) },
})
expect(wrapper.vm.rooms).toHaveLength(0)
})
it('returns early when room fetch fails', async () => {
wrapper = Wrapper()
wrapper.vm.rooms = []
mocks.$apollo.query.mockRejectedValue(new Error('fail'))
await subscriptionHandlers.chatMessageAdded.next({
data: { chatMessageAdded: mockMessage({ room: { id: 'unknown' } }) },
})
expect(wrapper.vm.rooms).toHaveLength(0)
})
it('fetches and inserts new room without auto-select', async () => {
wrapper = Wrapper()
wrapper.vm.rooms = [mockRoom()]
wrapper.vm.selectedRoom = mockRoom()
wrapper.vm.activeRoomId = 'room-1'
const newRoomData = mockRoom({
id: 'new-room',
roomId: 'new-room',
users: [
{ _id: 'current-user', id: 'current-user', name: 'Me', avatar: null },
{ _id: 'sender', id: 'sender', name: 'Sender', avatar: null },
],
})
mocks.$apollo.query.mockResolvedValue({ data: { Room: [newRoomData] } })
await subscriptionHandlers.chatMessageAdded.next({
data: {
chatMessageAdded: mockMessage({
room: { id: 'new-room' },
senderId: 'sender',
}),
},
})
expect(wrapper.vm.rooms[0].id).toBe('new-room')
expect(wrapper.vm._externalRoomIds.has('new-room')).toBe(true)
})
})
describe('toggleUserSearch', () => {
it('emits toggle-user-search', () => {
wrapper = Wrapper()
wrapper.vm.toggleUserSearch()
expect(wrapper.emitted('toggle-user-search')).toHaveLength(1)
})
})
describe('navigateToUserProfile', () => {
it('navigates using messageUserProfile', () => {
wrapper = Wrapper()
wrapper.vm.selectedRoom = mockRoom()
wrapper.vm.rooms = [mockRoom()]
wrapper.vm.navigateToUserProfile('other-user')
expect(mocks.$router.push).toHaveBeenCalledWith({
path: '/profile/other-user/other',
})
})
})
describe('newRoom with string userId', () => {
it('fetches user profile and creates virtual room', async () => {
wrapper = Wrapper()
mocks.$apollo.query
.mockResolvedValueOnce({ data: { User: [{ id: 'u1', name: 'Test User', avatar: null }] } })
.mockResolvedValueOnce({ data: { Room: [] } })
await wrapper.vm.newRoom('u1')
expect(wrapper.vm.rooms[0].roomName).toBe('Test User')
expect(wrapper.vm.rooms[0].id).toBe('temp-u1')
})
it('falls back to userId as name on profile fetch error', async () => {
wrapper = Wrapper()
mocks.$apollo.query
.mockRejectedValueOnce(new Error('fail'))
.mockResolvedValueOnce({ data: { Room: [] } })
await wrapper.vm.newRoom('u1')
expect(wrapper.vm.rooms[0].roomName).toBe('u1')
})
})
describe('sendMessage virtual room replacement', () => {
it('replaces virtual room with real room after send', async () => {
wrapper = Wrapper()
const virtualRoom = mockRoom({ id: 'temp-u1', roomId: 'temp-u1', _virtualUserId: 'u1' })
wrapper.vm.rooms = [virtualRoom]
wrapper.vm.selectedRoom = virtualRoom
wrapper.vm.activeRoomId = 'temp-u1'
const realRoom = mockRoom({ id: 'real-1', roomId: 'real-1' })
mocks.$apollo.mutate.mockResolvedValue({
data: { CreateMessage: { id: 'm1', room: { id: 'real-1' } } },
})
mocks.$apollo.query.mockResolvedValue({ data: { Room: [realRoom] } })
await wrapper.vm.sendMessage({ roomId: 'temp-u1', content: 'hi', files: [] })
expect(wrapper.vm.rooms.some((r) => r.id === 'real-1')).toBe(true)
})
})
})