class TestTutorApplicationEpc(TestCase):
    def setUp(self):
        self.academic_year = AcademicYearFactory(year=2017)
        external_id = tutor_application_osis.LEARNING_CONTAINER_YEAR_PREFIX_EXTERNAL_ID + '35654987_2017'
        self.lbir1200 = LearningContainerYearFactory(academic_year=self.academic_year, acronym="LBIR1200",
                                                     external_id=external_id)
        self.lagro2630 = LearningContainerYearFactory(academic_year=self.academic_year, acronym="LAGRO2630")
        self.bio = LearningContainerYearFactory(academic_year=self.academic_year, acronym="BIO5213")

        # Creation Person/Tutor
        Group.objects.create(name="tutors")
        person = PersonFactory(global_id="98363454")
        external_id = tutor_application_osis.TUTOR_PREFIX_EXTERNAL_ID + '2089590559'
        self.tutor = TutorFactory(external_id=external_id, person=person)

        # Create two tutor applications
        applications = [_get_application_example(self.lbir1200, '30.5', '40.5'),
                        _get_application_example(self.lagro2630, '12.5', '10.5'),
                        _get_application_example(self.bio, '10.5', '9.5')]
        self.attribution_new = AttributionNewFactory(
            global_id=person.global_id,
            applications=applications
        )

    def test_process_message_update_operation(self):
        person = self.tutor.person
        _set_all_application_in_pending_state(self.attribution_new.applications)
        self.attribution_new.save()
        self.assertEqual(len(self.attribution_new.applications), 3)
        self.assertEqual(self.attribution_new.applications[0]['pending'], tutor_application_osis.UPDATE_OPERATION)
        self.assertEqual(self.attribution_new.applications[1]['pending'], tutor_application_osis.UPDATE_OPERATION)

        body = [{
            'global_id': person.global_id,
            'tutor_applications': [{
                'acronym': 'LBIR1200',
                'year': self.academic_year.year,
                'charge_lecturing_asked': '0',
                'charge_practical_asked': '0',
                'last_changed': "2020-12-08 09:58:57+00:00"
            }]
        }]
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_osis.process_message(body_encoded)
        self.attribution_new.refresh_from_db()
        self.assertEqual(self.attribution_new.applications[0]['charge_lecturing_asked'], '0')

    def test_process_message_no_update_operation(self):
        person = self.tutor.person
        _set_all_application_in_pending_state(self.attribution_new.applications)
        self.attribution_new.save()
        self.assertEqual(len(self.attribution_new.applications), 3)
        self.assertEqual(self.attribution_new.applications[0]['pending'], tutor_application_osis.UPDATE_OPERATION)
        self.assertEqual(self.attribution_new.applications[1]['pending'], tutor_application_osis.UPDATE_OPERATION)

        body = [{
            'global_id': person.global_id,
            'tutor_applications': [{
                'acronym': 'LAGRO2630',
                'year': self.academic_year.year,
                'charge_lecturing_asked': '0',
                'charge_practical_asked': '0',
                'last_changed': "2013-12-08 09:58:57+00:00"
            }]
        }]
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_osis.process_message(body_encoded)
        self.attribution_new.refresh_from_db()
        self.assertEqual(self.attribution_new.applications[0]['charge_lecturing_asked'], '12.5')

    def test_process_message_with_delete_pending(self):
        person = self.tutor.person
        _set_all_application_in_pending_delete(self.attribution_new.applications)
        self.attribution_new.save()
        self.assertEqual(len(self.attribution_new.applications), 3)

        body = [{
            'global_id': person.global_id,
            'tutor_applications': [{
                'acronym': 'LAGRO2630',
                'year': self.academic_year.year,
                'charge_lecturing_asked': '0',
                'charge_practical_asked': '0',
                'last_changed': "2016-12-08 09:58:57+00:00"
            }]
        }]
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_osis.process_message(body_encoded)
        self.attribution_new.refresh_from_db()
        self.assertEqual(len(self.attribution_new.applications), 1)
        self.assertEqual(self.attribution_new.applications[0]['charge_lecturing_asked'], '12.5')

    def test_process_when_attribution_new_not_exist(self):
        body = [{
            'global_id': "321654",
            'tutor_applications': [{
                'acronym': 'LAGRO2630',
                'year': self.academic_year.year,
                'charge_lecturing_asked': '0',
                'charge_practical_asked': '0',
                'last_changed': "2016-12-08 09:58:57+00:00"
            }]
        }]
        self.assertEqual(find_by_global_id("321654"), None)
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_osis.process_message(body_encoded)
        self.assertEqual(find_by_global_id("321654").global_id, "321654")

    def test_process_with_many_change(self):
        person = self.tutor.person
        self.assertEqual(len(self.attribution_new.applications), 3)
        self.attribution_new.applications[0]['pending'] = tutor_application_osis.UPDATE_OPERATION
        self.attribution_new.applications[1]['pending'] = tutor_application_osis.DELETE_OPERATION
        self.attribution_new.save()
        self.attribution_new.refresh_from_db()
        body = [{
            'global_id': person.global_id,
            'tutor_applications': [
                {'acronym': 'LAGRO2630',
                 'year': self.academic_year.year,
                 'charge_lecturing_asked': '0',
                 'charge_practical_asked': '0',
                 'last_changed': "2021-12-08 09:58:57+00:00"
                 },
                {'acronym': 'LBIR1200',
                 'year': self.academic_year.year,
                 'charge_lecturing_asked': '0',
                 'charge_practical_asked': '0',
                 'last_changed': "2013-12-08 09:58:57+00:00"
                 },
                {'acronym': 'BIO5213',
                 'year': self.academic_year.year,
                 'charge_lecturing_asked': '0',
                 'charge_practical_asked': '0',
                 'last_changed': "2013-12-08 09:58:57+00:00"}
            ]
        }]
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_osis.process_message(body_encoded)
        self.attribution_new.refresh_from_db()
        self.assertEqual(len(self.attribution_new.applications), 3)
        self.assertEqual(self.attribution_new.applications[0]['charge_lecturing_asked'], '12.5')
        self.assertEqual(self.attribution_new.applications[1]['charge_lecturing_asked'], '30.5')
        self.assertEqual(self.attribution_new.applications[2]['charge_lecturing_asked'], '0')
class TestOnlineApplication(TestCase):
    def setUp(self):
        # Create Group tutor
        Group.objects.create(name="tutors")

        # Create user
        user = UserFactory(username="******")
        person = PersonFactory(global_id="578945612", user=user)
        self.tutor = TutorFactory(person=person)

        # Add permission and log into app
        add_permission(user, "can_access_attribution_application")
        self.client.force_login(user)

        # Create current academic year
        self.current_academic_year = create_current_academic_year()

        # Create application year
        # Application is always next year
        self.application_academic_year = AcademicYearFactory(

            year=self.current_academic_year.year + 1
        )

        # Create Event to allow teacher to register
        start_date = datetime.datetime.today() - datetime.timedelta(days=10)
        end_date = datetime.datetime.today() + datetime.timedelta(days=15)
        self.academic_calendar = AcademicCalendarFactory(
            academic_year=self.current_academic_year,
            reference=academic_calendar_type.TEACHING_CHARGE_APPLICATION,
            start_date=start_date,
            end_date=end_date
        )
        self.agro_entity = EntityFactory()
        self.agro_entity_version = EntityVersionFactory(entity=self.agro_entity, acronym="AGRO",
                                                        entity_type='FACULTY',
                                                        start_date=self.academic_calendar.start_date,
                                                        end_date=self.academic_calendar.end_date)

        self.drt_entity = EntityFactory()
        self.drt_entity_version = EntityVersionFactory(entity=self.drt_entity, acronym="DRT",
                                                       entity_type='FACULTY',
                                                       start_date=self.academic_calendar.start_date,
                                                       end_date=self.academic_calendar.end_date)

        # Creation context with multiple learning container year
        self._create_multiple_learning_container_year()
        self.attribution = AttributionNewFactory(
            global_id=person.global_id,
            applications=self._get_default_application_list(),
            attributions=self._get_default_attribution_list()
        )

    def test_redirection_to_outside_encoding_period(self):
        # Remove teaching charge application event
        self.academic_calendar.delete()
        url = reverse('applications_overview')
        url_outside = reverse('outside_applications_period')
        response = self.client.get(url)
        self.assertRedirects(response, "%s?next=%s" % (url_outside, url))  # Redirection

    def test_message_outside_encoding_period(self):
        # Remove teaching charge application event
        self.academic_calendar.delete()
        url = reverse('outside_applications_period')
        response = self.client.get(url)
        messages = list(response.context['messages'])
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0].tags, 'warning')
        self.assertEqual(messages[0].message, _('The period of online application is closed'))

    def test_applications_overview(self):
        url = reverse('applications_overview')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        context = response.context[-1]
        self.assertEqual(context['a_tutor'], self.tutor)
        self.assertEqual(context['current_academic_year'], self.current_academic_year)
        self.assertEqual(context['application_year'], self.application_academic_year)
        self.assertEqual(len(context['attributions']), 1)
        self.assertEqual(context['attributions'][0]['acronym'], self.lagro2500_next.acronym)
        self.assertEqual(len(context['applications']), 1)
        self.assertEqual(context['applications'][0]['acronym'], self.lagro1600_next.acronym)
        self.assertEqual(len(context['attributions_about_to_expire']), 1)
        self.assertEqual(context['attributions_about_to_expire'][0]['acronym'], self.lbir1300_current.acronym)

    def test_applications_overview_post_method_not_allowed(self):
        url = reverse('applications_overview')
        response = self.client.post(url)
        self.assertEqual(response.status_code, 405)

    def test_search_vacant_attribution_initial(self):
        url = reverse('vacant_attributions_search')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        context = response.context[0]
        self.assertEqual(context['a_tutor'], self.tutor)
        self.assertTrue(context['search_form'])
        self.assertIsNone(context['attributions_vacant'])

    def test_search_vacant_attribution_post_not_allowed(self):
        url = reverse('vacant_attributions_search')
        response = self.client.post(url)
        self.assertEqual(response.status_code, 405)

    def test_search_vacant_attribution_search_list(self):
        url = reverse('vacant_attributions_search')
        response = self.client.get(url, data={'learning_container_acronym': 'LAGRO'})
        self.assertEqual(response.status_code, 200)
        context = response.context[-1]
        self.assertEqual(context['a_tutor'], self.tutor)
        self.assertTrue(context['search_form'])
        self.assertEqual(len(context['attributions_vacant']), 2)
        # Check if LAGRO1600 have the boolean already applied
        self.assertTrue((next(attrib for attrib in context['attributions_vacant']
                              if attrib.get('acronym') == self.lagro1600_next.acronym and
                              attrib.get('already_applied')), False))

    def test_search_vacant_attribution_search_list_by_faculty(self):
        url = reverse('vacant_attributions_search')
        response = self.client.get(
            url, data={
                'learning_container_acronym': 'LAGRO',
                'faculty': self.agro_entity_version.id
            }
        )
        self.assertEqual(response.status_code, 200)
        context = response.context[-1]
        self.assertEqual(len(context['attributions_vacant']), 2)

    def test_search_vacant_attribution_with_declaration_vac_not_allowed(self):
        # Create container with type_declaration_vacant not in [RESEVED_FOR_INTERNS, OPEN_FOR_EXTERNS]
        self.lagro1234_current = _create_learning_container_with_components("LAGRO1234", self.current_academic_year)
        # Creation learning container for next academic year [==> application academic year]
        self.lagro1234_next = _create_learning_container_with_components\
            ("LAGRO1234", self.application_academic_year, 70, 70,
             type_declaration_vacant=vacant_declaration_type.DO_NOT_ASSIGN)
        url = reverse('vacant_attributions_search')
        response = self.client.get(url, data={'learning_container_acronym': 'LAGRO1234'})
        self.assertEqual(response.status_code, 200)
        context = response.context[0]
        self.assertEqual(context['a_tutor'], self.tutor)
        self.assertTrue(context['search_form'])
        self.assertFalse(context['attributions_vacant'])

    def test_renew_applications(self):
        url = reverse('renew_applications')
        post_data = {'learning_container_year_' + self.lbir1300_next.acronym: 'on'}
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302)  # redirection
        self.attribution.refresh_from_db()
        self.assertEqual(len(self.attribution.applications), 2)  # Now we have two applications

    def test_renew_applications_with_bad_learning_container(self):
        url = reverse('renew_applications')
        post_data = {'learning_container_year_' + self.lagro2500_next.acronym: 'on'}
        response = self.client.post(url, data=post_data, follow=True)
        self.assertEqual(response.status_code, 200)
        messages = list(response.context['messages'])
        self.assertEqual(len(messages), 1)
        self.assertEqual(messages[0].tags, 'error')
        self.assertEqual(messages[0].message, _('No attribution renewed'))

    def test_renew_applications_method_not_allowed(self):
        url = reverse('renew_applications')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 405)

    def test_delete_application(self):
        url = reverse('delete_tutor_application', kwargs={'learning_container_year_id': self.lagro1600_next.id})
        response = self.client.post(url)
        self.assertEqual(response.status_code, 302)  # redirection
        self.attribution.refresh_from_db()
        # pending flag must be set to 'deleted'
        self.assertTrue((next(attrib for attrib in self.attribution.applications
                              if attrib.get('acronym') == self.lagro1600_next.acronym and
                              attrib.get('pending') == tutor_application_epc.DELETE_OPERATION), False))

    def test_delete_application_with_wrong_container(self):
        url = reverse('delete_tutor_application', kwargs={'learning_container_year_id': self.lbir1300_next.id})
        response = self.client.post(url)
        self.assertEqual(response.status_code, 404)  # Not found

    def test_delete_application_method_not_allowed(self):
        url = reverse('delete_tutor_application', kwargs={'learning_container_year_id': self.lagro1600_next.id})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 405)

    def test_get_edit_application_form(self):
        url = reverse('create_or_update_tutor_application',
                      kwargs={'learning_container_year_id': self.lagro1600_next.id})
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        context = response.context[0]
        self.assertEqual(context['a_tutor'], self.tutor)
        self.assertEqual(context['learning_container_year'], self.lagro1600_next)
        self.assertTrue(context['form'])

    def test_post_edit_application_form(self):
        url = reverse('create_or_update_tutor_application',
                      kwargs={'learning_container_year_id': self.lagro1600_next.id})
        post_data = _get_application_example(self.lagro1600_next, '54', '7')
        response = self.client.post(url, data=post_data, follow=True)
        self.assertEqual(response.status_code, 200)
        self.attribution.refresh_from_db()
        self.assertEqual(len(self.attribution.applications), 1)
        self.assertEqual(self.attribution.applications[0]['charge_lecturing_asked'], '54.0')
        self.assertEqual(self.attribution.applications[0]['charge_practical_asked'], '7.0')
        self.assertEqual(self.attribution.applications[0]['pending'], tutor_application_epc.UPDATE_OPERATION)

    def test_post_edit_application_form_with_empty_value(self):
        url = reverse('create_or_update_tutor_application',
                      kwargs={'learning_container_year_id': self.lagro1600_next.id})
        post_data = _get_application_example(self.lagro1600_next, None, None)
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 200)
        context = response.context[0]
        self.assertTrue(context.get('form'))
        form = context['form']
        self.assertTrue(form.errors)  # Not valid because not number entered

    def test_post_edit_application_form_with_empty_lecturing_value(self):
        url = reverse('create_or_update_tutor_application',
                      kwargs={'learning_container_year_id': self.lagro1600_next.id})
        post_data = _get_application_example(self.lagro1600_next, "15", "")
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 302)
        self.attribution.refresh_from_db()
        self.assertEqual(len(self.attribution.applications), 1)
        self.assertEqual(self.attribution.applications[0]['charge_lecturing_asked'], '15.0')
        self.assertEqual(self.attribution.applications[0]['charge_practical_asked'], '0.0')
        self.assertEqual(self.attribution.applications[0]['pending'], tutor_application_epc.UPDATE_OPERATION)

    def test_post_edit_application_form_with_value_under_zero(self):
        url = reverse('create_or_update_tutor_application',
                      kwargs={'learning_container_year_id': self.lagro1600_next.id})
        post_data = _get_application_example(self.lagro1600_next, '-1', '5')
        response = self.client.post(url, data=post_data)
        self.assertEqual(response.status_code, 200)
        context = response.context[0]
        self.assertTrue(context.get('form'))
        form = context['form']
        self.assertTrue(form.errors)  # Not valid because -1 entered

    def test_post_overview_with_lecturing_and_practical_component_partim(self):
        lbira2101a_next = _create_learning_container_with_components("LBIRA2101A", self.application_academic_year,
                                                                     volume_lecturing=20, volume_practical_exercices=20,
                                                                         subtype=learning_unit_year_subtypes.PARTIM)
        lbira2101a_current = _create_learning_container_with_components(
            "LBIRA2101A", self.current_academic_year,
            volume_lecturing=20, volume_practical_exercices=20,
            subtype=learning_unit_year_subtypes.PARTIM)
        _link_components_and_learning_unit_year_to_container(lbira2101a_current, "LBIRA2101",
                                                             subtype=learning_unit_year_subtypes.FULL)
        _link_components_and_learning_unit_year_to_container(lbira2101a_next, "LBIRA2101",
                                                             subtype=learning_unit_year_subtypes.FULL)
        self.attribution.delete()
        self.attribution = AttributionNewFactory(
            global_id=self.tutor.person.global_id,
            applications=[_get_application_example(lbira2101a_next, "10", "10")]
        )

        url = reverse('applications_overview')
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        context = response.context[0]
        self.assertEqual(len(context['applications']), 1)
        self.assertEqual(context['applications'][0]['acronym'], lbira2101a_next.acronym)
        with self.assertRaises(KeyError):
            context['applications'][0]['PRACTICAL_EXERCISES']
        with self.assertRaises(KeyError):
            context['applications'][0]['LECTURING']

    def _create_multiple_learning_container_year(self):
        # Creation learning container for current academic year
        self.lbir1200_current = _create_learning_container_with_components("LBIR1200", self.current_academic_year)
        self.lbir1300_current = _create_learning_container_with_components("LBIR1300", self.current_academic_year)
        self.ldroi1500_current = _create_learning_container_with_components("LDROI1500", self.current_academic_year)

        # Creation learning container for next academic year [==> application academic year]
        self.lbir1200_next = _create_learning_container_with_components("LBIR1200", self.application_academic_year,
                                                                        70, 70)
        self.lbir1300_next = _create_learning_container_with_components("LBIR1300", self.application_academic_year,
                                                                        60, 60)
        self.lagro1600_next = _create_learning_container_with_components("LAGRO1600", self.application_academic_year,
                                                                         54, 7)
        self.lagro2500_next = _create_learning_container_with_components("LAGRO2500", self.application_academic_year,
                                                                         0, 70)
        self._create_entity_container_yrs()

    def _get_default_application_list(self):
        return [
            _get_application_example(self.lagro1600_next, '15', '0')
        ]

    def _get_default_attribution_list(self):
        return [
            # Attribution in current year
            _get_attribution_example(self.lbir1200_current, '20.0', '31.5', 2015, 2019),
            _get_attribution_example(self.lbir1300_current, '21.5', '40', 2015, self.current_academic_year.year),
            # Attribution in next year
            _get_attribution_example(self.lagro2500_next, '29', '10', 2015, 2020)
        ]

    def _create_entity_container_yrs(self):
        self.lbir1200_current.allocation_entity = self.agro_entity
        self.lbir1200_current.save()
        self.lbir1300_current.allocation_entity = self.agro_entity
        self.lbir1300_current.save()
        self.lbir1200_next.allocation_entity = self.agro_entity
        self.lbir1200_next.save()
        self.lbir1300_next.allocation_entity = self.agro_entity
        self.lbir1300_next.save()
        self.lagro1600_next.allocation_entity = self.agro_entity
        self.lagro1600_next.save()
        self.lagro2500_next.allocation_entity = self.agro_entity
        self.lagro2500_next.save()
        self.ldroi1500_current.allocation_entity = self.drt_entity
        self.ldroi1500_current.save()
示例#3
0
class TestTutorApplicationEpc(TestCase):
    def setUp(self):
        self.academic_year = AcademicYearFactory(year=2017)
        external_id = tutor_application_epc.LEARNING_CONTAINER_YEAR_PREFIX_EXTERNAL_ID + '35654987_2017'
        self.lbir1200 = LearningContainerYearFactory(academic_year=self.academic_year, acronym="LBIR1200",
                                                     external_id=external_id)
        self.lagro2630 = LearningContainerYearFactory(academic_year=self.academic_year, acronym="LAGRO2630")

        # Creation Person/Tutor
        Group.objects.create(name="tutors")
        person = PersonFactory(global_id="98363454")
        external_id = tutor_application_epc.TUTOR_PREFIX_EXTERNAL_ID + '2089590559'
        self.tutor = TutorFactory(external_id=external_id, person=person)

        # Create two tutor applications
        applications = [_get_application_example(self.lbir1200, '30.5', '40.5'),
                        _get_application_example(self.lagro2630, '12.5', '0')]
        self.attribution = AttributionNewFactory(
            global_id=person.global_id,
            applications=applications
        )

    def test_extract_learning_container_year_epc_info(self):
        learning_container_info = tutor_application_epc._extract_learning_container_year_epc_info('LBIR1200', 2017)
        self.assertIsInstance(learning_container_info, dict)
        self.assertEqual(learning_container_info['reference'], '35654987')
        self.assertEqual(learning_container_info['year'], 2017)

    def test_extract_learning_container_year_epc_info_empty(self):
        learning_container_info = tutor_application_epc._extract_learning_container_year_epc_info('LBIR1250', 2017)
        self.assertIsInstance(learning_container_info, dict)
        self.assertFalse(learning_container_info)

    def test_extract_learning_container_year_epc_info_with_external_id_empty(self):
        self.lbir1200.external_id = None
        self.lbir1200.save()
        learning_container_info = tutor_application_epc._extract_learning_container_year_epc_info('LBIR1200', 2017)
        self.assertIsInstance(learning_container_info, dict)
        self.assertFalse(learning_container_info)

    def test_convert_to_epc_application(self):
        person = self.tutor.person
        application = _get_application_example(self.lbir1200, '30.5', '40.5')

        epc_message = tutor_application_epc._convert_to_epc_application(application=application)

        self.assertTrue(epc_message)
        self.assertEqual(epc_message['remark'], application['remark'])
        self.assertEqual(epc_message['course_summary'], application['course_summary'])
        self.assertEqual(epc_message['lecturing_allocation'], application['charge_lecturing_asked'])
        self.assertEqual(epc_message['practical_allocation'], application['charge_practical_asked'])
        self.assertIsInstance(epc_message['learning_container_year'], dict)
        self.assertEqual(epc_message['learning_container_year']['reference'], '35654987')
        self.assertEqual(epc_message['learning_container_year']['year'], 2017)

    def test_process_message_delete_operation(self):
        person = self.tutor.person
        self.assertEqual(len(self.attribution.applications), 2)
        body = {
            'operation': tutor_application_epc.DELETE_OPERATION,
            'global_id': person.global_id,
            'learning_container_year': {
                'acronym': 'LBIR1200',
                'year': 2017
            }
        }
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_epc.process_message(body_encoded)
        # Check if the application is removed
        self.attribution.refresh_from_db()
        self.assertEqual(len(self.attribution.applications), 1)
        attribution_left = self.attribution.applications[0]
        self.assertEqual(attribution_left['acronym'], self.lagro2630.acronym)

    def test_process_message_update_operation(self):
        person = self.tutor.person
        _set_all_application_in_pending_state(self.attribution.applications)
        self.attribution.save()
        ## Check if all are in pending
        self.assertEqual(len(self.attribution.applications), 2)
        self.assertEqual(self.attribution.applications[0]['pending'], tutor_application_epc.UPDATE_OPERATION)
        self.assertEqual(self.attribution.applications[1]['pending'], tutor_application_epc.UPDATE_OPERATION)

        body = {
            'operation': tutor_application_epc.UPDATE_OPERATION,
            'global_id': person.global_id,
            'learning_container_year': {
                'acronym': 'LBIR1200',
                'year': 2017
            }
        }
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_epc.process_message(body_encoded)
        # Check if the application is removed
        self.attribution.refresh_from_db()
        applications_not_pending = [application for application in self.attribution.applications if
                                    not "pending" in application]
        self.assertEqual(len(applications_not_pending), 1)


    def test_process_message_with_error_operation(self):
        person = self.tutor.person
        _set_all_application_in_pending_state(self.attribution.applications)
        self.attribution.save()
        ## Check if all are in pending
        self.assertEqual(len(self.attribution.applications), 2)
        self.assertEqual(self.attribution.applications[0]['pending'], tutor_application_epc.UPDATE_OPERATION)
        self.assertEqual(self.attribution.applications[1]['pending'], tutor_application_epc.UPDATE_OPERATION)

        body = {
            'operation': tutor_application_epc.UPDATE_OPERATION,
            'global_id': person.global_id,
            'learning_container_year': {
                'acronym': 'LBIR1200',
                'year': 2017
            },
            tutor_application_epc.ERROR_EPC_FIELD: 'An error occured in EPC'
        }
        body_encoded = bytearray(json.dumps(body), "utf-8")
        tutor_application_epc.process_message(body_encoded)
        # Check if the application is removed
        self.attribution.refresh_from_db()
        applications_not_pending = [application for application in self.attribution.applications if
                                    not "pending" in application]
        self.assertEqual(len(applications_not_pending), 0) # No changed