@sanity/sdk 2.7.0 → 3.0.0-rc.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.
- package/dist/index.d.ts +228 -239
- package/dist/index.js +287 -454
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/_exports/index.ts +16 -17
- package/src/agent/agentActions.test.ts +60 -16
- package/src/agent/agentActions.ts +29 -20
- package/src/auth/authMode.test.ts +0 -25
- package/src/auth/authMode.ts +3 -6
- package/src/auth/authStore.test.ts +129 -66
- package/src/auth/authStore.ts +9 -11
- package/src/auth/dashboardAuth.ts +2 -2
- package/src/auth/getOrganizationVerificationState.test.ts +10 -11
- package/src/auth/handleAuthCallback.test.ts +0 -12
- package/src/auth/handleAuthCallback.ts +9 -3
- package/src/auth/logout.test.ts +0 -6
- package/src/auth/refreshStampedToken.test.ts +121 -17
- package/src/auth/standaloneAuth.ts +9 -3
- package/src/auth/studioAuth.ts +35 -8
- package/src/auth/subscribeToStateAndFetchCurrentUser.test.ts +9 -3
- package/src/auth/subscribeToStateAndFetchCurrentUser.ts +1 -1
- package/src/auth/subscribeToStorageEventsAndSetToken.test.ts +0 -2
- package/src/auth/subscribeToStorageEventsAndSetToken.ts +2 -2
- package/src/auth/utils.ts +33 -0
- package/src/client/clientStore.test.ts +14 -61
- package/src/client/clientStore.ts +52 -28
- package/src/comlink/controller/actions/destroyController.test.ts +1 -4
- package/src/comlink/controller/actions/getOrCreateChannel.test.ts +1 -4
- package/src/comlink/controller/actions/getOrCreateController.test.ts +1 -4
- package/src/comlink/controller/actions/releaseChannel.test.ts +1 -1
- package/src/comlink/controller/comlinkControllerStore.test.ts +1 -4
- package/src/comlink/node/actions/getOrCreateNode.test.ts +1 -4
- package/src/comlink/node/actions/releaseNode.test.ts +1 -4
- package/src/comlink/node/comlinkNodeStore.test.ts +2 -2
- package/src/comlink/node/getNodeState.test.ts +1 -1
- package/src/config/__tests__/handles.test.ts +12 -18
- package/src/config/handles.ts +7 -25
- package/src/config/sanityConfig.ts +99 -52
- package/src/datasets/datasets.test.ts +2 -2
- package/src/datasets/datasets.ts +4 -10
- package/src/document/actions.test.ts +33 -4
- package/src/document/actions.ts +3 -10
- package/src/document/applyDocumentActions.test.ts +17 -18
- package/src/document/applyDocumentActions.ts +9 -12
- package/src/document/documentStore.test.ts +303 -133
- package/src/document/documentStore.ts +70 -61
- package/src/document/permissions.test.ts +44 -8
- package/src/document/processActions.test.ts +77 -7
- package/src/document/reducers.test.ts +35 -3
- package/src/document/sharedListener.test.ts +13 -13
- package/src/document/sharedListener.ts +8 -3
- package/src/favorites/favorites.test.ts +10 -2
- package/src/presence/presenceStore.test.ts +34 -9
- package/src/presence/presenceStore.ts +29 -13
- package/src/preview/previewProjectionUtils.test.ts +192 -0
- package/src/preview/previewProjectionUtils.ts +88 -0
- package/src/preview/{previewStore.ts → types.ts} +6 -25
- package/src/project/project.test.ts +1 -1
- package/src/project/project.ts +14 -20
- package/src/projection/getProjectionState.test.ts +4 -2
- package/src/projection/getProjectionState.ts +2 -21
- package/src/projection/projectionQuery.ts +2 -3
- package/src/projection/projectionStore.test.ts +3 -3
- package/src/projection/resolveProjection.test.ts +2 -1
- package/src/projection/resolveProjection.ts +2 -18
- package/src/projection/subscribeToStateAndFetchBatches.test.ts +2 -2
- package/src/projection/subscribeToStateAndFetchBatches.ts +23 -36
- package/src/projection/types.ts +1 -9
- package/src/projects/projects.test.ts +1 -1
- package/src/query/queryStore.test.ts +86 -28
- package/src/query/queryStore.ts +23 -38
- package/src/releases/getPerspectiveState.test.ts +14 -13
- package/src/releases/getPerspectiveState.ts +6 -6
- package/src/releases/releasesStore.test.ts +21 -6
- package/src/releases/releasesStore.ts +18 -8
- package/src/store/createActionBinder.test.ts +114 -111
- package/src/store/createActionBinder.ts +52 -101
- package/src/store/createSanityInstance.test.ts +13 -83
- package/src/store/createSanityInstance.ts +2 -78
- package/src/store/createStateSourceAction.test.ts +2 -2
- package/src/store/createStateSourceAction.ts +5 -5
- package/src/store/createStoreInstance.test.ts +2 -4
- package/src/users/reducers.test.ts +1 -6
- package/src/users/reducers.ts +2 -2
- package/src/users/types.ts +4 -4
- package/src/users/usersStore.test.ts +12 -15
- package/src/utils/createFetcherStore.test.ts +1 -1
- package/src/utils/logger.test.ts +0 -12
- package/src/utils/logger.ts +3 -8
- package/src/preview/getPreviewState.test.ts +0 -120
- package/src/preview/getPreviewState.ts +0 -91
- package/src/preview/previewQuery.test.ts +0 -236
- package/src/preview/previewQuery.ts +0 -153
- package/src/preview/previewStore.test.ts +0 -36
- package/src/preview/resolvePreview.test.ts +0 -47
- package/src/preview/resolvePreview.ts +0 -20
- package/src/preview/subscribeToStateAndFetchBatches.test.ts +0 -221
- package/src/preview/subscribeToStateAndFetchBatches.ts +0 -112
- package/src/preview/util.ts +0 -13
|
@@ -51,38 +51,24 @@ interface TestDocument extends SanityDocument {
|
|
|
51
51
|
title?: string
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
// Scope the TestDocument type to the project/datasets used in tests
|
|
55
|
-
type AllTestSchemaTypes = TestDocument
|
|
56
|
-
|
|
57
|
-
// Augment the 'groq' module
|
|
58
|
-
declare module 'groq' {
|
|
59
|
-
interface SanitySchemas {
|
|
60
|
-
default: AllTestSchemaTypes
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
54
|
let instance: SanityInstance
|
|
65
|
-
|
|
66
|
-
|
|
55
|
+
|
|
56
|
+
// bindActionByResource should ensure docs from different resources are isolated
|
|
57
|
+
const resource = {projectId: 'p', dataset: 'd'}
|
|
58
|
+
const resource1 = {projectId: 'p', dataset: 'd1'}
|
|
59
|
+
const resource2 = {projectId: 'p', dataset: 'd2'}
|
|
67
60
|
|
|
68
61
|
beforeEach(() => {
|
|
69
|
-
instance = createSanityInstance(
|
|
70
|
-
// test uses two instances that share the same in-memory dataset, but separate
|
|
71
|
-
// store instances. in real scenarios, this would be separate machines but with
|
|
72
|
-
// the same project + dataset
|
|
73
|
-
instance1 = createSanityInstance({projectId: 'p', dataset: 'd1'})
|
|
74
|
-
instance2 = createSanityInstance({projectId: 'p', dataset: 'd2'})
|
|
62
|
+
instance = createSanityInstance()
|
|
75
63
|
})
|
|
76
64
|
|
|
77
65
|
afterEach(() => {
|
|
78
66
|
instance?.dispose()
|
|
79
|
-
instance1?.dispose()
|
|
80
|
-
instance2?.dispose()
|
|
81
67
|
})
|
|
82
68
|
|
|
83
69
|
it('creates, edits, and publishes a document', async () => {
|
|
84
|
-
const doc = createDocumentHandle({documentId: 'doc-single', documentType: 'article'})
|
|
85
|
-
const documentState = getDocumentState(instance, doc)
|
|
70
|
+
const doc = createDocumentHandle({documentId: 'doc-single', documentType: 'article', resource})
|
|
71
|
+
const documentState = getDocumentState<TestDocument>(instance, doc)
|
|
86
72
|
|
|
87
73
|
// Initially the document is undefined
|
|
88
74
|
expect(documentState.getCurrent()).toBeUndefined()
|
|
@@ -90,7 +76,10 @@ it('creates, edits, and publishes a document', async () => {
|
|
|
90
76
|
const unsubscribe = documentState.subscribe()
|
|
91
77
|
|
|
92
78
|
// Create a new document
|
|
93
|
-
const {appeared} = await applyDocumentActions(instance, {
|
|
79
|
+
const {appeared} = await applyDocumentActions(instance, {
|
|
80
|
+
actions: [createDocument(doc)],
|
|
81
|
+
resource,
|
|
82
|
+
})
|
|
94
83
|
expect(appeared).toContain(getDraftId(doc.documentId))
|
|
95
84
|
|
|
96
85
|
let currentDoc = documentState.getCurrent()
|
|
@@ -99,6 +88,7 @@ it('creates, edits, and publishes a document', async () => {
|
|
|
99
88
|
// Edit the document – add a title
|
|
100
89
|
await applyDocumentActions(instance, {
|
|
101
90
|
actions: [editDocument(doc, {set: {title: 'My First Article'}})],
|
|
91
|
+
resource,
|
|
102
92
|
})
|
|
103
93
|
currentDoc = documentState.getCurrent()
|
|
104
94
|
expect(currentDoc?.title).toEqual('My First Article')
|
|
@@ -106,6 +96,7 @@ it('creates, edits, and publishes a document', async () => {
|
|
|
106
96
|
// Publish the document; the resulting transactionId is used as the new _rev
|
|
107
97
|
const {transactionId, submitted} = await applyDocumentActions(instance, {
|
|
108
98
|
actions: [publishDocument(doc)],
|
|
99
|
+
resource,
|
|
109
100
|
})
|
|
110
101
|
await submitted()
|
|
111
102
|
currentDoc = documentState.getCurrent()
|
|
@@ -115,8 +106,12 @@ it('creates, edits, and publishes a document', async () => {
|
|
|
115
106
|
})
|
|
116
107
|
|
|
117
108
|
it('creates a document with initial values', async () => {
|
|
118
|
-
const doc = createDocumentHandle({
|
|
119
|
-
|
|
109
|
+
const doc = createDocumentHandle({
|
|
110
|
+
documentId: 'doc-with-initial',
|
|
111
|
+
documentType: 'article',
|
|
112
|
+
resource,
|
|
113
|
+
})
|
|
114
|
+
const documentState = getDocumentState<TestDocument>(instance, doc)
|
|
120
115
|
|
|
121
116
|
expect(documentState.getCurrent()).toBeUndefined()
|
|
122
117
|
|
|
@@ -131,6 +126,7 @@ it('creates a document with initial values', async () => {
|
|
|
131
126
|
count: 42,
|
|
132
127
|
}),
|
|
133
128
|
],
|
|
129
|
+
resource,
|
|
134
130
|
})
|
|
135
131
|
expect(appeared).toContain(getDraftId(doc.documentId))
|
|
136
132
|
|
|
@@ -144,8 +140,8 @@ it('creates a document with initial values', async () => {
|
|
|
144
140
|
})
|
|
145
141
|
|
|
146
142
|
it('edits existing documents', async () => {
|
|
147
|
-
const doc = createDocumentHandle({documentId: 'existing-doc', documentType: 'article'})
|
|
148
|
-
const state = getDocumentState(instance, doc)
|
|
143
|
+
const doc = createDocumentHandle({documentId: 'existing-doc', documentType: 'article', resource})
|
|
144
|
+
const state = getDocumentState<TestDocument>(instance, doc)
|
|
149
145
|
|
|
150
146
|
// not subscribed yet so the value is undefined
|
|
151
147
|
expect(state.getCurrent()).toBeUndefined()
|
|
@@ -162,6 +158,7 @@ it('edits existing documents', async () => {
|
|
|
162
158
|
|
|
163
159
|
await applyDocumentActions(instance, {
|
|
164
160
|
actions: [editDocument(doc, {set: {title: 'updated title'}})],
|
|
161
|
+
resource,
|
|
165
162
|
})
|
|
166
163
|
expect(state.getCurrent()).toMatchObject({
|
|
167
164
|
_id: getDraftId(doc.documentId),
|
|
@@ -172,23 +169,33 @@ it('edits existing documents', async () => {
|
|
|
172
169
|
})
|
|
173
170
|
|
|
174
171
|
it('sets optimistic changes synchronously', async () => {
|
|
175
|
-
const
|
|
172
|
+
const doc1 = createDocumentHandle({
|
|
173
|
+
documentId: 'optimistic',
|
|
174
|
+
documentType: 'article',
|
|
175
|
+
resource: resource1,
|
|
176
|
+
})
|
|
177
|
+
const doc2 = createDocumentHandle({
|
|
178
|
+
documentId: 'optimistic',
|
|
179
|
+
documentType: 'article',
|
|
180
|
+
resource: resource2,
|
|
181
|
+
})
|
|
176
182
|
|
|
177
|
-
const state1 = getDocumentState(
|
|
178
|
-
const state2 = getDocumentState(
|
|
183
|
+
const state1 = getDocumentState<TestDocument>(instance, doc1)
|
|
184
|
+
const state2 = getDocumentState<TestDocument>(instance, doc2)
|
|
179
185
|
|
|
180
186
|
const unsubscribe1 = state1.subscribe()
|
|
181
187
|
const unsubscribe2 = state2.subscribe()
|
|
182
188
|
|
|
183
189
|
// wait until the value is primed in the store
|
|
184
|
-
await resolveDocument(
|
|
190
|
+
await resolveDocument(instance, doc1)
|
|
185
191
|
|
|
186
192
|
// then the actions are synchronous
|
|
187
193
|
expect(state1.getCurrent()).toBeNull()
|
|
188
|
-
applyDocumentActions(
|
|
189
|
-
expect(state1.getCurrent()).toMatchObject({_id: getDraftId(
|
|
190
|
-
const actionResult1Promise = applyDocumentActions(
|
|
191
|
-
actions: [editDocument(
|
|
194
|
+
applyDocumentActions(instance, {actions: [createDocument(doc1)], resource: resource1})
|
|
195
|
+
expect(state1.getCurrent()).toMatchObject({_id: getDraftId(doc1.documentId)})
|
|
196
|
+
const actionResult1Promise = applyDocumentActions(instance, {
|
|
197
|
+
actions: [editDocument(doc1, {set: {title: 'initial title'}})],
|
|
198
|
+
resource: resource1,
|
|
192
199
|
})
|
|
193
200
|
expect(state1.getCurrent()?.title).toBe('initial title')
|
|
194
201
|
|
|
@@ -207,8 +214,9 @@ it('sets optimistic changes synchronously', async () => {
|
|
|
207
214
|
expect(state2.getCurrent()?.title).toBe('initial title')
|
|
208
215
|
|
|
209
216
|
// synchronous for state 2
|
|
210
|
-
const actionResult2Promise = applyDocumentActions(
|
|
211
|
-
actions: [editDocument(
|
|
217
|
+
const actionResult2Promise = applyDocumentActions(instance, {
|
|
218
|
+
actions: [editDocument(doc2, {set: {title: 'updated title'}})],
|
|
219
|
+
resource: resource2,
|
|
212
220
|
})
|
|
213
221
|
expect(state2.getCurrent()?.title).toBe('updated title')
|
|
214
222
|
// async for state 1
|
|
@@ -223,24 +231,37 @@ it('sets optimistic changes synchronously', async () => {
|
|
|
223
231
|
})
|
|
224
232
|
|
|
225
233
|
it('propagates changes between two instances', async () => {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
234
|
+
const doc1 = createDocumentHandle({
|
|
235
|
+
documentId: 'doc-collab',
|
|
236
|
+
documentType: 'article',
|
|
237
|
+
resource: resource1,
|
|
238
|
+
})
|
|
239
|
+
const doc2 = createDocumentHandle({
|
|
240
|
+
documentId: 'doc-collab',
|
|
241
|
+
documentType: 'article',
|
|
242
|
+
resource: resource2,
|
|
243
|
+
})
|
|
244
|
+
const state1 = getDocumentState<TestDocument>(instance, doc1)
|
|
245
|
+
const state2 = getDocumentState<TestDocument>(instance, doc2)
|
|
229
246
|
|
|
230
247
|
const state1Unsubscribe = state1.subscribe()
|
|
231
248
|
const state2Unsubscribe = state2.subscribe()
|
|
232
249
|
|
|
233
|
-
// Create the document from
|
|
234
|
-
await applyDocumentActions(
|
|
250
|
+
// Create the document from the store instance.
|
|
251
|
+
await applyDocumentActions(instance, {
|
|
252
|
+
actions: [createDocument(doc1)],
|
|
253
|
+
resource: resource1,
|
|
254
|
+
}).then((r) => r.submitted())
|
|
235
255
|
|
|
236
|
-
const
|
|
237
|
-
const
|
|
238
|
-
expect(
|
|
239
|
-
expect(
|
|
256
|
+
const docState1 = state1.getCurrent()
|
|
257
|
+
const docState2 = state2.getCurrent()
|
|
258
|
+
expect(docState1?._id).toEqual(getDraftId(doc1.documentId))
|
|
259
|
+
expect(docState2?._id).toEqual(getDraftId(doc1.documentId))
|
|
240
260
|
|
|
241
|
-
// Now, edit the document from
|
|
242
|
-
await applyDocumentActions(
|
|
243
|
-
actions: [editDocument(
|
|
261
|
+
// Now, edit the document from the other store instance.
|
|
262
|
+
await applyDocumentActions(instance, {
|
|
263
|
+
actions: [editDocument(doc2, {set: {title: 'Hello world!'}})],
|
|
264
|
+
resource: resource2,
|
|
244
265
|
}).then((r) => r.submitted())
|
|
245
266
|
|
|
246
267
|
const updated1 = state1.getCurrent()
|
|
@@ -253,31 +274,43 @@ it('propagates changes between two instances', async () => {
|
|
|
253
274
|
})
|
|
254
275
|
|
|
255
276
|
it('handles concurrent edits and resolves conflicts', async () => {
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
277
|
+
const doc1 = createDocumentHandle({
|
|
278
|
+
documentId: 'doc-concurrent',
|
|
279
|
+
documentType: 'article',
|
|
280
|
+
resource: resource1,
|
|
281
|
+
})
|
|
282
|
+
const doc2 = createDocumentHandle({
|
|
283
|
+
documentId: 'doc-concurrent',
|
|
284
|
+
documentType: 'article',
|
|
285
|
+
resource: resource2,
|
|
286
|
+
})
|
|
287
|
+
const state1 = getDocumentState<TestDocument>(instance, doc1)
|
|
288
|
+
const state2 = getDocumentState<TestDocument>(instance, doc2)
|
|
259
289
|
|
|
260
290
|
const state1Unsubscribe = state1.subscribe()
|
|
261
291
|
const state2Unsubscribe = state2.subscribe()
|
|
262
292
|
|
|
263
|
-
const oneOffInstance = createSanityInstance(
|
|
293
|
+
const oneOffInstance = createSanityInstance()
|
|
264
294
|
|
|
265
295
|
// Create the initial document from a one-off instance.
|
|
266
296
|
await applyDocumentActions(oneOffInstance, {
|
|
267
297
|
actions: [
|
|
268
|
-
createDocument(
|
|
269
|
-
editDocument(
|
|
298
|
+
createDocument(doc1),
|
|
299
|
+
editDocument(doc1, {set: {title: 'The quick brown fox jumps over the lazy dog'}}),
|
|
270
300
|
],
|
|
301
|
+
resource,
|
|
271
302
|
}).then((res) => res.submitted())
|
|
272
303
|
|
|
273
|
-
// Both instances now issue an edit simultaneously.
|
|
274
|
-
const p1 = applyDocumentActions(
|
|
275
|
-
actions: [editDocument(
|
|
304
|
+
// Both store instances now issue an edit simultaneously.
|
|
305
|
+
const p1 = applyDocumentActions(instance, {
|
|
306
|
+
actions: [editDocument(doc1, {set: {title: 'The quick brown fox jumps over the lazy cat'}})],
|
|
307
|
+
resource: resource1,
|
|
276
308
|
}).then((r) => r.submitted())
|
|
277
|
-
const p2 = applyDocumentActions(
|
|
309
|
+
const p2 = applyDocumentActions(instance, {
|
|
278
310
|
actions: [
|
|
279
|
-
editDocument(
|
|
311
|
+
editDocument(doc2, {set: {title: 'The quick brown elephant jumps over the lazy dog'}}),
|
|
280
312
|
],
|
|
313
|
+
resource: resource2,
|
|
281
314
|
}).then((r) => r.submitted())
|
|
282
315
|
|
|
283
316
|
// Wait for both actions to complete (or reject).
|
|
@@ -294,13 +327,16 @@ it('handles concurrent edits and resolves conflicts', async () => {
|
|
|
294
327
|
})
|
|
295
328
|
|
|
296
329
|
it('unpublishes and discards a document', async () => {
|
|
297
|
-
const doc = createDocumentHandle({documentId: 'doc-pub-unpub', documentType: 'article'})
|
|
298
|
-
const documentState = getDocumentState(instance, doc)
|
|
330
|
+
const doc = createDocumentHandle({documentId: 'doc-pub-unpub', documentType: 'article', resource})
|
|
331
|
+
const documentState = getDocumentState<TestDocument>(instance, doc)
|
|
299
332
|
const unsubscribe = documentState.subscribe()
|
|
300
333
|
|
|
301
334
|
// Create and publish the document.
|
|
302
|
-
await applyDocumentActions(instance, {actions: [createDocument(doc)]})
|
|
303
|
-
const afterPublish = await applyDocumentActions(instance, {
|
|
335
|
+
await applyDocumentActions(instance, {actions: [createDocument(doc)], resource})
|
|
336
|
+
const afterPublish = await applyDocumentActions(instance, {
|
|
337
|
+
actions: [publishDocument(doc)],
|
|
338
|
+
resource,
|
|
339
|
+
})
|
|
304
340
|
const publishedDoc = documentState.getCurrent()
|
|
305
341
|
expect(publishedDoc).toMatchObject({
|
|
306
342
|
_id: getPublishedId(doc.documentId),
|
|
@@ -308,13 +344,13 @@ it('unpublishes and discards a document', async () => {
|
|
|
308
344
|
})
|
|
309
345
|
|
|
310
346
|
// Unpublish the document (which should delete the published version and create a draft).
|
|
311
|
-
await applyDocumentActions(instance, {actions: [unpublishDocument(doc)]})
|
|
347
|
+
await applyDocumentActions(instance, {actions: [unpublishDocument(doc)], resource})
|
|
312
348
|
const afterUnpublish = documentState.getCurrent()
|
|
313
349
|
// In our mock implementation the _id remains the same but the published copy is removed.
|
|
314
350
|
expect(afterUnpublish?._id).toEqual(getDraftId(doc.documentId))
|
|
315
351
|
|
|
316
352
|
// Discard the draft (which deletes the draft version).
|
|
317
|
-
await applyDocumentActions(instance, {actions: [discardDocument(doc)]})
|
|
353
|
+
await applyDocumentActions(instance, {actions: [discardDocument(doc)], resource})
|
|
318
354
|
const afterDiscard = documentState.getCurrent()
|
|
319
355
|
expect(afterDiscard).toBeNull()
|
|
320
356
|
|
|
@@ -322,17 +358,20 @@ it('unpublishes and discards a document', async () => {
|
|
|
322
358
|
})
|
|
323
359
|
|
|
324
360
|
it('deletes a document', async () => {
|
|
325
|
-
const doc = createDocumentHandle({documentId: 'doc-delete', documentType: 'article'})
|
|
361
|
+
const doc = createDocumentHandle({documentId: 'doc-delete', documentType: 'article', resource})
|
|
326
362
|
|
|
327
|
-
const documentState = getDocumentState(instance, doc)
|
|
363
|
+
const documentState = getDocumentState<TestDocument>(instance, doc)
|
|
328
364
|
const unsubscribe = documentState.subscribe()
|
|
329
365
|
|
|
330
|
-
await applyDocumentActions(instance, {
|
|
366
|
+
await applyDocumentActions(instance, {
|
|
367
|
+
actions: [createDocument(doc), publishDocument(doc)],
|
|
368
|
+
resource,
|
|
369
|
+
})
|
|
331
370
|
const docValue = documentState.getCurrent()
|
|
332
371
|
expect(docValue).toBeDefined()
|
|
333
372
|
|
|
334
373
|
// Delete the document.
|
|
335
|
-
await applyDocumentActions(instance, {actions: [deleteDocument(doc)]})
|
|
374
|
+
await applyDocumentActions(instance, {actions: [deleteDocument(doc)], resource})
|
|
336
375
|
const afterDelete = documentState.getCurrent()
|
|
337
376
|
expect(afterDelete).toBeNull()
|
|
338
377
|
|
|
@@ -340,14 +379,14 @@ it('deletes a document', async () => {
|
|
|
340
379
|
})
|
|
341
380
|
|
|
342
381
|
it('cleans up document state when there are no subscribers', async () => {
|
|
343
|
-
const doc = createDocumentHandle({documentId: 'doc-cleanup', documentType: 'article'})
|
|
344
|
-
const documentState = getDocumentState(instance, doc)
|
|
382
|
+
const doc = createDocumentHandle({documentId: 'doc-cleanup', documentType: 'article', resource})
|
|
383
|
+
const documentState = getDocumentState<TestDocument>(instance, doc)
|
|
345
384
|
|
|
346
385
|
// Subscribe to the document state.
|
|
347
386
|
const unsubscribe = documentState.subscribe()
|
|
348
387
|
|
|
349
388
|
// Create a document.
|
|
350
|
-
await applyDocumentActions(instance, {actions: [createDocument(doc)]})
|
|
389
|
+
await applyDocumentActions(instance, {actions: [createDocument(doc)], resource})
|
|
351
390
|
expect(documentState.getCurrent()).toBeDefined()
|
|
352
391
|
|
|
353
392
|
// Unsubscribe from the document.
|
|
@@ -358,14 +397,14 @@ it('cleans up document state when there are no subscribers', async () => {
|
|
|
358
397
|
await new Promise((resolve) => setTimeout(resolve, 30))
|
|
359
398
|
|
|
360
399
|
// When a new subscriber is created, if the state was cleared it should return undefined.
|
|
361
|
-
const newDocumentState = getDocumentState(instance, doc)
|
|
400
|
+
const newDocumentState = getDocumentState<TestDocument>(instance, doc)
|
|
362
401
|
expect(newDocumentState.getCurrent()).toBeUndefined()
|
|
363
402
|
})
|
|
364
403
|
|
|
365
404
|
it('fetches documents if there are no active subscriptions for the actions applied', async () => {
|
|
366
|
-
const doc = createDocumentHandle({documentId: 'existing-doc', documentType: 'article'})
|
|
405
|
+
const doc = createDocumentHandle({documentId: 'existing-doc', documentType: 'article', resource})
|
|
367
406
|
|
|
368
|
-
const {getCurrent} = getDocumentState(instance, doc)
|
|
407
|
+
const {getCurrent} = getDocumentState<TestDocument>(instance, doc)
|
|
369
408
|
expect(getCurrent()).toBeUndefined()
|
|
370
409
|
expect(getDocumentSyncStatus(instance, doc).getCurrent()).toBeUndefined()
|
|
371
410
|
|
|
@@ -374,6 +413,7 @@ it('fetches documents if there are no active subscriptions for the actions appli
|
|
|
374
413
|
// transaction for this action has been accepted by the server
|
|
375
414
|
const setNewTitle = applyDocumentActions(instance, {
|
|
376
415
|
actions: [editDocument(doc, {set: {title: 'new title'}})],
|
|
416
|
+
resource,
|
|
377
417
|
})
|
|
378
418
|
expect(getCurrent()?.title).toBeUndefined()
|
|
379
419
|
expect(getDocumentSyncStatus(instance, doc).getCurrent()).toBe(false)
|
|
@@ -382,9 +422,15 @@ it('fetches documents if there are no active subscriptions for the actions appli
|
|
|
382
422
|
expect(getCurrent()?.title).toBe('new title')
|
|
383
423
|
|
|
384
424
|
// there is an active subscriber now so the edits are synchronous
|
|
385
|
-
applyDocumentActions(instance, {
|
|
425
|
+
applyDocumentActions(instance, {
|
|
426
|
+
actions: [editDocument(doc, {set: {title: 'updated title'}})],
|
|
427
|
+
resource,
|
|
428
|
+
})
|
|
386
429
|
expect(getCurrent()?.title).toBe('updated title')
|
|
387
|
-
applyDocumentActions(instance, {
|
|
430
|
+
applyDocumentActions(instance, {
|
|
431
|
+
actions: [editDocument(doc, {set: {title: 'updated title!'}})],
|
|
432
|
+
resource,
|
|
433
|
+
})
|
|
388
434
|
expect(getCurrent()?.title).toBe('updated title!')
|
|
389
435
|
|
|
390
436
|
expect(getDocumentSyncStatus(instance, doc).getCurrent()).toBe(false)
|
|
@@ -392,6 +438,7 @@ it('fetches documents if there are no active subscriptions for the actions appli
|
|
|
392
438
|
// await submitted in order to test that there is no subscriptions
|
|
393
439
|
const result = await applyDocumentActions(instance, {
|
|
394
440
|
actions: [editDocument(doc, {set: {title: 'updated title'}})],
|
|
441
|
+
resource,
|
|
395
442
|
})
|
|
396
443
|
await result.submitted()
|
|
397
444
|
|
|
@@ -400,6 +447,7 @@ it('fetches documents if there are no active subscriptions for the actions appli
|
|
|
400
447
|
|
|
401
448
|
const setNewNewTitle = applyDocumentActions(instance, {
|
|
402
449
|
actions: [editDocument(doc, {set: {title: 'new new title'}})],
|
|
450
|
+
resource,
|
|
403
451
|
})
|
|
404
452
|
// now we'll have to await again
|
|
405
453
|
expect(getCurrent()?.title).toBe(undefined)
|
|
@@ -409,19 +457,27 @@ it('fetches documents if there are no active subscriptions for the actions appli
|
|
|
409
457
|
})
|
|
410
458
|
|
|
411
459
|
it('batches edit transaction into one outgoing transaction', async () => {
|
|
412
|
-
const doc = createDocumentHandle({
|
|
460
|
+
const doc = createDocumentHandle({
|
|
461
|
+
documentId: crypto.randomUUID(),
|
|
462
|
+
documentType: 'article',
|
|
463
|
+
resource,
|
|
464
|
+
})
|
|
413
465
|
|
|
414
|
-
const unsubscribe = getDocumentState(instance, doc).subscribe()
|
|
466
|
+
const unsubscribe = getDocumentState<TestDocument>(instance, doc).subscribe()
|
|
415
467
|
|
|
416
468
|
// this creates its own transaction
|
|
417
|
-
applyDocumentActions(instance, {actions: [createDocument(doc)]})
|
|
469
|
+
applyDocumentActions(instance, {actions: [createDocument(doc)], resource})
|
|
418
470
|
|
|
419
471
|
// these get batched into one
|
|
420
|
-
applyDocumentActions(instance, {actions: [editDocument(doc, {set: {title: 'name!'}})]})
|
|
421
|
-
applyDocumentActions(instance, {actions: [editDocument(doc, {set: {title: 'name!!'}})]})
|
|
422
|
-
applyDocumentActions(instance, {
|
|
472
|
+
applyDocumentActions(instance, {actions: [editDocument(doc, {set: {title: 'name!'}})], resource})
|
|
473
|
+
applyDocumentActions(instance, {actions: [editDocument(doc, {set: {title: 'name!!'}})], resource})
|
|
474
|
+
applyDocumentActions(instance, {
|
|
475
|
+
actions: [editDocument(doc, {set: {title: 'name!!!'}})],
|
|
476
|
+
resource,
|
|
477
|
+
})
|
|
423
478
|
const res = await applyDocumentActions(instance, {
|
|
424
479
|
actions: [editDocument(doc, {set: {title: 'name!!!!'}})],
|
|
480
|
+
resource,
|
|
425
481
|
})
|
|
426
482
|
await res.submitted()
|
|
427
483
|
|
|
@@ -435,7 +491,11 @@ it('batches edit transaction into one outgoing transaction', async () => {
|
|
|
435
491
|
})
|
|
436
492
|
|
|
437
493
|
it('provides the consistency status via `getDocumentSyncStatus`', async () => {
|
|
438
|
-
const doc = createDocumentHandle({
|
|
494
|
+
const doc = createDocumentHandle({
|
|
495
|
+
documentId: crypto.randomUUID(),
|
|
496
|
+
documentType: 'article',
|
|
497
|
+
resource,
|
|
498
|
+
})
|
|
439
499
|
|
|
440
500
|
const syncStatus = getDocumentSyncStatus(instance, doc)
|
|
441
501
|
expect(syncStatus.getCurrent()).toBeUndefined()
|
|
@@ -443,7 +503,7 @@ it('provides the consistency status via `getDocumentSyncStatus`', async () => {
|
|
|
443
503
|
const unsubscribe = syncStatus.subscribe()
|
|
444
504
|
expect(syncStatus.getCurrent()).toBe(true)
|
|
445
505
|
|
|
446
|
-
const applied = applyDocumentActions(instance, {actions: [createDocument(doc)]})
|
|
506
|
+
const applied = applyDocumentActions(instance, {actions: [createDocument(doc)], resource})
|
|
447
507
|
expect(syncStatus.getCurrent()).toBe(false)
|
|
448
508
|
|
|
449
509
|
const createResult = await applied
|
|
@@ -452,11 +512,17 @@ it('provides the consistency status via `getDocumentSyncStatus`', async () => {
|
|
|
452
512
|
await createResult.submitted()
|
|
453
513
|
expect(syncStatus.getCurrent()).toBe(true)
|
|
454
514
|
|
|
455
|
-
applyDocumentActions(instance, {
|
|
515
|
+
applyDocumentActions(instance, {
|
|
516
|
+
actions: [editDocument(doc, {set: {title: 'initial name'}})],
|
|
517
|
+
resource,
|
|
518
|
+
})
|
|
456
519
|
expect(syncStatus.getCurrent()).toBe(false)
|
|
457
520
|
|
|
458
|
-
applyDocumentActions(instance, {
|
|
459
|
-
|
|
521
|
+
applyDocumentActions(instance, {
|
|
522
|
+
actions: [editDocument(doc, {set: {title: 'updated name'}})],
|
|
523
|
+
resource,
|
|
524
|
+
})
|
|
525
|
+
const publishResult = applyDocumentActions(instance, {actions: [publishDocument(doc)], resource})
|
|
460
526
|
expect(syncStatus.getCurrent()).toBe(false)
|
|
461
527
|
await publishResult.then((res) => res.submitted())
|
|
462
528
|
expect(syncStatus.getCurrent()).toBe(true)
|
|
@@ -473,35 +539,48 @@ it('reverts failed outgoing transaction locally', async () => {
|
|
|
473
539
|
})
|
|
474
540
|
|
|
475
541
|
const revertedEventPromise = new Promise<TransactionRevertedEvent>((resolve) => {
|
|
476
|
-
const unsubscribe = subscribeDocumentEvents(instance,
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
542
|
+
const unsubscribe = subscribeDocumentEvents(instance, {
|
|
543
|
+
resource,
|
|
544
|
+
eventHandler: (e) => {
|
|
545
|
+
if (e.type === 'reverted') {
|
|
546
|
+
resolve(e)
|
|
547
|
+
unsubscribe()
|
|
548
|
+
}
|
|
549
|
+
},
|
|
481
550
|
})
|
|
482
551
|
})
|
|
483
552
|
|
|
484
|
-
const doc = createDocumentHandle({
|
|
553
|
+
const doc = createDocumentHandle({
|
|
554
|
+
documentId: crypto.randomUUID(),
|
|
555
|
+
documentType: 'article',
|
|
556
|
+
resource,
|
|
557
|
+
})
|
|
485
558
|
|
|
486
|
-
const {getCurrent, subscribe} = getDocumentState(instance, doc)
|
|
559
|
+
const {getCurrent, subscribe} = getDocumentState<TestDocument>(instance, doc)
|
|
487
560
|
const unsubscribe = subscribe()
|
|
488
561
|
|
|
489
|
-
await applyDocumentActions(instance, {actions: [createDocument(doc)]})
|
|
490
|
-
applyDocumentActions(instance, {actions: [editDocument(doc, {set: {title: 'the'}})]})
|
|
491
|
-
applyDocumentActions(instance, {
|
|
562
|
+
await applyDocumentActions(instance, {actions: [createDocument(doc)], resource})
|
|
563
|
+
applyDocumentActions(instance, {actions: [editDocument(doc, {set: {title: 'the'}})], resource})
|
|
564
|
+
applyDocumentActions(instance, {
|
|
565
|
+
actions: [editDocument(doc, {set: {title: 'the quick'}})],
|
|
566
|
+
resource,
|
|
567
|
+
})
|
|
492
568
|
|
|
493
569
|
// this edit action is simulated to fail from the backend and will be reverted
|
|
494
570
|
const revertedActionResult = applyDocumentActions(instance, {
|
|
495
571
|
actions: [editDocument(doc, {set: {title: 'the quick brown'}})],
|
|
496
572
|
transactionId: 'force-revert',
|
|
497
573
|
disableBatching: true,
|
|
574
|
+
resource,
|
|
498
575
|
})
|
|
499
576
|
|
|
500
577
|
applyDocumentActions(instance, {
|
|
501
578
|
actions: [editDocument(doc, {set: {title: 'the quick brown fox'}})],
|
|
579
|
+
resource,
|
|
502
580
|
})
|
|
503
581
|
await applyDocumentActions(instance, {
|
|
504
582
|
actions: [editDocument(doc, {set: {title: 'the quick brown fox jumps'}})],
|
|
583
|
+
resource,
|
|
505
584
|
}).then((e) => e.submitted())
|
|
506
585
|
|
|
507
586
|
await expect(revertedEventPromise).resolves.toMatchObject({
|
|
@@ -521,6 +600,7 @@ it('reverts failed outgoing transaction locally', async () => {
|
|
|
521
600
|
// check that we can still edit after recovering from the error
|
|
522
601
|
applyDocumentActions(instance, {
|
|
523
602
|
actions: [editDocument(doc, {set: {title: 'TEST the quick fox jumps'}})],
|
|
603
|
+
resource,
|
|
524
604
|
})
|
|
525
605
|
expect(getCurrent()?.title).toBe('TEST the quick fox jumps')
|
|
526
606
|
|
|
@@ -530,20 +610,30 @@ it('reverts failed outgoing transaction locally', async () => {
|
|
|
530
610
|
|
|
531
611
|
it('removes a queued transaction if it fails to apply', async () => {
|
|
532
612
|
const actionErrorEventPromise = new Promise<ActionErrorEvent>((resolve) => {
|
|
533
|
-
const unsubscribe = subscribeDocumentEvents(instance,
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
613
|
+
const unsubscribe = subscribeDocumentEvents(instance, {
|
|
614
|
+
resource,
|
|
615
|
+
eventHandler: (e) => {
|
|
616
|
+
if (e.type === 'error') {
|
|
617
|
+
resolve(e)
|
|
618
|
+
unsubscribe()
|
|
619
|
+
}
|
|
620
|
+
},
|
|
538
621
|
})
|
|
539
622
|
})
|
|
540
623
|
|
|
541
|
-
const doc = createDocumentHandle({
|
|
542
|
-
|
|
624
|
+
const doc = createDocumentHandle({
|
|
625
|
+
documentId: crypto.randomUUID(),
|
|
626
|
+
documentType: 'article',
|
|
627
|
+
resource,
|
|
628
|
+
})
|
|
629
|
+
const state = getDocumentState<TestDocument>(instance, doc)
|
|
543
630
|
const unsubscribe = state.subscribe()
|
|
544
631
|
|
|
545
632
|
await expect(
|
|
546
|
-
applyDocumentActions(instance, {
|
|
633
|
+
applyDocumentActions(instance, {
|
|
634
|
+
actions: [editDocument(doc, {set: {title: "can't set"}})],
|
|
635
|
+
resource,
|
|
636
|
+
}),
|
|
547
637
|
).rejects.toThrowError(/Cannot edit document/)
|
|
548
638
|
|
|
549
639
|
await expect(actionErrorEventPromise).resolves.toMatchObject({
|
|
@@ -553,8 +643,11 @@ it('removes a queued transaction if it fails to apply', async () => {
|
|
|
553
643
|
})
|
|
554
644
|
|
|
555
645
|
// editing should still work after though (no crashing)
|
|
556
|
-
await applyDocumentActions(instance, {actions: [createDocument(doc)]})
|
|
557
|
-
applyDocumentActions(instance, {
|
|
646
|
+
await applyDocumentActions(instance, {actions: [createDocument(doc)], resource})
|
|
647
|
+
applyDocumentActions(instance, {
|
|
648
|
+
actions: [editDocument(doc, {set: {title: 'can set!'}})],
|
|
649
|
+
resource,
|
|
650
|
+
})
|
|
558
651
|
|
|
559
652
|
expect(state.getCurrent()?.title).toBe('can set!')
|
|
560
653
|
|
|
@@ -571,13 +664,17 @@ it('returns allowed true when no permission errors occur', async () => {
|
|
|
571
664
|
const doc = createDocumentHandle({
|
|
572
665
|
documentId: 'doc-perm-allowed',
|
|
573
666
|
documentType: 'article',
|
|
667
|
+
resource,
|
|
574
668
|
})
|
|
575
|
-
const state = getDocumentState(instance, doc)
|
|
669
|
+
const state = getDocumentState<TestDocument>(instance, doc)
|
|
576
670
|
const unsubscribe = state.subscribe()
|
|
577
|
-
await applyDocumentActions(instance, {actions: [createDocument(doc)]}).then((r) =>
|
|
671
|
+
await applyDocumentActions(instance, {actions: [createDocument(doc)], resource}).then((r) =>
|
|
672
|
+
r.submitted(),
|
|
673
|
+
)
|
|
578
674
|
|
|
579
675
|
// Use an action that includes a patch (so that update permission check is bypassed).
|
|
580
676
|
const permissionsState = getPermissionsState(instance, {
|
|
677
|
+
resource,
|
|
581
678
|
actions: [
|
|
582
679
|
{
|
|
583
680
|
...doc,
|
|
@@ -594,30 +691,42 @@ it('returns allowed true when no permission errors occur', async () => {
|
|
|
594
691
|
})
|
|
595
692
|
|
|
596
693
|
it("should reject applying the action if a precondition isn't met", async () => {
|
|
597
|
-
const doc = createDocumentHandle({
|
|
694
|
+
const doc = createDocumentHandle({
|
|
695
|
+
documentId: 'does-not-exist',
|
|
696
|
+
documentType: 'article',
|
|
697
|
+
resource,
|
|
698
|
+
})
|
|
598
699
|
|
|
599
|
-
await expect(
|
|
600
|
-
|
|
601
|
-
)
|
|
700
|
+
await expect(
|
|
701
|
+
applyDocumentActions(instance, {actions: [deleteDocument(doc)], resource}),
|
|
702
|
+
).rejects.toThrow('The document you are trying to delete does not exist.')
|
|
602
703
|
})
|
|
603
704
|
|
|
604
705
|
it("should reject applying the action if a permission isn't met", async () => {
|
|
605
|
-
const doc = createDocumentHandle({
|
|
706
|
+
const doc = createDocumentHandle({
|
|
707
|
+
documentId: 'does-not-exist',
|
|
708
|
+
documentType: 'article',
|
|
709
|
+
resource,
|
|
710
|
+
})
|
|
606
711
|
|
|
607
712
|
const datasetAcl = [{filter: 'false', permissions: ['create']}]
|
|
608
713
|
vi.mocked(client.request).mockResolvedValue(datasetAcl)
|
|
609
714
|
|
|
610
|
-
await expect(
|
|
611
|
-
|
|
612
|
-
)
|
|
715
|
+
await expect(
|
|
716
|
+
applyDocumentActions(instance, {actions: [createDocument(doc)], resource}),
|
|
717
|
+
).rejects.toThrow('You do not have permission to create a draft for document "does-not-exist".')
|
|
613
718
|
})
|
|
614
719
|
|
|
615
720
|
it('returns allowed false with reasons when permission errors occur', async () => {
|
|
616
721
|
const datasetAcl = [{filter: 'false', permissions: ['create']}]
|
|
617
722
|
vi.mocked(client.request).mockResolvedValue(datasetAcl)
|
|
618
723
|
|
|
619
|
-
const doc = createDocumentHandle({
|
|
620
|
-
|
|
724
|
+
const doc = createDocumentHandle({
|
|
725
|
+
documentId: 'doc-perm-denied',
|
|
726
|
+
documentType: 'article',
|
|
727
|
+
resource,
|
|
728
|
+
})
|
|
729
|
+
const result = await resolvePermissions(instance, {actions: [createDocument(doc)], resource})
|
|
621
730
|
|
|
622
731
|
const message = 'You do not have permission to create a draft for document "doc-perm-denied".'
|
|
623
732
|
expect(result).toMatchObject({
|
|
@@ -635,27 +744,86 @@ it('fetches dataset ACL and updates grants in the document store state', async (
|
|
|
635
744
|
]
|
|
636
745
|
vi.mocked(client.request).mockResolvedValue(datasetAcl)
|
|
637
746
|
|
|
638
|
-
const book = createDocumentHandle({
|
|
639
|
-
|
|
747
|
+
const book = createDocumentHandle({
|
|
748
|
+
documentId: crypto.randomUUID(),
|
|
749
|
+
documentType: 'book',
|
|
750
|
+
resource,
|
|
751
|
+
})
|
|
752
|
+
const author = createDocumentHandle({
|
|
753
|
+
documentId: crypto.randomUUID(),
|
|
754
|
+
documentType: 'author',
|
|
755
|
+
resource,
|
|
756
|
+
})
|
|
640
757
|
|
|
641
|
-
expect(await resolvePermissions(instance, {actions: [createDocument(book)]})).toEqual({
|
|
758
|
+
expect(await resolvePermissions(instance, {actions: [createDocument(book)], resource})).toEqual({
|
|
642
759
|
allowed: true,
|
|
643
760
|
})
|
|
644
|
-
expect(
|
|
761
|
+
expect(
|
|
762
|
+
await resolvePermissions(instance, {actions: [createDocument(author)], resource}),
|
|
763
|
+
).toMatchObject({
|
|
645
764
|
allowed: false,
|
|
646
765
|
message: expect.stringContaining('You do not have permission to create a draft for document'),
|
|
647
766
|
})
|
|
648
767
|
})
|
|
649
768
|
|
|
769
|
+
it('fetches ACL for MediaLibraryResource', async () => {
|
|
770
|
+
const mediaLibraryInstance = createSanityInstance()
|
|
771
|
+
|
|
772
|
+
const datasetAcl = [{filter: 'true', permissions: ['read', 'update', 'create', 'history']}]
|
|
773
|
+
vi.mocked(client.request).mockResolvedValue(datasetAcl)
|
|
774
|
+
|
|
775
|
+
const doc = createDocumentHandle({
|
|
776
|
+
documentId: crypto.randomUUID(),
|
|
777
|
+
documentType: 'article',
|
|
778
|
+
resource,
|
|
779
|
+
})
|
|
780
|
+
const mediaLibraryResource = {mediaLibraryId: 'test-media-library'}
|
|
781
|
+
|
|
782
|
+
const result = await resolvePermissions(mediaLibraryInstance, {
|
|
783
|
+
actions: [createDocument(doc)],
|
|
784
|
+
resource: mediaLibraryResource,
|
|
785
|
+
})
|
|
786
|
+
|
|
787
|
+
expect(result).toEqual({allowed: true})
|
|
788
|
+
mediaLibraryInstance.dispose()
|
|
789
|
+
})
|
|
790
|
+
|
|
791
|
+
it('fetches ACL for CanvasResource', async () => {
|
|
792
|
+
const canvasInstance = createSanityInstance()
|
|
793
|
+
|
|
794
|
+
const datasetAcl = [{filter: 'true', permissions: ['read', 'update', 'create', 'history']}]
|
|
795
|
+
vi.mocked(client.request).mockResolvedValue(datasetAcl)
|
|
796
|
+
|
|
797
|
+
const doc = createDocumentHandle({
|
|
798
|
+
documentId: crypto.randomUUID(),
|
|
799
|
+
documentType: 'article',
|
|
800
|
+
resource,
|
|
801
|
+
})
|
|
802
|
+
const canvasResource = {canvasId: 'test-canvas'}
|
|
803
|
+
|
|
804
|
+
const result = await resolvePermissions(canvasInstance, {
|
|
805
|
+
actions: [createDocument(doc)],
|
|
806
|
+
resource: canvasResource,
|
|
807
|
+
})
|
|
808
|
+
|
|
809
|
+
expect(result).toEqual({allowed: true})
|
|
810
|
+
canvasInstance.dispose()
|
|
811
|
+
})
|
|
812
|
+
|
|
650
813
|
it('returns a promise that resolves when a document has been loaded in the store (useful for suspense)', async () => {
|
|
651
|
-
const doc = createDocumentHandle({
|
|
814
|
+
const doc = createDocumentHandle({
|
|
815
|
+
documentId: crypto.randomUUID(),
|
|
816
|
+
documentType: 'article',
|
|
817
|
+
resource,
|
|
818
|
+
})
|
|
652
819
|
|
|
653
820
|
expect(await resolveDocument(instance, doc)).toBe(null)
|
|
654
821
|
|
|
655
822
|
// use one-off instance to create the document in the mock backend
|
|
656
|
-
const oneOffInstance = createSanityInstance(
|
|
823
|
+
const oneOffInstance = createSanityInstance()
|
|
657
824
|
const result = await applyDocumentActions(oneOffInstance, {
|
|
658
825
|
actions: [createDocument(doc), editDocument(doc, {set: {title: 'initial title'}})],
|
|
826
|
+
resource,
|
|
659
827
|
})
|
|
660
828
|
await result.submitted() // wait till submitted to server before resolving
|
|
661
829
|
|
|
@@ -669,10 +837,10 @@ it('returns a promise that resolves when a document has been loaded in the store
|
|
|
669
837
|
|
|
670
838
|
it('emits an event for each action after an outgoing transaction has been accepted', async () => {
|
|
671
839
|
const handler = vi.fn()
|
|
672
|
-
const unsubscribe = subscribeDocumentEvents(instance, handler)
|
|
840
|
+
const unsubscribe = subscribeDocumentEvents(instance, {resource, eventHandler: handler})
|
|
673
841
|
|
|
674
842
|
const documentId = crypto.randomUUID()
|
|
675
|
-
const doc = createDocumentHandle({documentId, documentType: 'article'})
|
|
843
|
+
const doc = createDocumentHandle({documentId, documentType: 'article', resource})
|
|
676
844
|
expect(handler).toHaveBeenCalledTimes(0)
|
|
677
845
|
|
|
678
846
|
const tnx1 = await applyDocumentActions(instance, {
|
|
@@ -681,6 +849,7 @@ it('emits an event for each action after an outgoing transaction has been accept
|
|
|
681
849
|
editDocument(doc, {set: {title: 'new name'}}),
|
|
682
850
|
publishDocument(doc),
|
|
683
851
|
],
|
|
852
|
+
resource,
|
|
684
853
|
}).then((e) => e.submitted())
|
|
685
854
|
expect(handler).toHaveBeenCalledTimes(4)
|
|
686
855
|
|
|
@@ -691,6 +860,7 @@ it('emits an event for each action after an outgoing transaction has been accept
|
|
|
691
860
|
editDocument(doc, {set: {title: 'updated name'}}),
|
|
692
861
|
discardDocument(doc),
|
|
693
862
|
],
|
|
863
|
+
resource,
|
|
694
864
|
}).then((e) => e.submitted())
|
|
695
865
|
expect(handler).toHaveBeenCalledTimes(9)
|
|
696
866
|
|
|
@@ -706,7 +876,7 @@ it('emits an event for each action after an outgoing transaction has been accept
|
|
|
706
876
|
[{type: 'accepted', outgoing: {transactionId: tnx2.transactionId}}],
|
|
707
877
|
])
|
|
708
878
|
|
|
709
|
-
await applyDocumentActions(instance, {actions: [deleteDocument(doc)]})
|
|
879
|
+
await applyDocumentActions(instance, {actions: [deleteDocument(doc)], resource})
|
|
710
880
|
|
|
711
881
|
unsubscribe()
|
|
712
882
|
})
|
|
@@ -859,8 +1029,8 @@ beforeEach(() => {
|
|
|
859
1029
|
continue
|
|
860
1030
|
}
|
|
861
1031
|
case 'sanity.action.document.edit': {
|
|
862
|
-
const
|
|
863
|
-
if (!
|
|
1032
|
+
const documentSource = next[i.draftId] ?? next[i.publishedId]
|
|
1033
|
+
if (!documentSource) {
|
|
864
1034
|
throw new Error(
|
|
865
1035
|
`Could not find a document to edit from \`draftId\` \`${i.draftId}\` or \`publishedId\` ${i.publishedId}`,
|
|
866
1036
|
)
|
|
@@ -869,7 +1039,7 @@ beforeEach(() => {
|
|
|
869
1039
|
next = processMutations({
|
|
870
1040
|
documents: next,
|
|
871
1041
|
mutations: [
|
|
872
|
-
{createIfNotExists: {...
|
|
1042
|
+
{createIfNotExists: {...documentSource, _id: i.draftId}},
|
|
873
1043
|
{patch: {id: i.draftId, ...i.patch}},
|
|
874
1044
|
],
|
|
875
1045
|
transactionId,
|