Add Classroom server model and endpoints

This commit is contained in:
Scott Erickson 2015-11-02 17:07:23 -08:00
parent d6b57f0e76
commit 27d423a410
6 changed files with 208 additions and 0 deletions

View file

@ -0,0 +1,14 @@
c = require './../schemas'
ClassroomSchema = c.object {title: 'Classroom', required: ['name']}
c.extendNamedProperties ClassroomSchema # name first
_.extend ClassroomSchema.properties,
members: c.array {title: 'Members'}, c.objectId()
ownerID: c.objectId()
description: {type: 'string'}
code: c.shortString(title: "Unique code to redeem")
c.extendBasicProperties ClassroomSchema, 'Classroom'
module.exports = ClassroomSchema

View file

@ -0,0 +1,36 @@
mongoose = require 'mongoose'
log = require 'winston'
config = require '../../server_config'
plugins = require '../plugins/plugins'
User = require '../users/User'
jsonSchema = require '../../app/schemas/models/classroom.schema'
ClassroomSchema = new mongoose.Schema {}, {strict: false, minimize: false, read:config.mongo.readpref}
ClassroomSchema.statics.privateProperties = []
ClassroomSchema.statics.editableProperties = [
'description'
'name'
]
ClassroomSchema.statics.generateNewCode = (done) ->
tryCode = ->
code = _.sample("abcdefghijklmnopqrstuvwxyz0123456789", 8).join('')
Classroom.findOne code: code, (err, classroom) ->
return done() if err
return done(code) unless classroom
tryCode()
tryCode()
ClassroomSchema.plugin plugins.NamedPlugin
ClassroomSchema.pre('save', (next) ->
return next() if @get('code')
Classroom.generateNewCode (code) =>
@set 'code', code
next()
)
ClassroomSchema.statics.jsonSchema = jsonSchema
module.exports = Classroom = mongoose.model 'classroom', ClassroomSchema, 'classrooms'

View file

@ -0,0 +1,58 @@
async = require 'async'
mongoose = require 'mongoose'
Handler = require '../commons/Handler'
Classroom = require './Classroom'
User = require '../users/User'
ClassroomHandler = class ClassroomHandler extends Handler
modelClass: Classroom
jsonSchema: require '../../app/schemas/models/classroom.schema'
allowedMethods: ['GET', 'POST', 'PUT', 'DELETE']
hasAccess: (req) ->
return false unless req.user
return true if req.method is 'GET'
req.method in @allowedMethods or req.user?.isAdmin()
hasAccessToDocument: (req, document, method=null) ->
return false unless document?
return true if req.user?.isAdmin()
return true if document.get('ownerID')?.equals req.user?._id
isGet = (method or req.method).toLowerCase() is 'get'
isMember = _.any(document.get('members') or [], (memberID) -> memberID.equals(req.user.get('_id')))
return true if isGet and isMember
false
makeNewInstance: (req) ->
instance = super(req)
instance.set 'ownerID', req.user._id
instance.set 'members', []
instance
getByRelationship: (req, res, args...) ->
method = req.method.toLowerCase()
return @joinClassroomAPI(req, res, args[0]) if method is 'post' and args[1] is 'members'
super(arguments...)
joinClassroomAPI: (req, res, classroomID) ->
return @sendBadInputError(res, 'Need an object with a code') unless req.body?.code
Classroom.findById classroomID, (err, classroom) =>
return @sendDatabaseError(res, err) if err
return @sendNotFoundError(res) if not classroom
return @sendBadInputError(res, 'Bad code') unless req.body.code is classroom.get('code')
members = _.clone(classroom.get('members'))
if _.any(members, (memberID) -> memberID.equals(req.user.get('_id')))
return @sendSuccess(res, @formatEntity(req, classroom))
members.push req.user.get('_id')
classroom.set('members', members)
classroom.save (err, classroom) =>
return @sendDatabaseError(res, err) if err
return @sendSuccess(res, @formatEntity(req, classroom))
formatEntity: (req, doc) ->
if req.user?.isAdmin() or req.user?.get('_id').equals(doc.get('ownerID'))
return doc.toObject()
return _.omit(doc.toObject(), 'code')
module.exports = new ClassroomHandler()

View file

@ -8,6 +8,7 @@ module.exports.handlers =
'article': 'articles/article_handler'
'campaign': 'campaigns/campaign_handler'
'clan': 'clans/clan_handler'
'classroom': 'classrooms/classroom_handler'
'course': 'courses/course_handler'
'course_instance': 'courses/course_instance_handler'
'level': 'levels/level_handler'

View file

@ -32,6 +32,7 @@ models_path = [
'../../server/articles/Article'
'../../server/campaigns/Campaign'
'../../server/clans/Clan'
'../../server/classrooms/Classroom'
'../../server/courses/Course'
'../../server/courses/CourseInstance'
'../../server/levels/Level'

View file

@ -0,0 +1,98 @@
config = require '../../../server_config'
require '../common'
utils = require '../../../app/core/utils' # Must come after require /common
mongoose = require 'mongoose'
classroomsURL = getURL('/db/classroom')
describe 'GET /db/classrooms/:id', ->
it 'Clear database users and clans', (done) ->
clearModels [User, Classroom], (err) ->
throw err if err
done()
it 'creates a new classroom for the given user', (done) ->
loginNewUser (user1) ->
data = { name: 'Classroom 1' }
request.post {uri: classroomsURL, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(200)
classroomID = body._id
request.get {uri: classroomsURL + '/' + body._id }, (err, res, body) ->
expect(res.statusCode).toBe(200)
expect(body._id).toBe(classroomID = body._id)
done()
describe 'POST /db/classrooms', ->
it 'Clear database users and clans', (done) ->
clearModels [User, Classroom], (err) ->
throw err if err
done()
it 'creates a new classroom for the given user', (done) ->
loginNewUser (user1) ->
data = { name: 'Classroom 1' }
request.post {uri: classroomsURL, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(200)
expect(body.name).toBe('Classroom 1')
expect(body.members.length).toBe(0)
expect(body.ownerID).toBe(user1.id)
done()
it 'does not work for anonymous users', (done) ->
logoutUser ->
data = { name: 'Classroom 2' }
request.post {uri: classroomsURL, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(401)
done()
describe 'PUT /db/classrooms', ->
it 'Clear database users and clans', (done) ->
clearModels [User, Classroom], (err) ->
throw err if err
done()
it 'edits name and description', (done) ->
loginNewUser (user1) ->
data = { name: 'Classroom 2' }
request.post {uri: classroomsURL, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(200)
data = { name: 'Classroom 3', description: 'New Description' }
url = classroomsURL + '/' + body._id
request.put { uri: url, json: data }, (err, res, body) ->
expect(body.name).toBe('Classroom 3')
expect(body.description).toBe('New Description')
done()
it 'is not allowed if you are just a member', (done) ->
loginNewUser (user1) ->
data = { name: 'Classroom 4' }
request.post {uri: classroomsURL, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(200)
classroomCode = body.code
loginNewUser (user2) ->
url = classroomsURL + '/' + body._id + '/members'
data = { code: classroomCode }
request.post { uri: url, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(200)
url = classroomsURL + '/' + body._id
request.put { uri: url, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(403)
done()
describe 'POST /db/classrooms/:id/members', ->
it 'adds the signed in user to the list of members in the classroom', (done) ->
loginNewUser (user1) ->
data = { name: 'Classroom 5' }
request.post {uri: classroomsURL, json: data }, (err, res, body) ->
classroomCode = body.code
expect(res.statusCode).toBe(200)
loginNewUser (user2) ->
url = classroomsURL + '/' + body._id + '/members'
data = { code: classroomCode }
request.post { uri: url, json: data }, (err, res, body) ->
expect(res.statusCode).toBe(200)
done()