overleaf/services/real-time/test/unit/js/WebApiManagerTests.js
Jakob Ackermann 385d3f9c1b Merge pull request #16980 from overleaf/jpa-join-project-remove-sl-2
[misc] joinProject: pass userId and anonymous access token in body 2/2

GitOrigin-RevId: b1a11941a6d9c7cc779769d1e97d3a0f03bed610
2024-02-13 09:03:39 +00:00

268 lines
7.6 KiB
JavaScript

/* eslint-disable
no-return-assign,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const sinon = require('sinon')
const modulePath = '../../../app/js/WebApiManager.js'
const SandboxedModule = require('sandboxed-module')
const { CodedError } = require('../../../app/js/Errors')
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 = {}),
'@overleaf/settings': (this.settings = {
apis: {
web: {
url: 'http://web.example.com',
user: 'username',
pass: 'password',
},
},
}),
},
}))
})
return describe('joinProject', function () {
describe('successfully', function () {
beforeEach(function () {
this.response = {
project: { name: 'Test project' },
privilegeLevel: 'owner',
isRestrictedUser: true,
isTokenMember: true,
isInvitedMember: true,
}
this.request.post = sinon
.stub()
.callsArgWith(1, null, { statusCode: 200 }, this.response)
return this.WebApiManager.joinProject(
this.project_id,
this.user,
this.callback
)
})
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,
sendImmediately: true,
},
json: {
userId: this.user_id,
anonymousAccessToken: undefined,
},
jar: false,
})
.should.equal(true)
})
return it('should return the project, privilegeLevel, and restricted flag', function () {
return this.callback
.calledWith(
null,
this.response.project,
this.response.privilegeLevel,
{
isRestrictedUser: this.response.isRestrictedUser,
isTokenMember: this.response.isTokenMember,
isInvitedMember: this.response.isInvitedMember,
}
)
.should.equal(true)
})
})
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,
}
)
})
})
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({
message: 'not authorized',
})
)
.should.equal(true)
})
})
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({
message: 'project not found',
info: { code: 'ProjectNotFound' },
})
)
.should.equal(true)
})
})
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
)
})
return it('should call the callback with an error', function () {
return this.callback
.calledWith(
sinon.match({
message: 'non-success status code from web',
info: { statusCode: 500 },
})
)
.should.equal(true)
})
})
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
)
})
return it('should call the callback with an error', function () {
return this.callback
.calledWith(
sinon.match({
message: 'no data returned from joinProject request',
})
)
.should.equal(true)
})
})
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
)
})
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',
info: {
code: 'TooManyRequests',
},
})
)
.should.equal(true)
})
})
})
})