@sanity/sdk
Version:
237 lines (210 loc) • 7.2 kB
text/typescript
import {describe, expect, it} from 'vitest'
import {SUBTITLE_CANDIDATES, TITLE_CANDIDATES} from './previewConstants'
import {createPreviewQuery, normalizeMedia, processPreviewQuery} from './previewQuery'
import {STABLE_EMPTY_PREVIEW} from './util'
describe('createPreviewQuery', () => {
it('creates a query and params for given ids and schema', () => {
const ids = new Set(['book1', 'book2'])
const {query, params} = createPreviewQuery(ids)
expect(query).toMatch(/.*_id in \$__ids_.*/)
expect(Object.keys(params)).toHaveLength(1)
})
})
describe('processPreviewQuery', () => {
it('returns STABLE_EMPTY_PREVIEW if documentType is missing', () => {
const ids = new Set(['doc1'])
const result = processPreviewQuery({
projectId: 'p',
dataset: 'd',
results: [],
ids,
})
expect(result['doc1']).toEqual(STABLE_EMPTY_PREVIEW)
})
it('returns STABLE_EMPTY_PREVIEW if no candidates found', () => {
const ids = new Set(['doc1'])
const result = processPreviewQuery({
projectId: 'p',
dataset: 'd',
results: [], // no results, so no selectResult
ids,
})
expect(result['doc1']).toEqual(STABLE_EMPTY_PREVIEW)
})
// it.only('returns STABLE_ERROR_PREVIEW if an error occurs', () => {
// const ids = new Set(['doc1'])
// const result = processPreviewQuery({
// projectId: 'p',
// dataset: 'd',
// results: [
// {
// _id: 'doc1',
// _type: 'someType',
// _updatedAt: new Date().toISOString(),
// titleCandidates: {title: null},
// subtitleCandidates: {subtitle: null},
// },
// ], // no results, so no selectResult
// ids,
// })
// expect(result['doc1']).toEqual(STABLE_ERROR_PREVIEW)
// })
it('processes query results into preview values', () => {
const results = [
{
_id: 'person1',
_type: 'person',
_updatedAt: '2021-01-01',
titleCandidates: {title: 'John'},
subtitleCandidates: {subtitle: null},
},
]
const processed = processPreviewQuery({
projectId: 'p',
dataset: 'd',
ids: new Set(['person1']),
results,
})
const val = processed['person1']
expect(val?.data).toEqual({
title: 'John',
media: null,
_status: {lastEditedPublishedAt: '2021-01-01'},
})
expect(val?.isPending).toBe(false)
})
it('resolves status preferring draft over published when available', () => {
const results = [
{
_id: 'drafts.article1',
_type: 'article',
_updatedAt: '2023-12-16T12:00:00Z',
titleCandidates: {
title: 'Draft Title',
name: null,
},
subtitleCandidates: {
title: null,
name: null,
},
},
{
_id: 'article1',
_type: 'article',
_updatedAt: '2023-12-15T12:00:00Z',
titleCandidates: {
title: 'Published Title',
name: null,
},
subtitleCandidates: {
title: null,
name: null,
},
},
]
const processed = processPreviewQuery({
projectId: 'p',
dataset: 'd',
ids: new Set(['article1']),
results,
})
const val = processed['article1']
expect(val?.data).toEqual({
title: 'Draft Title',
media: null,
_status: {
lastEditedDraftAt: '2023-12-16T12:00:00Z',
lastEditedPublishedAt: '2023-12-15T12:00:00Z',
},
})
expect(val?.isPending).toBe(false)
})
it('uses the first defined title or subtitle from the candidates', () => {
const titleCandidates = {
title: 'Draft Title',
name: 'Draft Name',
label: 'Draft Label',
heading: 'Draft Heading',
header: 'Draft Header',
caption: 'Draft Caption',
}
const subtitleCandidates = {
subtitle: 'Draft Subtitle',
description: 'Draft Description',
name: 'Draft Name',
label: 'Draft Label',
heading: 'Draft Heading',
header: 'Draft Header',
caption: 'Draft Caption',
}
const results = [
{
_id: 'article1',
_type: 'article',
_updatedAt: '2023-12-15T12:00:00Z',
titleCandidates,
subtitleCandidates,
},
]
const processed = processPreviewQuery({
projectId: 'p',
dataset: 'd',
ids: new Set(['article1']),
results,
})
const val = processed['article1']
expect(val?.data).toEqual({
title: titleCandidates[TITLE_CANDIDATES[0] as keyof typeof titleCandidates],
subtitle: subtitleCandidates[SUBTITLE_CANDIDATES[0] as keyof typeof subtitleCandidates],
media: null,
_status: {lastEditedPublishedAt: '2023-12-15T12:00:00Z'},
})
expect(val?.isPending).toBe(false)
})
})
describe('normalizeMedia', () => {
it('returns null if media is null or undefined', () => {
expect(normalizeMedia(null, 'projectId', 'dataset')).toBeNull()
expect(normalizeMedia(undefined, 'projectId', 'dataset')).toBeNull()
})
it('returns null if media does not have a valid asset', () => {
const invalidMedia1 = {media: {_ref: 'image-abc123-200x200-png'}} // Missing `asset` property
const invalidMedia2 = {asset: {ref: 'image-abc123-200x200-png'}} // Incorrect property name `ref`
expect(normalizeMedia(invalidMedia1, 'projectId', 'dataset')).toBeNull()
expect(normalizeMedia(invalidMedia2, 'projectId', 'dataset')).toBeNull()
})
it('returns null if media is not an object', () => {
expect(normalizeMedia(123, 'projectId', 'dataset')).toBeNull()
expect(normalizeMedia('invalid', 'projectId', 'dataset')).toBeNull()
})
it('returns a normalized URL for valid image asset objects', () => {
const validMedia = {type: 'image-asset', _ref: 'image-abc123-200x200-png'}
const result = normalizeMedia(validMedia, 'projectId', 'dataset')
expect(result).toEqual({
type: 'image-asset',
_ref: 'image-abc123-200x200-png',
url: 'https://cdn.sanity.io/images/projectId/dataset/abc123-200x200.png',
})
})
it('throws an error for invalid asset IDs in the media', () => {
const invalidMedia = {type: 'image-asset', _ref: 'invalid-asset-id'}
expect(() => normalizeMedia(invalidMedia, 'projectId', 'dataset')).toThrow(
'Invalid asset ID `invalid-asset-id`. Expected: image-{assetName}-{width}x{height}-{format}',
)
})
it('handles image assets with expected URL format', () => {
const media = {type: 'image-asset', _ref: 'image-xyz456-400x400-jpg'}
const result = normalizeMedia(media, 'projectId', 'dataset')
expect(result).toEqual({
type: 'image-asset',
_ref: 'image-xyz456-400x400-jpg',
url: 'https://cdn.sanity.io/images/projectId/dataset/xyz456-400x400.jpg',
})
})
it('ensures assetIdToUrl throws for asset IDs with missing groups', () => {
const invalidMedia = {type: 'image-asset', _ref: 'image-missinggroups'}
expect(() => normalizeMedia(invalidMedia, 'projectId', 'dataset')).toThrow(
'Invalid asset ID `image-missinggroups`. Expected: image-{assetName}-{width}x{height}-{format}',
)
})
})