@sanity/sdk-react 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/index.d.ts +2 -3
  2. package/dist/index.js +92 -19
  3. package/dist/index.js.map +1 -1
  4. package/package.json +6 -5
  5. package/src/components/auth/AuthBoundary.test.tsx +33 -20
  6. package/src/components/auth/AuthBoundary.tsx +11 -1
  7. package/src/components/auth/LoginError.tsx +9 -12
  8. package/src/components/errors/CorsErrorComponent.test.tsx +48 -0
  9. package/src/components/errors/CorsErrorComponent.tsx +37 -0
  10. package/src/components/errors/Error.styles.ts +35 -0
  11. package/src/components/errors/Error.tsx +40 -0
  12. package/src/context/ComlinkTokenRefresh.test.tsx +53 -40
  13. package/src/hooks/auth/useDashboardOrganizationId.test.tsx +16 -7
  14. package/src/hooks/auth/useVerifyOrgProjects.test.tsx +56 -14
  15. package/src/hooks/dashboard/{useManageFavorite.test.ts → useManageFavorite.test.tsx} +99 -44
  16. package/src/hooks/document/{useDocument.test.ts → useDocument.test.tsx} +25 -22
  17. package/src/hooks/document/{useDocumentEvent.test.ts → useDocumentEvent.test.tsx} +17 -16
  18. package/src/hooks/document/{useDocumentPermissions.test.ts → useDocumentPermissions.test.tsx} +101 -40
  19. package/src/hooks/document/{useEditDocument.test.ts → useEditDocument.test.tsx} +52 -22
  20. package/src/hooks/documents/useDocuments.test.tsx +63 -25
  21. package/src/hooks/helpers/createCallbackHook.test.tsx +41 -37
  22. package/src/hooks/paginatedDocuments/usePaginatedDocuments.test.tsx +2 -2
  23. package/src/hooks/presence/usePresence.test.tsx +9 -6
  24. package/src/hooks/preview/useDocumentPreview.test.tsx +15 -16
  25. package/src/hooks/projection/useDocumentProjection.test.tsx +23 -38
  26. package/src/hooks/projection/useDocumentProjection.ts +3 -8
  27. package/src/hooks/query/useQuery.test.tsx +18 -10
  28. package/src/hooks/releases/useActiveReleases.test.tsx +25 -21
  29. package/src/hooks/releases/usePerspective.test.tsx +16 -22
  30. package/src/hooks/users/useUser.test.tsx +32 -15
  31. package/src/hooks/users/useUsers.test.tsx +19 -11
  32. package/src/hooks/_synchronous-groq-js.mjs +0 -4
@@ -1,24 +1,18 @@
1
- import {
2
- type DocumentAction,
3
- type DocumentPermissionsResult,
4
- getPermissionsState,
5
- type SanityInstance,
6
- } from '@sanity/sdk'
1
+ import {type DocumentAction, type DocumentPermissionsResult, getPermissionsState} from '@sanity/sdk'
7
2
  import {act, renderHook, waitFor} from '@testing-library/react'
8
3
  import {BehaviorSubject, firstValueFrom} from 'rxjs'
9
4
  import {afterEach, beforeEach, describe, expect, it, vi} from 'vitest'
10
5
 
11
- import {useSanityInstance} from '../context/useSanityInstance'
6
+ import {ResourceProvider} from '../../context/ResourceProvider'
12
7
  import {useDocumentPermissions} from './useDocumentPermissions'
13
8
 
14
- // Mock dependencies before any imports
15
- vi.mock('../context/useSanityInstance', () => ({
16
- useSanityInstance: vi.fn(),
17
- }))
18
-
19
- vi.mock('@sanity/sdk', () => ({
20
- getPermissionsState: vi.fn(),
21
- }))
9
+ vi.mock('@sanity/sdk', async (importActual) => {
10
+ const actual = await importActual<typeof import('@sanity/sdk')>()
11
+ return {
12
+ ...actual,
13
+ getPermissionsState: vi.fn(),
14
+ }
15
+ })
22
16
 
23
17
  // Move this mock to the top level
24
18
  vi.mock('rxjs', async (importOriginal) => {
@@ -30,7 +24,6 @@ vi.mock('rxjs', async (importOriginal) => {
30
24
  })
31
25
 
32
26
  describe('usePermissions', () => {
33
- const mockInstance = {id: 'mock-instance'} as unknown as SanityInstance
34
27
  const mockAction: DocumentAction = {
35
28
  type: 'document.publish',
36
29
  documentId: 'doc1',
@@ -59,8 +52,6 @@ describe('usePermissions', () => {
59
52
  beforeEach(() => {
60
53
  vi.clearAllMocks()
61
54
 
62
- vi.mocked(useSanityInstance).mockReturnValue(mockInstance)
63
-
64
55
  // Create a subject to simulate permissions state updates
65
56
  permissionsSubject = new BehaviorSubject<DocumentPermissionsResult | undefined>(
66
57
  mockPermissionAllowed,
@@ -93,13 +84,20 @@ describe('usePermissions', () => {
93
84
  permissionsSubject.next(mockPermissionAllowed)
94
85
  })
95
86
 
96
- const {result} = renderHook(() => useDocumentPermissions(mockAction))
97
-
98
- expect(useSanityInstance).toHaveBeenCalledWith({
99
- projectId: mockAction.projectId,
100
- dataset: mockAction.dataset,
87
+ const {result} = renderHook(() => useDocumentPermissions(mockAction), {
88
+ wrapper: ({children}) => (
89
+ <ResourceProvider
90
+ projectId={mockAction.projectId}
91
+ dataset={mockAction.dataset}
92
+ fallback={null}
93
+ >
94
+ {children}
95
+ </ResourceProvider>
96
+ ),
101
97
  })
102
- expect(getPermissionsState).toHaveBeenCalledWith(mockInstance, mockAction)
98
+
99
+ // ResourceProvider handles the instance configuration
100
+ expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), mockAction)
103
101
  expect(result.current).toEqual(mockPermissionAllowed)
104
102
  })
105
103
 
@@ -109,7 +107,17 @@ describe('usePermissions', () => {
109
107
  permissionsSubject.next(mockPermissionDenied)
110
108
  })
111
109
 
112
- const {result} = renderHook(() => useDocumentPermissions(mockAction))
110
+ const {result} = renderHook(() => useDocumentPermissions(mockAction), {
111
+ wrapper: ({children}) => (
112
+ <ResourceProvider
113
+ projectId={mockAction.projectId}
114
+ dataset={mockAction.dataset}
115
+ fallback={null}
116
+ >
117
+ {children}
118
+ </ResourceProvider>
119
+ ),
120
+ })
113
121
 
114
122
  expect(result.current).toEqual(mockPermissionDenied)
115
123
  expect(result.current.allowed).toBe(false)
@@ -120,9 +128,19 @@ describe('usePermissions', () => {
120
128
  it('should accept an array of actions', () => {
121
129
  const actions = [mockAction, {...mockAction, documentId: 'doc2'}]
122
130
 
123
- renderHook(() => useDocumentPermissions(actions))
131
+ renderHook(() => useDocumentPermissions(actions), {
132
+ wrapper: ({children}) => (
133
+ <ResourceProvider
134
+ projectId={mockAction.projectId}
135
+ dataset={mockAction.dataset}
136
+ fallback={null}
137
+ >
138
+ {children}
139
+ </ResourceProvider>
140
+ ),
141
+ })
124
142
 
125
- expect(getPermissionsState).toHaveBeenCalledWith(mockInstance, actions)
143
+ expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), actions)
126
144
  })
127
145
 
128
146
  it('should throw an error if actions have mismatched project IDs', () => {
@@ -132,7 +150,17 @@ describe('usePermissions', () => {
132
150
  ]
133
151
 
134
152
  expect(() => {
135
- renderHook(() => useDocumentPermissions(actions))
153
+ renderHook(() => useDocumentPermissions(actions), {
154
+ wrapper: ({children}) => (
155
+ <ResourceProvider
156
+ projectId={mockAction.projectId}
157
+ dataset={mockAction.dataset}
158
+ fallback={null}
159
+ >
160
+ {children}
161
+ </ResourceProvider>
162
+ ),
163
+ })
136
164
  }).toThrow(/Mismatched project IDs found in actions/)
137
165
  })
138
166
 
@@ -140,7 +168,17 @@ describe('usePermissions', () => {
140
168
  const actions = [mockAction, {...mockAction, dataset: 'different-dataset', documentId: 'doc2'}]
141
169
 
142
170
  expect(() => {
143
- renderHook(() => useDocumentPermissions(actions))
171
+ renderHook(() => useDocumentPermissions(actions), {
172
+ wrapper: ({children}) => (
173
+ <ResourceProvider
174
+ projectId={mockAction.projectId}
175
+ dataset={mockAction.dataset}
176
+ fallback={null}
177
+ >
178
+ {children}
179
+ </ResourceProvider>
180
+ ),
181
+ })
144
182
  }).toThrow(/Mismatched datasets found in actions/)
145
183
  })
146
184
 
@@ -155,16 +193,29 @@ describe('usePermissions', () => {
155
193
  vi.mocked(firstValueFrom).mockReturnValueOnce(mockPromise)
156
194
 
157
195
  // This should throw the promise and suspend
158
- const {result} = renderHook(() => {
159
- try {
160
- return useDocumentPermissions(mockAction)
161
- } catch (error) {
162
- if (error instanceof Promise) {
163
- return 'suspended'
196
+ const {result} = renderHook(
197
+ () => {
198
+ try {
199
+ return useDocumentPermissions(mockAction)
200
+ } catch (error) {
201
+ if (error instanceof Promise) {
202
+ return 'suspended'
203
+ }
204
+ throw error
164
205
  }
165
- throw error
166
- }
167
- })
206
+ },
207
+ {
208
+ wrapper: ({children}) => (
209
+ <ResourceProvider
210
+ projectId={mockAction.projectId}
211
+ dataset={mockAction.dataset}
212
+ fallback={null}
213
+ >
214
+ {children}
215
+ </ResourceProvider>
216
+ ),
217
+ },
218
+ )
168
219
 
169
220
  expect(result.current).toBe('suspended')
170
221
 
@@ -175,7 +226,7 @@ describe('usePermissions', () => {
175
226
 
176
227
  // Now it should render properly
177
228
  await waitFor(() => {
178
- expect(getPermissionsState).toHaveBeenCalledWith(mockInstance, mockAction)
229
+ expect(getPermissionsState).toHaveBeenCalledWith(expect.any(Object), mockAction)
179
230
  })
180
231
  })
181
232
 
@@ -185,7 +236,17 @@ describe('usePermissions', () => {
185
236
  permissionsSubject.next(mockPermissionAllowed)
186
237
  })
187
238
 
188
- const {result, rerender} = renderHook(() => useDocumentPermissions(mockAction))
239
+ const {result, rerender} = renderHook(() => useDocumentPermissions(mockAction), {
240
+ wrapper: ({children}) => (
241
+ <ResourceProvider
242
+ projectId={mockAction.projectId}
243
+ dataset={mockAction.dataset}
244
+ fallback={null}
245
+ >
246
+ {children}
247
+ </ResourceProvider>
248
+ ),
249
+ })
189
250
 
190
251
  expect(result.current).toEqual(mockPermissionAllowed)
191
252
 
@@ -1,7 +1,6 @@
1
1
  // tests/useEditDocument.test.ts
2
2
  import {
3
3
  createDocumentHandle,
4
- createSanityInstance,
5
4
  editDocument,
6
5
  getDocumentState,
7
6
  resolveDocument,
@@ -11,7 +10,7 @@ import {type SanityDocument} from '@sanity/types'
11
10
  import {renderHook} from '@testing-library/react'
12
11
  import {beforeEach, describe, expect, it, vi} from 'vitest'
13
12
 
14
- import {useSanityInstance} from '../context/useSanityInstance'
13
+ import {ResourceProvider} from '../../context/ResourceProvider'
15
14
  import {useApplyDocumentActions} from './useApplyDocumentActions'
16
15
  import {useEditDocument} from './useEditDocument'
17
16
 
@@ -25,17 +24,10 @@ vi.mock('@sanity/sdk', async (importOriginal) => {
25
24
  }
26
25
  })
27
26
 
28
- vi.mock('../context/useSanityInstance', () => ({
29
- useSanityInstance: vi.fn(),
30
- }))
31
-
32
27
  vi.mock('./useApplyDocumentActions', () => ({
33
28
  useApplyDocumentActions: vi.fn(),
34
29
  }))
35
30
 
36
- // Create a fake instance to be returned by useSanityInstance.
37
- const instance = createSanityInstance({projectId: 'p', dataset: 'd'})
38
-
39
31
  const doc = {
40
32
  _id: 'doc1',
41
33
  foo: 'bar',
@@ -71,7 +63,6 @@ declare module 'groq' {
71
63
  describe('useEditDocument hook', () => {
72
64
  beforeEach(() => {
73
65
  vi.clearAllMocks()
74
- vi.mocked(useSanityInstance).mockReturnValue(instance)
75
66
  })
76
67
 
77
68
  it('applies a single edit action for the given path', async () => {
@@ -85,7 +76,13 @@ describe('useEditDocument hook', () => {
85
76
  const apply = vi.fn().mockResolvedValue({transactionId: 'tx1'})
86
77
  vi.mocked(useApplyDocumentActions).mockReturnValue(apply)
87
78
 
88
- const {result} = renderHook(() => useEditDocument<string>({...docHandle, path: 'foo'}))
79
+ const {result} = renderHook(() => useEditDocument<string>({...docHandle, path: 'foo'}), {
80
+ wrapper: ({children}) => (
81
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
82
+ {children}
83
+ </ResourceProvider>
84
+ ),
85
+ })
89
86
  const promise = result.current('newValue')
90
87
  expect(editDocument).toHaveBeenCalledWith(docHandle, {set: {foo: 'newValue'}})
91
88
  expect(apply).toHaveBeenCalledWith(editDocument(docHandle, {set: {foo: 'newValue'}}))
@@ -106,7 +103,13 @@ describe('useEditDocument hook', () => {
106
103
  const apply = vi.fn().mockResolvedValue({transactionId: 'tx2'})
107
104
  vi.mocked(useApplyDocumentActions).mockReturnValue(apply)
108
105
 
109
- const {result} = renderHook(() => useEditDocument(docHandle))
106
+ const {result} = renderHook(() => useEditDocument(docHandle), {
107
+ wrapper: ({children}) => (
108
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
109
+ {children}
110
+ </ResourceProvider>
111
+ ),
112
+ })
110
113
  const promise = result.current({...doc, foo: 'baz', extra: 'old', _id: 'doc1'})
111
114
  expect(apply).toHaveBeenCalledWith([editDocument(docHandle, {set: {foo: 'baz'}})])
112
115
  const actionsResult = await promise
@@ -124,7 +127,13 @@ describe('useEditDocument hook', () => {
124
127
  const apply = vi.fn().mockResolvedValue({transactionId: 'tx3'})
125
128
  vi.mocked(useApplyDocumentActions).mockReturnValue(apply)
126
129
 
127
- const {result} = renderHook(() => useEditDocument<string>({...docHandle, path: 'foo'}))
130
+ const {result} = renderHook(() => useEditDocument<string>({...docHandle, path: 'foo'}), {
131
+ wrapper: ({children}) => (
132
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
133
+ {children}
134
+ </ResourceProvider>
135
+ ),
136
+ })
128
137
  const promise = result.current((prev: unknown) => `${prev}Updated`) // 'bar' becomes 'barUpdated'
129
138
  expect(editDocument).toHaveBeenCalledWith(docHandle, {set: {foo: 'barUpdated'}})
130
139
  expect(apply).toHaveBeenCalledWith(editDocument(docHandle, {set: {foo: 'barUpdated'}}))
@@ -144,7 +153,13 @@ describe('useEditDocument hook', () => {
144
153
  const apply = vi.fn().mockResolvedValue({transactionId: 'tx4'})
145
154
  vi.mocked(useApplyDocumentActions).mockReturnValue(apply)
146
155
 
147
- const {result} = renderHook(() => useEditDocument(docHandle))
156
+ const {result} = renderHook(() => useEditDocument(docHandle), {
157
+ wrapper: ({children}) => (
158
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
159
+ {children}
160
+ </ResourceProvider>
161
+ ),
162
+ })
148
163
  const promise = result.current((prevDoc) => ({...prevDoc, foo: 'baz'}))
149
164
  expect(apply).toHaveBeenCalledWith([editDocument(docHandle, {set: {foo: 'baz'}})])
150
165
  const actionsResult = await promise
@@ -162,7 +177,13 @@ describe('useEditDocument hook', () => {
162
177
  const fakeApply = vi.fn()
163
178
  vi.mocked(useApplyDocumentActions).mockReturnValue(fakeApply)
164
179
 
165
- const {result} = renderHook(() => useEditDocument(docHandle))
180
+ const {result} = renderHook(() => useEditDocument(docHandle), {
181
+ wrapper: ({children}) => (
182
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
183
+ {children}
184
+ </ResourceProvider>
185
+ ),
186
+ })
166
187
  expect(() => result.current('notAnObject' as unknown as Book)).toThrowError(
167
188
  'No path was provided to `useEditDocument` and the value provided was not a document object.',
168
189
  )
@@ -182,13 +203,22 @@ describe('useEditDocument hook', () => {
182
203
  vi.mocked(resolveDocument).mockReturnValue(resolveDocPromise)
183
204
 
184
205
  // Render the hook and capture the thrown promise.
185
- const {result} = renderHook(() => {
186
- try {
187
- return useEditDocument(docHandle)
188
- } catch (e) {
189
- return e
190
- }
191
- })
206
+ const {result} = renderHook(
207
+ () => {
208
+ try {
209
+ return useEditDocument(docHandle)
210
+ } catch (e) {
211
+ return e
212
+ }
213
+ },
214
+ {
215
+ wrapper: ({children}) => (
216
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
217
+ {children}
218
+ </ResourceProvider>
219
+ ),
220
+ },
221
+ )
192
222
 
193
223
  // When the document is not ready, the hook throws the promise from resolveDocument.
194
224
  expect(result.current).toBe(resolveDocPromise)
@@ -1,14 +1,12 @@
1
- import {type SanityInstance} from '@sanity/sdk'
2
1
  import {act, renderHook} from '@testing-library/react'
2
+ import {evaluateSync, parse, toJS} from 'groq-js'
3
3
  import {describe, vi} from 'vitest'
4
4
 
5
- import {evaluateSync, parse} from '../_synchronous-groq-js.mjs'
6
- import {useSanityInstance} from '../context/useSanityInstance'
5
+ import {ResourceProvider} from '../../context/ResourceProvider'
7
6
  import {useQuery} from '../query/useQuery'
8
7
  import {useDocuments} from './useDocuments'
9
8
 
10
9
  vi.mock('../query/useQuery')
11
- vi.mock('../context/useSanityInstance')
12
10
 
13
11
  describe('useDocuments', () => {
14
12
  beforeEach(() => {
@@ -69,24 +67,35 @@ describe('useDocuments', () => {
69
67
  ]
70
68
 
71
69
  vi.mocked(useQuery).mockImplementation(({query, ...options}) => {
72
- const result = evaluateSync(parse(query), {dataset, params: options?.params}).get()
70
+ const result = toJS(evaluateSync(parse(query), {dataset, params: options?.params}))
73
71
  return {
74
72
  data: result,
75
73
  isPending: false,
76
74
  }
77
75
  })
78
- vi.mocked(useSanityInstance).mockReturnValue({config: {}} as SanityInstance)
79
76
  })
80
77
 
81
78
  it('should respect custom page size', () => {
82
79
  const customBatchSize = 2
83
- const {result} = renderHook(() => useDocuments({batchSize: customBatchSize}))
80
+ const {result} = renderHook(() => useDocuments({batchSize: customBatchSize}), {
81
+ wrapper: ({children}) => (
82
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
83
+ {children}
84
+ </ResourceProvider>
85
+ ),
86
+ })
84
87
 
85
88
  expect(result.current.data.length).toBe(customBatchSize)
86
89
  })
87
90
 
88
91
  it('should filter by document type', () => {
89
- const {result} = renderHook(() => useDocuments({filter: '_type == "movie"'}))
92
+ const {result} = renderHook(() => useDocuments({filter: '_type == "movie"'}), {
93
+ wrapper: ({children}) => (
94
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
95
+ {children}
96
+ </ResourceProvider>
97
+ ),
98
+ })
90
99
 
91
100
  expect(result.current.data.every((doc) => doc.documentType === 'movie')).toBe(true)
92
101
  expect(result.current.count).toBe(5) // 5 movies in the dataset
@@ -94,18 +103,32 @@ describe('useDocuments', () => {
94
103
 
95
104
  // groq-js doesn't support search filters yet
96
105
  it.skip('should apply search filter', () => {
97
- const {result} = renderHook(() => useDocuments({search: 'inter'}))
106
+ const {result} = renderHook(() => useDocuments({search: 'inter'}), {
107
+ wrapper: ({children}) => (
108
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
109
+ {children}
110
+ </ResourceProvider>
111
+ ),
112
+ })
98
113
 
99
114
  // Should match "Interstellar"
100
115
  expect(result.current.data.some((doc) => doc.documentId === 'movie3')).toBe(true)
101
116
  })
102
117
 
103
118
  it('should apply ordering', () => {
104
- const {result} = renderHook(() =>
105
- useDocuments({
106
- filter: '_type == "movie"',
107
- orderings: [{field: 'releaseYear', direction: 'desc'}],
108
- }),
119
+ const {result} = renderHook(
120
+ () =>
121
+ useDocuments({
122
+ filter: '_type == "movie"',
123
+ orderings: [{field: 'releaseYear', direction: 'desc'}],
124
+ }),
125
+ {
126
+ wrapper: ({children}) => (
127
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
128
+ {children}
129
+ </ResourceProvider>
130
+ ),
131
+ },
109
132
  )
110
133
 
111
134
  // First item should be the most recent movie (Interstellar, 2014)
@@ -114,7 +137,13 @@ describe('useDocuments', () => {
114
137
 
115
138
  it('should load more data when loadMore is called', () => {
116
139
  const batchSize = 2
117
- const {result} = renderHook(() => useDocuments({batchSize: batchSize}))
140
+ const {result} = renderHook(() => useDocuments({batchSize: batchSize}), {
141
+ wrapper: ({children}) => (
142
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
143
+ {children}
144
+ </ResourceProvider>
145
+ ),
146
+ })
118
147
 
119
148
  expect(result.current.data.length).toBe(batchSize)
120
149
 
@@ -126,7 +155,13 @@ describe('useDocuments', () => {
126
155
  })
127
156
 
128
157
  it('should indicate when there is more data to load', () => {
129
- const {result} = renderHook(() => useDocuments({batchSize: 3}))
158
+ const {result} = renderHook(() => useDocuments({batchSize: 3}), {
159
+ wrapper: ({children}) => (
160
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
161
+ {children}
162
+ </ResourceProvider>
163
+ ),
164
+ })
130
165
  expect(result.current.hasMore).toBe(true)
131
166
  // Load all remaining data
132
167
  act(() => {
@@ -139,6 +174,11 @@ describe('useDocuments', () => {
139
174
  it('should reset limit when filter changes', () => {
140
175
  const {result, rerender} = renderHook((props) => useDocuments(props), {
141
176
  initialProps: {batchSize: 2, filter: ''},
177
+ wrapper: ({children}) => (
178
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
179
+ {children}
180
+ </ResourceProvider>
181
+ ),
142
182
  })
143
183
  // Initially, data length equals pageSize (2)
144
184
  expect(result.current.data.length).toBe(2)
@@ -155,15 +195,13 @@ describe('useDocuments', () => {
155
195
  })
156
196
 
157
197
  it('should add projectId and dataset to document handles', () => {
158
- // Update the mock to include specific projectId and dataset
159
- vi.mocked(useSanityInstance).mockReturnValue({
160
- config: {
161
- projectId: 'test-project',
162
- dataset: 'test-dataset',
163
- },
164
- } as SanityInstance)
165
-
166
- const {result} = renderHook(() => useDocuments({}))
198
+ const {result} = renderHook(() => useDocuments({}), {
199
+ wrapper: ({children}) => (
200
+ <ResourceProvider projectId="test-project" dataset="test-dataset" fallback={null}>
201
+ {children}
202
+ </ResourceProvider>
203
+ ),
204
+ })
167
205
 
168
206
  // Check that the first document handle has the projectId and dataset
169
207
  expect(result.current.data[0].projectId).toBe('test-project')
@@ -1,15 +1,10 @@
1
- import {createSanityInstance, type SanityInstance} from '@sanity/sdk'
1
+ import {type SanityInstance} from '@sanity/sdk'
2
2
  import {renderHook} from '@testing-library/react'
3
3
  import {describe, expect, it, vi} from 'vitest'
4
4
 
5
- import {useSanityInstance} from '../context/useSanityInstance'
5
+ import {ResourceProvider} from '../../context/ResourceProvider'
6
6
  import {createCallbackHook} from './createCallbackHook'
7
7
 
8
- // Mock the useSanityInstance hook
9
- vi.mock('../context/useSanityInstance', () => ({
10
- useSanityInstance: vi.fn(),
11
- }))
12
-
13
8
  describe('createCallbackHook', () => {
14
9
  // Reset all mocks before each test
15
10
  beforeEach(() => {
@@ -17,12 +12,6 @@ describe('createCallbackHook', () => {
17
12
  })
18
13
 
19
14
  it('should create a hook that provides a memoized callback', () => {
20
- // Create a mock Sanity instance
21
- const mockInstance = createSanityInstance({projectId: 'p', dataset: 'd'})
22
-
23
- // Mock the useSanityInstance to return our mock instance
24
- vi.mocked(useSanityInstance).mockReturnValue(mockInstance)
25
-
26
15
  // Create a test callback function
27
16
  const testCallback = (instance: object, param1: string, param2: number) => {
28
17
  return `${param1}-${param2}-${instance ? 'valid' : 'invalid'}`
@@ -32,7 +21,13 @@ describe('createCallbackHook', () => {
32
21
  const useTestHook = createCallbackHook(testCallback)
33
22
 
34
23
  // Render the hook
35
- const {result, rerender} = renderHook(() => useTestHook())
24
+ const {result, rerender} = renderHook(() => useTestHook(), {
25
+ wrapper: ({children}) => (
26
+ <ResourceProvider projectId="p" dataset="d" fallback={null}>
27
+ {children}
28
+ </ResourceProvider>
29
+ ),
30
+ })
36
31
 
37
32
  // Test the callback with parameters
38
33
  const result1 = result.current('test', 123)
@@ -48,38 +43,41 @@ describe('createCallbackHook', () => {
48
43
  })
49
44
 
50
45
  it('should create new callback when instance changes', () => {
51
- // Create two different mock instances
52
- const mockInstance1 = createSanityInstance({projectId: 'p1', dataset: 'd'})
53
- const mockInstance2 = createSanityInstance({projectId: 'p2', dataset: 'd'})
54
-
55
- vi.mocked(useSanityInstance).mockReturnValueOnce(mockInstance1)
56
-
57
46
  // Create a test callback
58
47
  const testCallback = (instance: SanityInstance) => instance.config.projectId
59
48
 
60
- // Create and render our hook
49
+ // Create and render our hook with first provider
61
50
  const useTestHook = createCallbackHook(testCallback)
62
- const {result, rerender} = renderHook(() => useTestHook())
51
+ const {result, unmount} = renderHook(() => useTestHook(), {
52
+ wrapper: ({children}) => (
53
+ <ResourceProvider projectId="p1" dataset="d" fallback={null}>
54
+ {children}
55
+ </ResourceProvider>
56
+ ),
57
+ })
63
58
 
64
- // Store the first callback reference
59
+ // Store the first callback reference and result
65
60
  const firstCallback = result.current
61
+ const firstResult = firstCallback()
62
+ expect(firstResult).toBe('p1')
63
+
64
+ unmount()
65
+
66
+ // Re-render with different provider configuration
67
+ const {result: result2} = renderHook(() => useTestHook(), {
68
+ wrapper: ({children}) => (
69
+ <ResourceProvider projectId="p2" dataset="d" fallback={null}>
70
+ {children}
71
+ </ResourceProvider>
72
+ ),
73
+ })
66
74
 
67
- // Change the instance
68
- vi.mocked(useSanityInstance).mockReturnValueOnce(mockInstance2)
69
- rerender()
70
-
71
- // Verify the callback reference changed
72
- expect(result.current).not.toBe(firstCallback)
73
-
74
- // Verify the callbacks return different results
75
- expect(firstCallback()).toBe('p1')
76
- expect(result.current()).toBe('p2')
75
+ // Verify the callback reference changed and returns different result
76
+ expect(result2.current).not.toBe(firstCallback)
77
+ expect(result2.current()).toBe('p2')
77
78
  })
78
79
 
79
80
  it('should handle callbacks with multiple parameters', () => {
80
- const mockInstance = createSanityInstance({projectId: 'p', dataset: 'd'})
81
- vi.mocked(useSanityInstance).mockReturnValue(mockInstance)
82
-
83
81
  // Create a callback with multiple parameters
84
82
  const testCallback = (
85
83
  instance: SanityInstance,
@@ -93,7 +91,13 @@ describe('createCallbackHook', () => {
93
91
  })
94
92
 
95
93
  const useTestHook = createCallbackHook(testCallback)
96
- const {result} = renderHook(() => useTestHook())
94
+ const {result} = renderHook(() => useTestHook(), {
95
+ wrapper: ({children}) => (
96
+ <ResourceProvider projectId="p" dataset="d" fallback={null}>
97
+ {children}
98
+ </ResourceProvider>
99
+ ),
100
+ })
97
101
 
98
102
  const response = result.current('/users', 'POST', {name: 'Test User'})
99
103
 
@@ -1,8 +1,8 @@
1
1
  import {act, renderHook} from '@testing-library/react'
2
+ import {evaluateSync, parse, toJS} from 'groq-js'
2
3
  import {describe, vi} from 'vitest'
3
4
 
4
5
  import {ResourceProvider} from '../../context/ResourceProvider'
5
- import {evaluateSync, parse} from '../_synchronous-groq-js.mjs'
6
6
  import {useQuery} from '../query/useQuery'
7
7
  import {usePaginatedDocuments} from './usePaginatedDocuments'
8
8
 
@@ -73,7 +73,7 @@ describe('usePaginatedDocuments', () => {
73
73
  ]
74
74
 
75
75
  vi.mocked(useQuery).mockImplementation(({query, ...options}) => {
76
- const result = evaluateSync(parse(query), {dataset, params: options?.params}).get()
76
+ const result = toJS(evaluateSync(parse(query), {dataset, params: options?.params}))
77
77
  return {
78
78
  data: result,
79
79
  isPending: false,