Skip to content

Commit 728311e

Browse files
authored
fix(core): drafts not using server actions always generate a created at (#7503)
* fix(core): drafts not using server actions generate a created at always * test(core): resolving failing tests due to no mocked global date in SquashingBuffer * refactor(core): simplifiying guarantee on createdAt date; testing around missing timestamp
1 parent a6e0389 commit 728311e

File tree

3 files changed

+48
-9
lines changed

3 files changed

+48
-9
lines changed

packages/@sanity/mutator/src/document/Mutation.ts

+9-5
Original file line numberDiff line numberDiff line change
@@ -106,17 +106,21 @@ export class Mutation {
106106
compile(): void {
107107
const operations: ((doc: Doc | null) => Doc | null)[] = []
108108

109+
// creation requires a _createdAt
110+
const getGuaranteedCreatedAt = (doc: Doc): string =>
111+
doc?._createdAt || this.params.timestamp || new Date().toISOString()
112+
109113
this.mutations.forEach((mutation) => {
110114
if (mutation.create) {
111115
// TODO: Fail entire patch if document did exist
112-
const create = mutation.create || {}
116+
const create = (mutation.create || {}) as Doc
113117
operations.push((doc): Doc => {
114118
if (doc) {
115119
return doc
116120
}
117121

118-
return Object.assign(create as Doc, {
119-
_createdAt: create._createdAt || this.params.timestamp,
122+
return Object.assign(create, {
123+
_createdAt: getGuaranteedCreatedAt(create),
120124
})
121125
})
122126
return
@@ -127,7 +131,7 @@ export class Mutation {
127131
operations.push((doc) =>
128132
doc === null
129133
? Object.assign(createIfNotExists, {
130-
_createdAt: createIfNotExists._createdAt || this.params.timestamp,
134+
_createdAt: getGuaranteedCreatedAt(createIfNotExists),
131135
})
132136
: doc,
133137
)
@@ -138,7 +142,7 @@ export class Mutation {
138142
const createOrReplace = mutation.createOrReplace || {}
139143
operations.push(() =>
140144
Object.assign(createOrReplace, {
141-
_createdAt: createOrReplace._createdAt || this.params.timestamp,
145+
_createdAt: getGuaranteedCreatedAt(createOrReplace),
142146
}),
143147
)
144148
return

packages/@sanity/mutator/src/document/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface Doc {
1616
_type: string
1717
_rev?: string
1818
_updatedAt?: string
19+
_createdAt?: string
1920
[attribute: string]: unknown
2021
}
2122

packages/@sanity/mutator/test/SquashingBuffer.test.ts

+38-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {expect, test} from '@jest/globals'
1+
import {expect, jest, test} from '@jest/globals'
22
import {type PatchMutationOperation} from '@sanity/types'
33

44
import {Mutation} from '../src/document/Mutation'
@@ -109,7 +109,39 @@ test('de-duplicate createIfNotExists', () => {
109109
expect(tx2 && tx2.mutations.length).toBe(1)
110110
})
111111

112+
test.each(['create', 'createIfNotExists', 'createOrReplace'])(
113+
'%s defaults to current created at time',
114+
(createFnc) => {
115+
const globalMockDate = new Date('2020-01-01T12:34:55.000Z')
116+
const globalDateSpy = jest.spyOn(global, 'Date').mockReturnValue(globalMockDate)
117+
118+
const sb = new SquashingBuffer(null)
119+
120+
add(sb, {[createFnc]: {_id: '1', _type: 'test', a: 'A string value'}})
121+
122+
const tx = sb.purge('txn_id')
123+
if (!tx) {
124+
throw new Error('buffer purge did not result in a mutation')
125+
}
126+
127+
const final = tx.apply(null)
128+
129+
expect(final).toEqual({
130+
_id: '1',
131+
_rev: 'txn_id',
132+
_createdAt: '2020-01-01T12:34:55.000Z',
133+
_type: 'test',
134+
a: 'A string value',
135+
})
136+
137+
globalDateSpy.mockRestore()
138+
},
139+
)
140+
112141
test('de-duplicate create respects deletes', () => {
142+
const globalMockDate = new Date('2020-01-01T12:34:55.000Z')
143+
const globalDateSpy = jest.spyOn(global, 'Date').mockReturnValue(globalMockDate)
144+
113145
const initial = {_id: '1', _type: 'test', a: 'A string value', c: 'Some value'}
114146
const sb = new SquashingBuffer(initial)
115147
add(sb, {createIfNotExists: {_id: '1', _type: 'test', a: 'A string value', c: 'Some value'}})
@@ -124,7 +156,7 @@ test('de-duplicate create respects deletes', () => {
124156
if (!tx) {
125157
throw new Error('buffer purge did not result in a mutation')
126158
}
127-
tx.params.timestamp = '2021-01-01T12:34:55Z'
159+
tx.params.timestamp = '2021-01-01T12:34:55.000Z'
128160

129161
const creates = tx.mutations.filter((mut) => !!mut.createIfNotExists)
130162
expect(creates.length).toBe(2) // Only a single create mutation expected (note: bn - is this correct?)
@@ -134,14 +166,16 @@ test('de-duplicate create respects deletes', () => {
134166
expect(final).toEqual({
135167
_id: '1',
136168
_type: 'test',
137-
_createdAt: '2021-01-01T12:34:55Z',
138-
_updatedAt: '2021-01-01T12:34:55Z',
169+
_createdAt: '2020-01-01T12:34:55.000Z',
170+
_updatedAt: '2021-01-01T12:34:55.000Z',
139171
_rev: 'txn_id',
140172
a: {
141173
b: 'A wrapped value',
142174
},
143175
c: 'Changed',
144176
})
177+
178+
globalDateSpy.mockRestore()
145179
})
146180

147181
test('de-duplicate create respects rebasing', () => {

0 commit comments

Comments
 (0)