1053 lines
48 KiB
Python
1053 lines
48 KiB
Python
import base64
|
|
# pyrefly: ignore [missing-import]
|
|
from odoo.tests.common import TransactionCase
|
|
# pyrefly: ignore [missing-import]
|
|
from odoo.exceptions import AccessError, ValidationError
|
|
from datetime import date, timedelta
|
|
# pyrefly: ignore [missing-import]
|
|
from odoo import fields
|
|
|
|
class TestEducationLMS(TransactionCase):
|
|
|
|
def setUp(self):
|
|
super(TestEducationLMS, self).setUp()
|
|
self.env.user.tz = 'UTC'
|
|
|
|
# Groups
|
|
self.group_faculty = self.env.ref('education_lms.group_education_lms_faculty')
|
|
self.group_student = self.env.ref('education_lms.group_education_lms_student')
|
|
self.group_admin = self.env.ref('education_lms.group_education_lms_admin')
|
|
|
|
# Create Users
|
|
self.user_faculty_a = self.env['res.users'].create({
|
|
'name': 'Faculty A',
|
|
'login': 'faculty_a',
|
|
'group_ids': [(4, self.group_faculty.id)]
|
|
})
|
|
self.user_faculty_b = self.env['res.users'].create({
|
|
'name': 'Faculty B',
|
|
'login': 'faculty_b',
|
|
'group_ids': [(4, self.group_faculty.id)]
|
|
})
|
|
self.user_student_a = self.env['res.users'].create({
|
|
'name': 'Student A',
|
|
'login': 'student_a',
|
|
'group_ids': [(4, self.group_student.id), (4, self.env.ref('education_student.group_education_student_user').id)]
|
|
})
|
|
self.user_student_b = self.env['res.users'].create({
|
|
'name': 'Student B',
|
|
'login': 'student_b',
|
|
'group_ids': [(4, self.group_student.id), (4, self.env.ref('education_student.group_education_student_user').id)]
|
|
})
|
|
|
|
# Academic structure
|
|
self.campus = self.env['education.campus'].create({'name': 'Campus A', 'code': 'CA'})
|
|
self.department = self.env['education.department'].create({
|
|
'name': 'Dept A', 'code': 'DA', 'campus_id': self.campus.id
|
|
})
|
|
self.level = self.env['education.academic.level'].create({'name': 'Level A', 'code': 'LA'})
|
|
self.program = self.env['education.program'].create({
|
|
'name': 'Program A', 'code': 'PA', 'department_id': self.department.id, 'level_id': self.level.id
|
|
})
|
|
self.academic_year = self.env['education.academic.year'].create({
|
|
'name': 'Year 2024',
|
|
'code': 'Y24',
|
|
'start_date': date(2024, 1, 1),
|
|
'end_date': date(2024, 12, 31)
|
|
})
|
|
self.term = self.env['education.academic.term'].create({
|
|
'name': 'Term 1', 'code': 'T1', 'academic_year_id': self.academic_year.id,
|
|
'start_date': date(2024, 1, 1), 'end_date': date(2024, 6, 30)
|
|
})
|
|
self.batch = self.env['education.batch'].create({
|
|
'name': 'Batch A', 'code': 'BA'
|
|
})
|
|
self.semester = self.env['education.semester'].create({
|
|
'name': 'Sem 1', 'code': 'S1'
|
|
})
|
|
self.section = self.env['education.section'].create({'name': 'Section A', 'code': 'SECA'})
|
|
|
|
self.subject = self.env['education.subject'].create({
|
|
'name': 'Subject A', 'code': 'SUB_A', 'program_id': self.program.id
|
|
})
|
|
|
|
# Create Students
|
|
self.student_a = self.env['education.student'].create({
|
|
'first_name': 'Student',
|
|
'last_name': 'A',
|
|
'portal_user_id': self.user_student_a.id,
|
|
'campus_id': self.campus.id,
|
|
'department_id': self.department.id,
|
|
'program_id': self.program.id,
|
|
'level_id': self.level.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'academic_term_id': self.term.id,
|
|
'batch_id': self.batch.id,
|
|
'semester_id': self.semester.id,
|
|
'section_id': self.section.id,
|
|
'admission_type': 'regular'
|
|
})
|
|
self.student_b = self.env['education.student'].create({
|
|
'first_name': 'Student',
|
|
'last_name': 'B',
|
|
'portal_user_id': self.user_student_b.id,
|
|
'campus_id': self.campus.id,
|
|
'department_id': self.department.id,
|
|
'program_id': self.program.id,
|
|
'level_id': self.level.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'academic_term_id': self.term.id,
|
|
'batch_id': self.batch.id,
|
|
'semester_id': self.semester.id,
|
|
'section_id': self.section.id,
|
|
'admission_type': 'regular'
|
|
})
|
|
|
|
# Courses
|
|
self.course_faculty_a = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course A',
|
|
'subject_id': self.subject.id,
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'term_id': self.term.id,
|
|
'batch_id': self.batch.id,
|
|
'state': 'draft'
|
|
})
|
|
self.course_faculty_b = self.env['education.lms.course'].with_user(self.user_faculty_b).create({
|
|
'name': 'Course B',
|
|
'subject_id': self.subject.id,
|
|
'faculty_id': self.user_faculty_b.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'state': 'draft'
|
|
})
|
|
self.course_faculty_a.write({'state': 'published'})
|
|
self.course_faculty_b.write({'state': 'published'})
|
|
|
|
# 1. Faculty A creates assignment on Faculty A course -> PASS
|
|
def test_01_faculty_creates_own_assignment(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'assigned_date': fields.Date.today(),
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'maximum_marks': 100
|
|
})
|
|
self.assertTrue(assignment.id)
|
|
|
|
# 2. Faculty A creates assignment on Faculty B course -> REJECT
|
|
def test_02_faculty_creates_other_assignment(self):
|
|
with self.assertRaises(AccessError):
|
|
self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign B',
|
|
'course_id': self.course_faculty_b.id,
|
|
'assigned_date': fields.Date.today(),
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
|
|
# 3. Faculty B edits Faculty A assignment -> REJECT
|
|
def test_03_faculty_edits_other_assignment(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
assignment.with_user(self.user_faculty_b).write({'name': 'Hacked'})
|
|
|
|
# 4. Faculty B deletes Faculty A assignment -> REJECT
|
|
def test_04_faculty_deletes_other_assignment(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
assignment.with_user(self.user_faculty_b).unlink()
|
|
|
|
# 5. Faculty A publishes assignment under Draft course -> REJECT
|
|
def test_05_publish_under_draft_course(self):
|
|
self.course_faculty_a.with_user(self.user_faculty_a).write({'state': 'draft'})
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
assignment.with_user(self.user_faculty_a).write({'state': 'published'})
|
|
|
|
# 6. Faculty A publishes assignment under Published course -> PASS
|
|
def test_06_publish_under_published_course(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.with_user(self.user_faculty_a).write({'state': 'published'})
|
|
self.assertEqual(assignment.state, 'published')
|
|
|
|
# 7. due_date before assigned_date -> REJECT
|
|
def test_07_invalid_dates(self):
|
|
with self.assertRaises(ValidationError):
|
|
self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'assigned_date': fields.Date.today(),
|
|
'due_date': fields.Date.today() - timedelta(days=1)
|
|
})
|
|
|
|
# 8. maximum_marks <= 0 -> REJECT
|
|
def test_08_invalid_marks(self):
|
|
with self.assertRaises(ValidationError):
|
|
self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'maximum_marks': 0
|
|
})
|
|
|
|
# 9. Section from another course selected -> REJECT
|
|
def test_09_invalid_section(self):
|
|
section_b = self.env['education.lms.section'].create({
|
|
'name': 'Section B', 'course_id': self.course_faculty_b.id
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'section_id': section_b.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
|
|
# 10. Lesson from another section/course selected -> REJECT
|
|
def test_10_invalid_lesson(self):
|
|
section_a = self.env['education.lms.section'].create({
|
|
'name': 'Section A', 'course_id': self.course_faculty_a.id
|
|
})
|
|
section_b = self.env['education.lms.section'].create({
|
|
'name': 'Section B', 'course_id': self.course_faculty_b.id
|
|
})
|
|
lesson_b = self.env['education.lms.lesson'].create({
|
|
'name': 'Lesson B', 'section_id': section_b.id, 'course_id': self.course_faculty_b.id
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'section_id': section_a.id,
|
|
'lesson_id': lesson_b.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
|
|
# 11. Student A creates submission for eligible assignment -> PASS
|
|
def test_11_student_creates_submission(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
self.assertTrue(submission.id)
|
|
|
|
# 12. Student A creates submission for Student B -> REJECT
|
|
def test_12_student_creates_for_other(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_b.id
|
|
})
|
|
|
|
# 13. Student A submits assignment for an ineligible course -> REJECT
|
|
def test_13_student_ineligible_course(self):
|
|
# Create course for different program
|
|
program2 = self.env['education.program'].create({
|
|
'name': 'Program 2', 'code': 'P2', 'department_id': self.department.id, 'level_id': self.level.id
|
|
})
|
|
course_ineligible = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course 2',
|
|
'subject_id': self.subject.id,
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': program2.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'state': 'published'
|
|
})
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 2',
|
|
'course_id': course_ineligible.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
|
|
# 14. Student A submits with no text and no attachment -> REJECT
|
|
def test_14_submit_without_content(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
submission.with_user(self.user_student_a).write({'status': 'submitted'})
|
|
|
|
# 15. Student A submits before due date -> status Submitted
|
|
def test_15_submit_before_due_date(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
submission.with_user(self.user_student_a).write({'status': 'submitted', 'text_submission': 'Done'})
|
|
self.assertEqual(submission.status, 'submitted')
|
|
self.assertFalse(submission.is_late)
|
|
|
|
# 16. Student A submits after due date -> status Late
|
|
def test_16_submit_after_due_date(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'assigned_date': fields.Date.today() - timedelta(days=2),
|
|
'due_date': fields.Date.today() - timedelta(days=1)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
submission.with_user(self.user_student_a).write({'status': 'submitted', 'text_submission': 'Done'})
|
|
self.assertEqual(submission.status, 'late')
|
|
self.assertTrue(submission.is_late)
|
|
|
|
# 17. Student A cannot edit another student's submission -> REJECT
|
|
def test_17_student_edit_other_submission(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_b).write({'text_submission': 'Hacked'})
|
|
|
|
# 18. Faculty A can view/evaluate Student A submission for Faculty A course -> PASS
|
|
def test_18_faculty_evaluates_submission(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
submission.with_user(self.user_faculty_a).write({'status': 'evaluated', 'marks': 90})
|
|
self.assertEqual(submission.status, 'evaluated')
|
|
self.assertEqual(submission.marks, 90)
|
|
self.assertTrue(submission.evaluation_date)
|
|
|
|
# 19. Faculty B cannot view/evaluate that submission -> REJECT
|
|
def test_19_faculty_b_evaluates_faculty_a_submission(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_faculty_b).write({'status': 'evaluated', 'marks': 90})
|
|
|
|
# 20. Faculty evaluates with marks = 0 -> PASS
|
|
def test_20_faculty_evaluate_zero_marks(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
submission.with_user(self.user_faculty_a).write({'status': 'evaluated', 'marks': 0.0})
|
|
self.assertEqual(submission.status, 'evaluated')
|
|
self.assertEqual(submission.marks, 0.0)
|
|
|
|
# 21. Faculty evaluates with marks > maximum_marks -> REJECT
|
|
def test_21_faculty_evaluate_exceed_max_marks(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'maximum_marks': 100
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
submission.with_user(self.user_faculty_a).write({'status': 'evaluated', 'marks': 105})
|
|
|
|
# 22. Faculty evaluates with negative marks -> REJECT
|
|
def test_22_faculty_evaluate_negative_marks(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
submission.with_user(self.user_faculty_a).write({'status': 'evaluated', 'marks': -5})
|
|
|
|
# 23. Empty marks remain unevaluated; never convert empty to 0.
|
|
def test_23_empty_marks(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
self.assertFalse(submission.marks)
|
|
|
|
# 24. Duplicate submission for same student + assignment -> REJECT
|
|
def test_24_duplicate_submission(self):
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
# Try to create another one
|
|
with self.assertRaises(Exception):
|
|
self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
self.env.flush_all()
|
|
|
|
# 25. Admin can manage all assignments and submissions -> PASS
|
|
def test_25_admin_access(self):
|
|
user_admin = self.env['res.users'].create({
|
|
'name': 'Admin User',
|
|
'login': 'lms_admin',
|
|
'group_ids': [(4, self.group_admin.id)]
|
|
})
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign 1',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.with_user(user_admin).write({'title': 'Admin Edited'})
|
|
self.assertEqual(assignment.title, 'Admin Edited')
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
submission.with_user(user_admin).write({'marks': 100, 'status': 'evaluated'})
|
|
self.assertEqual(submission.marks, 100)
|
|
|
|
|
|
# PHASE G TESTS
|
|
|
|
# 26. Draft -> Published
|
|
def test_26_draft_to_published(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
self.assertEqual(assignment.state, 'draft')
|
|
assignment.action_publish()
|
|
self.assertEqual(assignment.state, 'published')
|
|
|
|
# 27. Published -> Closed
|
|
def test_27_published_to_closed(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
assignment.action_close()
|
|
self.assertEqual(assignment.state, 'closed')
|
|
|
|
# 28. Closed -> Published rejected
|
|
def test_28_closed_to_published_rejected(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
assignment.action_close()
|
|
with self.assertRaises(ValidationError):
|
|
assignment.write({'state': 'published'})
|
|
|
|
# 29. Closed -> Draft rejected
|
|
def test_29_closed_to_draft_rejected(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
assignment.action_close()
|
|
with self.assertRaises(ValidationError):
|
|
assignment.write({'state': 'draft'})
|
|
|
|
# 30. Closed assignment rejects new submission
|
|
def test_30_closed_assignment_rejects_new_submission(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
assignment.action_close()
|
|
with self.assertRaises(ValidationError):
|
|
self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id
|
|
})
|
|
|
|
# 31. Faculty evaluation succeeds on own course
|
|
def test_31_faculty_evaluation_own_course(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
submission.with_user(self.user_faculty_a).write({'marks': 10, 'status': 'evaluated'})
|
|
self.assertEqual(submission.status, 'evaluated')
|
|
|
|
# 32. Cross-faculty evaluation rejected
|
|
def test_32_cross_faculty_evaluation_rejected(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_faculty_b).write({'marks': 10, 'status': 'evaluated'})
|
|
|
|
# 33. Student cannot modify evaluation fields
|
|
def test_33_student_cannot_modify_evaluation(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_a).write({'marks': 10})
|
|
|
|
# 34. Faculty cannot modify another faculty's evaluation
|
|
def test_34_faculty_cannot_modify_other_faculty_eval(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
submission.with_user(self.user_faculty_a).write({'marks': 10, 'status': 'evaluated'})
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_faculty_b).write({'marks': 15})
|
|
|
|
# 35. 0 marks accepted
|
|
def test_35_0_marks_accepted(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
submission.with_user(self.user_faculty_a).write({'marks': 0.0, 'status': 'evaluated'})
|
|
self.assertEqual(submission.marks, 0.0)
|
|
|
|
# 36. empty marks rejected for Evaluated status
|
|
def test_36_empty_marks_rejected(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Phase G',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5)
|
|
})
|
|
assignment.action_publish()
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Done',
|
|
'status': 'submitted'
|
|
})
|
|
with self.assertRaises(ValidationError):
|
|
submission.with_user(self.user_faculty_a).write({'marks': False, 'status': 'evaluated'})
|
|
|
|
|
|
# ==========================================
|
|
# PHASE H SECURITY TESTS
|
|
# ==========================================
|
|
|
|
# 37. Faculty A cannot read/modify Faculty B courses/content
|
|
def test_37_faculty_isolation(self):
|
|
# Faculty B course
|
|
course_b = self.env['education.lms.course'].with_user(self.user_faculty_b).create({
|
|
'name': 'Course B',
|
|
'faculty_id': self.user_faculty_b.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
})
|
|
# Faculty A tries to read -> AccessError
|
|
with self.assertRaises(AccessError):
|
|
course_b.with_user(self.user_faculty_a).read(['name'])
|
|
|
|
# Faculty A tries to modify
|
|
with self.assertRaises(AccessError):
|
|
course_b.with_user(self.user_faculty_a).write({'name': 'Hacked'})
|
|
|
|
# Faculty A tries to delete
|
|
with self.assertRaises(AccessError):
|
|
course_b.with_user(self.user_faculty_a).unlink()
|
|
|
|
# Faculty A tries to create section under Course B -> AccessError
|
|
with self.assertRaises(AccessError):
|
|
self.env['education.lms.section'].with_user(self.user_faculty_a).create({
|
|
'name': 'Sec B',
|
|
'course_id': course_b.id
|
|
})
|
|
|
|
# 38. Student Isolation (cannot read/modify other student submission)
|
|
def test_38_student_isolation(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign H',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'state': 'published'
|
|
})
|
|
submission_a = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Student A Work',
|
|
})
|
|
# Student B tries to read
|
|
with self.assertRaises(AccessError):
|
|
submission_a.with_user(self.user_student_b).read(['text_submission'])
|
|
|
|
# Student B tries to write
|
|
with self.assertRaises(AccessError):
|
|
submission_a.with_user(self.user_student_b).write({'text_submission': 'Hacked'})
|
|
|
|
# Student B tries to create submission for Student A
|
|
assignment_new = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign H New',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'state': 'published'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
self.env['education.lms.submission'].with_user(self.user_student_b).create({
|
|
'assignment_id': assignment_new.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Student B Work',
|
|
})
|
|
|
|
# 39. Course Eligibility Security
|
|
def test_39_course_eligibility(self):
|
|
# A. Matching
|
|
course_a = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course A',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'term_id': self.term.id,
|
|
'batch_id': self.batch.id,
|
|
'state': 'published'
|
|
})
|
|
|
|
# Student A matches program, year, term, batch
|
|
self.env.invalidate_all()
|
|
res = course_a.with_user(self.user_student_a).read(['name'])
|
|
self.assertTrue(len(res) > 0)
|
|
self.assertTrue(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_a.id)])))
|
|
|
|
# B. Different Program
|
|
program_2 = self.env['education.program'].create({
|
|
'name': 'Program 2', 'code': 'P2', 'department_id': self.department.id, 'level_id': self.level.id
|
|
})
|
|
course_b = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course B',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': program_2.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'term_id': self.term.id,
|
|
'batch_id': self.batch.id,
|
|
'state': 'published'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
course_b.with_user(self.user_student_a).read(['name'])
|
|
self.assertFalse(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_b.id)])))
|
|
|
|
# C. Different Year
|
|
year_2 = self.env['education.academic.year'].create({
|
|
'name': 'Year 2025', 'code': 'Y25', 'start_date': date(2025, 1, 1), 'end_date': date(2025, 12, 31)
|
|
})
|
|
course_c = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course C',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': year_2.id,
|
|
'subject_id': self.subject.id,
|
|
'term_id': self.term.id,
|
|
'batch_id': self.batch.id,
|
|
'state': 'published'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
course_c.with_user(self.user_student_a).read(['name'])
|
|
self.assertFalse(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_c.id)])))
|
|
|
|
# D. Different Term
|
|
term_2 = self.env['education.academic.term'].create({
|
|
'name': 'Term 2', 'code': 'T2', 'academic_year_id': self.academic_year.id,
|
|
'start_date': date(2024, 7, 1), 'end_date': date(2024, 12, 31),
|
|
'sequence': 2
|
|
})
|
|
course_d = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course D',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'term_id': term_2.id,
|
|
'batch_id': self.batch.id,
|
|
'state': 'published'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
course_d.with_user(self.user_student_a).read(['name'])
|
|
self.assertFalse(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_d.id)])))
|
|
|
|
# E. Course with no term -> Matches
|
|
course_e = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course E',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'batch_id': self.batch.id,
|
|
'state': 'published'
|
|
})
|
|
res = course_e.with_user(self.user_student_a).read(['name'])
|
|
self.assertTrue(len(res) > 0)
|
|
self.assertTrue(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_e.id)])))
|
|
|
|
# F. Different batch
|
|
batch_2 = self.env['education.batch'].create({'name': 'Batch B', 'code': 'BB'})
|
|
course_f = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course F',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'term_id': self.term.id,
|
|
'batch_id': batch_2.id,
|
|
'state': 'published'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
course_f.with_user(self.user_student_a).read(['name'])
|
|
self.assertFalse(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_f.id)])))
|
|
|
|
# G. Course with no batch
|
|
course_g = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course G',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'term_id': self.term.id,
|
|
'state': 'published'
|
|
})
|
|
res = course_g.with_user(self.user_student_a).read(['name'])
|
|
self.assertTrue(len(res) > 0)
|
|
self.assertTrue(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_g.id)])))
|
|
|
|
# H. Course with no term AND no batch (should match)
|
|
course_h = self.env['education.lms.course'].with_user(self.user_faculty_a).create({
|
|
'name': 'Course H',
|
|
'faculty_id': self.user_faculty_a.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
'state': 'published'
|
|
})
|
|
res = course_h.with_user(self.user_student_a).read(['name'])
|
|
self.assertTrue(len(res) > 0)
|
|
self.assertTrue(bool(self.env['education.lms.course'].with_user(self.user_student_a).search([('id', '=', course_h.id)])))
|
|
|
|
|
|
# 40. Assignment access and states
|
|
def test_40_assignment_access(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign Draft',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'state': 'draft'
|
|
})
|
|
self.env.invalidate_all()
|
|
# Draft assignment -> Student A cannot read
|
|
with self.assertRaises(AccessError):
|
|
assignment.with_user(self.user_student_a).read(['title'])
|
|
self.assertFalse(bool(self.env['education.lms.assignment'].with_user(self.user_student_a).search([('id', '=', assignment.id)])))
|
|
|
|
# Published -> Student A can read
|
|
assignment.with_user(self.user_faculty_a).action_publish()
|
|
self.env.invalidate_all()
|
|
res = assignment.with_user(self.user_student_a).read(['title'])
|
|
self.assertTrue(len(res) > 0)
|
|
self.assertTrue(bool(self.env['education.lms.assignment'].with_user(self.user_student_a).search([('id', '=', assignment.id)])))
|
|
|
|
# Closed -> Student A can read, but cannot submit
|
|
assignment.with_user(self.user_faculty_a).action_close()
|
|
self.env.invalidate_all()
|
|
res = assignment.with_user(self.user_student_a).read(['title'])
|
|
self.assertTrue(len(res) > 0)
|
|
|
|
with self.assertRaises(ValidationError):
|
|
self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Student A Work',
|
|
})
|
|
|
|
# 41. Submission edge cases
|
|
def test_41_submission_security_edge_cases(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign H2',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'state': 'published'
|
|
})
|
|
submission = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'Student A Work',
|
|
})
|
|
|
|
# Spoof student_id
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_a).write({'student_id': self.student_b.id})
|
|
|
|
# Spoof assignment_id
|
|
assignment_2 = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign H3',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'state': 'published'
|
|
})
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_a).write({'assignment_id': assignment_2.id})
|
|
|
|
submission.with_user(self.user_student_a).action_submit()
|
|
|
|
# Change marks
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_a).write({'marks': 100})
|
|
|
|
# Change feedback
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_a).write({'feedback': 'Good job me'})
|
|
|
|
# Change status
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_a).write({'status': 'evaluated'})
|
|
|
|
# Change evaluation metadata
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_student_a).write({'evaluated_by': self.user_student_a.id})
|
|
|
|
# Faculty B cannot evaluate Faculty A's submissions
|
|
with self.assertRaises(AccessError):
|
|
submission.with_user(self.user_faculty_b).write({'marks': 50})
|
|
|
|
# Faculty A CAN evaluate
|
|
submission.with_user(self.user_faculty_a).write({'marks': 50, 'status': 'evaluated'})
|
|
self.assertEqual(submission.marks, 50)
|
|
|
|
# 42. Attachment Security Direct Test
|
|
def test_42_attachment_security(self):
|
|
self.course_faculty_a.state = 'published'
|
|
assignment = self.env['education.lms.assignment'].with_user(self.user_faculty_a).create({
|
|
'title': 'Assign H Attachments',
|
|
'course_id': self.course_faculty_a.id,
|
|
'due_date': fields.Date.today() + timedelta(days=5),
|
|
'state': 'published'
|
|
})
|
|
|
|
# Student A submission
|
|
sub_a = self.env['education.lms.submission'].with_user(self.user_student_a).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_a.id,
|
|
'text_submission': 'A',
|
|
})
|
|
attach_a = self.env['ir.attachment'].with_user(self.user_student_a).create({
|
|
'name': 'file_a.txt',
|
|
'datas': base64.b64encode(b'student A file'),
|
|
'res_model': 'education.lms.submission',
|
|
'res_id': sub_a.id,
|
|
})
|
|
|
|
sub_b = self.env['education.lms.submission'].with_user(self.user_student_b).create({
|
|
'assignment_id': assignment.id,
|
|
'student_id': self.student_b.id,
|
|
'text_submission': 'B',
|
|
})
|
|
attach_b = self.env['ir.attachment'].with_user(self.user_student_b).create({
|
|
'name': 'file_b.txt',
|
|
'datas': base64.b64encode(b'student B file'),
|
|
'res_model': 'education.lms.submission',
|
|
'res_id': sub_b.id,
|
|
})
|
|
|
|
# Verify A can read attach A binary data
|
|
res_a = attach_a.with_user(self.user_student_a).read(['raw', 'datas'])
|
|
self.assertTrue(len(res_a) > 0)
|
|
|
|
# Verify A cannot read attach B binary data
|
|
with self.assertRaises(AccessError):
|
|
attach_b.with_user(self.user_student_a).read(['raw', 'datas'])
|
|
|
|
# Verify Faculty A can read both
|
|
res_fa1 = attach_a.with_user(self.user_faculty_a).read(['raw'])
|
|
self.assertTrue(len(res_fa1) > 0)
|
|
res_fa2 = attach_b.with_user(self.user_faculty_a).read(['raw'])
|
|
self.assertTrue(len(res_fa2) > 0)
|
|
|
|
# Verify Faculty B cannot read either
|
|
with self.assertRaises(AccessError):
|
|
attach_a.with_user(self.user_faculty_b).read(['raw'])
|
|
with self.assertRaises(AccessError):
|
|
attach_b.with_user(self.user_faculty_b).read(['raw'])
|
|
|
|
# 43. Admin override
|
|
def test_43_admin_override(self):
|
|
user_admin = self.env['res.users'].create({
|
|
'name': 'Admin User 2',
|
|
'login': 'lms_admin2',
|
|
'group_ids': [(4, self.group_admin.id)]
|
|
})
|
|
# Admin can read faculty B's course
|
|
course_b = self.env['education.lms.course'].with_user(self.user_faculty_b).create({
|
|
'name': 'Course B',
|
|
'faculty_id': self.user_faculty_b.id,
|
|
'program_id': self.program.id,
|
|
'academic_year_id': self.academic_year.id,
|
|
'subject_id': self.subject.id,
|
|
})
|
|
res = course_b.with_user(user_admin).read(['name'])
|
|
self.assertTrue(len(res) > 0)
|
|
|
|
course_b.with_user(user_admin).write({'name': 'Admin changed'})
|
|
self.assertEqual(course_b.name, 'Admin changed')
|
|
|
|
# 44. Portal User Mapping
|
|
def test_44_portal_user_mapping(self):
|
|
# A user without student_id should not see Student A's courses/submissions in LMS Context
|
|
user_no_student = self.env['res.users'].create({
|
|
'name': 'No Student',
|
|
'login': 'no_student',
|
|
'group_ids': [(4, self.group_student.id)]
|
|
})
|
|
self.course_faculty_a.state = 'published'
|
|
with self.assertRaises(AccessError):
|
|
self.course_faculty_a.with_user(user_no_student).read(['name'])
|