Mirror: The highly customizable and versatile GraphQL client with which you add on features like normalized caching as you grow.
at main 3.8 kB view raw
1// @vitest-environment jsdom 2 3import { OperationResult, OperationResultSource } from '@urql/core'; 4import { nextTick, readonly, ref } from 'vue'; 5import { vi, expect, it, describe } from 'vitest'; 6 7vi.mock('./useClient.ts', async () => ({ 8 __esModule: true, 9 ...(await vi.importActual<typeof import('./useClient')>('./useClient.ts')), 10 useClient: () => ref(client), 11})); 12 13import { makeSubject } from 'wonka'; 14import { createClient } from '@urql/core'; 15import { useSubscription } from './useSubscription'; 16 17const client = createClient({ url: '/graphql', exchanges: [] }); 18 19describe('useSubscription', () => { 20 it('subscribes to a subscription and updates data', async () => { 21 const subject = makeSubject<any>(); 22 const executeQuery = vi 23 .spyOn(client, 'executeSubscription') 24 .mockImplementation( 25 () => subject.source as OperationResultSource<OperationResult> 26 ); 27 28 const sub = useSubscription({ 29 query: `{ test }`, 30 }); 31 32 expect(readonly(sub)).toMatchObject({ 33 data: undefined, 34 stale: false, 35 fetching: true, 36 error: undefined, 37 extensions: undefined, 38 operation: undefined, 39 isPaused: false, 40 pause: expect.any(Function), 41 resume: expect.any(Function), 42 executeSubscription: expect.any(Function), 43 }); 44 45 expect(executeQuery).toHaveBeenCalledWith( 46 { 47 key: expect.any(Number), 48 query: expect.any(Object), 49 variables: {}, 50 }, 51 expect.any(Object) 52 ); 53 54 expect(sub.fetching.value).toBe(true); 55 56 subject.next({ data: { test: true } }); 57 expect(sub.data.value).toHaveProperty('test', true); 58 59 subject.complete(); 60 expect(sub.fetching.value).toBe(false); 61 }); 62 63 it('updates the executed subscription when inputs change', async () => { 64 const subject = makeSubject<any>(); 65 const executeSubscription = vi 66 .spyOn(client, 'executeSubscription') 67 .mockImplementation( 68 () => subject.source as OperationResultSource<OperationResult> 69 ); 70 71 const variables = ref({}); 72 const sub = useSubscription({ 73 query: `{ test }`, 74 variables, 75 }); 76 77 expect(executeSubscription).toHaveBeenCalledWith( 78 { 79 key: expect.any(Number), 80 query: expect.any(Object), 81 variables: {}, 82 }, 83 expect.any(Object) 84 ); 85 86 subject.next({ data: { test: true } }); 87 expect(sub.data.value).toHaveProperty('test', true); 88 89 variables.value = { test: true }; 90 await nextTick(); 91 expect(executeSubscription).toHaveBeenCalledTimes(2); 92 expect(executeSubscription).toHaveBeenCalledWith( 93 { 94 key: expect.any(Number), 95 query: expect.any(Object), 96 variables: { test: true }, 97 }, 98 expect.any(Object) 99 ); 100 101 expect(sub.fetching.value).toBe(true); 102 expect(sub.data.value).toHaveProperty('test', true); 103 }); 104 105 it('supports a custom scanning handler', async () => { 106 const subject = makeSubject<any>(); 107 const executeSubscription = vi 108 .spyOn(client, 'executeSubscription') 109 .mockImplementation( 110 () => subject.source as OperationResultSource<OperationResult> 111 ); 112 113 const scanHandler = (currentState: any, nextState: any) => ({ 114 counter: (currentState ? currentState.counter : 0) + nextState.counter, 115 }); 116 117 const sub = useSubscription( 118 { 119 query: `subscription { counter }`, 120 }, 121 scanHandler 122 ); 123 124 expect(executeSubscription).toHaveBeenCalledWith( 125 { 126 key: expect.any(Number), 127 query: expect.any(Object), 128 variables: {}, 129 }, 130 expect.any(Object) 131 ); 132 133 subject.next({ data: { counter: 1 } }); 134 expect(sub.data.value).toHaveProperty('counter', 1); 135 136 subject.next({ data: { counter: 2 } }); 137 expect(sub.data.value).toHaveProperty('counter', 3); 138 }); 139});