diff --git a/app/coffee/Features/User/UserGetter.coffee b/app/coffee/Features/User/UserGetter.coffee index 59e45e179562acee037ea2da459ea20352ed6a18..21969656a033a5de35f065de071e891cc4e0a554 100644 --- a/app/coffee/Features/User/UserGetter.coffee +++ b/app/coffee/Features/User/UserGetter.coffee @@ -3,6 +3,8 @@ metrics = require('metrics-sharelatex') logger = require('logger-sharelatex') db = mongojs.db ObjectId = mongojs.ObjectId +settings = require "settings-sharelatex" +request = require "request" module.exports = UserGetter = getUser: (query, projection, callback = (error, user) ->) -> @@ -30,11 +32,9 @@ module.exports = UserGetter = return callback error if error? return callback new Error('User not Found') unless user - fullEmails = user.emails.map (emailData) -> - emailData.default = emailData.email == user.email - emailData - - callback null, fullEmails + getAffiliations userId, (error, affiliationsData) -> + return callback error if error? + callback null, decorateFullEmails(user.email, user.emails, affiliationsData) getUserByMainEmail: (email, projection, callback = (error, user) ->) -> email = email.trim() @@ -81,6 +81,35 @@ module.exports = UserGetter = return callback(message: 'alread_exists') if user? callback(error) +decorateFullEmails = (defaultEmail, emailsData, affiliationsData) -> + emailsData.map (emailData) -> + emailData.default = emailData.email == defaultEmail + + affiliation = affiliationsData.find (aff) -> aff.email == emailData.email + if affiliation? + { institution, inferred, role, department } = affiliation + emailData.affiliation = { institution, inferred, role, department } + else + emailsData.affiliation = null + + emailData + +getAffiliations = (userId, callback = (error) ->) -> + return callback(null, []) unless settings?.apis?.v1?.url # service is not configured + request { + method: 'GET' + url: "#{settings.apis.v1.url}/api/v2/users/#{userId.toString()}/affiliations" + auth: { user: settings.apis.v1.user, pass: settings.apis.v1.pass } + json: true, + timeout: 20 * 1000 + }, (error, response, body) -> + return callback(error) if error? + unless 200 <= response.statusCode < 300 + errorMessage = "Couldn't get affiliations: #{response.statusCode}" + return callback(new Error(errorMessage)) + + callback(null, body) + [ 'getUser', 'getUserEmail', diff --git a/test/acceptance/coffee/helpers/MockV1Api.coffee b/test/acceptance/coffee/helpers/MockV1Api.coffee index 65a77eb0e423aee03c95f6bc26e98855c7256bd3..91e3f0b25ce6c2a6dcf0e6481d37c2cbafebd32c 100644 --- a/test/acceptance/coffee/helpers/MockV1Api.coffee +++ b/test/acceptance/coffee/helpers/MockV1Api.coffee @@ -42,6 +42,9 @@ module.exports = MockV1Api = @exportParams = Object.assign({}, req.body) res.json exportId: @exportId + app.get "/api/v2/users/:userId/affiliations", (req, res, next) => + res.json [] + app.post "/api/v2/users/:userId/affiliations", (req, res, next) => res.sendStatus 201 diff --git a/test/unit/coffee/User/UserGetterTests.coffee b/test/unit/coffee/User/UserGetterTests.coffee index f2b7895b575920ab296d15b0687b634acda1c401..6b80b5a2a7a03f910783f7a691f4bcfd72f06536 100644 --- a/test/unit/coffee/User/UserGetterTests.coffee +++ b/test/unit/coffee/User/UserGetterTests.coffee @@ -20,11 +20,15 @@ describe "UserGetter", -> @Mongo = db: users: findOne: @findOne ObjectId: (id) -> return id + settings = apis: { v1: { url: 'v1.url', user: '', pass: '' } } + @request = sinon.stub() @UserGetter = SandboxedModule.require modulePath, requires: "logger-sharelatex": log:-> "../../infrastructure/mongojs": @Mongo "metrics-sharelatex": timeAsyncMethod: sinon.stub() + 'settings-sharelatex': settings + 'request': @request describe "getUser", -> it "should get user", (done)-> @@ -42,6 +46,9 @@ describe "UserGetter", -> done() describe "getUserFullEmails", - + beforeEach -> + @request.callsArgWith(1, null, { statusCode: 200 }, []) + it "should get user", (done)-> @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @fakeUser) projection = email: 1, emails: 1 @@ -59,6 +66,33 @@ describe "UserGetter", -> ] done() + it "should merge affiliation data", (done)-> + @UserGetter.getUser = sinon.stub().callsArgWith(2, null, @fakeUser) + affiliationsData = [ + { + email: 'email1@foo.bar' + role: 'Prof' + department: 'Maths' + inferred: false + institution: { name: 'University Name', isUniversity: true } + } + ] + @request.callsArgWith(1, null, { statusCode: 200 }, affiliationsData) + @UserGetter.getUserFullEmails @fakeUser._id, (error, fullEmails) => + assert.deepEqual fullEmails, [ + { + email: 'email1@foo.bar' + default: false + affiliation: + institution: affiliationsData[0].institution + inferred: affiliationsData[0].inferred + department: affiliationsData[0].department + role: affiliationsData[0].role + } + { email: 'email2@foo.bar', default: true } + ] + done() + describe "getUserbyMainEmail", -> it "query user by main email", (done)-> email = 'hello@world.com'