mirror of
https://github.com/overleaf/overleaf.git
synced 2025-04-11 01:57:23 +00:00
Add in clientTracking.updatePosition end point
This commit is contained in:
parent
84778b5961
commit
e769819521
6 changed files with 188 additions and 20 deletions
|
@ -5,6 +5,16 @@ HttpController = require "./HttpController"
|
|||
Utils = require "./Utils"
|
||||
|
||||
module.exports = Router =
|
||||
_handleError: (callback, error, client, method, extraAttrs = {}) ->
|
||||
Utils.getClientAttributes client, ["project_id", "doc_id", "user_id"], (_, attrs) ->
|
||||
for key, value of extraAttrs
|
||||
attrs[key] = value
|
||||
attrs.client_id = client.id
|
||||
attrs.err = error
|
||||
logger.error attrs, "server side error in #{method}"
|
||||
# Don't return raw error to prevent leaking server side info
|
||||
return callback {message: "Something went wrong"}
|
||||
|
||||
configure: (app, io, session) ->
|
||||
app.set("io", io)
|
||||
app.get "/clients", HttpController.getConnectedClients
|
||||
|
@ -29,9 +39,7 @@ module.exports = Router =
|
|||
client.on "joinProject", (data = {}, callback) ->
|
||||
WebsocketController.joinProject client, user, data.project_id, (err, args...) ->
|
||||
if err?
|
||||
logger.error {err, user_id: user?.id, project_id: data.project_id}, "server side error in joinProject"
|
||||
# Don't return raw error to prevent leaking server side info
|
||||
return callback {message: "Something went wrong"}
|
||||
Router._handleError callback, err, client, "joinProject", {project_id: data.project_id, user_id: user?.id}
|
||||
else
|
||||
callback(null, args...)
|
||||
|
||||
|
@ -44,30 +52,27 @@ module.exports = Router =
|
|||
|
||||
WebsocketController.joinDoc client, doc_id, fromVersion, (err, args...) ->
|
||||
if err?
|
||||
Utils.getClientAttributes client, ["project_id", "user_id"], (_, {project_id, user_id}) ->
|
||||
logger.error {err, client_id: client.id, user_id, project_id, doc_id, fromVersion}, "server side error in joinDoc"
|
||||
# Don't return raw error to prevent leaking server side info
|
||||
return callback {message: "Something went wrong"}
|
||||
Router._handleError callback, err, client, "joinDoc", {doc_id, fromVersion}
|
||||
else
|
||||
callback(null, args...)
|
||||
|
||||
client.on "leaveDoc", (doc_id, callback) ->
|
||||
WebsocketController.leaveDoc client, doc_id, (err, args...) ->
|
||||
if err?
|
||||
Utils.getClientAttributes client, ["project_id", "user_id"], (_, {project_id, user_id}) ->
|
||||
logger.error {err, client_id: client.id, user_id, project_id, doc_id}, "server side error in leaveDoc"
|
||||
# Don't return raw error to prevent leaking server side info
|
||||
return callback {message: "Something went wrong"}
|
||||
Router._handleError callback, err, client, "leaveDoc"
|
||||
else
|
||||
callback(null, args...)
|
||||
|
||||
client.on "getConnectedUsers", (callback = (error, users) ->) ->
|
||||
client.on "clientTracking.getConnectedUsers", (callback = (error, users) ->) ->
|
||||
WebsocketController.getConnectedUsers client, (err, users) ->
|
||||
if err?
|
||||
Utils.getClientAttributes client, ["project_id", "user_id", "doc_id"], (_, {project_id, user_id, doc_id}) ->
|
||||
logger.error {err, client_id: client.id, user_id, project_id, doc_id}, "server side error in getConnectedUsers"
|
||||
# Don't return raw error to prevent leaking server side info
|
||||
return callback {message: "Something went wrong"}
|
||||
Router._handleError callback, err, client, "clientTracking.getConnectedUsers"
|
||||
else
|
||||
callback(null, users)
|
||||
|
||||
|
||||
client.on "clientTracking.updatePosition", (cursorData, callback = (error) ->) ->
|
||||
WebsocketController.updateClientPosition client, cursorData, (err) ->
|
||||
if err?
|
||||
Router._handleError callback, err, client, "clientTracking.updatePosition"
|
||||
else
|
||||
callback()
|
|
@ -70,7 +70,37 @@ module.exports = WebsocketController =
|
|||
client.leave doc_id
|
||||
callback()
|
||||
|
||||
updateClientPosition: (client, cursorData, callback = (error) ->) ->
|
||||
Utils.getClientAttributes client, [
|
||||
"project_id", "first_name", "last_name", "email", "user_id"
|
||||
], (error, {project_id, first_name, last_name, email, user_id}) ->
|
||||
return callback(error) if error?
|
||||
logger.log {user_id, project_id, client_id: client.id, cursorData: cursorData}, "updating client position"
|
||||
cursorData.id = client.id
|
||||
cursorData.user_id = user_id if user_id?
|
||||
cursorData.email = email if email?
|
||||
if first_name? and last_name?
|
||||
cursorData.name = first_name + " " + last_name
|
||||
ConnectedUsersManager.updateUserPosition(project_id, client.id, {
|
||||
first_name: first_name,
|
||||
last_name: last_name,
|
||||
email: email,
|
||||
user_id: user_id
|
||||
}, {
|
||||
row: cursorData.row,
|
||||
column: cursorData.column,
|
||||
doc_id: cursorData.doc_id
|
||||
}, callback)
|
||||
else
|
||||
cursorData.name = "Anonymous"
|
||||
callback()
|
||||
#EditorRealTimeController.emitToRoom(project_id, "clientTracking.clientUpdated", cursorData)
|
||||
#callback()
|
||||
|
||||
getConnectedUsers: (client, callback = (error, users) ->) ->
|
||||
Utils.getClientAttributes client, ["project_id", "user_id"], (error, {project_id, user_id}) ->
|
||||
logger.log {user_id, project_id, client_id: client.id}, "getting connected users"
|
||||
|
||||
AuthorizationManager.assertClientCanViewProject client, (error) ->
|
||||
return callback(error) if error?
|
||||
client.get "project_id", (error, project_id) ->
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
chai = require("chai")
|
||||
expect = chai.expect
|
||||
chai.should()
|
||||
|
||||
RealTimeClient = require "./helpers/RealTimeClient"
|
||||
MockWebServer = require "./helpers/MockWebServer"
|
||||
FixturesManager = require "./helpers/FixturesManager"
|
||||
|
||||
describe "clientTracking", ->
|
||||
before (done) ->
|
||||
FixturesManager.setUpProject {
|
||||
privilegeLevel: "owner"
|
||||
project: {
|
||||
name: "Test Project"
|
||||
}
|
||||
}, (error, data) =>
|
||||
throw error if error?
|
||||
{@user_id, @project_id} = data
|
||||
@clientA = RealTimeClient.connect()
|
||||
@clientB = RealTimeClient.connect()
|
||||
@clientA.emit "joinProject", {
|
||||
project_id: @project_id
|
||||
}, (error) =>
|
||||
throw error if error?
|
||||
@clientB.emit "joinProject", {
|
||||
project_id: @project_id
|
||||
}, (error) =>
|
||||
throw error if error?
|
||||
done()
|
||||
|
||||
describe "when a client updates its cursor location", ->
|
||||
before (done) ->
|
||||
@updates = []
|
||||
@clientB.on "clientTracking.clientUpdated", (data) ->
|
||||
@updates.push data
|
||||
|
||||
@clientA.emit "clientTracking.updatePosition", {
|
||||
row: @row = 42
|
||||
column: @column = 36
|
||||
doc_id: @doc_id = "mock-doc-id"
|
||||
}, (error) ->
|
||||
throw error if error?
|
||||
done()
|
||||
|
||||
it "should tell other clients about the update"
|
||||
|
||||
it "should record the update in getConnectedUsers", (done) ->
|
||||
@clientB.emit "clientTracking.getConnectedUsers", (error, users) =>
|
||||
for user in users
|
||||
if user.client_id == @clientA.socket.sessionid
|
||||
expect(user.cursorData).to.deep.equal({
|
||||
row: @row
|
||||
column: @column
|
||||
doc_id: @doc_id
|
||||
})
|
||||
return done()
|
||||
throw new Error("user was never found")
|
||||
|
||||
|
||||
describe "anonymous users", ->
|
||||
it "should test something..."
|
|
@ -47,7 +47,7 @@ describe "joinProject", ->
|
|||
done()
|
||||
|
||||
it "should have marked the user as connected", (done) ->
|
||||
@client.emit "getConnectedUsers", (error, users) =>
|
||||
@client.emit "clientTracking.getConnectedUsers", (error, users) =>
|
||||
connected = false
|
||||
for user in users
|
||||
if user.client_id == @client.socket.sessionid and user.user_id == @user_id
|
||||
|
|
|
@ -16,7 +16,11 @@ module.exports = FixturesManager =
|
|||
MockWebServer.run (error) =>
|
||||
throw error if error?
|
||||
RealTimeClient.setSession {
|
||||
user: { _id: user_id }
|
||||
user: {
|
||||
_id: user_id
|
||||
first_name: "Joe"
|
||||
last_name: "Bloggs"
|
||||
}
|
||||
}, (error) =>
|
||||
throw error if error?
|
||||
callback null, {project_id, user_id, privilegeLevel, project}
|
||||
|
|
|
@ -217,4 +217,72 @@ describe 'WebsocketController', ->
|
|||
it "should return an error", ->
|
||||
@callback.calledWith(@err).should.equal true
|
||||
|
||||
|
||||
describe "updateClientPosition", ->
|
||||
beforeEach ->
|
||||
#@EditorRealTimeController.emitToRoom = sinon.stub()
|
||||
@ConnectedUsersManager.updateUserPosition = sinon.stub().callsArgWith(4)
|
||||
@update = {
|
||||
doc_id: @doc_id = "doc-id-123"
|
||||
row: @row = 42
|
||||
column: @column = 37
|
||||
}
|
||||
|
||||
describe "with a logged in user", ->
|
||||
beforeEach ->
|
||||
@clientParams = {
|
||||
project_id: @project_id
|
||||
first_name: @first_name = "Douglas"
|
||||
last_name: @last_name = "Adams"
|
||||
email: @email = "joe@example.com"
|
||||
user_id: @user_id = "user-id-123"
|
||||
}
|
||||
@client.get = (param, callback) => callback null, @clientParams[param]
|
||||
@WebsocketController.updateClientPosition @client, @update
|
||||
|
||||
@populatedCursorData =
|
||||
doc_id: @doc_id,
|
||||
id: @client.id
|
||||
name: "#{@first_name} #{@last_name}"
|
||||
row: @row
|
||||
column: @column
|
||||
email: @email
|
||||
user_id: @user_id
|
||||
|
||||
# it "should send the update to the project room with the user's name", ->
|
||||
# @EditorRealTimeController.emitToRoom.calledWith(@project_id, "clientTracking.clientUpdated", @populatedCursorData).should.equal true
|
||||
|
||||
it "should send the cursor data to the connected user manager", (done)->
|
||||
@ConnectedUsersManager.updateUserPosition.calledWith(@project_id, @client.id, {
|
||||
user_id: @user_id,
|
||||
email: @email,
|
||||
first_name: @first_name,
|
||||
last_name: @last_name
|
||||
}, {
|
||||
row: @row
|
||||
column: @column
|
||||
doc_id: @doc_id
|
||||
}).should.equal true
|
||||
done()
|
||||
|
||||
describe "with an anonymous user", ->
|
||||
beforeEach ->
|
||||
@clientParams = {
|
||||
project_id: @project_id
|
||||
}
|
||||
@client.get = (param, callback) => callback null, @clientParams[param]
|
||||
@WebsocketController.updateClientPosition @client, @update
|
||||
|
||||
# it "should send the update to the project room with an anonymous name", ->
|
||||
# @EditorRealTimeController.emitToRoom
|
||||
# .calledWith(@project_id, "clientTracking.clientUpdated", {
|
||||
# doc_id: @doc_id,
|
||||
# id: @client.id
|
||||
# name: "Anonymous"
|
||||
# row: @row
|
||||
# column: @column
|
||||
# })
|
||||
# .should.equal true
|
||||
|
||||
it "should not send cursor data to the connected user manager", (done)->
|
||||
@ConnectedUsersManager.updateUserPosition.called.should.equal false
|
||||
done()
|
Loading…
Add table
Reference in a new issue