Skip to content

Commit

Permalink
test(preview): add tests for createObserveDocument
Browse files Browse the repository at this point in the history
  • Loading branch information
bjoerge committed Aug 27, 2024
1 parent 49f1a58 commit 5887a68
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import {describe, expect, it, jest} from '@jest/globals'
import {createClient, type WelcomeEvent} from '@sanity/client'
import {firstValueFrom, of, skip, Subject} from 'rxjs'
import {take} from 'rxjs/operators'

import {createObserveDocument, type ListenerMutationEventLike} from '../createObserveDocument'

describe(createObserveDocument.name, () => {
it('fetches the current version of the document when receiving welcome event', async () => {
const mockedClient = createClient({
projectId: 'abc',
dataset: 'production',
apiVersion: '2024-08-27',
useCdn: false,
})

jest
.spyOn(mockedClient.observable, 'fetch')
.mockImplementation(() => of([{_id: 'foo', fetched: true}]) as any)
jest.spyOn(mockedClient, 'withConfig').mockImplementation(() => mockedClient)

const mutationChannel = new Subject<WelcomeEvent | ListenerMutationEventLike>()

const observeDocument = createObserveDocument({
mutationChannel,
client: mockedClient,
})

const initial = firstValueFrom(observeDocument('foo').pipe(take(1)))

mutationChannel.next({type: 'welcome'})

expect(await initial).toEqual({_id: 'foo', fetched: true})
})

it('emits undefined if the document does not exist', async () => {
const mockedClient = createClient({
projectId: 'abc',
dataset: 'production',
apiVersion: '2024-08-27',
useCdn: false,
})

jest.spyOn(mockedClient.observable, 'fetch').mockImplementation(() => of([]) as any)
jest.spyOn(mockedClient, 'withConfig').mockImplementation(() => mockedClient)

const mutationChannel = new Subject<WelcomeEvent | ListenerMutationEventLike>()

const observeDocument = createObserveDocument({
mutationChannel,
client: mockedClient,
})

const initial = firstValueFrom(observeDocument('foo').pipe(take(1)))

mutationChannel.next({type: 'welcome'})

expect(await initial).toEqual(undefined)
})

it('applies a mendoza patch when received over the listener', async () => {
const mockedClient = createClient({
projectId: 'abc',
dataset: 'production',
apiVersion: '2024-08-27',
useCdn: false,
})

jest.spyOn(mockedClient.observable, 'fetch').mockImplementation(
() =>
of([
{
_createdAt: '2024-08-27T09:01:42Z',
_id: '1c32390c',
_rev: 'a8403810-81f7-49e6-8860-e52cb9111431',
_type: 'foo',
_updatedAt: '2024-08-27T09:03:38Z',
name: 'foo',
},
]) as any,
)
jest.spyOn(mockedClient, 'withConfig').mockImplementation(() => mockedClient)

const mutationChannel = new Subject<WelcomeEvent | ListenerMutationEventLike>()

const observeDocument = createObserveDocument({
mutationChannel,
client: mockedClient,
})

const final = firstValueFrom(observeDocument('1c32390c').pipe(skip(1), take(1)))

mutationChannel.next({type: 'welcome'})
mutationChannel.next({
type: 'mutation',
documentId: '1c32390c',
previousRev: 'a8403810-81f7-49e6-8860-e52cb9111431',
resultRev: 'b3e7ebce-2bdd-4ab7-9056-b525773bd17a',
effects: {
apply: [11, 3, 23, 0, 18, 22, '8', 23, 19, 20, 15, 17, 'foos', 'name'],
},
})

expect(await final).toEqual({
_createdAt: '2024-08-27T09:01:42Z',
_id: '1c32390c',
_rev: 'b3e7ebce-2bdd-4ab7-9056-b525773bd17a',
_type: 'foo',
_updatedAt: '2024-08-27T09:03:38Z',
name: 'foos',
})
})
})
13 changes: 11 additions & 2 deletions packages/sanity/src/core/preview/createObserveDocument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,21 @@ import {type ApiConfig} from './types'
import {applyMutationEventEffects} from './utils/applyMendozaPatch'
import {debounceCollect} from './utils/debounceCollect'

export type ListenerMutationEventLike = Pick<
MutationEvent,
'type' | 'documentId' | 'previousRev' | 'resultRev'
> & {
effects: {
apply: unknown[]
}
}

export function createObserveDocument({
mutationChannel,
client,
}: {
client: SanityClient
mutationChannel: Observable<WelcomeEvent | MutationEvent>
mutationChannel: Observable<WelcomeEvent | ListenerMutationEventLike>
}) {
const getBatchFetcher = memoize(
function getBatchFetcher(apiConfig: {dataset: string; projectId: string}) {
Expand Down Expand Up @@ -72,7 +81,7 @@ export function createObserveDocument({
}
}

function applyMutationEvent(current: SanityDocument | undefined, event: MutationEvent) {
function applyMutationEvent(current: SanityDocument | undefined, event: ListenerMutationEventLike) {
if (event.previousRev !== current?._rev) {
console.warn('Document out of sync, skipping mutation')
return current
Expand Down

0 comments on commit 5887a68

Please sign in to comment.