2020-06-23 13:30:03 -04:00
|
|
|
/* eslint-disable
|
|
|
|
no-return-assign,
|
|
|
|
no-unused-vars,
|
|
|
|
*/
|
|
|
|
// TODO: This file was created by bulk-decaffeinate.
|
|
|
|
// Fix any style issues and re-enable lint.
|
2020-06-23 13:29:59 -04:00
|
|
|
/*
|
|
|
|
* decaffeinate suggestions:
|
|
|
|
* DS102: Remove unnecessary code created because of implicit returns
|
|
|
|
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
|
|
*/
|
2020-06-23 13:30:16 -04:00
|
|
|
const sinon = require('sinon')
|
|
|
|
const modulePath = '../../../app/js/WebApiManager.js'
|
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
const { CodedError } = require('../../../app/js/Errors')
|
2014-11-10 06:27:08 -05:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
describe('WebApiManager', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.project_id = 'project-id-123'
|
|
|
|
this.user_id = 'user-id-123'
|
|
|
|
this.user = { _id: this.user_id }
|
|
|
|
this.callback = sinon.stub()
|
|
|
|
return (this.WebApiManager = SandboxedModule.require(modulePath, {
|
|
|
|
requires: {
|
|
|
|
request: (this.request = {}),
|
2021-07-12 12:47:18 -04:00
|
|
|
'@overleaf/settings': (this.settings = {
|
2020-06-23 13:30:16 -04:00
|
|
|
apis: {
|
|
|
|
web: {
|
|
|
|
url: 'http://web.example.com',
|
|
|
|
user: 'username',
|
2021-07-13 07:04:45 -04:00
|
|
|
pass: 'password',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}),
|
|
|
|
},
|
2020-06-23 13:30:16 -04:00
|
|
|
}))
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
return describe('joinProject', function () {
|
|
|
|
describe('successfully', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.response = {
|
|
|
|
project: { name: 'Test project' },
|
|
|
|
privilegeLevel: 'owner',
|
2021-07-13 07:04:45 -04:00
|
|
|
isRestrictedUser: true,
|
2023-05-30 08:21:55 -04:00
|
|
|
isTokenMember: true,
|
|
|
|
isInvitedMember: true,
|
2020-06-23 13:30:16 -04:00
|
|
|
}
|
|
|
|
this.request.post = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { statusCode: 200 }, this.response)
|
|
|
|
return this.WebApiManager.joinProject(
|
|
|
|
this.project_id,
|
|
|
|
this.user,
|
|
|
|
this.callback
|
|
|
|
)
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
it('should send a request to web to join the project', function () {
|
|
|
|
return this.request.post
|
|
|
|
.calledWith({
|
|
|
|
url: `${this.settings.apis.web.url}/project/${this.project_id}/join`,
|
|
|
|
auth: {
|
|
|
|
user: this.settings.apis.web.user,
|
|
|
|
pass: this.settings.apis.web.pass,
|
2021-07-13 07:04:45 -04:00
|
|
|
sendImmediately: true,
|
2020-06-23 13:30:16 -04:00
|
|
|
},
|
2024-02-09 06:26:16 -05:00
|
|
|
json: {
|
|
|
|
userId: this.user_id,
|
|
|
|
anonymousAccessToken: undefined,
|
|
|
|
},
|
2020-06-23 13:30:16 -04:00
|
|
|
jar: false,
|
|
|
|
})
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
return it('should return the project, privilegeLevel, and restricted flag', function () {
|
|
|
|
return this.callback
|
|
|
|
.calledWith(
|
|
|
|
null,
|
|
|
|
this.response.project,
|
|
|
|
this.response.privilegeLevel,
|
2023-05-30 08:21:55 -04:00
|
|
|
{
|
|
|
|
isRestrictedUser: this.response.isRestrictedUser,
|
|
|
|
isTokenMember: this.response.isTokenMember,
|
|
|
|
isInvitedMember: this.response.isInvitedMember,
|
|
|
|
}
|
2020-06-23 13:30:16 -04:00
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2020-08-27 05:51:34 -04:00
|
|
|
|
2024-02-09 06:26:16 -05:00
|
|
|
describe('with anon user', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.user_id = 'anonymous-user'
|
|
|
|
this.token = 'a-ro-token'
|
|
|
|
this.user = {
|
|
|
|
_id: this.user_id,
|
|
|
|
anonymousAccessToken: this.token,
|
|
|
|
}
|
|
|
|
this.response = {
|
|
|
|
project: { name: 'Test project' },
|
|
|
|
privilegeLevel: 'readOnly',
|
|
|
|
isRestrictedUser: true,
|
|
|
|
isTokenMember: false,
|
|
|
|
isInvitedMember: false,
|
|
|
|
}
|
|
|
|
this.request.post = sinon
|
|
|
|
.stub()
|
|
|
|
.yields(null, { statusCode: 200 }, this.response)
|
|
|
|
this.WebApiManager.joinProject(
|
|
|
|
this.project_id,
|
|
|
|
this.user,
|
|
|
|
this.callback
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should send a request to web to join the project', function () {
|
|
|
|
this.request.post.should.have.been.calledWith({
|
|
|
|
url: `${this.settings.apis.web.url}/project/${this.project_id}/join`,
|
|
|
|
auth: {
|
|
|
|
user: this.settings.apis.web.user,
|
|
|
|
pass: this.settings.apis.web.pass,
|
|
|
|
sendImmediately: true,
|
|
|
|
},
|
|
|
|
json: {
|
|
|
|
userId: this.user_id,
|
|
|
|
anonymousAccessToken: this.token,
|
|
|
|
},
|
|
|
|
jar: false,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should return the project, privilegeLevel, and restricted flag', function () {
|
|
|
|
this.callback.should.have.been.calledWith(
|
|
|
|
null,
|
|
|
|
this.response.project,
|
|
|
|
this.response.privilegeLevel,
|
|
|
|
{
|
|
|
|
isRestrictedUser: this.response.isRestrictedUser,
|
|
|
|
isTokenMember: this.response.isTokenMember,
|
|
|
|
isInvitedMember: this.response.isInvitedMember,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2020-08-27 05:51:34 -04:00
|
|
|
describe('when web replies with a 403', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.request.post = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { statusCode: 403 }, null)
|
|
|
|
this.WebApiManager.joinProject(
|
|
|
|
this.project_id,
|
|
|
|
this.user_id,
|
|
|
|
this.callback
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should call the callback with an error', function () {
|
|
|
|
this.callback
|
|
|
|
.calledWith(
|
|
|
|
sinon.match({
|
2021-07-13 07:04:45 -04:00
|
|
|
message: 'not authorized',
|
2020-08-27 05:51:34 -04:00
|
|
|
})
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2020-08-27 06:39:25 -04:00
|
|
|
|
|
|
|
describe('when web replies with a 404', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.request.post = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { statusCode: 404 }, null)
|
|
|
|
this.WebApiManager.joinProject(
|
|
|
|
this.project_id,
|
|
|
|
this.user_id,
|
|
|
|
this.callback
|
|
|
|
)
|
|
|
|
})
|
|
|
|
|
|
|
|
it('should call the callback with an error', function () {
|
|
|
|
this.callback
|
|
|
|
.calledWith(
|
|
|
|
sinon.match({
|
2020-08-27 06:47:50 -04:00
|
|
|
message: 'project not found',
|
2021-07-13 07:04:45 -04:00
|
|
|
info: { code: 'ProjectNotFound' },
|
2020-08-27 06:39:25 -04:00
|
|
|
})
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
describe('with an error from web', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.request.post = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { statusCode: 500 }, null)
|
|
|
|
return this.WebApiManager.joinProject(
|
|
|
|
this.project_id,
|
|
|
|
this.user_id,
|
|
|
|
this.callback
|
|
|
|
)
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
return it('should call the callback with an error', function () {
|
|
|
|
return this.callback
|
|
|
|
.calledWith(
|
2020-08-20 07:03:54 -04:00
|
|
|
sinon.match({
|
|
|
|
message: 'non-success status code from web',
|
2021-07-13 07:04:45 -04:00
|
|
|
info: { statusCode: 500 },
|
2020-08-20 07:03:54 -04:00
|
|
|
})
|
2020-06-23 13:30:16 -04:00
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
describe('with no data from web', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.request.post = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { statusCode: 200 }, null)
|
|
|
|
return this.WebApiManager.joinProject(
|
|
|
|
this.project_id,
|
|
|
|
this.user_id,
|
|
|
|
this.callback
|
|
|
|
)
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
return it('should call the callback with an error', function () {
|
|
|
|
return this.callback
|
|
|
|
.calledWith(
|
|
|
|
sinon.match({
|
2021-07-13 07:04:45 -04:00
|
|
|
message: 'no data returned from joinProject request',
|
2020-06-23 13:30:16 -04:00
|
|
|
})
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
2019-10-30 09:52:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
return describe('when the project is over its rate limit', function () {
|
|
|
|
beforeEach(function () {
|
|
|
|
this.request.post = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { statusCode: 429 }, null)
|
|
|
|
return this.WebApiManager.joinProject(
|
|
|
|
this.project_id,
|
|
|
|
this.user_id,
|
|
|
|
this.callback
|
|
|
|
)
|
|
|
|
})
|
2019-08-31 09:04:36 -04:00
|
|
|
|
2020-06-23 13:30:16 -04:00
|
|
|
return it('should call the callback with a TooManyRequests error code', function () {
|
|
|
|
return this.callback
|
|
|
|
.calledWith(
|
|
|
|
sinon.match({
|
|
|
|
message: 'rate-limit hit when joining project',
|
2020-08-20 05:41:16 -04:00
|
|
|
info: {
|
2021-07-13 07:04:45 -04:00
|
|
|
code: 'TooManyRequests',
|
|
|
|
},
|
2020-06-23 13:30:16 -04:00
|
|
|
})
|
|
|
|
)
|
|
|
|
.should.equal(true)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|