123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- import { waitFor } from '@testing-library/vue'
- import { stringifyQuery } from 'vue-router'
- import { visitView } from '#tests/support/components/visitView.ts'
- import { mockApplicationConfig } from '#tests/support/mock-applicationConfig.ts'
- import { mockPermissions } from '#tests/support/mock-permissions.ts'
- import { mockTicketOverviews } from '#tests/support/mocks/ticket-overviews.ts'
- import { waitForNextTick } from '#tests/support/utils.ts'
- import { EnumOrderDirection } from '#shared/graphql/types.ts'
- import { mockTicketsByOverview, ticketDefault } from './mocks/overview.ts'
- beforeEach(() => {
- mockTicketOverviews()
- })
- it('see default list when opening page', async () => {
- mockPermissions(['ticket.agent'])
- mockTicketsByOverview([])
- const view = await visitView('/tickets/view')
- const plusSign = view.getByIconName('add')
- expect(plusSign, 'can create a new ticket from here').toBeInTheDocument()
- expect(view.getLinkFromElement(plusSign)).toHaveAttribute(
- 'href',
- '/mobile/tickets/create',
- )
- await waitForNextTick(true)
- expect(
- await view.findByTestId('overview'),
- 'has default overview',
- ).toHaveTextContent('Overview 1')
- expect(
- await view.findByTestId('column'),
- 'has default column',
- ).toHaveTextContent('Created at')
- expect(
- view.getByIconName('arrow-down'),
- 'descending by default',
- ).not.toHaveClass('rotate-180')
- expect(
- await view.findByText('No entries'),
- 'see a message when nothing is found',
- ).toBeInTheDocument()
- expect(window.location.pathname).toBe('/mobile/tickets/view/overview_1')
- })
- it('can filter by overview type', async () => {
- const ticketsMock = mockTicketsByOverview()
- const view = await visitView('/tickets/view')
- const overview = await view.findByTestId('overview')
- await view.events.click(overview)
- await view.events.click(view.getByText('Overview 1'))
- expect(ticketsMock.spies.resolve).toHaveBeenCalledWith(
- expect.objectContaining({
- orderBy: 'created_at',
- orderDirection: EnumOrderDirection.Descending,
- overviewId: '1',
- }),
- )
- const ticketItem = view.getByText('Ticket 1')
- expect(ticketItem).toBeInTheDocument()
- expect(view.getLinkFromElement(ticketItem)).toHaveAttribute(
- 'href',
- '/mobile/tickets/1',
- )
- })
- it('can filter by columns and direction', async () => {
- const ticketsMock = mockTicketsByOverview()
- const view = await visitView('/tickets/view')
- const columnSelector = await view.findByTestId('column')
- await view.events.click(columnSelector)
- await view.events.click(view.getByText('Updated at'))
- await view.events.click(view.getByText('ascending'))
- expect(ticketsMock.spies.resolve).toHaveBeenCalledWith(
- expect.objectContaining({
- orderBy: 'updated_at',
- orderDirection: EnumOrderDirection.Ascending,
- overviewId: '1',
- }),
- )
- expect(view.getByText('Ticket 1')).toBeInTheDocument()
- })
- it('can filter by type and columns and direction', async () => {
- const ticketsMock = mockTicketsByOverview()
- const view = await visitView('/tickets/view')
- const overview = await view.findByTestId('overview')
- await view.events.click(overview)
- await view.events.click(view.getByText('Overview 1'))
- const columnSelector = view.getByTestId('column')
- await view.events.click(columnSelector)
- await view.events.click(view.getByText('Updated at'))
- await view.events.click(view.getByText('ascending'))
- expect(ticketsMock.spies.resolve).toHaveBeenCalledWith(
- expect.objectContaining({
- overviewId: '1',
- orderBy: 'updated_at',
- orderDirection: EnumOrderDirection.Ascending,
- }),
- )
- expect(view.getByText('Ticket 1')).toBeInTheDocument()
- })
- it('takes filter from query', async () => {
- const ticketsMock = mockTicketsByOverview()
- const query = stringifyQuery({
- column: 'number',
- direction: EnumOrderDirection.Ascending,
- })
- const view = await visitView(`/tickets/view?${query}`)
- await view.findByTestId('overview')
- await waitFor(() => {
- expect(ticketsMock.spies.resolve).toHaveBeenCalledWith(
- expect.objectContaining({
- overviewId: '1',
- orderBy: 'number',
- orderDirection: EnumOrderDirection.Ascending,
- }),
- )
- })
- })
- // TODO 2023-05-08 Sheremet V.A. rewrite test to run in Vitest browser mode
- describe.skip('paginating ticket list', () => {
- const emulateScroll = async (scroll: number) => {
- document.documentElement.scrollTop = scroll
- document.dispatchEvent(
- new Event('scroll', { bubbles: true, cancelable: true }),
- )
- await waitForNextTick()
- }
- it("doesn't load more, when there is nothing to load", async () => {
- const ticketOverviewsApi = mockTicketsByOverview([ticketDefault()], {
- hasNextPage: false,
- endCursor: 'cursor',
- })
- mockApplicationConfig({
- ui_ticket_overview_ticket_limit: 2000,
- })
- const view = await visitView(`/tickets/view`)
- await waitFor(() => view.getByText('Ticket 1'))
- expect(
- view.queryByRole('button', { name: 'load 10 more' }),
- ).not.toBeInTheDocument()
- await emulateScroll(1000)
- expect(ticketOverviewsApi.spies.resolve).not.toHaveBeenCalledWith(
- expect.objectContaining({
- cursor: 'cursor',
- }),
- )
- })
- it('load more button loads more tickets', async () => {
- const ticketOverviewsApi = mockTicketsByOverview([ticketDefault()], {
- hasNextPage: true,
- endCursor: 'cursor',
- })
- mockApplicationConfig({
- ui_ticket_overview_ticket_limit: 2000,
- })
- const view = await visitView(`/tickets/view`)
- await waitFor(() => view.getByText('Ticket 1'))
- const loadMoreButton = view.getByRole('button', { name: 'load 10 more' })
- expect(loadMoreButton).toBeInTheDocument()
- await view.events.click(loadMoreButton)
- expect(ticketOverviewsApi.spies.resolve).toHaveBeenCalledWith(
- expect.objectContaining({
- cursor: 'cursor',
- }),
- )
- // page now has 2 links to tickets
- // the last link before pressing "load more" has the focus
- expect(view.getAllByRole('link', { name: /Ticket 1/ })[0]).toHaveFocus()
- })
- it('pagination loads additional list', async () => {
- const ticketOverviewsApi = mockTicketsByOverview([ticketDefault()], {
- hasNextPage: true,
- endCursor: 'cursor',
- })
- mockApplicationConfig({
- ui_ticket_overview_ticket_limit: 2000,
- })
- const view = await visitView(`/tickets/view`)
- await waitFor(() => view.getByText('Ticket 1'))
- await emulateScroll(1000)
- expect(ticketOverviewsApi.spies.resolve).toHaveBeenCalledWith(
- expect.objectContaining({
- cursor: 'cursor',
- }),
- )
- })
- it("pagination doesn't load if it is already loading more", async () => {
- const ticketOverviewsApi = mockTicketsByOverview([ticketDefault()], {
- hasNextPage: true,
- endCursor: 'cursor',
- })
- const view = await visitView(`/tickets/view`)
- await waitFor(() => view.getByTestId('overview'))
- await emulateScroll(1000)
- expect(ticketOverviewsApi.spies.resolve).not.toHaveBeenCalledWith(
- expect.objectContaining({
- cursor: 'cursor',
- }),
- )
- })
- })
|