mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-26 12:50:31 -04:00
Add school and teacher names to invite email context
This commit is contained in:
parent
0ed99565d3
commit
f7a6d354af
8 changed files with 89 additions and 42 deletions
app
server
spec/server
|
@ -91,3 +91,10 @@ module.exports = class Classroom extends CocoModel
|
|||
url: _.result(courseInstance, 'url') + '/classroom'
|
||||
})
|
||||
@fetch(options)
|
||||
|
||||
inviteMembers: (emails, options={}) ->
|
||||
options.data ?= {}
|
||||
options.data.email = emails
|
||||
options.url = @url() + '/invite-members'
|
||||
options.type = 'POST'
|
||||
@fetch(options)
|
||||
|
|
|
@ -20,17 +20,12 @@ module.exports = class InviteToClassroomModal extends ModalView
|
|||
emails = _.filter((_.string.trim(email) for email in emails))
|
||||
if not emails.length
|
||||
return
|
||||
url = @classroom.url() + '/invite-members'
|
||||
|
||||
@$('#send-invites-btn, #invite-emails-textarea').addClass('hide')
|
||||
@$('#invite-emails-sending-alert').removeClass('hide')
|
||||
application.tracker?.trackEvent 'Classroom invite via email', category: 'Courses', classroomID: @classroom.id, emails: emails
|
||||
|
||||
$.ajax({
|
||||
url: url
|
||||
data: {emails: emails}
|
||||
method: 'POST'
|
||||
context: @
|
||||
success: ->
|
||||
@classroom.inviteMembers(emails, {
|
||||
success: =>
|
||||
@$('#invite-emails-sending-alert').addClass('hide')
|
||||
@$('#invite-emails-success-alert').removeClass('hide')
|
||||
})
|
||||
|
|
|
@ -94,26 +94,6 @@ ClassroomHandler = class ClassroomHandler extends Handler
|
|||
return doc.toObject()
|
||||
return _.omit(doc.toObject(), 'code', 'codeCamel')
|
||||
|
||||
inviteStudents: (req, res, classroomID) ->
|
||||
if not req.body.emails
|
||||
return @sendBadInputError(res, 'Emails not included')
|
||||
|
||||
Classroom.findById classroomID, (err, classroom) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
return @sendNotFoundError(res) unless classroom
|
||||
return @sendForbiddenError(res) unless classroom.get('ownerID').equals(req.user.get('_id'))
|
||||
|
||||
for email in req.body.emails
|
||||
context =
|
||||
email_id: sendwithus.templates.course_invite_email
|
||||
recipient:
|
||||
address: email
|
||||
email_data:
|
||||
class_name: classroom.get('name')
|
||||
join_link: "https://codecombat.com/courses?_cc=" + (classroom.get('codeCamel') or classroom.get('code'))
|
||||
sendwithus.api.send context, _.noop
|
||||
return @sendSuccess(res, {})
|
||||
|
||||
get: (req, res) ->
|
||||
if ownerID = req.query.ownerID
|
||||
return @sendForbiddenError(res) unless req.user and (req.user.isAdmin() or ownerID is req.user.id)
|
||||
|
|
|
@ -12,6 +12,8 @@ Level = require '../models/Level'
|
|||
parse = require '../commons/parse'
|
||||
LevelSession = require '../models/LevelSession'
|
||||
User = require '../models/User'
|
||||
TrialRequest = require '../models/TrialRequest'
|
||||
sendwithus = require '../sendwithus'
|
||||
|
||||
module.exports =
|
||||
getByOwner: wrap (req, res, next) ->
|
||||
|
@ -141,3 +143,33 @@ module.exports =
|
|||
database.validateDoc(classroom)
|
||||
classroom = yield classroom.save()
|
||||
res.status(201).send(classroom.toObject({req: req}))
|
||||
|
||||
inviteMembers: wrap (req, res) ->
|
||||
if not req.body.emails
|
||||
throw new errors.UnprocessableEntity('Emails not included')
|
||||
|
||||
classroom = yield database.getDocFromHandle(req, Classroom)
|
||||
if not classroom
|
||||
throw new errors.NotFound('Classroom not found.')
|
||||
|
||||
unless classroom.get('ownerID').equals(req.user?._id)
|
||||
throw new errors.Forbidden('Must be owner of classroom to send invites.')
|
||||
|
||||
user = req.user
|
||||
teacherName = user.get('name')
|
||||
teacherName ?= _.filter([user.get('firstName'), user.get('lastName')]).join(' ')
|
||||
trialRequest = yield TrialRequest.findOne({applicant: user._id})
|
||||
schoolName = trialRequest?.get('properties')?.organization
|
||||
|
||||
for email in req.body.emails
|
||||
context =
|
||||
email_id: sendwithus.templates.course_invite_email
|
||||
recipient:
|
||||
address: email
|
||||
email_data:
|
||||
class_name: classroom.get('name')
|
||||
teacher_name: teacherName
|
||||
school_name: schoolName
|
||||
join_link: "https://codecombat.com/courses?_cc=" + (classroom.get('codeCamel') or classroom.get('code'))
|
||||
sendwithus.api.send context, _.noop
|
||||
res.status(200).send({})
|
||||
|
|
|
@ -58,6 +58,7 @@ module.exports.setup = (app) ->
|
|||
app.get('/db/classroom', mw.classrooms.getByOwner)
|
||||
app.get('/db/classroom/:handle/levels', mw.classrooms.fetchAllLevels)
|
||||
app.get('/db/classroom/:handle/courses/:courseID/levels', mw.classrooms.fetchLevelsForCourse)
|
||||
app.post('/db/classroom/:handle/invite-members', mw.classrooms.inviteMembers)
|
||||
app.get('/db/classroom/:handle/member-sessions', mw.classrooms.fetchMemberSessions)
|
||||
app.get('/db/classroom/:handle/members', mw.classrooms.fetchMembers) # TODO: Use mw.auth?
|
||||
app.get('/db/classroom/:handle', mw.auth.checkLoggedIn()) # TODO: Finish migrating route, adding now so 401 is returned
|
||||
|
|
|
@ -9,7 +9,7 @@ module.exports.setupRoutes = (app) ->
|
|||
debug = not config.isProduction
|
||||
module.exports.api =
|
||||
send: (context, cb) ->
|
||||
log.debug('Tried to send email with context: ', JSON.stringify(context, null, '\t'))
|
||||
log.debug('Tried to send email with context: ', JSON.stringify(context, null, ' '))
|
||||
setTimeout(cb, 10)
|
||||
|
||||
if swuAPIKey
|
||||
|
|
|
@ -355,18 +355,22 @@ describe 'DELETE /db/classroom/:id/members', ->
|
|||
|
||||
describe 'POST /db/classroom/:id/invite-members', ->
|
||||
|
||||
it 'takes a list of emails and sends invites', (done) ->
|
||||
loginNewUser (user1) ->
|
||||
user1.set('role', 'teacher')
|
||||
user1.save (err) ->
|
||||
data = { name: 'Classroom 6' }
|
||||
request.post {uri: classroomsURL, json: data }, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(201)
|
||||
url = classroomsURL + '/' + body._id + '/invite-members'
|
||||
data = { emails: ['test@test.com'] }
|
||||
request.post { uri: url, json: data }, (err, res, body) ->
|
||||
expect(res.statusCode).toBe(200)
|
||||
done()
|
||||
it 'takes a list of emails and sends invites', utils.wrap (done) ->
|
||||
user = yield utils.initUser({role: 'teacher', name: 'Mr Professerson'})
|
||||
yield utils.loginUser(user)
|
||||
yield utils.makeTrialRequest({ properties: { organization: 'Greendale' } })
|
||||
classroom = yield utils.makeClassroom()
|
||||
url = classroomsURL + "/#{classroom.id}/invite-members"
|
||||
data = { emails: ['test@test.com'] }
|
||||
sendwithus = require '../../../server/sendwithus'
|
||||
spyOn(sendwithus.api, 'send').and.callFake (context, cb) ->
|
||||
expect(context.email_id).toBe(sendwithus.templates.course_invite_email)
|
||||
expect(context.recipient.address).toBe('test@test.com')
|
||||
expect(context.email_data.teacher_name).toBe('Mr Professerson')
|
||||
expect(context.email_data.school_name).toBe('Greendale')
|
||||
done()
|
||||
[res, body] = yield request.postAsync { uri: url, json: data }
|
||||
expect(res.statusCode).toBe(200)
|
||||
|
||||
|
||||
describe 'GET /db/classroom/:handle/member-sessions', ->
|
||||
|
|
|
@ -6,6 +6,8 @@ User = require '../../server/models/User'
|
|||
Level = require '../../server/models/Level'
|
||||
Achievement = require '../../server/models/Achievement'
|
||||
Campaign = require '../../server/models/Campaign'
|
||||
Classroom = require '../../server/models/Classroom'
|
||||
TrialRequest = require '../../server/models/TrialRequest'
|
||||
campaignSchema = require '../../app/schemas/models/campaign.schema'
|
||||
campaignLevelProperties = _.keys(campaignSchema.properties.levels.additionalProperties.properties)
|
||||
campaignAdjacentCampaignProperties = _.keys(campaignSchema.properties.adjacentCampaigns.additionalProperties.properties)
|
||||
|
@ -124,4 +126,30 @@ module.exports = mw =
|
|||
|
||||
request.post { uri: getURL('/db/campaign'), json: data }, (err, res) ->
|
||||
return done(err) if err
|
||||
Campaign.findById(res.body._id).exec done
|
||||
Campaign.findById(res.body._id).exec done
|
||||
|
||||
makeClassroom: Promise.promisify (data, sources, done) ->
|
||||
args = Array.from(arguments)
|
||||
[done, [data, sources]] = [args.pop(), args]
|
||||
|
||||
data = _.extend({}, {
|
||||
name: _.uniqueId('Classroom ')
|
||||
}, data)
|
||||
|
||||
request.post { uri: getURL('/db/classroom'), json: data }, (err, res) ->
|
||||
return done(err) if err
|
||||
Classroom.findById(res.body._id).exec done
|
||||
|
||||
makeTrialRequest: Promise.promisify (data, sources, done) ->
|
||||
args = Array.from(arguments)
|
||||
[done, [data, sources]] = [args.pop(), args]
|
||||
|
||||
data = _.extend({}, {
|
||||
type: 'course'
|
||||
properties: {}
|
||||
}, data)
|
||||
|
||||
request.post { uri: getURL('/db/trial.request'), json: data }, (err, res) ->
|
||||
return done(err) if err
|
||||
expect(res.statusCode).toBe(201)
|
||||
TrialRequest.findById(res.body._id).exec done
|
||||
|
|
Loading…
Add table
Reference in a new issue