Skip to content

Commit e773182

Browse files
committed
refactor(realtime): updateNote
Signed-off-by: BoHong Li <[email protected]>
1 parent 2dedc84 commit e773182

File tree

4 files changed

+378
-116
lines changed

4 files changed

+378
-116
lines changed

lib/realtime.js

Lines changed: 77 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -111,65 +111,96 @@ function disconnectSocketOnNote (note) {
111111
}
112112

113113
function updateNote (note, callback) {
114-
models.Note.findOne({
114+
_updateNoteAsync(note).then(_note => {
115+
callback(null, _note)
116+
}).catch((err) => {
117+
logger.error(err)
118+
return callback(err, null)
119+
})
120+
}
121+
122+
function findNoteByIdAsync (id) {
123+
return models.Note.findOne({
115124
where: {
116-
id: note.id
125+
id: id
117126
}
118-
}).then(function (_note) {
119-
if (!_note) return callback(null, null)
120-
// update user note history
121-
var tempUsers = Object.assign({}, note.tempUsers)
122-
note.tempUsers = {}
123-
Object.keys(tempUsers).forEach(function (key) {
124-
updateHistory(key, note, tempUsers[key])
125-
})
126-
if (note.lastchangeuser) {
127-
if (_note.lastchangeuserId !== note.lastchangeuser) {
128-
models.User.findOne({
129-
where: {
130-
id: note.lastchangeuser
131-
}
132-
}).then(function (user) {
133-
if (!user) return callback(null, null)
134-
note.lastchangeuserprofile = models.User.getProfile(user)
135-
return finishUpdateNote(note, _note, callback)
136-
}).catch(function (err) {
137-
logger.error(err)
138-
return callback(err, null)
139-
})
140-
} else {
141-
return finishUpdateNote(note, _note, callback)
142-
}
143-
} else {
144-
note.lastchangeuserprofile = null
145-
return finishUpdateNote(note, _note, callback)
127+
})
128+
}
129+
130+
function updateHistoryForEveryUserCollaborateNote (note) {
131+
// update history to every user in this note
132+
const tempUsers = Object.assign({}, note.tempUsers)
133+
note.tempUsers = {}
134+
// update history should async function, but in there return values is not matter
135+
Object.keys(tempUsers).forEach(function (key) {
136+
exports.updateHistory(key, note, tempUsers[key])
137+
})
138+
}
139+
140+
async function getUserProfileByIdAsync (id) {
141+
const user = await models.User.findOne({
142+
where: {
143+
id: id
146144
}
147-
}).catch(function (err) {
148-
logger.error(err)
149-
return callback(err, null)
150145
})
146+
if (!user) return null
147+
return models.User.getProfile(user)
148+
}
149+
150+
class UserNotFoundException extends Error {
151+
constructor () {
152+
super('user not found')
153+
this.name = this.constructor.name
154+
Error.captureStackTrace(this, this.constructor)
155+
}
151156
}
152157

153-
function finishUpdateNote (note, _note, callback) {
154-
if (!note || !note.server) return callback(null, null)
155-
var body = note.server.document
156-
var title = note.title = models.Note.parseNoteTitle(body)
157-
var values = {
158+
async function getLastChangeUserProfileAsync (currentLastChangeUserId, lastChangeUserIdInDatabase, lastChangeUserProfileInDatabase) {
159+
if (!currentLastChangeUserId) return null
160+
if (currentLastChangeUserId === lastChangeUserIdInDatabase) return lastChangeUserProfileInDatabase
161+
const profile = await getUserProfileByIdAsync(currentLastChangeUserId)
162+
if (!profile) {
163+
throw new UserNotFoundException()
164+
}
165+
return profile
166+
}
167+
168+
function buildNoteUpdateData (note) {
169+
const body = note.server.document
170+
const title = note.title = models.Note.parseNoteTitle(body)
171+
return {
158172
title: title,
159173
content: body,
160174
authorship: note.authorship,
161175
lastchangeuserId: note.lastchangeuser,
162176
lastchangeAt: Date.now()
163177
}
164-
_note.update(values).then(function (_note) {
165-
saveRevisionJob.setSaverSleep(false)
166-
return callback(null, _note)
167-
}).catch(function (err) {
168-
logger.error(err)
169-
return callback(err, null)
170-
})
171178
}
172179

180+
async function _updateNoteAsync (note) {
181+
let noteModel = await findNoteByIdAsync(note.id)
182+
if (!noteModel) return null
183+
184+
updateHistoryForEveryUserCollaborateNote(note)
185+
186+
try {
187+
note.lastchangeuserprofile = await getLastChangeUserProfileAsync(
188+
note.lastchangeuser,
189+
noteModel.lastchangeuserId,
190+
noteModel.lastchangeuserprofile
191+
)
192+
} catch (err) {
193+
if (err instanceof UserNotFoundException) {
194+
return null
195+
}
196+
throw err
197+
}
198+
199+
if (!note || !note.server) return null
200+
noteModel = await noteModel.update(buildNoteUpdateData(note))
201+
saveRevisionJob.setSaverSleep(false)
202+
return noteModel
203+
}
173204

174205
function getStatus (callback) {
175206
models.Note.count().then(function (notecount) {
@@ -776,7 +807,6 @@ exports = module.exports = realtime
776807
exports.extractNoteIdFromSocket = extractNoteIdFromSocket
777808
exports.parseNoteIdFromSocket = parseNoteIdFromSocket
778809
exports.updateNote = updateNote
779-
exports.finishUpdateNote = finishUpdateNote
780810
exports.failConnection = failConnection
781811
exports.isDuplicatedInSocketQueue = isDuplicatedInSocketQueue
782812
exports.updateUserData = updateUserData
@@ -794,6 +824,7 @@ exports.disconnectSocketOnNote = disconnectSocketOnNote
794824
exports.queueForDisconnect = queueForDisconnect
795825
exports.terminate = terminate
796826
exports.getUserPool = getUserPool
827+
exports.updateHistory = updateHistory
797828
exports.disconnectProcessQueue = disconnectProcessQueue
798829
exports.notes = notes
799830
exports.users = users

test/realtime/realtime.test.js

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -37,76 +37,6 @@ function removeModuleFromRequireCache (modulePath) {
3737
}
3838

3939
describe('realtime', function () {
40-
describe('updateNote', function () {
41-
let realtime, fakeNote
42-
beforeEach(() => {
43-
mock('../../lib/logger', {
44-
error: () => {
45-
}
46-
})
47-
mock('../../lib/history', {})
48-
mock('../../lib/models', {
49-
Note: {
50-
findOne: async function () {
51-
return fakeNote
52-
}
53-
}
54-
})
55-
mock('../../lib/config', {})
56-
})
57-
58-
afterEach(() => {
59-
mock.stopAll()
60-
})
61-
62-
it('should return null when note not found', function (done) {
63-
fakeNote = null
64-
realtime = require('../../lib/realtime')
65-
66-
sinon.stub(realtime, 'finishUpdateNote').callsFake(function (a, b, callback) {
67-
callback(null, b)
68-
})
69-
70-
const fakeCallback = sinon.fake()
71-
realtime.updateNote({ id: '123' }, fakeCallback)
72-
setTimeout(() => {
73-
assert.ok(fakeCallback.called)
74-
assert.deepStrictEqual(fakeCallback.getCall(0).args, [null, null])
75-
sinon.restore()
76-
done()
77-
}, 50)
78-
})
79-
})
80-
81-
describe('finishUpdateNote', function () {
82-
let realtime
83-
beforeEach(() => {
84-
mock('../../lib/logger', {})
85-
mock('../../lib/history', {})
86-
mock('../../lib/models', {
87-
Note: {
88-
parseNoteTitle: (data) => (data)
89-
}
90-
})
91-
mock('../../lib/config', {})
92-
realtime = require('../../lib/realtime')
93-
})
94-
95-
afterEach(() => {
96-
removeModuleFromRequireCache('../../lib/realtime')
97-
mock.stopAll()
98-
})
99-
100-
it('return null when note is null', () => {
101-
const fakeCallback = sinon.fake()
102-
103-
realtime.finishUpdateNote(null, {}, fakeCallback)
104-
105-
assert.ok(fakeCallback.calledOnce)
106-
assert.deepStrictEqual(fakeCallback.lastCall.args, [null, null])
107-
})
108-
})
109-
11040
describe('connection', function () {
11141
let realtime
11242
beforeEach(() => {

0 commit comments

Comments
 (0)