123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- // Copyright (C) 2012-2025 Zammad Foundation, https://zammad-foundation.org/
- import '#tests/graphql/builders/mocks.ts'
- import renderComponent from '#tests/support/components/renderComponent.ts'
- import { mockUserCurrent } from '#tests/support/mock-userCurrent.ts'
- import { waitForNextTick } from '#tests/support/utils.ts'
- import {
- EnumTicketStateColorCode,
- type Organization,
- } from '#shared/graphql/types.ts'
- import { convertToGraphQLId } from '#shared/graphql/utils.ts'
- import QuickSearch from '#desktop/components/QuickSearch/QuickSearch.vue'
- import { useRecentSearches } from '#desktop/composables/useRecentSearches.ts'
- import { mockUserCurrentRecentViewResetMutation } from '#desktop/entities/user/current/graphql/mutations/userCurrentRecentViewReset.mocks.ts'
- import { mockUserCurrentRecentViewListQuery } from '#desktop/entities/user/current/graphql/queries/userCurrentRecentViewList.mocks.ts'
- import { getUserCurrentRecentViewUpdatesSubscriptionHandler } from '#desktop/entities/user/current/graphql/subscriptions/userCurrentRecentViewUpdates.mocks.ts'
- import { mockQuickSearchQuery } from '../graphql/queries/quickSearch.mocks.ts'
- const renderQuickSearch = async (search: string = '') => {
- const wrapper = renderComponent(QuickSearch, {
- props: {
- collapsed: false,
- search,
- },
- router: true,
- store: true,
- dialog: true,
- })
- await waitForNextTick()
- return wrapper
- }
- mockUserCurrent()
- describe('QuickSearch', () => {
- const { addSearch, removeSearch, clearSearches } = useRecentSearches()
- beforeEach(() => {
- clearSearches()
- })
- describe('default state', () => {
- it('shows empty state message when no searches or recently viewed items exist', async () => {
- mockUserCurrentRecentViewListQuery({ userCurrentRecentViewList: [] })
- const wrapper = await renderQuickSearch()
- expect(
- wrapper.getByText(
- 'Start typing i.e. the name of a ticket, an organization or a user.',
- ),
- ).toBeInTheDocument()
- expect(
- wrapper.queryByRole('button', { name: 'Clear All' }),
- ).not.toBeInTheDocument()
- })
- })
- describe('recent searches', () => {
- beforeEach(() => {
- mockUserCurrentRecentViewListQuery({ userCurrentRecentViewList: [] })
- })
- it('displays recent searches when added', async () => {
- const wrapper = await renderQuickSearch()
- addSearch('Foobar')
- addSearch('Dummy')
- await waitForNextTick()
- expect(
- wrapper.getByRole('heading', { level: 3, name: 'Recent searches' }),
- ).toBeInTheDocument()
- expect(wrapper.getByText('Foobar')).toBeInTheDocument()
- expect(wrapper.getByText('Dummy')).toBeInTheDocument()
- expect(
- wrapper.getByRole('link', { name: 'Clear recent searches' }),
- ).toBeInTheDocument()
- })
- it('allows clearing all recent searches', async () => {
- const wrapper = await renderQuickSearch()
- addSearch('Foobar')
- addSearch('Dummy')
- await waitForNextTick()
- expect(
- wrapper.getByRole('link', { name: 'Clear recent searches' }),
- ).toBeInTheDocument()
- clearSearches()
- await waitForNextTick()
- expect(
- wrapper.getByText(
- 'Start typing i.e. the name of a ticket, an organization or a user.',
- ),
- ).toBeInTheDocument()
- expect(
- wrapper.queryByRole('link', { name: 'Clear recent searches' }),
- ).not.toBeInTheDocument()
- })
- it('allows removing individual recent searches', async () => {
- const wrapper = await renderQuickSearch()
- addSearch('Foobar')
- addSearch('Dummy')
- await waitForNextTick()
- let removeIcons = wrapper.getAllByIconName('x-lg')
- expect(removeIcons.length).toBe(2)
- removeSearch('Foobar')
- await waitForNextTick()
- removeIcons = wrapper.getAllByIconName('x-lg')
- expect(removeIcons.length).toBe(1)
- })
- })
- describe('recently viewed items', () => {
- const recentlyViewedItems = [
- {
- __typename: 'Ticket',
- id: convertToGraphQLId('Ticket', 1),
- title: 'Ticket 1',
- number: '1',
- stateColorCode: EnumTicketStateColorCode.Open,
- },
- {
- __typename: 'User',
- id: convertToGraphQLId('User', 1),
- internalId: 1,
- fullname: 'User 1',
- },
- {
- __typename: 'Organization',
- id: convertToGraphQLId('Organization', 1),
- internalId: 1,
- name: 'Organization 1',
- },
- ]
- it('displays recently viewed items', async () => {
- mockUserCurrentRecentViewListQuery({
- userCurrentRecentViewList: recentlyViewedItems as Organization[],
- })
- const wrapper = await renderQuickSearch()
- expect(
- wrapper.getByRole('heading', { level: 3, name: 'Recently viewed' }),
- ).toBeInTheDocument()
- expect(
- wrapper.getByRole('link', { name: 'check-circle-no Ticket 1' }),
- ).toBeInTheDocument()
- expect(wrapper.getByRole('link', { name: 'User 1' })).toBeInTheDocument()
- expect(
- wrapper.getByRole('link', { name: 'Organization 1' }),
- ).toBeInTheDocument()
- })
- it('allows clearing all recently viewed items', async () => {
- mockUserCurrentRecentViewListQuery({
- userCurrentRecentViewList: recentlyViewedItems as Organization[],
- })
- mockUserCurrentRecentViewResetMutation({
- userCurrentRecentViewReset: { success: true },
- })
- const wrapper = await renderQuickSearch()
- expect(
- wrapper.getByRole('link', { name: 'Clear recently viewed' }),
- ).toBeInTheDocument()
- mockUserCurrentRecentViewListQuery({ userCurrentRecentViewList: [] })
- await getUserCurrentRecentViewUpdatesSubscriptionHandler().trigger({
- userCurrentRecentViewUpdates: {
- recentViewsUpdated: true,
- },
- })
- await waitForNextTick()
- expect(
- wrapper.getByText(
- 'Start typing i.e. the name of a ticket, an organization or a user.',
- ),
- ).toBeInTheDocument()
- expect(
- wrapper.queryByRole('link', { name: 'Clear recently viewed' }),
- ).not.toBeInTheDocument()
- })
- it('display search results when typing', async () => {
- mockQuickSearchQuery({
- quickSearchUsers: {
- totalCount: 0,
- items: [],
- },
- quickSearchOrganizations: {
- totalCount: 0,
- items: [],
- },
- quickSearchTickets: {
- totalCount: 0,
- items: [],
- },
- })
- const wrapper = await renderQuickSearch('test')
- expect(
- await wrapper.findByText('No results for this query.'),
- ).toBeInTheDocument()
- })
- })
- })
|