Browse Source

Maintenance: Move testing from selenium to graphql tests and frontend integration tests.

Dominik Klein 2 years ago
parent
commit
7a60d782c0

+ 2 - 0
app/frontend/apps/mobile/components/layout/__tests__/LayoutBottomNavigation.spec.ts

@@ -22,6 +22,8 @@ describe('bottom navigation in layout', () => {
     await flushPromises()
 
     expect(view.getByIconName('home')).toBeInTheDocument()
+    expect(view.getByIconName('home').closest('a')).toHaveClass('text-blue')
+
     expect(view.getByIconName('bell')).toBeInTheDocument()
     expect(view.getByText('UT')).toBeInTheDocument()
   })

+ 5 - 5
app/frontend/apps/mobile/modules/account/__tests__/view-account.spec.ts

@@ -5,7 +5,7 @@ import { mockAccount } from '@tests/support/mock-account'
 
 describe('account page', () => {
   // TODO pretty much static page, not a lot of tests needed for now
-  test('can view my account page', async () => {
+  it('can view my account page', async () => {
     mockAccount({
       lastname: 'Doe',
       firstname: 'John',
@@ -13,9 +13,9 @@ describe('account page', () => {
 
     const view = await visitView('/account')
 
-    expect(view.getByText('JD'), 'have avatar').toBeInTheDocument()
-    expect(view.getByText('John Doe'), 'have my name').toBeInTheDocument()
-
-    expect(view.getByText('Sign out'), 'have logout button').toBeInTheDocument()
+    const mainContent = view.getByTestId('appMain')
+    expect(mainContent, 'have avatar').toHaveTextContent('JD')
+    expect(mainContent, 'have my name').toHaveTextContent('John Doe')
+    expect(mainContent, 'have logout button').toHaveTextContent('Sign out')
   })
 })

+ 18 - 0
app/frontend/apps/mobile/modules/home/__tests__/home-quick-action.spec.ts

@@ -0,0 +1,18 @@
+// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+import { visitView } from '@tests/support/components/visitView'
+
+describe('testing home section menu', () => {
+  it('home icon is highlighted on home page', async () => {
+    const view = await visitView('/')
+
+    expect(view.getByIconName('plus')).toBeInTheDocument()
+
+    // TODO: Check on ticket create form, when route exists
+    // await view.events.click(quickAction)
+
+    // await waitFor(() => {
+    //   expect(view.getByText('TODO')).toBeInTheDocument()
+    // })
+  })
+})

+ 24 - 0
app/frontend/apps/mobile/modules/home/__tests__/home-section-menu.spec.ts

@@ -0,0 +1,24 @@
+// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+import { waitFor } from '@testing-library/vue'
+import { visitView } from '@tests/support/components/visitView'
+import { waitForNextTick } from '@tests/support/utils'
+
+describe('testing home section menu', () => {
+  it('home icon is highlighted on home page', async () => {
+    const view = await visitView('/')
+
+    const ticketOverviewLink = view.getByRole('link', {
+      name: 'Ticket Overviews',
+    })
+
+    await view.events.click(ticketOverviewLink)
+
+    await waitForNextTick(true)
+
+    await waitFor(() => {
+      // TODO: Switch to better identifier, when real ticket lists exists.
+      expect(view.getByText('Go to link Home')).toBeInTheDocument()
+    })
+  })
+})

+ 1 - 1
app/frontend/apps/mobile/modules/home/views/Home.vue

@@ -17,7 +17,7 @@ const menu: MenuItem[] = [
   {
     type: 'link',
     link: '/tickets',
-    title: __('All Tickets'),
+    title: __('Ticket Overviews'),
     icon: { name: 'stack', size: 'base' },
     iconBg: 'bg-pink',
   },

+ 0 - 15
app/frontend/apps/mobile/modules/login/__tests__/login-maintenance.spec.ts

@@ -14,12 +14,7 @@ import { ApplicationConfigDocument } from '@shared/graphql/queries/applicationCo
 import { waitFor } from '@testing-library/vue'
 import useAuthenticationStore from '@shared/stores/authentication'
 import { waitForNextTick } from '@tests/support/utils'
-import createMockClient, {
-  resetMockClient,
-} from '@tests/support/mock-apollo-client'
 import { mockPermissions } from '@tests/support/mock-permissions'
-import { getApiTicketOverviews } from '@mobile/modules/home/__tests__/mocks'
-import { OverviewsDocument } from '@shared/entities/ticket/graphql/queries/overviews.api'
 
 vi.mock('@shared/server/apollo/client', () => {
   return {
@@ -30,16 +25,6 @@ vi.mock('@shared/server/apollo/client', () => {
 })
 
 describe('testing login maintenance mode', () => {
-  beforeEach(() => {
-    resetMockClient()
-    createMockClient([
-      {
-        operationDocument: OverviewsDocument,
-        handler: async () => ({ data: getApiTicketOverviews() }),
-      },
-    ])
-  })
-
   it('check not visible maintenance mode message, when maintenance mode is not active', async () => {
     mockApplicationConfig({
       maintenance_mode: false,

+ 3 - 6
app/frontend/shared/components/CommonAvatar/__tests__/CommonAvatar.spec.ts

@@ -69,9 +69,8 @@ describe('CommonAvatar.vue', () => {
   })
 
   it('renders different sizes', async () => {
-    const view = renderComponent(CommonAvatar, {
-      unmount: false,
-    })
+    const view = renderComponent(CommonAvatar)
+
     const avatar = view.getByTestId('common-avatar')
 
     expect(avatar).toHaveClass('size-medium')
@@ -92,9 +91,7 @@ describe('CommonAvatar.vue', () => {
   })
 
   it('renders vip icon', async () => {
-    const view = renderComponent(CommonAvatar, {
-      unmount: false,
-    })
+    const view = renderComponent(CommonAvatar)
     expect(view.queryByIconName('crown')).not.toBeInTheDocument()
     await view.rerender({ vip: true })
     expect(view.getByIconName('crown')).toBeInTheDocument()

+ 108 - 0
app/frontend/shared/composables/__tests__/useAppMaintenanceCheck.spec.ts

@@ -0,0 +1,108 @@
+// Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+import { useNotifications } from '@shared/components/CommonNotifications'
+import { ApplicationBuildChecksumDocument } from '@shared/graphql/queries/applicationBuildChecksum.api'
+import { AppMaintenanceDocument } from '@shared/graphql/subscriptions/appMaintenance.api'
+import { AppMaintenanceType } from '@shared/graphql/types'
+import { renderComponent } from '@tests/support/components'
+import {
+  mockGraphQLApi,
+  mockGraphQLSubscription,
+} from '@tests/support/mock-graphql-api'
+import { IMockSubscription } from 'mock-apollo-client'
+import useAppMaintenanceCheck from '../useAppMaintenanceCheck'
+
+let subscriptionAppMaintenance: IMockSubscription
+
+describe('useAppMaintenanceCheck', () => {
+  beforeAll(() => {
+    mockGraphQLApi(ApplicationBuildChecksumDocument).willResolve({
+      applicationBuildChecksum: {
+        applicationBuildChecksum: 'initial-checksum',
+      },
+    })
+
+    subscriptionAppMaintenance = mockGraphQLSubscription(AppMaintenanceDocument)
+
+    renderComponent(
+      {
+        template: '<div>App Maintenance Check</div>',
+        setup() {
+          useAppMaintenanceCheck()
+        },
+      },
+      {
+        router: true,
+        unmount: false,
+      },
+    )
+  })
+
+  afterEach(() => {
+    useNotifications().clearAllNotifications()
+  })
+
+  it('reacts to config_updated message', () => {
+    subscriptionAppMaintenance.next({
+      data: {
+        appMaintenance: {
+          type: AppMaintenanceType.ConfigChanged,
+        },
+      },
+    })
+
+    const { notifications } = useNotifications()
+
+    expect(notifications.value[0].message).toBe(
+      'The configuration of Zammad has changed. Please reload at your earliest.',
+    )
+  })
+
+  it('reacts to app_version message', () => {
+    subscriptionAppMaintenance.next({
+      data: {
+        appMaintenance: {
+          type: AppMaintenanceType.AppVersion,
+        },
+      },
+    })
+
+    const { notifications } = useNotifications()
+
+    expect(notifications.value[0].message).toBe(
+      'A newer version of the app is available. Please reload at your earliest.',
+    )
+  })
+
+  it('reacts to reload_auto message', () => {
+    subscriptionAppMaintenance.next({
+      data: {
+        appMaintenance: {
+          type: AppMaintenanceType.RestartAuto,
+        },
+      },
+    })
+
+    const { notifications } = useNotifications()
+
+    expect(notifications.value[0].message).toBe(
+      'A newer version of the app is available. Please reload at your earliest.',
+    )
+  })
+
+  it('reacts to reload_manual message', () => {
+    subscriptionAppMaintenance.next({
+      data: {
+        appMaintenance: {
+          type: AppMaintenanceType.RestartManual,
+        },
+      },
+    })
+
+    const { notifications } = useNotifications()
+
+    expect(notifications.value[0].message).toBe(
+      'A newer version of the app is available. Please reload at your earliest.',
+    )
+  })
+})

+ 14 - 10
app/frontend/shared/composables/useAppMaintenanceCheck.ts

@@ -21,12 +21,12 @@ import {
 } from '@shared/server/apollo/handler'
 import testFlags from '@shared/utils/testFlags'
 
-let query: QueryHandler<
+let checksumQuery: QueryHandler<
   ApplicationBuildChecksumQuery,
   ApplicationBuildChecksumQueryVariables
 >
 let previousChecksum: string
-let subscription: SubscriptionHandler<
+let appMaintenanceSubscription: SubscriptionHandler<
   AppMaintenanceSubscription,
   AppMaintenanceSubscriptionVariables
 >
@@ -44,7 +44,7 @@ const useAppMaintenanceCheck = () => {
   }
 
   onMounted(() => {
-    if (query) return
+    if (checksumQuery) return
 
     // Default poll interval: every minute.
     const defaultPollInterval = 60 * 1000
@@ -62,13 +62,13 @@ const useAppMaintenanceCheck = () => {
       options.pollInterval = parseInt(applicationRebuildCheckInterval.value, 10)
     })
 
-    query = new QueryHandler(useApplicationBuildChecksumQuery(options))
+    checksumQuery = new QueryHandler(useApplicationBuildChecksumQuery(options))
 
-    let notificationMessage = __(
+    const notificationMessage = __(
       'A newer version of the app is available. Please reload at your earliest.',
     )
 
-    query.watchOnResult((queryResult): void => {
+    checksumQuery.watchOnResult((queryResult): void => {
       if (!queryResult?.applicationBuildChecksum.length) return
       if (!previousChecksum) {
         previousChecksum = queryResult?.applicationBuildChecksum
@@ -79,16 +79,20 @@ const useAppMaintenanceCheck = () => {
       }
     })
 
-    subscription = new SubscriptionHandler(useAppMaintenanceSubscription())
-    subscription.onResult((result) => {
+    appMaintenanceSubscription = new SubscriptionHandler(
+      useAppMaintenanceSubscription(),
+    )
+    appMaintenanceSubscription.onResult((result) => {
       const type = result.data?.appMaintenance.type
+      let message = notificationMessage
+
       if (!type) {
         testFlags.set('useAppMaintenanceSubscription.subscribed')
         return
       }
       switch (type) {
         case AppMaintenanceType.ConfigChanged:
-          notificationMessage = __(
+          message = __(
             'The configuration of Zammad has changed. Please reload at your earliest.',
           )
           break
@@ -99,7 +103,7 @@ const useAppMaintenanceCheck = () => {
         default:
           break
       }
-      notify(notificationMessage)
+      notify(message)
     })
   })
 }

+ 0 - 17
app/frontend/shared/server/apollo/handler/QueryHandler.ts

@@ -8,8 +8,6 @@ import {
   SubscribeToMoreOptions,
 } from '@apollo/client/core'
 import {
-  BaseHandlerOptions,
-  CommonHandlerOptionsParameter,
   OperationQueryOptionsReturn,
   OperationQueryResult,
   WatchResultCallback,
@@ -31,15 +29,6 @@ export default class QueryHandler<
 > {
   private firstResultLoaded = false
 
-  constructor(
-    operationResult: UseQueryReturn<TResult, TVariables>,
-    handlerOptions?: CommonHandlerOptionsParameter<BaseHandlerOptions>,
-  ) {
-    super(operationResult, handlerOptions)
-
-    handlers.push(this as unknown as QueryHandler)
-  }
-
   public options(): OperationQueryOptionsReturn<TResult, TVariables> {
     return this.operationResult.options
   }
@@ -48,12 +37,6 @@ export default class QueryHandler<
     return this.operationResult.result
   }
 
-  public reset() {
-    this.operationResult.result.value = undefined
-    this.operationResult.start()
-    return this.operationResult.refetch(this.operationResult.variables.value)
-  }
-
   public subscribeToMore<TSubscriptionData = TResult>(
     options: ReactiveFunction<
       SubscribeToMoreOptions<TResult, TVariables, TSubscriptionData>

Some files were not shown because too many files changed in this diff