123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- // Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- import { useMutation } from '@vue/apollo-composable'
- import { SampleTypedMutationDocument } from '#tests/fixtures/graphqlSampleTypes.ts'
- import type {
- SampleUpdateMutation,
- SampleUpdateMutationVariables,
- } from '#tests/fixtures/graphqlSampleTypes.ts'
- import createMockClient from '#tests/support/mock-apollo-client.ts'
- import { useNotifications } from '#shared/components/CommonNotifications/index.ts'
- import UserError from '#shared/errors/UserError.ts'
- import { GraphQLErrorTypes } from '#shared/types/error.ts'
- import MutationHandler from '../MutationHandler.ts'
- const mutationFunctionCallSpy = vi.fn()
- let mutationSampleResult: Record<string, unknown> = {
- Sample: {
- __typename: 'Sample',
- id: 1,
- title: 'Test Title',
- text: 'Test Text',
- errors: null,
- },
- }
- let errorType = 'Exceptions::UnknownError'
- const getMutationSampleErrorResult = () => {
- return {
- errors: [
- {
- message: 'GraphQL Error',
- extensions: { type: errorType },
- },
- ],
- }
- }
- const mutationSampleNetworkErrorResult = new Error('GraphQL Network Error')
- const mockClient = (error = false, errorType = 'GraphQL') => {
- createMockClient([
- {
- operationDocument: SampleTypedMutationDocument,
- handler: () => {
- if (error) {
- return errorType === 'GraphQL'
- ? Promise.resolve(getMutationSampleErrorResult())
- : Promise.reject(mutationSampleNetworkErrorResult)
- }
- return Promise.resolve({
- data: mutationSampleResult,
- })
- },
- },
- ])
- mutationFunctionCallSpy.mockClear()
- }
- describe('MutationHandler', () => {
- const sampleMutation = () => {
- mutationFunctionCallSpy()
- return useMutation<SampleUpdateMutation, SampleUpdateMutationVariables>(
- SampleTypedMutationDocument,
- )
- }
- describe('constructor', () => {
- beforeEach(() => {
- mockClient()
- })
- it('instance can be created', () => {
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- expect(mutationHandlerObject).toBeInstanceOf(MutationHandler)
- })
- it('default handler options can be changed', () => {
- const errorNotificationMessage = 'A test message.'
- const mutationHandlerObject = new MutationHandler(sampleMutation(), {
- errorNotificationMessage,
- })
- expect(
- mutationHandlerObject.handlerOptions.errorNotificationMessage,
- ).toBe(errorNotificationMessage)
- })
- it('given mutation function was executed', () => {
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- expect(mutationFunctionCallSpy).toBeCalled()
- expect(mutationHandlerObject.operationResult).toBeTruthy()
- })
- })
- describe('loading', () => {
- beforeEach(() => {
- mockClient()
- })
- it('loading state should be false without called send function', () => {
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- expect(mutationHandlerObject.loading().value).toBe(false)
- })
- it('loading state should be changed after called send function', () => {
- expect.assertions(1)
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- mutationHandlerObject.send()
- expect(mutationHandlerObject.loading().value).toBe(true)
- })
- it('loading state will be updated', async () => {
- expect.assertions(1)
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- await mutationHandlerObject.send()
- expect(mutationHandlerObject.loading().value).toBe(false)
- })
- })
- describe('send', () => {
- beforeEach(() => {
- mockClient()
- })
- it('result is available', async () => {
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- await expect(
- mutationHandlerObject.send({ id: 1, Sample: {} }),
- ).resolves.toEqual(mutationSampleResult)
- })
- it('result with user error', async () => {
- const userErrors = [
- {
- field: null,
- message: 'Example error message',
- },
- {
- field: 'id',
- message: 'Id field is wrong',
- },
- ]
- const userErrorObject = new UserError(userErrors)
- mutationSampleResult = {
- Sample: {
- id: null,
- title: null,
- text: null,
- errors: userErrors,
- },
- }
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- await expect(mutationHandlerObject.send()).rejects.toEqual(
- userErrorObject,
- )
- })
- })
- describe('error handling', () => {
- describe('GraphQL errors', () => {
- it('notification is triggerd', async () => {
- mockClient(true)
- expect.assertions(1)
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- await mutationHandlerObject.send().catch(() => {
- return null
- })
- const { notifications } = useNotifications()
- expect(notifications.value.length).toBe(1)
- })
- it('use error callback', async () => {
- mockClient(true)
- expect.assertions(1)
- const errorCallbackSpy = vi.fn()
- const mutationHandlerObject = new MutationHandler(sampleMutation(), {
- errorCallback: (error) => {
- errorCallbackSpy(error)
- },
- })
- await mutationHandlerObject.send().catch(() => {
- return null
- })
- expect(errorCallbackSpy).toHaveBeenCalledWith({
- type: 'Exceptions::UnknownError',
- message: 'GraphQL Error',
- })
- })
- it('use error callback with known error type', async () => {
- errorType = 'Exceptions::Forbidden'
- mockClient(true)
- expect.assertions(1)
- const errorCallbackSpy = vi.fn()
- const mutationHandlerObject = new MutationHandler(sampleMutation(), {
- errorCallback: (error) => {
- errorCallbackSpy(error)
- },
- })
- await mutationHandlerObject.send().catch(() => {
- return null
- })
- expect(errorCallbackSpy).toHaveBeenCalledWith({
- type: 'Exceptions::Forbidden',
- message: 'GraphQL Error',
- })
- })
- })
- describe('Network errors', () => {
- beforeEach(() => {
- mockClient(true, 'NetworkError')
- })
- it('use error callback', async () => {
- expect.assertions(1)
- const mutationHandlerObject = new MutationHandler(sampleMutation(), {
- errorCallback: (error) => {
- expect(error).toEqual({
- type: GraphQLErrorTypes.NetworkError,
- })
- },
- })
- await mutationHandlerObject.send().catch(() => {
- return null
- })
- })
- })
- })
- describe('use operation result wrapper', () => {
- beforeEach(() => {
- mockClient()
- })
- it('check called', () => {
- const mutationHandlerObject = new MutationHandler(sampleMutation())
- expect(mutationHandlerObject.called().value).toBe(false)
- mutationHandlerObject.send().catch(() => {
- return null
- })
- expect(mutationHandlerObject.called().value).toBe(true)
- })
- })
- })
|