Skip to content

Commit

Permalink
Afral[premieroctet#90]: added user resources
Browse files Browse the repository at this point in the history
  • Loading branch information
SeghirOumo committed Aug 9, 2024
1 parent 9405291 commit 94eefb5
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 4 deletions.
2 changes: 1 addition & 1 deletion backend/web/server/plugins/aftral-lms/consts.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ module.exports={
BLOCK_STATUS, BLOCK_STATUS_TO_COME, BLOCK_STATUS_CURRENT, BLOCK_STATUS_FINISHED, BLOCK_STATUS_UNAVAILABLE,
FEED_TYPE, FEED_TYPE_GENERAL, FEED_TYPE_GROUP, FEED_TYPE_SESSION, RESOURCE_TYPE_EXCEL, RESOURCE_TYPE_PDF,
RESOURCE_TYPE_PPT, RESOURCE_TYPE_VIDEO, RESOURCE_TYPE_WORD,
ACHIEVEMENT_RULE, ACHIEVEMENT_RULE_SUCCESS,
ACHIEVEMENT_RULE, ACHIEVEMENT_RULE_SUCCESS, ACHIEVEMENT_RULE_CONSULT, ACHIEVEMENT_RULE_DOWNLOAD,
SCALE, RESOURCE_TYPE_EXT, RESOURCE_TYPE_LINK, DEFAULT_ACHIEVEMENT_RULE, AVAILABLE_ACHIEVEMENT_RULES,
ACHIEVEMENT_RULE_CHECK,
}
4 changes: 3 additions & 1 deletion backend/web/server/plugins/aftral-lms/functions.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const Post = require('../../models/Post')
require('../../models/Module')
require('../../models/Sequence')
require('../../models/Search')
require('../../models/Chapter') //Added chapter, it was removed somehow
const { computeStatistics } = require('./statistics')
const { searchUsers, searchBlocks } = require('./search')
const { getUserHomeworks, getResourceType, getAchievementRules, getBlockSpentTime, getBlockSpentTimeStr, getResourcesCount, getFinishedResourcesCount } = require('./resources')
Expand All @@ -29,6 +30,7 @@ const Resource = require('../../models/Resource')
const { parseAsync } = require('@babel/core')
const Progress = require('../../models/Progress')
const { BadRequestError } = require('../../utils/errors')
const { getTraineeResources } = require('./user')

const GENERAL_FEED_ID='FFFFFFFFFFFFFFFFFFFFFFFF'

Expand Down Expand Up @@ -75,7 +77,6 @@ declareComputedField({model: 'program', field: 'available_codes', requires: 'cod

declareComputedField({model: 'resource', field: 'mine', getterFn: isResourceMine})


declareEnumField({model: 'feed', field: 'type', enumValues: FEED_TYPE})

declareEnumField({model: 'post', field: '_feed_type', enumValues: FEED_TYPE})
Expand All @@ -85,6 +86,7 @@ declareEnumField({model: 'purchase', field: 'status', enumValues: PURCHASE_STATU
const USER_MODELS=['user', 'loggedUser', 'contact']
USER_MODELS.forEach(model => {
declareEnumField({model, field: 'role', instance: 'String', enumValues: ROLES})
declareComputedField({model, field: 'resources', getterFn: getTraineeResources})
})

// search start
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,6 @@ BlockSchema.pre('validate', async function(next) {
// If this is a type resource and achievement rule is success and this is not a scorm,
// must select between min/max notes and scale
if (!this._locked && this.type=='resource') {
console.log(this)
const resourceType= this.resource_type || await getAttribute('resource_type')(null, null, this)
const allowedAchievementRules=AVAILABLE_ACHIEVEMENT_RULES[resourceType]
// TODO allowedAchievementRules may be null if the block is not still inserted in DB
Expand Down
7 changes: 6 additions & 1 deletion backend/web/server/plugins/aftral-lms/schemas/UserSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,12 @@ const UserSchema = new Schema({
type: Schema.Types.ObjectId,
ref: 'program',
required: false,
}
},
resources: [{
type: Schema.Types.ObjectId,
ref: 'resource',
required: false
}],
}, schemaOptions)

/* eslint-disable prefer-arrow-callback */
Expand Down
50 changes: 50 additions & 0 deletions backend/web/server/plugins/aftral-lms/user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const mongoose = require('mongoose')
const Session = require('../../models/Session')
const { getBlockResources } = require('./resources')
const Block = require('../../models/Block')
const Resource = require('../../models/Resource')
const Program = require('../../models/Program')
const Chapter = require('../../models/Chapter')
const Module = require('../../models/Module')
const Sequence = require('../../models/Sequence')

const getRelatedDocuments = async (Model, ids) => {
return await Model.find({ _id: { $in: ids } }).populate('children')
}

const getIdsFromChildren = (documents) => {
return documents.flatMap(doc => doc.children.map(child => child._id))
}

const getTraineeResources = async (userId, params, data) => {
const sessions = await Session.find({ trainees: data._id }).populate('children')

const programIds = getIdsFromChildren(sessions)
const programs = await getRelatedDocuments(Program, programIds)

let modules

if (programs[0]?.children[0]?.type === 'chapter') {
const chapterIds = getIdsFromChildren(programs)
const chapters = await getRelatedDocuments(Chapter, chapterIds)

const moduleIds = getIdsFromChildren(chapters)
modules = await getRelatedDocuments(Module, moduleIds)
} else {
const moduleIds = getIdsFromChildren(programs)
modules = await getRelatedDocuments(Module, moduleIds)
}

const sequenceIds = getIdsFromChildren(modules)
const sequences = await getRelatedDocuments(Sequence, sequenceIds)

const resourceIds = getIdsFromChildren(sequences)
const resources = await Resource.find({ _id: { $in: resourceIds } })

return resources
}


module.exports = {
getTraineeResources
}
161 changes: 161 additions & 0 deletions backend/web/tests/aftral-lms/user.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
const mongoose = require('mongoose')
const { MONGOOSE_OPTIONS, loadFromDb } = require('../../server/utils/database')
require('../../server/plugins/aftral-lms/functions')
const User = require('../../server/models/User')
const Resource = require('../../server/models/Resource')
const Sequence = require('../../server/models/Sequence')
const Module = require('../../server/models/Module')
const Program = require('../../server/models/Program')
const Session = require('../../server/models/Session')
const { ROLE_APPRENANT, ROLE_FORMATEUR, RESOURCE_TYPE_PDF, ACHIEVEMENT_RULE_CHECK, ACHIEVEMENT_RULE_SUCCESS, ACHIEVEMENT_RULE_CONSULT, RESOURCE_TYPE_VIDEO, ACHIEVEMENT_RULE_DOWNLOAD, ROLE_CONCEPTEUR } = require('../../server/plugins/aftral-lms/consts')
const ProductCode = require('../../server/models/ProductCode')
const { addChildAction } = require('../../server/plugins/aftral-lms/actions')
const { getBlockResources } = require('../../server/plugins/aftral-lms/resources')
const Block = require('../../server/models/Block')

jest.setTimeout(60000)

describe('User', () => {
let conceptor, trainee, trainer, session, program, productCode, modulee1, modulee2, sequence1, sequence2, sequence3, resource1, resource2, resource3, resource4
beforeAll(async () => {
await mongoose.connect(`mongodb://localhost/aftral-test`, MONGOOSE_OPTIONS)

trainee = await User.create({
role: ROLE_APPRENANT,
email: `a@a.com`,
password: `Je déteste Python`,
firstname: `John`,
lastname: `Doe`,
})

trainer = await User.create({
role: ROLE_FORMATEUR,
email: `b@b.com`,
password: `J'enseigne le Python`,
firstname: `Jeanette`,
lastname: `Doe`,
})

conceptor = await User.create({
role: ROLE_CONCEPTEUR,
email: `c@c.com`,
password: `J'impose le Python`,
firstname: `Jack`,
lastname: `Doe`,
})

session = await Block.create({
type: 'session',
name: `Test session`,
creator: trainer._id,
start_date: new Date(),
end_date: new Date('2025-07-07'),
trainees:[trainee._id]
})

productCode = await ProductCode.create({code: 'Product Code Test'})

program = await Block.create({
type: 'program',
codes:[productCode.id],
name: `Test program`,
creator: trainer._id
})

modulee1 = await Block.create({
type: 'module',
name: `Test Module 1`,
creator: trainer._id
})

modulee2 = await Block.create({
type: 'module',
name: `Test Module 2`,
creator: trainer._id
})

sequence1 = await Block.create({
type: 'sequence',
name: `Test Sequence 1`,
creator: trainer._id
})

sequence2 = await Block.create({
type: 'sequence',
name: `Test Sequence 2`,
creator: trainer._id
})

sequence3 = await Block.create({
type: 'sequence',
name: `Test Sequence 3`,
creator: trainer._id
})

resource1 = await Block.create({
type: 'resource',
name: `Test Resource 1`,
resource_type: RESOURCE_TYPE_VIDEO,
creator: trainer._id,
url: `hi.pdf`,
achievement_rule: ACHIEVEMENT_RULE_DOWNLOAD
})

resource2 = await Block.create({
type: 'resource',
name: `Test Resource 2`,
resource_type: RESOURCE_TYPE_VIDEO,
creator: trainer._id,
url: `hi.pdf`,
achievement_rule: ACHIEVEMENT_RULE_DOWNLOAD
})

resource3 = await Block.create({
type: 'resource',
name: `Test Resource 3`,
resource_type: RESOURCE_TYPE_VIDEO,
creator: trainer._id,
url: `hi.pdf`,
achievement_rule: ACHIEVEMENT_RULE_DOWNLOAD
})

resource4 = await Block.create({
type: 'resource',
name: `Test Resource 4`,
resource_type: RESOURCE_TYPE_VIDEO,
creator: trainer._id,
url: `hi.pdf`,
achievement_rule: ACHIEVEMENT_RULE_DOWNLOAD
})

await addChildAction({parent: session._id, child: program._id}, conceptor)
await addChildAction({parent: program._id, child: modulee1._id}, conceptor)
await addChildAction({parent: program._id, child: modulee2._id}, conceptor)
await addChildAction({parent: modulee1._id, child: sequence1._id}, conceptor)
await addChildAction({parent: modulee1._id, child: sequence2._id}, conceptor)
await addChildAction({parent: modulee2._id, child: sequence3._id}, conceptor)
await addChildAction({parent: sequence1._id, child: resource1._id}, conceptor)
await addChildAction({parent: sequence1._id, child: resource2._id}, conceptor)
await addChildAction({parent: sequence2._id, child: resource3._id}, conceptor)
await addChildAction({parent: sequence3._id, child: resource4._id}, conceptor)

await session.save()
await program.save()
await program.save()
await modulee1.save()
await modulee2.save()
await sequence1.save()
await sequence2.save()
await sequence3.save()
})

afterAll(async () => {
await mongoose.connection.dropDatabase()
await mongoose.connection.close()
})

it(`it must user's resources`, async () => {
const [u] = await loadFromDb({model:'user', fields:['resources'], id:trainee._id})
expect(u.resources.length).toEqual(4)
})
})

0 comments on commit 94eefb5

Please sign in to comment.