Skip to content

Commit

Permalink
[mutator] Respect embedded _createdAt property on create patches. Fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
simen authored and bjoerge committed Jan 30, 2018
1 parent 20df70e commit 75d7b61
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 26 deletions.
2 changes: 1 addition & 1 deletion packages/@sanity/mutator/src/document/Document.js
Expand Up @@ -147,7 +147,7 @@ export default class Document {
}
mustRebase = mustRebase || this.applyIncoming(nextMut)
if (protect++ > 100) {
throw new Error('Mutator stuck flusing incoming mutations. Probably stuck here:', JSON.stringify(nextMut))
throw new Error('Mutator stuck flushing incoming mutations. Probably stuck here:', JSON.stringify(nextMut))
}
} while (nextMut)

Expand Down
6 changes: 3 additions & 3 deletions packages/@sanity/mutator/src/document/Mutation.js
Expand Up @@ -74,14 +74,14 @@ export default class Mutation {
if (mutation.create) {
// TODO: Fail entire patch if document did exist
operations.push(
doc => (doc === null ? Object.assign(mutation.create, {_createdAt: this.params.timestamp}) : doc)
doc => (doc === null ? Object.assign(mutation.create, {_createdAt: mutation.create._createdAt || this.params.timestamp}) : doc)
)
} else if (mutation.createIfNotExists) {
operations.push(
doc => (doc === null ? Object.assign(mutation.createIfNotExists, {_createdAt: this.params.timestamp}) : doc)
doc => (doc === null ? Object.assign(mutation.createIfNotExists, {_createdAt: mutation.create._createdAt || this.params.timestamp}) : doc)
)
} else if (mutation.createOrReplace) {
operations.push(() => Object.assign(mutation.createOrReplace, {_createdAt: this.params.timestamp}))
operations.push(() => Object.assign(mutation.createOrReplace, {_createdAt: mutation.create._createdAt || this.params.timestamp}))
} else if (mutation.delete) {
operations.push(() => null)
} else if (mutation.patch) {
Expand Down
5 changes: 4 additions & 1 deletion packages/@sanity/mutator/test/BufferedDocument.test.js
Expand Up @@ -159,7 +159,10 @@ test('document being deleted by remote', tap => {

.stage('when local user creates document')
.localMutation(null, '3', {
create: {_id: 'a', text: 'good morning'}
create: {_id: 'a', text: 'good morning', _createdAt: '2018-01-25T15:18:12.114Z'}
})
.assert((tap, bufDoc) => {
tap.type(bufDoc.LOCAL._createdAt, 'string', "New documents must have a _createdAt time")
})
.assertLOCAL('text', 'good morning')
.assertHEADDeleted()
Expand Down
110 changes: 89 additions & 21 deletions packages/@sanity/mutator/test/util/BufferedDocumentTester.js
Expand Up @@ -8,8 +8,13 @@ import debugLogger from 'debug'
const debug = debugLogger('buffered-document-tester')

export default class BufferedDocumentTester {
doc : BufferedDocument
pendingCommit : Object
doc: BufferedDocument
pendingCommit: Object
onMutationCalled: boolean
onRebaseCalled: boolean
onDeleteCalled: boolean
tap: Object

constructor(tap, attrs) {
this.doc = new BufferedDocument(attrs)
this.onRebaseCalled = false
Expand All @@ -19,7 +24,7 @@ export default class BufferedDocumentTester {
this.doc.onMutation = (edge, mutation) => {
this.onMutationCalled = true
}
this.doc.onDelete = (local) => {
this.doc.onDelete = local => {
this.onDeleteCalled = true
}
this.doc.commitHandler = opts => {
Expand Down Expand Up @@ -119,15 +124,27 @@ export default class BufferedDocumentTester {
return this
}
assertLOCAL(path, value) {
this.tap.same(extract(path, this.doc.LOCAL)[0], value, `assert value ${path} of LOCAL failed ${this.context}`)
this.tap.same(
extract(path, this.doc.LOCAL)[0],
value,
`assert value ${path} of LOCAL failed ${this.context}`
)
return this
}
assertEDGE(path, value) {
this.tap.same(extract(path, this.doc.document.EDGE)[0], value, `assert value ${path} of EDGE failed ${this.context}`)
this.tap.same(
extract(path, this.doc.document.EDGE)[0],
value,
`assert value ${path} of EDGE failed ${this.context}`
)
return this
}
assertHEAD(path, value) {
this.tap.same(extract(path, this.doc.document.HEAD)[0], value, `assert value ${path} of HEAD failed ${this.context}`)
this.tap.same(
extract(path, this.doc.document.HEAD)[0],
value,
`assert value ${path} of HEAD failed ${this.context}`
)
return this
}
assertALL(path, values) {
Expand All @@ -137,15 +154,24 @@ export default class BufferedDocumentTester {
return this
}
assertLOCALDeleted() {
this.tap.ok(this.doc.LOCAL === null, `LOCAL should be deleted ${this.context}`)
this.tap.ok(
this.doc.LOCAL === null,
`LOCAL should be deleted ${this.context}`
)
return this
}
assertEDGEDeleted() {
this.tap.ok(this.doc.document.EDGE === null, `EDGE should be deleted ${this.context}`)
this.tap.ok(
this.doc.document.EDGE === null,
`EDGE should be deleted ${this.context}`
)
return this
}
assertHEADDeleted() {
this.tap.ok(this.doc.document.HEAD === null, `HEAD should be deleted ${this.context}`)
this.tap.ok(
this.doc.document.HEAD === null,
`HEAD should be deleted ${this.context}`
)
return this
}
assertALLDeleted() {
Expand All @@ -154,6 +180,10 @@ export default class BufferedDocumentTester {
this.assertHEADDeleted()
return this
}
assert(cb) {
cb(this.tap, this.doc)
return this
}
didRebase() {
this.tap.ok(this.onRebaseCalled, `should rebase ${this.context}`)
return this
Expand All @@ -171,45 +201,83 @@ export default class BufferedDocumentTester {
return this
}
onDeleteDidFire() {
this.tap.ok(this.onDeleteCalled, `should fire onDelete event ${this.context}`)
this.tap.ok(
this.onDeleteCalled,
`should fire onDelete event ${this.context}`
)
return this
}
onDeleteDidNotFire() {
this.tap.notOk(this.onDeleteCalled, `should not fire onDelete event ${this.context}`)
this.tap.notOk(
this.onDeleteCalled,
`should not fire onDelete event ${this.context}`
)
return this
}
isConsistent() {
this.tap.ok(this.doc.document.isConsistent(), `should be consistent ${this.context}`)
this.tap.same(this.doc.document.EDGE, this.doc.document.HEAD, `HEAD and EDGE should be equal ${this.context}`)
this.tap.ok(
this.doc.document.isConsistent(),
`should be consistent ${this.context}`
)
this.tap.same(
this.doc.document.EDGE,
this.doc.document.HEAD,
`HEAD and EDGE should be equal ${this.context}`
)
return this
}
isInconsistent() {
this.tap.notOk(this.doc.document.isConsistent(), `should not be consistent ${this.context}`)
this.tap.notSame(this.doc.document.EDGE, this.doc.document.HEAD, `HEAD and EDGE should be different ${this.context}`)
this.tap.notOk(
this.doc.document.isConsistent(),
`should not be consistent ${this.context}`
)
this.tap.notSame(
this.doc.document.EDGE,
this.doc.document.HEAD,
`HEAD and EDGE should be different ${this.context}`
)
return this
}
hasUnresolvedLocalMutations() {
this.tap.ok(this.doc.document.anyUnresolvedMutations(), `should be unresolved local mutations ${this.context}`)
this.tap.ok(
this.doc.document.anyUnresolvedMutations(),
`should be unresolved local mutations ${this.context}`
)
return this
}
noUnresolvedLocalMutations() {
this.tap.notOk(this.doc.document.anyUnresolvedMutations(), `should be no unresolved local mutations ${this.context}`)
this.tap.notOk(
this.doc.document.anyUnresolvedMutations(),
`should be no unresolved local mutations ${this.context}`
)
return this
}
hasLocalEdits() {
this.tap.true(this.doc.buffer.hasChanges(), `should have local edits ${this.context}`)
this.tap.true(
this.doc.buffer.hasChanges(),
`should have local edits ${this.context}`
)
return this
}
hasNoLocalEdits() {
this.tap.false(this.doc.buffer.hasChanges(), `should not have local edits ${this.context}`)
this.tap.false(
this.doc.buffer.hasChanges(),
`should not have local edits ${this.context}`
)
return this
}
hasPendingCommit() {
this.tap.ok(this.doc.committerRunning, `should have pending commits ${this.context}`)
this.tap.ok(
this.doc.committerRunning,
`should have pending commits ${this.context}`
)
return this
}
hasNoPendingCommit() {
this.tap.notOk(this.doc.committerRunning, `should not have pending commits ${this.context}`)
this.tap.notOk(
this.doc.committerRunning,
`should not have pending commits ${this.context}`
)
return this
}
end() {
Expand Down

0 comments on commit 75d7b61

Please sign in to comment.