diff --git a/services/real-time/test/acceptance/coffee/JoinDocTests.coffee b/services/real-time/test/acceptance/coffee/JoinDocTests.coffee
index a9d5406345..6c204b6079 100644
--- a/services/real-time/test/acceptance/coffee/JoinDocTests.coffee
+++ b/services/real-time/test/acceptance/coffee/JoinDocTests.coffee
@@ -166,4 +166,81 @@ describe "joinDoc", ->
 		it "should have joined the doc room", (done) ->
 			RealTimeClient.getConnectedClient @client.socket.sessionid, (error, client) =>
 				expect(@doc_id in client.rooms).to.equal true
-				done()
\ No newline at end of file
+				done()
+
+	describe "with options", ->
+		before (done) ->
+			@options = { encodeRanges: true }
+			async.series [
+				(cb) =>
+					FixturesManager.setUpProject {
+						privilegeLevel: "readAndWrite"
+					}, (e, {@project_id, @user_id}) =>
+						cb(e)
+
+				(cb) =>
+					FixturesManager.setUpDoc @project_id, {@lines, @version, @ops, @ranges}, (e, {@doc_id}) =>
+						cb(e)
+
+				(cb) =>
+					@client = RealTimeClient.connect()
+					@client.on "connectionAccepted", cb
+
+				(cb) =>
+					@client.emit "joinProject", project_id: @project_id, cb
+
+				(cb) =>
+					@client.emit "joinDoc", @doc_id, @options, (error, @returnedArgs...) => cb(error)
+			], done
+
+		it "should get the doc from the doc updater with the default fromVersion", ->
+			MockDocUpdaterServer.getDocument
+				.calledWith(@project_id, @doc_id, -1)
+				.should.equal true
+
+		it "should return the doc lines, version, ranges and ops", ->
+			@returnedArgs.should.deep.equal [@lines, @version, @ops, @ranges]
+
+		it "should have joined the doc room", (done) ->
+			RealTimeClient.getConnectedClient @client.socket.sessionid, (error, client) =>
+				expect(@doc_id in client.rooms).to.equal true
+				done()
+
+	describe "with fromVersion and options", ->
+		before (done) ->
+			@fromVersion = 36
+			@options = { encodeRanges: true }
+			async.series [
+				(cb) =>
+					FixturesManager.setUpProject {
+						privilegeLevel: "readAndWrite"
+					}, (e, {@project_id, @user_id}) =>
+						cb(e)
+
+				(cb) =>
+					FixturesManager.setUpDoc @project_id, {@lines, @version, @ops, @ranges}, (e, {@doc_id}) =>
+						cb(e)
+
+				(cb) =>
+					@client = RealTimeClient.connect()
+					@client.on "connectionAccepted", cb
+
+				(cb) =>
+					@client.emit "joinProject", project_id: @project_id, cb
+
+				(cb) =>
+					@client.emit "joinDoc", @doc_id, @fromVersion, @options, (error, @returnedArgs...) => cb(error)
+			], done
+
+		it "should get the doc from the doc updater with the fromVersion", ->
+			MockDocUpdaterServer.getDocument
+				.calledWith(@project_id, @doc_id, @fromVersion)
+				.should.equal true
+
+		it "should return the doc lines, version, ranges and ops", ->
+			@returnedArgs.should.deep.equal [@lines, @version, @ops, @ranges]
+
+		it "should have joined the doc room", (done) ->
+			RealTimeClient.getConnectedClient @client.socket.sessionid, (error, client) =>
+				expect(@doc_id in client.rooms).to.equal true
+				done()
diff --git a/services/real-time/test/unit/coffee/WebsocketControllerTests.coffee b/services/real-time/test/unit/coffee/WebsocketControllerTests.coffee
index 8db81b716e..a8a3841faf 100644
--- a/services/real-time/test/unit/coffee/WebsocketControllerTests.coffee
+++ b/services/real-time/test/unit/coffee/WebsocketControllerTests.coffee
@@ -221,49 +221,59 @@ describe 'WebsocketController', ->
 			@version = 42
 			@ops = ["mock", "ops"]
 			@ranges = { "mock": "ranges" }
+			@options = {}
 			
 			@client.params.project_id = @project_id
 			@AuthorizationManager.addAccessToDoc = sinon.stub()
 			@AuthorizationManager.assertClientCanViewProject = sinon.stub().callsArgWith(1, null)
 			@DocumentUpdaterManager.getDocument = sinon.stub().callsArgWith(3, null, @doc_lines, @version, @ranges, @ops)
-			
-		describe "with a fromVersion", ->
+
+		describe "works", ->
 			beforeEach ->
-				@fromVersion = 40
-				@WebsocketController.joinDoc @client, @doc_id, @fromVersion, @callback
-				
+				@WebsocketController.joinDoc @client, @doc_id, -1, @options, @callback
+
 			it "should check that the client is authorized to view the project", ->
 				@AuthorizationManager.assertClientCanViewProject
 					.calledWith(@client)
 					.should.equal true
-					
-			it "should get the document from the DocumentUpdaterManager", ->
+
+			it "should get the document from the DocumentUpdaterManager with fromVersion", ->
 				@DocumentUpdaterManager.getDocument
-					.calledWith(@project_id, @doc_id, @fromVersion)
+					.calledWith(@project_id, @doc_id, -1)
 					.should.equal true
 
 			it "should add permissions for the client to access the doc", ->
 				@AuthorizationManager.addAccessToDoc
 					.calledWith(@client, @doc_id)
 					.should.equal true
-					
+
 			it "should join the client to room for the doc_id", ->
 				@client.join
 					.calledWith(@doc_id)
 					.should.equal true
-					
+
 			it "should call the callback with the lines, version, ranges and ops", ->
 				@callback
 					.calledWith(null, @doc_lines, @version, @ops, @ranges)
 					.should.equal true
-					
+
 			it "should increment the join-doc metric", ->
 				@metrics.inc.calledWith("editor.join-doc").should.equal true
+
+		describe "with a fromVersion", ->
+			beforeEach ->
+				@fromVersion = 40
+				@WebsocketController.joinDoc @client, @doc_id, @fromVersion, @options, @callback
 					
+			it "should get the document from the DocumentUpdaterManager with fromVersion", ->
+				@DocumentUpdaterManager.getDocument
+					.calledWith(@project_id, @doc_id, @fromVersion)
+					.should.equal true
+
 		describe "with doclines that need escaping", ->
 			beforeEach ->
 				@doc_lines.push ["räksmörgås"]
-				@WebsocketController.joinDoc @client, @doc_id, -1, @callback
+				@WebsocketController.joinDoc @client, @doc_id, -1, @options, @callback
 						
 			it "should call the callback with the escaped lines", ->
 				escaped_lines = @callback.args[0][1]
@@ -271,11 +281,41 @@ describe 'WebsocketController', ->
 				escaped_word.should.equal 'räksmörgås'
 				# Check that unescaping works
 				decodeURIComponent(escape(escaped_word)).should.equal "räksmörgås"
-				
+
+		describe "with comments that need encoding", ->
+			beforeEach ->
+				@ranges.comments = [{ op: { c: "räksmörgås" } }]
+				@WebsocketController.joinDoc @client, @doc_id, -1, { encodeRanges: true }, @callback
+
+			it "should call the callback with the encoded comment", ->
+				encoded_comments = @callback.args[0][4]
+				encoded_comment = encoded_comments.comments.pop()
+				encoded_comment_text = encoded_comment.op.c
+				encoded_comment_text.should.equal 'räksmörgås'
+
+		describe "with changes that need encoding", ->
+			it "should call the callback with the encoded insert change", ->
+				@ranges.changes = [{ op: { i: "räksmörgås" } }]
+				@WebsocketController.joinDoc @client, @doc_id, -1, { encodeRanges: true }, @callback
+
+				encoded_changes = @callback.args[0][4]
+				encoded_change = encoded_changes.changes.pop()
+				encoded_change_text = encoded_change.op.i
+				encoded_change_text.should.equal 'räksmörgås'
+
+			it "should call the callback with the encoded delete change", ->
+				@ranges.changes = [{ op: { d: "räksmörgås" } }]
+				@WebsocketController.joinDoc @client, @doc_id, -1, { encodeRanges: true }, @callback
+
+				encoded_changes = @callback.args[0][4]
+				encoded_change = encoded_changes.changes.pop()
+				encoded_change_text = encoded_change.op.d
+				encoded_change_text.should.equal 'räksmörgås'
+
 		describe "when not authorized", ->
 			beforeEach ->
 				@AuthorizationManager.assertClientCanViewProject = sinon.stub().callsArgWith(1, @err = new Error("not authorized"))
-				@WebsocketController.joinDoc @client, @doc_id, -1, @callback
+				@WebsocketController.joinDoc @client, @doc_id, -1, @options, @callback
 				
 			it "should call the callback with an error", ->
 				@callback.calledWith(@err).should.equal true