mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-14 07:00:01 -04:00
parent
346c29361b
commit
b803080bed
4 changed files with 59 additions and 22 deletions
|
@ -4,6 +4,7 @@ module.exports =
|
|||
# Result: Each course instance gains a property, numCompleted, that is the
|
||||
# number of students in that course instance who have completed ALL of
|
||||
# the levels in thate course
|
||||
# TODO: simplify, classroom.sessions only includes sessions for assigned courses now
|
||||
calculateDots: (classrooms, courses, courseInstances) ->
|
||||
for classroom in classrooms.models
|
||||
# map [user, level] => session so we don't have to do find TODO
|
||||
|
|
|
@ -106,18 +106,34 @@ module.exports =
|
|||
res.status(200).send(levels)
|
||||
|
||||
fetchMemberSessions: wrap (req, res, next) ->
|
||||
# Return member sessions for assigned courses
|
||||
throw new errors.Unauthorized() unless req.user
|
||||
memberLimit = parse.getLimitFromReq(req, {default: 10, max: 100, param: 'memberLimit'})
|
||||
memberSkip = parse.getSkipFromReq(req, {param: 'memberSkip'})
|
||||
classroom = yield database.getDocFromHandle(req, Classroom)
|
||||
throw new errors.NotFound('Classroom not found.') if not classroom
|
||||
throw new errors.Forbidden('You do not own this classroom.') unless req.user.isAdmin() or classroom.get('ownerID').equals(req.user._id)
|
||||
courseLevelsMap = {}
|
||||
for course in classroom.get('courses') ? []
|
||||
# TODO: is LevelSession.level.original really a string in practice, instead of ObjectId set in schema?
|
||||
# https://github.com/codecombat/codecombat/blob/master/server/middleware/levels.coffee#L18
|
||||
courseLevelsMap[course._id.toHexString()] = _.map(course.levels, (l) -> l.original?.toHexString())
|
||||
courseInstances = yield CourseInstance.find({classroomID: classroom._id}).select('_id courseID members').lean()
|
||||
memberCoursesMap = {}
|
||||
for courseInstance in courseInstances
|
||||
for userID in courseInstance.members ? []
|
||||
memberCoursesMap[userID.toHexString()] ?= []
|
||||
memberCoursesMap[userID.toHexString()].push(courseInstance.courseID)
|
||||
memberLimit = parse.getLimitFromReq(req, {default: 10, max: 100, param: 'memberLimit'})
|
||||
memberSkip = parse.getSkipFromReq(req, {param: 'memberSkip'})
|
||||
members = classroom.get('members') or []
|
||||
members = members.slice(memberSkip, memberSkip + memberLimit)
|
||||
dbqs = []
|
||||
select = 'state.complete level creator playtime changed created dateFirstCompleted submitted'
|
||||
for member in members
|
||||
dbqs.push(LevelSession.find({creator: member.toHexString()}).select(select).exec())
|
||||
levelOriginals = []
|
||||
for courseID in memberCoursesMap[member.toHexString()] ? []
|
||||
levelOriginals = levelOriginals.concat(courseLevelsMap[courseID.toHexString()] ? [])
|
||||
query = {creator: member.toHexString(), 'level.original': {$in: levelOriginals}}
|
||||
dbqs.push(LevelSession.find(query).select(select).lean().exec())
|
||||
results = yield dbqs
|
||||
sessions = _.flatten(results)
|
||||
res.status(200).send(sessions)
|
||||
|
|
|
@ -488,29 +488,36 @@ describe 'POST /db/classroom/:id/invite-members', ->
|
|||
describe 'GET /db/classroom/:handle/member-sessions', ->
|
||||
|
||||
beforeEach utils.wrap (done) ->
|
||||
yield utils.clearModels([User, Classroom, LevelSession, Level])
|
||||
@artisan = yield utils.initUser()
|
||||
@teacher = yield utils.initUser()
|
||||
@student1 = yield utils.initUser()
|
||||
@student2 = yield utils.initUser()
|
||||
@levelA = new Level({name: 'Level A', permissions: [{target: @artisan._id, access: 'owner'}]})
|
||||
@levelA.set('original', @levelA._id)
|
||||
@levelA = yield @levelA.save()
|
||||
@levelB = new Level({name: 'Level B', permissions: [{target: @artisan._id, access: 'owner'}]})
|
||||
@levelB.set('original', @levelB._id)
|
||||
@levelB = yield @levelB.save()
|
||||
@classroom = yield new Classroom({name: 'Classroom', ownerID: @teacher._id, members: [@student1._id, @student2._id] }).save()
|
||||
@session1A = yield new LevelSession({creator: @student1.id, state: { complete: true }, level: {original: @levelA._id}, permissions: [{target: @student1._id, access: 'owner'}]}).save()
|
||||
@session1B = yield new LevelSession({creator: @student1.id, state: { complete: false }, level: {original: @levelB._id}, permissions: [{target: @student1._id, access: 'owner'}]}).save()
|
||||
@session2A = yield new LevelSession({creator: @student2.id, state: { complete: true }, level: {original: @levelA._id}, permissions: [{target: @student2._id, access: 'owner'}]}).save()
|
||||
@session2B = yield new LevelSession({creator: @student2.id, state: { complete: false }, level: {original: @levelB._id}, permissions: [{target: @student2._id, access: 'owner'}]}).save()
|
||||
yield utils.clearModels([CourseInstance, Course, User, Classroom, Campaign, Level, LevelSession])
|
||||
@teacher = yield utils.initUser({role: 'teacher'})
|
||||
admin = yield utils.initAdmin()
|
||||
yield utils.loginUser(admin)
|
||||
@levelA = yield utils.makeLevel({type: 'course'})
|
||||
@levelB = yield utils.makeLevel({type: 'course'})
|
||||
@campaignA = yield utils.makeCampaign({}, {levels: [@levelA]})
|
||||
@campaignB = yield utils.makeCampaign({}, {levels: [@levelB]})
|
||||
@courseA = yield utils.makeCourse({free: true, releasePhase: 'released'}, {campaign: @campaignA})
|
||||
@courseB = yield utils.makeCourse({free: true, releasePhase: 'released'}, {campaign: @campaignB})
|
||||
@student1 = yield utils.initUser({role: 'student'})
|
||||
yield utils.loginUser(@student1)
|
||||
@session1A = yield utils.makeLevelSession({state: { complete: true }, level: {original: @levelA._id.toHexString()}})
|
||||
@session1B = yield utils.makeLevelSession({state: { complete: false }, level: {original: @levelB._id.toHexString()}})
|
||||
@student2 = yield utils.initUser({role: 'student'})
|
||||
yield utils.loginUser(@student2)
|
||||
@session2A = yield utils.makeLevelSession({state: { complete: true }, level: {original: @levelA._id.toHexString()}})
|
||||
@session2B = yield utils.makeLevelSession({state: { complete: false }, level: {original: @levelB._id.toHexString()}})
|
||||
yield utils.loginUser(@teacher)
|
||||
@classroom = yield utils.makeClassroom({}, { members: [@student1, @student2] })
|
||||
@courseInstanceA = yield utils.makeCourseInstance({courseID: @courseA.id, classroomID: @classroom.id}, { members: [@student1, @student2] })
|
||||
@courseInstanceB = yield utils.makeCourseInstance({courseID: @courseB.id, classroomID: @classroom.id}, { members: [@student1] })
|
||||
yield utils.logout()
|
||||
done()
|
||||
|
||||
it 'returns all sessions for all members in the classroom with only properties level, creator and state.complete', utils.wrap (done) ->
|
||||
it 'returns all sessions for all members in the classroom with assigned courses', utils.wrap (done) ->
|
||||
yield utils.loginUser(@teacher)
|
||||
[res, body] = yield request.getAsync getURL("/db/classroom/#{@classroom.id}/member-sessions"), { json: true }
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.length).toBe(4)
|
||||
expect(body.length).toBe(3)
|
||||
done()
|
||||
|
||||
it 'does not work if you are not the owner of the classroom', utils.wrap (done) ->
|
||||
|
@ -532,7 +539,7 @@ describe 'GET /db/classroom/:handle/member-sessions', ->
|
|||
expect(session.creator).toBe(@student1.id) for session in body
|
||||
[res, body] = yield request.getAsync getURL("/db/classroom/#{@classroom.id}/member-sessions?memberSkip=1"), { json: true }
|
||||
expect(res.statusCode).toBe(200)
|
||||
expect(body.length).toBe(2)
|
||||
expect(body.length).toBe(1)
|
||||
expect(session.creator).toBe(@student2.id) for session in body
|
||||
done()
|
||||
|
||||
|
|
|
@ -209,6 +209,19 @@ module.exports = mw =
|
|||
expect(res.statusCode).toBe(200)
|
||||
ThangType.findById(res.body._id).exec done
|
||||
|
||||
makeLevelSession: Promise.promisify (data, sources, done) ->
|
||||
args = Array.from(arguments)
|
||||
[done, [data, sources]] = [args.pop(), args]
|
||||
|
||||
data = _.extend({}, {
|
||||
creator: mw.lastLogin.id
|
||||
permissions: [{target: mw.lastLogin.id, access: 'owner'}]
|
||||
}, data)
|
||||
|
||||
# TODO: using request.post strips the creator field for some reason
|
||||
session = new LevelSession data
|
||||
session.save done
|
||||
|
||||
makeAchievement: Promise.promisify (data, sources, done) ->
|
||||
args = Array.from(arguments)
|
||||
[done, [data, sources]] = [args.pop(), args]
|
||||
|
|
Loading…
Reference in a new issue