From acb7d7df5a85db3fc6b88b4d00be9215dfcef8ec Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 9 Jun 2020 16:30:03 +0100 Subject: [PATCH] [misc] add test cases for the validation of the callback argument When the user provides a function as last argument for socket.emit, socket.io will flag this as an RPC and add a cb as the last argument to the client.on('event', ...) handler on the server side. Without a function as last argument for socket.emit, the callback argument on the server side is undefined, leading to invalid function calls (`undefined()`) and an unhandled exception. The user can also provide lots of other arguments, so the 2nd/3rd ... argument is of arbitrary type, again leading to invalid function calls -- e.g. `1()`. --- services/real-time/app/coffee/Router.coffee | 1 + .../test/acceptance/coffee/RouterTests.coffee | 76 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 services/real-time/test/acceptance/coffee/RouterTests.coffee diff --git a/services/real-time/app/coffee/Router.coffee b/services/real-time/app/coffee/Router.coffee index 276c64e2dd..93cdd07926 100644 --- a/services/real-time/app/coffee/Router.coffee +++ b/services/real-time/app/coffee/Router.coffee @@ -26,6 +26,7 @@ module.exports = Router = logger.warn attrs, error.message, code: error.code return callback {message: error.message, code: error.code} if error.message == 'unexpected arguments' + # the payload might be very large, put it on level info logger.log attrs, 'unexpected arguments' metrics.inc 'unexpected-arguments', 1, { status: method } return callback { message: error.message } diff --git a/services/real-time/test/acceptance/coffee/RouterTests.coffee b/services/real-time/test/acceptance/coffee/RouterTests.coffee new file mode 100644 index 0000000000..c3952a2887 --- /dev/null +++ b/services/real-time/test/acceptance/coffee/RouterTests.coffee @@ -0,0 +1,76 @@ +async = require "async" +{expect} = require("chai") + +RealTimeClient = require "./helpers/RealTimeClient" +FixturesManager = require "./helpers/FixturesManager" + + +describe "Router", -> + describe "joinProject", -> + describe "when there is no callback provided", -> + after () -> + process.removeListener('unhandledRejection', @onUnhandled) + + before (done) -> + @onUnhandled = (error) -> + done(error) + process.on('unhandledRejection', @onUnhandled) + async.series [ + (cb) => + FixturesManager.setUpProject { + privilegeLevel: "owner" + project: { + name: "Test Project" + } + }, (e, {@project_id, @user_id}) => + cb(e) + + (cb) => + @client = RealTimeClient.connect() + @client.on "connectionAccepted", cb + + (cb) => + @client = RealTimeClient.connect() + @client.on "connectionAccepted", cb + + (cb) => + @client.emit "joinProject", project_id: @project_id + setTimeout(cb, 100) + ], done + + it "should keep on going", -> + expect('still running').to.exist + + describe "when there are too many arguments", -> + after () -> + process.removeListener('unhandledRejection', @onUnhandled) + + before (done) -> + @onUnhandled = (error) -> + done(error) + process.on('unhandledRejection', @onUnhandled) + async.series [ + (cb) => + FixturesManager.setUpProject { + privilegeLevel: "owner" + project: { + name: "Test Project" + } + }, (e, {@project_id, @user_id}) => + cb(e) + + (cb) => + @client = RealTimeClient.connect() + @client.on "connectionAccepted", cb + + (cb) => + @client = RealTimeClient.connect() + @client.on "connectionAccepted", cb + + (cb) => + @client.emit "joinProject", 1, 2, 3, 4, 5, (@error) => + cb() + ], done + + it "should return an error message", -> + expect(@error.message).to.equal('unexpected arguments')