def test_postpone_with_same_child_branch_existing_in_N1(self): n1_child_branch = EducationGroupYearFactory( academic_year=self.next_academic_year, education_group=self.current_group_element_year.child_branch. education_group, ) n_child_branch = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year, child_branch__education_group__end_year=None) GroupElementYearFactory(parent=self.next_education_group_year, child_branch=n1_child_branch) AuthorizedRelationshipFactory( parent_type=self.next_education_group_year.education_group_type, child_type=n1_child_branch.education_group_type, min_count_authorized=1) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual( new_child_branch.groupelementyear_set.get().child_branch. education_group, n_child_branch.child_branch.education_group)
def test_postpone_with_child_branches(self): sub_group = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year, child_branch__education_group__end_year=None, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual(new_child_branch.acronym, self.current_group_element_year.child_branch.acronym) self.assertEqual(new_child_branch.academic_year, self.next_academic_year) self.assertEqual(new_child_branch.groupelementyear_set.count(), 1) new_child_branch_2 = new_child_branch.groupelementyear_set.get( ).child_branch self.assertEqual(new_child_branch_2.acronym, sub_group.child_branch.acronym) self.assertEqual(new_child_branch_2.academic_year, self.next_academic_year)
def test_postpone_with_same_child_branch_existing_in_N1_without_relationship( self): """ When the postponed child has a min_count_authorized relation to 1, we have to check if the link to the existing egy is correctly created. """ n1_gr = GroupElementYearFactory( parent=self.next_education_group_year, child_branch__education_group=self.current_group_element_year. child_branch.education_group, child_branch__academic_year=self.next_academic_year, ) AuthorizedRelationshipFactory( parent_type=self.next_education_group_year.education_group_type, child_type=n1_gr.child_branch.education_group_type, min_count_authorized=1) n_1_gr = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year) n1_1_child = EducationGroupYearFactory( education_group=n_1_gr.child_branch.education_group, academic_year=self.next_academic_year, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual( new_root.groupelementyear_set.first().child_branch. groupelementyear_set.first().child_branch, n1_1_child)
def test_when_education_group_year_exists_in_n1_has_no_child_and_is_reference_link( self): self.current_group_element_year.link_type = LinkTypes.REFERENCE.name self.current_group_element_year.save() n1_referenced_egy = EducationGroupYearFactory( academic_year=self.next_academic_year, education_group=self.current_group_element_year.child_branch. education_group, education_group_type=self.current_education_group_year. education_group_type, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_referenced_egy = new_root.groupelementyear_set.first().child_branch self.assertEqual(new_referenced_egy, n1_referenced_egy) self.assertFalse(new_referenced_egy.groupelementyear_set.all()) self.assertEqual( _("%(education_group_year)s (reference link) has not been copied. Its content is empty." ) % { "education_group_year": "{} - {}".format(new_referenced_egy.partial_acronym, new_referenced_egy.acronym) }, str(self.postponer.warnings[0]), )
def test_postpone_with_old_child_leaf(self): n_minus_1_luy = LearningUnitYearFactory( academic_year=self.previous_academic_year) LearningUnitYearFactory(learning_unit=n_minus_1_luy.learning_unit, academic_year=self.current_academic_year) group_leaf = GroupElementYearFactory( parent=self.current_education_group_year, child_branch=None, child_leaf=n_minus_1_luy) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_child_leaf = new_root.groupelementyear_set.last().child_leaf self.assertEqual(new_child_leaf.acronym, group_leaf.child_leaf.acronym) # If the luy does not exist in N+1, it should attach N instance self.assertEqual(new_child_leaf.academic_year, self.previous_academic_year) self.assertTrue(self.postponer.warnings) self.assertIsInstance(self.postponer.warnings[0], ReuseOldLearningUnitYearWarning) self.assertEqual( str(self.postponer.warnings[0]), _("Learning unit %(learning_unit_year)s does not exist in %(academic_year)s => " "Learning unit is postponed with academic year of %(learning_unit_academic_year)s." ) % { "learning_unit_year": n_minus_1_luy.acronym, "academic_year": self.next_academic_year, "learning_unit_academic_year": n_minus_1_luy.academic_year })
def test_init_not_postponed_root(self): self.next_education_group_year.delete() with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual( str(cm.exception), _("The root does not exist in the next academic year."))
def test_init_old_education_group(self): self.education_group.end_year = AcademicYearFactory(year=2000) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual( str(cm.exception), _("The end date of the education group is smaller than the year of postponement." ))
def test_init_already_postponed_content_with_child_leaf(self): GroupElementYearFactory(parent=self.next_education_group_year, child_branch=None, child_leaf=LearningUnitYearFactory()) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(str(cm.exception), _("The content has already been postponed."))
def test_postpone_with_child_branch(self): self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual(new_child_branch.acronym, self.current_group_element_year.child_branch.acronym) self.assertEqual(new_child_branch.academic_year, self.next_academic_year)
def test_postpone_with_new_child_leaf(self): luy = LearningUnitYearFactory(academic_year=self.current_academic_year) new_luy = LearningUnitYearFactory( academic_year=self.next_academic_year, learning_unit=luy.learning_unit) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=luy) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_child_leaf = new_root.groupelementyear_set.last().child_leaf self.assertEqual(new_child_leaf, new_luy) self.assertEqual(new_child_leaf.academic_year, self.next_academic_year)
def test_postpone_with_child_branch_existing_in_N1(self): n1_child_branch = EducationGroupYearFactory( education_group=self.current_group_element_year.child_branch. education_group, academic_year=self.next_academic_year) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual(new_child_branch, n1_child_branch) self.assertEqual(new_child_branch.academic_year, self.next_academic_year)
def test_faculty_cannot_copy_into_future(self): eg = EducationGroupFactory(end_year=AcademicYearFactory( year=self.current_academic_year.year + 4)) egy = EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 2) EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 3) with self.assertRaises( NotPostponeError, msg= _('You are not allowed to postpone this training in the future.' )): self.postponer = PostponeContent(egy, FacultyManagerFactory())
def test_central_can_copy_into_future(self): central_manager = CentralManagerFactory() eg = EducationGroupFactory(end_year=AcademicYearFactory( year=self.current_academic_year.year + 4)) egy = EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 2) GroupElementYearFactory(parent=egy, child_branch__academic_year=egy.academic_year, child_branch__education_group__end_year=None) EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 3) self.postponer = PostponeContent(egy, central_manager) self.assertIsNone(self.postponer.check_instance(central_manager))
def test_postpone_attach_an_existing_mandatory_group_with_existing_children( self): """ We have to postpone the mandatory children, but if they are already postponed, we have to reuse them. But the copy of the structure must be stopped if these mandatory children are not empty. """ AuthorizedRelationshipFactory( parent_type=self.current_education_group_year.education_group_type, child_type=self.current_group_element_year.child_branch. education_group_type, min_count_authorized=1) self.current_group_element_year.child_branch.acronym = "mandatory_child_n" self.current_group_element_year.child_branch.education_group_type = GroupEducationGroupTypeFactory( ) self.current_group_element_year.child_branch.save() n1_mandatory_egy = EducationGroupYearFactory( academic_year=self.next_academic_year, acronym='mandatory_child_n1', education_group=self.current_group_element_year.child_branch. education_group, education_group_type=self.current_group_element_year.child_branch. education_group_type, ) n1_child_gr = GroupElementYearFactory( parent=n1_mandatory_egy, child_branch__academic_year=self.next_academic_year, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_mandatory_child = new_root.groupelementyear_set.first( ).child_branch self.assertEqual(new_mandatory_child, n1_mandatory_egy) self.assertEqual(new_mandatory_child.groupelementyear_set.first(), n1_child_gr) self.assertEqual( _("%(education_group_year)s has already been copied in %(academic_year)s in another program. " "It may have been already modified.") % { "education_group_year": n1_mandatory_egy.partial_acronym, "academic_year": n1_mandatory_egy.academic_year }, str(self.postponer.warnings[0]))
def test_postpone_with_prerequisite(self): prerequisite = PrerequisiteFactory( learning_unit_year__academic_year=self.current_academic_year, education_group_year=self.current_education_group_year) item_luy = LearningUnitYearFactory( academic_year=self.current_academic_year) LearningUnitYearFactory(academic_year=self.previous_academic_year, learning_unit=item_luy.learning_unit) n1_item_luy = LearningUnitYearFactory( academic_year=self.next_academic_year, learning_unit=item_luy.learning_unit, ) PrerequisiteItemFactory(prerequisite=prerequisite, learning_unit=item_luy.learning_unit) n1_luy = LearningUnitYearFactory( learning_unit=prerequisite.learning_unit_year.learning_unit, academic_year=self.next_academic_year, ) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=item_luy) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=prerequisite.learning_unit_year) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_child_leaf = new_root.groupelementyear_set.last().child_leaf self.assertEqual(new_child_leaf.acronym, n1_luy.acronym) # If the luy does not exist in N+1, it should attach N instance self.assertEqual(new_child_leaf.academic_year, self.next_academic_year) self.assertFalse(self.postponer.warnings) self.assertEqual( new_child_leaf.prerequisite_set.first().prerequisiteitem_set.first( ).learning_unit, n1_item_luy.learning_unit)
def test_init_already_postponed_content(self): gr = GroupElementYearFactory(parent=self.next_education_group_year, child_branch__academic_year=self. next_education_group_year.academic_year) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(str(cm.exception), _("The content has already been postponed.")) AuthorizedRelationshipFactory( parent_type=self.next_education_group_year.education_group_type, child_type=gr.child_branch.education_group_type, min_count_authorized=1) self.postponer = PostponeContent(self.current_education_group_year) GroupElementYearFactory( parent=gr.child_branch, child_branch__academic_year=gr.child_branch.academic_year) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(str(cm.exception), _("The content has already been postponed."))
def test_postpone_with_terminated_child_branches(self): sub_group = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year, child_branch__education_group__end_year=self.current_academic_year, ) self.postponer = PostponeContent(self.current_education_group_year) self.postponer.postpone() self.assertTrue(self.postponer.warnings) self.assertEqual( _("%(education_group_year)s is closed in %(end_year)s. This element will not be copied " "in %(academic_year)s.") % { "education_group_year": "{} - {}".format(sub_group.child_branch.partial_acronym, sub_group.child_branch.acronym), "end_year": sub_group.child_branch.education_group.end_year, "academic_year": self.next_academic_year, }, str(self.postponer.warnings[0]))
def test_when_prerequisite_learning_unit_does_not_exist_in_n1(self): prerequisite = PrerequisiteFactory( learning_unit_year__academic_year=self.current_academic_year, education_group_year=self.current_education_group_year) PrerequisiteItemFactory(prerequisite=prerequisite, ) LearningUnitYearFactory( learning_unit=prerequisite.learning_unit_year.learning_unit, academic_year=self.next_academic_year, ) GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch=None, child_leaf=prerequisite.learning_unit_year) GroupElementYearFactory(parent=EducationGroupYearFactory( education_group=self.current_group_element_year.child_branch. education_group, academic_year=self.next_academic_year), child_branch=None, child_leaf=LearningUnitYearFactory( academic_year=self.next_academic_year)) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertIn( _("%(learning_unit_year)s is not anymore contained in " "%(education_group_year_root)s " "=> the prerequisite for %(learning_unit_year)s is not copied.") % { "education_group_year_root": "{} - {}".format(new_root.partial_acronym, new_root.acronym), "learning_unit_year": prerequisite.learning_unit_year.acronym, }, [str(warning) for warning in self.postponer.warnings])
def test_when_prerequisite_item_does_not_exist_in_formation(self): prerequisite = PrerequisiteFactory( learning_unit_year__academic_year=self.current_academic_year, education_group_year=self.current_education_group_year) item_luy = LearningUnitYearFactory( academic_year=self.current_academic_year) PrerequisiteItemFactory(prerequisite=prerequisite, learning_unit=item_luy.learning_unit) LearningUnitYearFactory( learning_unit=prerequisite.learning_unit_year.learning_unit, academic_year=self.next_academic_year, ) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=prerequisite.learning_unit_year) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual( _("%(prerequisite_item)s is not anymore contained in " "%(education_group_year_root)s " "=> the prerequisite for %(learning_unit_year)s " "having %(prerequisite_item)s as prerequisite is not copied.") % { "education_group_year_root": "{} - {}".format(new_root.partial_acronym, new_root.acronym), "learning_unit_year": prerequisite.learning_unit_year.acronym, "prerequisite_item": item_luy.acronym }, str(self.postponer.warnings[0]), )
def post(self, request, **kwargs): try: postponer = PostponeContent(self.root.previous_year(), request.user.person) postponer.postpone() success = _( "%(count_elements)s OF(s) and %(count_links)s link(s) have been postponed with success." ) % { 'count_elements': postponer.number_elements_created, 'count_links': postponer.number_links_created } display_success_messages(request, success) display_warning_messages(request, postponer.warnings) except NotPostponeError as e: display_error_messages(request, str(e)) return JsonResponse({ 'success_url': reverse( "education_group_read", args=[kwargs["root_id"], kwargs["education_group_year_id"]]) })
def test_init_postponement(self): self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(self.postponer.instance, self.current_education_group_year)
def test_when_options_in_finalities_are_not_consistent(self): root_grp = GroupElementYearFactory( parent=EducationGroupYearFactory( education_group_type__category=Categories.TRAINING.name, education_group_type__name=TrainingType.PGRM_MASTER_120.name, academic_year=self.current_academic_year, education_group__end_year=None), child_branch=EducationGroupYearFactory( education_group_type__category=Categories.GROUP.name, education_group_type__name=GroupType.FINALITY_120_LIST_CHOICE. name, academic_year=self.current_academic_year, education_group__end_year=None)) child_grp = GroupElementYearFactory( parent=root_grp.child_branch, child_branch=EducationGroupYearFactory( education_group_type__category=Categories.TRAINING.name, education_group_type__name=TrainingType.MASTER_MA_120.name, academic_year=self.current_academic_year, education_group__end_year=None)) child_child_grp = GroupElementYearFactory( parent=child_grp.child_branch, child_branch=EducationGroupYearFactory( education_group_type__category=Categories.MINI_TRAINING.name, education_group_type__name=MiniTrainingType.OPTION.name, academic_year=self.current_academic_year, education_group__end_year=None)) root_egy_n1 = EducationGroupYearFactory( education_group_type=root_grp.parent.education_group_type, education_group=root_grp.parent.education_group, academic_year=self.next_academic_year) EducationGroupYearFactory( acronym=child_grp.child_branch.acronym, partial_acronym=child_grp.child_branch.partial_acronym, education_group_type=child_grp.child_branch.education_group_type, education_group=child_grp.child_branch.education_group, academic_year=self.next_academic_year, ) EducationGroupYearFactory( acronym=child_child_grp.child_branch.acronym, partial_acronym=child_child_grp.child_branch.partial_acronym, education_group_type=child_child_grp.child_branch. education_group_type, education_group=child_child_grp.child_branch.education_group, academic_year=self.next_academic_year, ) self.postponer = PostponeContent(root_grp.parent) self.postponer.postpone() self.assertEqual( _("The option %(education_group_year_option)s is not anymore accessible in " "%(education_group_year_root)s " "in %(academic_year)s => It is retired of the finality %(education_group_year_finality)s." ) % { "education_group_year_option": "{}".format(child_child_grp.child_branch.partial_acronym), "education_group_year_root": "{} - {}".format(root_egy_n1.partial_acronym, root_egy_n1.acronym), "education_group_year_finality": "{} - {}".format(child_grp.child_branch.partial_acronym, child_grp.child_branch.acronym), "academic_year": self.next_academic_year }, str(self.postponer.warnings[0]))
class TestPostponeContent(TestCase): @classmethod def setUpTestData(cls): cls.current_academic_year = create_current_academic_year() cls.previous_academic_year = AcademicYearFactory( year=cls.current_academic_year.year - 1) cls.next_academic_year = AcademicYearFactory( year=cls.current_academic_year.year + 1) def setUp(self): self.education_group = EducationGroupFactory( end_year=self.next_academic_year) self.current_education_group_year = TrainingFactory( education_group=self.education_group, academic_year=self.current_academic_year) self.current_group_element_year = GroupElementYearFactory( parent=self.current_education_group_year, child_branch__academic_year=self.current_academic_year, child_branch__education_group__end_year=None) self.next_education_group_year = TrainingFactory( education_group=self.education_group, academic_year=self.next_academic_year, education_group_type=self.current_education_group_year. education_group_type) def test_init_postponement(self): self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(self.postponer.instance, self.current_education_group_year) def test_init_not_postponed_root(self): self.next_education_group_year.delete() with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual( str(cm.exception), _("The root does not exist in the next academic year.")) def test_init_already_postponed_content(self): gr = GroupElementYearFactory(parent=self.next_education_group_year, child_branch__academic_year=self. next_education_group_year.academic_year) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(str(cm.exception), _("The content has already been postponed.")) AuthorizedRelationshipFactory( parent_type=self.next_education_group_year.education_group_type, child_type=gr.child_branch.education_group_type, min_count_authorized=1) self.postponer = PostponeContent(self.current_education_group_year) GroupElementYearFactory( parent=gr.child_branch, child_branch__academic_year=gr.child_branch.academic_year) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(str(cm.exception), _("The content has already been postponed.")) def test_init_already_postponed_content_with_child_leaf(self): GroupElementYearFactory(parent=self.next_education_group_year, child_branch=None, child_leaf=LearningUnitYearFactory()) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual(str(cm.exception), _("The content has already been postponed.")) def test_init_old_education_group(self): self.education_group.end_year = AcademicYearFactory(year=2000) with self.assertRaises(NotPostponeError) as cm: self.postponer = PostponeContent(self.current_education_group_year) self.assertEqual( str(cm.exception), _("The end date of the education group is smaller than the year of postponement." )) def test_postpone_with_child_branch(self): self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual(new_child_branch.acronym, self.current_group_element_year.child_branch.acronym) self.assertEqual(new_child_branch.academic_year, self.next_academic_year) def test_postpone_with_child_branch_existing_in_N1(self): n1_child_branch = EducationGroupYearFactory( education_group=self.current_group_element_year.child_branch. education_group, academic_year=self.next_academic_year) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual(new_child_branch, n1_child_branch) self.assertEqual(new_child_branch.academic_year, self.next_academic_year) def test_postpone_with_same_child_branch_existing_in_N1(self): n1_child_branch = EducationGroupYearFactory( academic_year=self.next_academic_year, education_group=self.current_group_element_year.child_branch. education_group, ) n_child_branch = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year, child_branch__education_group__end_year=None) GroupElementYearFactory(parent=self.next_education_group_year, child_branch=n1_child_branch) AuthorizedRelationshipFactory( parent_type=self.next_education_group_year.education_group_type, child_type=n1_child_branch.education_group_type, min_count_authorized=1) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual( new_child_branch.groupelementyear_set.get().child_branch. education_group, n_child_branch.child_branch.education_group) def test_postpone_with_same_child_branch_existing_in_N1_without_relationship( self): """ When the postponed child has a min_count_authorized relation to 1, we have to check if the link to the existing egy is correctly created. """ n1_gr = GroupElementYearFactory( parent=self.next_education_group_year, child_branch__education_group=self.current_group_element_year. child_branch.education_group, child_branch__academic_year=self.next_academic_year, ) AuthorizedRelationshipFactory( parent_type=self.next_education_group_year.education_group_type, child_type=n1_gr.child_branch.education_group_type, min_count_authorized=1) n_1_gr = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year) n1_1_child = EducationGroupYearFactory( education_group=n_1_gr.child_branch.education_group, academic_year=self.next_academic_year, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual( new_root.groupelementyear_set.first().child_branch. groupelementyear_set.first().child_branch, n1_1_child) def test_postpone_attach_an_existing_mandatory_group_with_existing_children( self): """ We have to postpone the mandatory children, but if they are already postponed, we have to reuse them. But the copy of the structure must be stopped if these mandatory children are not empty. """ AuthorizedRelationshipFactory( parent_type=self.current_education_group_year.education_group_type, child_type=self.current_group_element_year.child_branch. education_group_type, min_count_authorized=1) self.current_group_element_year.child_branch.acronym = "mandatory_child_n" self.current_group_element_year.child_branch.education_group_type = GroupEducationGroupTypeFactory( ) self.current_group_element_year.child_branch.save() n1_mandatory_egy = EducationGroupYearFactory( academic_year=self.next_academic_year, acronym='mandatory_child_n1', education_group=self.current_group_element_year.child_branch. education_group, education_group_type=self.current_group_element_year.child_branch. education_group_type, ) n1_child_gr = GroupElementYearFactory( parent=n1_mandatory_egy, child_branch__academic_year=self.next_academic_year, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_mandatory_child = new_root.groupelementyear_set.first( ).child_branch self.assertEqual(new_mandatory_child, n1_mandatory_egy) self.assertEqual(new_mandatory_child.groupelementyear_set.first(), n1_child_gr) self.assertEqual( _("%(education_group_year)s has already been copied in %(academic_year)s in another program. " "It may have been already modified.") % { "education_group_year": n1_mandatory_egy.partial_acronym, "academic_year": n1_mandatory_egy.academic_year }, str(self.postponer.warnings[0])) def test_postpone_with_child_branches(self): sub_group = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year, child_branch__education_group__end_year=None, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual(new_root, self.next_education_group_year) self.assertEqual(new_root.groupelementyear_set.count(), 1) new_child_branch = new_root.groupelementyear_set.get().child_branch self.assertEqual(new_child_branch.acronym, self.current_group_element_year.child_branch.acronym) self.assertEqual(new_child_branch.academic_year, self.next_academic_year) self.assertEqual(new_child_branch.groupelementyear_set.count(), 1) new_child_branch_2 = new_child_branch.groupelementyear_set.get( ).child_branch self.assertEqual(new_child_branch_2.acronym, sub_group.child_branch.acronym) self.assertEqual(new_child_branch_2.academic_year, self.next_academic_year) def test_postpone_with_old_child_leaf(self): n_minus_1_luy = LearningUnitYearFactory( academic_year=self.previous_academic_year) LearningUnitYearFactory(learning_unit=n_minus_1_luy.learning_unit, academic_year=self.current_academic_year) group_leaf = GroupElementYearFactory( parent=self.current_education_group_year, child_branch=None, child_leaf=n_minus_1_luy) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_child_leaf = new_root.groupelementyear_set.last().child_leaf self.assertEqual(new_child_leaf.acronym, group_leaf.child_leaf.acronym) # If the luy does not exist in N+1, it should attach N instance self.assertEqual(new_child_leaf.academic_year, self.previous_academic_year) self.assertTrue(self.postponer.warnings) self.assertIsInstance(self.postponer.warnings[0], ReuseOldLearningUnitYearWarning) self.assertEqual( str(self.postponer.warnings[0]), _("Learning unit %(learning_unit_year)s does not exist in %(academic_year)s => " "Learning unit is postponed with academic year of %(learning_unit_academic_year)s." ) % { "learning_unit_year": n_minus_1_luy.acronym, "academic_year": self.next_academic_year, "learning_unit_academic_year": n_minus_1_luy.academic_year }) def test_postpone_with_new_child_leaf(self): luy = LearningUnitYearFactory(academic_year=self.current_academic_year) new_luy = LearningUnitYearFactory( academic_year=self.next_academic_year, learning_unit=luy.learning_unit) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=luy) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_child_leaf = new_root.groupelementyear_set.last().child_leaf self.assertEqual(new_child_leaf, new_luy) self.assertEqual(new_child_leaf.academic_year, self.next_academic_year) def test_when_prerequisite_learning_unit_does_not_exist_in_n1(self): prerequisite = PrerequisiteFactory( learning_unit_year__academic_year=self.current_academic_year, education_group_year=self.current_education_group_year) PrerequisiteItemFactory(prerequisite=prerequisite, ) LearningUnitYearFactory( learning_unit=prerequisite.learning_unit_year.learning_unit, academic_year=self.next_academic_year, ) GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch=None, child_leaf=prerequisite.learning_unit_year) GroupElementYearFactory(parent=EducationGroupYearFactory( education_group=self.current_group_element_year.child_branch. education_group, academic_year=self.next_academic_year), child_branch=None, child_leaf=LearningUnitYearFactory( academic_year=self.next_academic_year)) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertIn( _("%(learning_unit_year)s is not anymore contained in " "%(education_group_year_root)s " "=> the prerequisite for %(learning_unit_year)s is not copied.") % { "education_group_year_root": "{} - {}".format(new_root.partial_acronym, new_root.acronym), "learning_unit_year": prerequisite.learning_unit_year.acronym, }, [str(warning) for warning in self.postponer.warnings]) def test_when_prerequisite_item_does_not_exist_in_formation(self): prerequisite = PrerequisiteFactory( learning_unit_year__academic_year=self.current_academic_year, education_group_year=self.current_education_group_year) item_luy = LearningUnitYearFactory( academic_year=self.current_academic_year) PrerequisiteItemFactory(prerequisite=prerequisite, learning_unit=item_luy.learning_unit) LearningUnitYearFactory( learning_unit=prerequisite.learning_unit_year.learning_unit, academic_year=self.next_academic_year, ) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=prerequisite.learning_unit_year) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() self.assertEqual( _("%(prerequisite_item)s is not anymore contained in " "%(education_group_year_root)s " "=> the prerequisite for %(learning_unit_year)s " "having %(prerequisite_item)s as prerequisite is not copied.") % { "education_group_year_root": "{} - {}".format(new_root.partial_acronym, new_root.acronym), "learning_unit_year": prerequisite.learning_unit_year.acronym, "prerequisite_item": item_luy.acronym }, str(self.postponer.warnings[0]), ) def test_postpone_with_prerequisite(self): prerequisite = PrerequisiteFactory( learning_unit_year__academic_year=self.current_academic_year, education_group_year=self.current_education_group_year) item_luy = LearningUnitYearFactory( academic_year=self.current_academic_year) LearningUnitYearFactory(academic_year=self.previous_academic_year, learning_unit=item_luy.learning_unit) n1_item_luy = LearningUnitYearFactory( academic_year=self.next_academic_year, learning_unit=item_luy.learning_unit, ) PrerequisiteItemFactory(prerequisite=prerequisite, learning_unit=item_luy.learning_unit) n1_luy = LearningUnitYearFactory( learning_unit=prerequisite.learning_unit_year.learning_unit, academic_year=self.next_academic_year, ) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=item_luy) GroupElementYearFactory(parent=self.current_education_group_year, child_branch=None, child_leaf=prerequisite.learning_unit_year) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_child_leaf = new_root.groupelementyear_set.last().child_leaf self.assertEqual(new_child_leaf.acronym, n1_luy.acronym) # If the luy does not exist in N+1, it should attach N instance self.assertEqual(new_child_leaf.academic_year, self.next_academic_year) self.assertFalse(self.postponer.warnings) self.assertEqual( new_child_leaf.prerequisite_set.first().prerequisiteitem_set.first( ).learning_unit, n1_item_luy.learning_unit) def test_postpone_with_terminated_child_branches(self): sub_group = GroupElementYearFactory( parent=self.current_group_element_year.child_branch, child_branch__academic_year=self.current_academic_year, child_branch__education_group__end_year=self.current_academic_year, ) self.postponer = PostponeContent(self.current_education_group_year) self.postponer.postpone() self.assertTrue(self.postponer.warnings) self.assertEqual( _("%(education_group_year)s is closed in %(end_year)s. This element will not be copied " "in %(academic_year)s.") % { "education_group_year": "{} - {}".format(sub_group.child_branch.partial_acronym, sub_group.child_branch.acronym), "end_year": sub_group.child_branch.education_group.end_year, "academic_year": self.next_academic_year, }, str(self.postponer.warnings[0])) def test_when_education_group_year_exists_in_n1_has_no_child_and_is_reference_link( self): self.current_group_element_year.link_type = LinkTypes.REFERENCE.name self.current_group_element_year.save() n1_referenced_egy = EducationGroupYearFactory( academic_year=self.next_academic_year, education_group=self.current_group_element_year.child_branch. education_group, education_group_type=self.current_education_group_year. education_group_type, ) self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_referenced_egy = new_root.groupelementyear_set.first().child_branch self.assertEqual(new_referenced_egy, n1_referenced_egy) self.assertFalse(new_referenced_egy.groupelementyear_set.all()) self.assertEqual( _("%(education_group_year)s (reference link) has not been copied. Its content is empty." ) % { "education_group_year": "{} - {}".format(new_referenced_egy.partial_acronym, new_referenced_egy.acronym) }, str(self.postponer.warnings[0]), ) def test_when_education_group_year_does_not_exist_in_n1_and_is_reference_link( self): self.current_group_element_year.link_type = LinkTypes.REFERENCE.name self.current_group_element_year.save() self.postponer = PostponeContent(self.current_education_group_year) new_root = self.postponer.postpone() new_referenced_egy = new_root.groupelementyear_set.first().child_branch self.assertEqual(new_referenced_egy.acronym, new_referenced_egy.acronym) self.assertEqual(new_referenced_egy.academic_year, self.next_academic_year) self.assertEqual( _("%(education_group_year)s (reference link) has not been copied. Its content is empty." ) % { "education_group_year": "{} - {}".format(new_referenced_egy.partial_acronym, new_referenced_egy.acronym) }, str(self.postponer.warnings[0]), ) def test_when_options_in_finalities_are_not_consistent(self): root_grp = GroupElementYearFactory( parent=EducationGroupYearFactory( education_group_type__category=Categories.TRAINING.name, education_group_type__name=TrainingType.PGRM_MASTER_120.name, academic_year=self.current_academic_year, education_group__end_year=None), child_branch=EducationGroupYearFactory( education_group_type__category=Categories.GROUP.name, education_group_type__name=GroupType.FINALITY_120_LIST_CHOICE. name, academic_year=self.current_academic_year, education_group__end_year=None)) child_grp = GroupElementYearFactory( parent=root_grp.child_branch, child_branch=EducationGroupYearFactory( education_group_type__category=Categories.TRAINING.name, education_group_type__name=TrainingType.MASTER_MA_120.name, academic_year=self.current_academic_year, education_group__end_year=None)) child_child_grp = GroupElementYearFactory( parent=child_grp.child_branch, child_branch=EducationGroupYearFactory( education_group_type__category=Categories.MINI_TRAINING.name, education_group_type__name=MiniTrainingType.OPTION.name, academic_year=self.current_academic_year, education_group__end_year=None)) root_egy_n1 = EducationGroupYearFactory( education_group_type=root_grp.parent.education_group_type, education_group=root_grp.parent.education_group, academic_year=self.next_academic_year) EducationGroupYearFactory( acronym=child_grp.child_branch.acronym, partial_acronym=child_grp.child_branch.partial_acronym, education_group_type=child_grp.child_branch.education_group_type, education_group=child_grp.child_branch.education_group, academic_year=self.next_academic_year, ) EducationGroupYearFactory( acronym=child_child_grp.child_branch.acronym, partial_acronym=child_child_grp.child_branch.partial_acronym, education_group_type=child_child_grp.child_branch. education_group_type, education_group=child_child_grp.child_branch.education_group, academic_year=self.next_academic_year, ) self.postponer = PostponeContent(root_grp.parent) self.postponer.postpone() self.assertEqual( _("The option %(education_group_year_option)s is not anymore accessible in " "%(education_group_year_root)s " "in %(academic_year)s => It is retired of the finality %(education_group_year_finality)s." ) % { "education_group_year_option": "{}".format(child_child_grp.child_branch.partial_acronym), "education_group_year_root": "{} - {}".format(root_egy_n1.partial_acronym, root_egy_n1.acronym), "education_group_year_finality": "{} - {}".format(child_grp.child_branch.partial_acronym, child_grp.child_branch.acronym), "academic_year": self.next_academic_year }, str(self.postponer.warnings[0])) def test_faculty_cannot_copy_into_future(self): eg = EducationGroupFactory(end_year=AcademicYearFactory( year=self.current_academic_year.year + 4)) egy = EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 2) EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 3) with self.assertRaises( NotPostponeError, msg= _('You are not allowed to postpone this training in the future.' )): self.postponer = PostponeContent(egy, FacultyManagerFactory()) def test_central_can_copy_into_future(self): central_manager = CentralManagerFactory() eg = EducationGroupFactory(end_year=AcademicYearFactory( year=self.current_academic_year.year + 4)) egy = EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 2) GroupElementYearFactory(parent=egy, child_branch__academic_year=egy.academic_year, child_branch__education_group__end_year=None) EducationGroupYearFactory( education_group=eg, academic_year__year=self.current_academic_year.year + 3) self.postponer = PostponeContent(egy, central_manager) self.assertIsNone(self.postponer.check_instance(central_manager))