| 1 | import { noop } from '@internal/listenerMiddleware/utils'
|
|---|
| 2 | import type { QuerySubState } from '@internal/query/core/apiState'
|
|---|
| 3 | import type { Post } from '@internal/query/tests/mocks/handlers'
|
|---|
| 4 | import { posts } from '@internal/query/tests/mocks/handlers'
|
|---|
| 5 | import { actionsReducer, setupApiStore } from '@internal/tests/utils/helpers'
|
|---|
| 6 | import type { SerializedError } from '@reduxjs/toolkit'
|
|---|
| 7 | import { configureStore } from '@reduxjs/toolkit'
|
|---|
| 8 | import type { BaseQueryFn, FetchBaseQueryError } from '@reduxjs/toolkit/query'
|
|---|
| 9 | import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query'
|
|---|
| 10 |
|
|---|
| 11 | describe('queryFn base implementation tests', () => {
|
|---|
| 12 | const baseQuery: BaseQueryFn<string, { wrappedByBaseQuery: string }, string> =
|
|---|
| 13 | vi.fn((arg: string) =>
|
|---|
| 14 | arg.includes('withErrorQuery')
|
|---|
| 15 | ? { error: `cut${arg}` }
|
|---|
| 16 | : { data: { wrappedByBaseQuery: arg } },
|
|---|
| 17 | )
|
|---|
| 18 |
|
|---|
| 19 | const api = createApi({
|
|---|
| 20 | baseQuery,
|
|---|
| 21 | endpoints: (build) => ({
|
|---|
| 22 | withQuery: build.query<string, string>({
|
|---|
| 23 | query(arg: string) {
|
|---|
| 24 | return `resultFrom(${arg})`
|
|---|
| 25 | },
|
|---|
| 26 | transformResponse(response) {
|
|---|
| 27 | return response.wrappedByBaseQuery
|
|---|
| 28 | },
|
|---|
| 29 | }),
|
|---|
| 30 | withErrorQuery: build.query<string, string>({
|
|---|
| 31 | query(arg: string) {
|
|---|
| 32 | return `resultFrom(${arg})`
|
|---|
| 33 | },
|
|---|
| 34 | transformErrorResponse(response) {
|
|---|
| 35 | return response.slice(3)
|
|---|
| 36 | },
|
|---|
| 37 | }),
|
|---|
| 38 | withQueryFn: build.query<string, string>({
|
|---|
| 39 | queryFn(arg: string) {
|
|---|
| 40 | return { data: `resultFrom(${arg})` }
|
|---|
| 41 | },
|
|---|
| 42 | }),
|
|---|
| 43 | withInvalidDataQueryFn: build.query<string, string>({
|
|---|
| 44 | // @ts-expect-error
|
|---|
| 45 | queryFn(arg: string) {
|
|---|
| 46 | return { data: 5 }
|
|---|
| 47 | },
|
|---|
| 48 | }),
|
|---|
| 49 | withErrorQueryFn: build.query<string, string>({
|
|---|
| 50 | queryFn(arg: string) {
|
|---|
| 51 | return { error: `resultFrom(${arg})` }
|
|---|
| 52 | },
|
|---|
| 53 | }),
|
|---|
| 54 | withInvalidErrorQueryFn: build.query<string, string>({
|
|---|
| 55 | // @ts-expect-error
|
|---|
| 56 | queryFn(arg: string) {
|
|---|
| 57 | return { error: 5 }
|
|---|
| 58 | },
|
|---|
| 59 | }),
|
|---|
| 60 | withThrowingQueryFn: build.query<string, string>({
|
|---|
| 61 | queryFn(arg: string) {
|
|---|
| 62 | throw new Error(`resultFrom(${arg})`)
|
|---|
| 63 | },
|
|---|
| 64 | }),
|
|---|
| 65 | withAsyncQueryFn: build.query<string, string>({
|
|---|
| 66 | async queryFn(arg: string) {
|
|---|
| 67 | return { data: `resultFrom(${arg})` }
|
|---|
| 68 | },
|
|---|
| 69 | }),
|
|---|
| 70 | withInvalidDataAsyncQueryFn: build.query<string, string>({
|
|---|
| 71 | // @ts-expect-error
|
|---|
| 72 | async queryFn(arg: string) {
|
|---|
| 73 | return { data: 5 }
|
|---|
| 74 | },
|
|---|
| 75 | }),
|
|---|
| 76 | withAsyncErrorQueryFn: build.query<string, string>({
|
|---|
| 77 | async queryFn(arg: string) {
|
|---|
| 78 | return { error: `resultFrom(${arg})` }
|
|---|
| 79 | },
|
|---|
| 80 | }),
|
|---|
| 81 | withInvalidAsyncErrorQueryFn: build.query<string, string>({
|
|---|
| 82 | // @ts-expect-error
|
|---|
| 83 | async queryFn(arg: string) {
|
|---|
| 84 | return { error: 5 }
|
|---|
| 85 | },
|
|---|
| 86 | }),
|
|---|
| 87 | withAsyncThrowingQueryFn: build.query<string, string>({
|
|---|
| 88 | async queryFn(arg: string) {
|
|---|
| 89 | throw new Error(`resultFrom(${arg})`)
|
|---|
| 90 | },
|
|---|
| 91 | }),
|
|---|
| 92 | mutationWithQueryFn: build.mutation<string, string>({
|
|---|
| 93 | queryFn(arg: string) {
|
|---|
| 94 | return { data: `resultFrom(${arg})` }
|
|---|
| 95 | },
|
|---|
| 96 | }),
|
|---|
| 97 | mutationWithInvalidDataQueryFn: build.mutation<string, string>({
|
|---|
| 98 | // @ts-expect-error
|
|---|
| 99 | queryFn(arg: string) {
|
|---|
| 100 | return { data: 5 }
|
|---|
| 101 | },
|
|---|
| 102 | }),
|
|---|
| 103 | mutationWithErrorQueryFn: build.mutation<string, string>({
|
|---|
| 104 | queryFn(arg: string) {
|
|---|
| 105 | return { error: `resultFrom(${arg})` }
|
|---|
| 106 | },
|
|---|
| 107 | }),
|
|---|
| 108 | mutationWithInvalidErrorQueryFn: build.mutation<string, string>({
|
|---|
| 109 | // @ts-expect-error
|
|---|
| 110 | queryFn(arg: string) {
|
|---|
| 111 | return { error: 5 }
|
|---|
| 112 | },
|
|---|
| 113 | }),
|
|---|
| 114 | mutationWithThrowingQueryFn: build.mutation<string, string>({
|
|---|
| 115 | queryFn(arg: string) {
|
|---|
| 116 | throw new Error(`resultFrom(${arg})`)
|
|---|
| 117 | },
|
|---|
| 118 | }),
|
|---|
| 119 | mutationWithAsyncQueryFn: build.mutation<string, string>({
|
|---|
| 120 | async queryFn(arg: string) {
|
|---|
| 121 | return { data: `resultFrom(${arg})` }
|
|---|
| 122 | },
|
|---|
| 123 | }),
|
|---|
| 124 | mutationWithInvalidAsyncQueryFn: build.mutation<string, string>({
|
|---|
| 125 | // @ts-expect-error
|
|---|
| 126 | async queryFn(arg: string) {
|
|---|
| 127 | return { data: 5 }
|
|---|
| 128 | },
|
|---|
| 129 | }),
|
|---|
| 130 | mutationWithAsyncErrorQueryFn: build.mutation<string, string>({
|
|---|
| 131 | async queryFn(arg: string) {
|
|---|
| 132 | return { error: `resultFrom(${arg})` }
|
|---|
| 133 | },
|
|---|
| 134 | }),
|
|---|
| 135 | mutationWithInvalidAsyncErrorQueryFn: build.mutation<string, string>({
|
|---|
| 136 | // @ts-expect-error
|
|---|
| 137 | async queryFn(arg: string) {
|
|---|
| 138 | return { error: 5 }
|
|---|
| 139 | },
|
|---|
| 140 | }),
|
|---|
| 141 | mutationWithAsyncThrowingQueryFn: build.mutation<string, string>({
|
|---|
| 142 | async queryFn(arg: string) {
|
|---|
| 143 | throw new Error(`resultFrom(${arg})`)
|
|---|
| 144 | },
|
|---|
| 145 | }),
|
|---|
| 146 | // @ts-expect-error
|
|---|
| 147 | withNeither: build.query<string, string>({}),
|
|---|
| 148 | // @ts-expect-error
|
|---|
| 149 | mutationWithNeither: build.mutation<string, string>({}),
|
|---|
| 150 | }),
|
|---|
| 151 | })
|
|---|
| 152 |
|
|---|
| 153 | const {
|
|---|
| 154 | withQuery,
|
|---|
| 155 | withErrorQuery,
|
|---|
| 156 | withQueryFn,
|
|---|
| 157 | withErrorQueryFn,
|
|---|
| 158 | withThrowingQueryFn,
|
|---|
| 159 | withAsyncQueryFn,
|
|---|
| 160 | withAsyncErrorQueryFn,
|
|---|
| 161 | withAsyncThrowingQueryFn,
|
|---|
| 162 | mutationWithQueryFn,
|
|---|
| 163 | mutationWithErrorQueryFn,
|
|---|
| 164 | mutationWithThrowingQueryFn,
|
|---|
| 165 | mutationWithAsyncQueryFn,
|
|---|
| 166 | mutationWithAsyncErrorQueryFn,
|
|---|
| 167 | mutationWithAsyncThrowingQueryFn,
|
|---|
| 168 | withNeither,
|
|---|
| 169 | mutationWithNeither,
|
|---|
| 170 | } = api.endpoints
|
|---|
| 171 |
|
|---|
| 172 | const store = configureStore({
|
|---|
| 173 | reducer: {
|
|---|
| 174 | [api.reducerPath]: api.reducer,
|
|---|
| 175 | },
|
|---|
| 176 | middleware: (gDM) => gDM({}).concat(api.middleware),
|
|---|
| 177 | })
|
|---|
| 178 |
|
|---|
| 179 | test.each([
|
|---|
| 180 | ['withQuery', withQuery, 'data'],
|
|---|
| 181 | ['withErrorQuery', withErrorQuery, 'error'],
|
|---|
| 182 | ['withQueryFn', withQueryFn, 'data'],
|
|---|
| 183 | ['withErrorQueryFn', withErrorQueryFn, 'error'],
|
|---|
| 184 | ['withThrowingQueryFn', withThrowingQueryFn, 'throw'],
|
|---|
| 185 | ['withAsyncQueryFn', withAsyncQueryFn, 'data'],
|
|---|
| 186 | ['withAsyncErrorQueryFn', withAsyncErrorQueryFn, 'error'],
|
|---|
| 187 | ['withAsyncThrowingQueryFn', withAsyncThrowingQueryFn, 'throw'],
|
|---|
| 188 | ])('%s', async (endpointName, endpoint, expectedResult) => {
|
|---|
| 189 | const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(noop)
|
|---|
| 190 |
|
|---|
| 191 | const thunk = endpoint.initiate(endpointName)
|
|---|
| 192 |
|
|---|
| 193 | const result: undefined | QuerySubState<any> = await store.dispatch(thunk)
|
|---|
| 194 |
|
|---|
| 195 | if (endpointName.includes('Throw')) {
|
|---|
| 196 | expect(consoleErrorSpy).toHaveBeenCalledOnce()
|
|---|
| 197 |
|
|---|
| 198 | expect(consoleErrorSpy).toHaveBeenLastCalledWith(
|
|---|
| 199 | `An unhandled error occurred processing a request for the endpoint "${endpointName}".\nIn the case of an unhandled error, no tags will be "provided" or "invalidated".`,
|
|---|
| 200 | Error(`resultFrom(${endpointName})`),
|
|---|
| 201 | )
|
|---|
| 202 | } else {
|
|---|
| 203 | expect(consoleErrorSpy).not.toHaveBeenCalled()
|
|---|
| 204 | }
|
|---|
| 205 |
|
|---|
| 206 | if (expectedResult === 'data') {
|
|---|
| 207 | expect(result).toEqual(
|
|---|
| 208 | expect.objectContaining({
|
|---|
| 209 | data: `resultFrom(${endpointName})`,
|
|---|
| 210 | }),
|
|---|
| 211 | )
|
|---|
| 212 | } else if (expectedResult === 'error') {
|
|---|
| 213 | expect(result).toEqual(
|
|---|
| 214 | expect.objectContaining({
|
|---|
| 215 | error: `resultFrom(${endpointName})`,
|
|---|
| 216 | }),
|
|---|
| 217 | )
|
|---|
| 218 | } else {
|
|---|
| 219 | expect(result).toEqual(
|
|---|
| 220 | expect.objectContaining({
|
|---|
| 221 | error: expect.objectContaining({
|
|---|
| 222 | message: `resultFrom(${endpointName})`,
|
|---|
| 223 | }),
|
|---|
| 224 | }),
|
|---|
| 225 | )
|
|---|
| 226 | }
|
|---|
| 227 |
|
|---|
| 228 | consoleErrorSpy.mockRestore()
|
|---|
| 229 | })
|
|---|
| 230 |
|
|---|
| 231 | test.each([
|
|---|
| 232 | ['mutationWithQueryFn', mutationWithQueryFn, 'data'],
|
|---|
| 233 | ['mutationWithErrorQueryFn', mutationWithErrorQueryFn, 'error'],
|
|---|
| 234 | ['mutationWithThrowingQueryFn', mutationWithThrowingQueryFn, 'throw'],
|
|---|
| 235 | ['mutationWithAsyncQueryFn', mutationWithAsyncQueryFn, 'data'],
|
|---|
| 236 | ['mutationWithAsyncErrorQueryFn', mutationWithAsyncErrorQueryFn, 'error'],
|
|---|
| 237 | [
|
|---|
| 238 | 'mutationWithAsyncThrowingQueryFn',
|
|---|
| 239 | mutationWithAsyncThrowingQueryFn,
|
|---|
| 240 | 'throw',
|
|---|
| 241 | ],
|
|---|
| 242 | ])('%s', async (endpointName, endpoint, expectedResult) => {
|
|---|
| 243 | const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(noop)
|
|---|
| 244 |
|
|---|
| 245 | const thunk = endpoint.initiate(endpointName)
|
|---|
| 246 |
|
|---|
| 247 | const result:
|
|---|
| 248 | | undefined
|
|---|
| 249 | | { data: string }
|
|---|
| 250 | | { error: string | SerializedError } = await store.dispatch(thunk)
|
|---|
| 251 |
|
|---|
| 252 | if (endpointName.includes('Throw')) {
|
|---|
| 253 | expect(consoleErrorSpy).toHaveBeenCalledOnce()
|
|---|
| 254 |
|
|---|
| 255 | expect(consoleErrorSpy).toHaveBeenLastCalledWith(
|
|---|
| 256 | `An unhandled error occurred processing a request for the endpoint "${endpointName}".\nIn the case of an unhandled error, no tags will be "provided" or "invalidated".`,
|
|---|
| 257 | Error(`resultFrom(${endpointName})`),
|
|---|
| 258 | )
|
|---|
| 259 | } else {
|
|---|
| 260 | expect(consoleErrorSpy).not.toHaveBeenCalled()
|
|---|
| 261 | }
|
|---|
| 262 |
|
|---|
| 263 | if (expectedResult === 'data') {
|
|---|
| 264 | expect(result).toEqual(
|
|---|
| 265 | expect.objectContaining({
|
|---|
| 266 | data: `resultFrom(${endpointName})`,
|
|---|
| 267 | }),
|
|---|
| 268 | )
|
|---|
| 269 | } else if (expectedResult === 'error') {
|
|---|
| 270 | expect(result).toEqual(
|
|---|
| 271 | expect.objectContaining({
|
|---|
| 272 | error: `resultFrom(${endpointName})`,
|
|---|
| 273 | }),
|
|---|
| 274 | )
|
|---|
| 275 | } else {
|
|---|
| 276 | expect(result).toEqual(
|
|---|
| 277 | expect.objectContaining({
|
|---|
| 278 | error: expect.objectContaining({
|
|---|
| 279 | message: `resultFrom(${endpointName})`,
|
|---|
| 280 | }),
|
|---|
| 281 | }),
|
|---|
| 282 | )
|
|---|
| 283 | }
|
|---|
| 284 |
|
|---|
| 285 | consoleErrorSpy.mockRestore()
|
|---|
| 286 | })
|
|---|
| 287 |
|
|---|
| 288 | test('neither provided', async () => {
|
|---|
| 289 | const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(noop)
|
|---|
| 290 |
|
|---|
| 291 | {
|
|---|
| 292 | const thunk = withNeither.initiate('withNeither')
|
|---|
| 293 |
|
|---|
| 294 | const result: QuerySubState<any> = await store.dispatch(thunk)
|
|---|
| 295 |
|
|---|
| 296 | expect(consoleErrorSpy).toHaveBeenCalledOnce()
|
|---|
| 297 |
|
|---|
| 298 | expect(consoleErrorSpy).toHaveBeenLastCalledWith(
|
|---|
| 299 | `An unhandled error occurred processing a request for the endpoint "withNeither".\nIn the case of an unhandled error, no tags will be "provided" or "invalidated".`,
|
|---|
| 300 | TypeError('endpointDefinition.queryFn is not a function'),
|
|---|
| 301 | )
|
|---|
| 302 |
|
|---|
| 303 | expect(result.error).toEqual(
|
|---|
| 304 | expect.objectContaining({
|
|---|
| 305 | message: 'endpointDefinition.queryFn is not a function',
|
|---|
| 306 | }),
|
|---|
| 307 | )
|
|---|
| 308 |
|
|---|
| 309 | consoleErrorSpy.mockClear()
|
|---|
| 310 | }
|
|---|
| 311 | {
|
|---|
| 312 | const thunk = mutationWithNeither.initiate('mutationWithNeither')
|
|---|
| 313 |
|
|---|
| 314 | const result:
|
|---|
| 315 | | undefined
|
|---|
| 316 | | { data: string }
|
|---|
| 317 | | { error: string | SerializedError } = await store.dispatch(thunk)
|
|---|
| 318 |
|
|---|
| 319 | expect(consoleErrorSpy).toHaveBeenCalledOnce()
|
|---|
| 320 |
|
|---|
| 321 | expect(consoleErrorSpy).toHaveBeenLastCalledWith(
|
|---|
| 322 | `An unhandled error occurred processing a request for the endpoint "mutationWithNeither".\nIn the case of an unhandled error, no tags will be "provided" or "invalidated".`,
|
|---|
| 323 | TypeError('endpointDefinition.queryFn is not a function'),
|
|---|
| 324 | )
|
|---|
| 325 |
|
|---|
| 326 | if (!('error' in result)) {
|
|---|
| 327 | expect.fail()
|
|---|
| 328 | }
|
|---|
| 329 |
|
|---|
| 330 | expect(result.error).toEqual(
|
|---|
| 331 | expect.objectContaining({
|
|---|
| 332 | message: 'endpointDefinition.queryFn is not a function',
|
|---|
| 333 | }),
|
|---|
| 334 | )
|
|---|
| 335 | }
|
|---|
| 336 |
|
|---|
| 337 | consoleErrorSpy.mockRestore()
|
|---|
| 338 | })
|
|---|
| 339 | })
|
|---|
| 340 |
|
|---|
| 341 | describe('usage scenario tests', () => {
|
|---|
| 342 | const mockData = { id: 1, name: 'Banana' }
|
|---|
| 343 | const mockDocResult = {
|
|---|
| 344 | exists: () => true,
|
|---|
| 345 | data: () => mockData,
|
|---|
| 346 | }
|
|---|
| 347 | const get = vi.fn(() => Promise.resolve(mockDocResult))
|
|---|
| 348 | const doc = vi.fn((name) => ({
|
|---|
| 349 | get,
|
|---|
| 350 | }))
|
|---|
| 351 | const collection = vi.fn((name) => ({ get, doc }))
|
|---|
| 352 | const firestore = () => {
|
|---|
| 353 | return { collection, doc }
|
|---|
| 354 | }
|
|---|
| 355 |
|
|---|
| 356 | const baseQuery = fetchBaseQuery({ baseUrl: 'https://example.com/' })
|
|---|
| 357 | const api = createApi({
|
|---|
| 358 | baseQuery,
|
|---|
| 359 | endpoints: (build) => ({
|
|---|
| 360 | getRandomUser: build.query<Post, void>({
|
|---|
| 361 | async queryFn(_arg: void, _queryApi, _extraOptions, fetchWithBQ) {
|
|---|
| 362 | // get a random post
|
|---|
| 363 | const randomResult = await fetchWithBQ('posts/random')
|
|---|
| 364 | if (randomResult.error) {
|
|---|
| 365 | throw randomResult.error
|
|---|
| 366 | }
|
|---|
| 367 | const post = randomResult.data as Post
|
|---|
| 368 | const result = await fetchWithBQ(`/post/${post.id}`)
|
|---|
| 369 | return result.data
|
|---|
| 370 | ? { data: result.data as Post }
|
|---|
| 371 | : { error: result.error as FetchBaseQueryError }
|
|---|
| 372 | },
|
|---|
| 373 | }),
|
|---|
| 374 | getFirebaseUser: build.query<typeof mockData, number>({
|
|---|
| 375 | async queryFn(arg: number) {
|
|---|
| 376 | const getResult = await firestore().collection('users').doc(arg).get()
|
|---|
| 377 | if (!getResult.exists()) {
|
|---|
| 378 | throw new Error('Missing user')
|
|---|
| 379 | }
|
|---|
| 380 | return { data: getResult.data() }
|
|---|
| 381 | },
|
|---|
| 382 | }),
|
|---|
| 383 | getMissingFirebaseUser: build.query<typeof mockData, number>({
|
|---|
| 384 | async queryFn(arg: number) {
|
|---|
| 385 | const getResult = await firestore().collection('users').doc(arg).get()
|
|---|
| 386 | // intentionally throw if it exists to keep the mocking overhead low
|
|---|
| 387 | if (getResult.exists()) {
|
|---|
| 388 | throw new Error('Missing user')
|
|---|
| 389 | }
|
|---|
| 390 | return { data: getResult.data() }
|
|---|
| 391 | },
|
|---|
| 392 | }),
|
|---|
| 393 | }),
|
|---|
| 394 | })
|
|---|
| 395 |
|
|---|
| 396 | const storeRef = setupApiStore(api, {
|
|---|
| 397 | ...actionsReducer,
|
|---|
| 398 | })
|
|---|
| 399 |
|
|---|
| 400 | /**
|
|---|
| 401 | * Allow for a scenario where you can chain X requests
|
|---|
| 402 | * https://discord.com/channels/102860784329052160/103538784460615680/825430959247720449
|
|---|
| 403 | * const resp1 = await api.get(url);
|
|---|
| 404 | * const resp2 = await api.get(`${url2}/id=${resp1.data.id}`);
|
|---|
| 405 | */
|
|---|
| 406 |
|
|---|
| 407 | it('can chain multiple queries together', async () => {
|
|---|
| 408 | const result = await storeRef.store.dispatch(
|
|---|
| 409 | api.endpoints.getRandomUser.initiate(),
|
|---|
| 410 | )
|
|---|
| 411 | expect(result.data).toEqual(posts[1])
|
|---|
| 412 | })
|
|---|
| 413 |
|
|---|
| 414 | it('can wrap a service like Firebase', async () => {
|
|---|
| 415 | const result = await storeRef.store.dispatch(
|
|---|
| 416 | api.endpoints.getFirebaseUser.initiate(1),
|
|---|
| 417 | )
|
|---|
| 418 | expect(result.data).toEqual(mockData)
|
|---|
| 419 | })
|
|---|
| 420 |
|
|---|
| 421 | it('can wrap a service like Firebase and handle errors', async () => {
|
|---|
| 422 | const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(noop)
|
|---|
| 423 |
|
|---|
| 424 | const result: QuerySubState<any> = await storeRef.store.dispatch(
|
|---|
| 425 | api.endpoints.getMissingFirebaseUser.initiate(1),
|
|---|
| 426 | )
|
|---|
| 427 |
|
|---|
| 428 | expect(consoleErrorSpy).toHaveBeenCalledOnce()
|
|---|
| 429 |
|
|---|
| 430 | expect(consoleErrorSpy).toHaveBeenLastCalledWith(
|
|---|
| 431 | `An unhandled error occurred processing a request for the endpoint "getMissingFirebaseUser".\nIn the case of an unhandled error, no tags will be "provided" or "invalidated".`,
|
|---|
| 432 | Error('Missing user'),
|
|---|
| 433 | )
|
|---|
| 434 |
|
|---|
| 435 | expect(result.data).toBeUndefined()
|
|---|
| 436 | expect(result.error).toEqual(
|
|---|
| 437 | expect.objectContaining({
|
|---|
| 438 | message: 'Missing user',
|
|---|
| 439 | name: 'Error',
|
|---|
| 440 | }),
|
|---|
| 441 | )
|
|---|
| 442 |
|
|---|
| 443 | consoleErrorSpy.mockRestore()
|
|---|
| 444 | })
|
|---|
| 445 | })
|
|---|