예제 #1
0
 def test_update_person_failed(self):
     self.mock_api_client(200)
     self.mock_node_edit(500)
     self.mock_node_retrieval('uuid', self.uuid, status=200)
     people = MarketingSitePeople()
     with self.assertRaises(PersonToMarketingException):
         people.update_person(self.person)
예제 #2
0
 def test_create_node_failed(self):
     self.mock_api_client(200)
     self.mock_node_create({}, 500)
     people = MarketingSitePeople()
     people_data = people._get_node_data(self.person)  # pylint: disable=protected-access
     with pytest.raises(PersonToMarketingException):
         people._create_node(self.api_client, people_data)  # pylint: disable=protected-access
예제 #3
0
 def test_update_person(self):
     self.mock_api_client(200)
     self.mock_node_edit(200)
     self.mock_node_retrieval('uuid', self.uuid, status=200)
     people = MarketingSitePeople()
     data = people.update_person(self.person)
     self.assertEqual(data, {})
예제 #4
0
 def test_person_create_failed(self):
     self.mock_api_client(200)
     self.mock_node_create({}, 500)
     self.mock_node_retrieval('uuid', self.uuid, exists=False, status=200)
     people = MarketingSitePeople()
     with pytest.raises(PersonToMarketingException):
         people.update_or_publish_person(self.person)
예제 #5
0
 def test_update_node(self):
     self.mock_api_client(200)
     self.mock_node_edit(200)
     people = MarketingSitePeople()
     data = people._update_node(self.api_client, self.node_id,
                                self.updated_node_data)  # pylint: disable=protected-access
     self.assertEqual(data, {})
예제 #6
0
 def test_update_person_json(self, mock_update_node):
     self.mock_api_client(200)
     self.mock_node_retrieval('uuid', self.uuid, status=200)
     people = MarketingSitePeople()
     people.update_or_publish_person(self.person)
     assert mock_update_node.call_count == 1
     data = mock_update_node.call_args[0][2]
     self.assertDictEqual(data, self.expected_data)
예제 #7
0
 def test_delete_person_by_uuid_not_found(self):
     people = MarketingSitePeople()
     with LogCapture(LOGGER_NAME) as log:
         people.delete_person_by_uuid(self.partner, self.uuid)
         log.check(
             (LOGGER_NAME, 'INFO',
              'Person with UUID [{}] does not exist on the marketing site'.
              format(self.uuid)))
예제 #8
0
 def test_update_uuid_not_found(self):
     self.mock_api_client(200)
     people = MarketingSitePeople()
     with LogCapture(LOGGER_NAME) as log:
         people.update_person(self.person)
         log.check(
             (LOGGER_NAME, 'INFO',
              'Person with UUID [{}] does not exist on the marketing site'.
              format(self.uuid)))
예제 #9
0
 def test_person_create_json(self, mock_create_node):
     people = MarketingSitePeople()
     people.publish_person(self.person)
     self.assertEqual(mock_create_node.call_count, 1)
     data = mock_create_node.call_args[0][1]
     expected = self.expected_data
     expected.update({
         'status': 1,
         'uuid': self.uuid,
     })
     self.assertDictEqual(data, expected)
예제 #10
0
 def test_person_create_json(self, mock_create_node):
     self.mock_api_client(200)
     self.mock_node_retrieval('uuid', self.uuid, exists=False, status=200)
     people = MarketingSitePeople()
     people.update_or_publish_person(self.person)
     assert mock_create_node.call_count == 1
     data = mock_create_node.call_args[0][1]
     expected = self.expected_data
     expected.update({
         'status': 1,
         'uuid': self.uuid,
     })
     self.assertDictEqual(data, expected)
예제 #11
0
 def test_update_or_publish_person(self, exists):
     self.mock_api_client(200)
     if exists:
         self.mock_node_edit(200)
     else:
         self.mock_node_create(self.expected_node, 201)
     self.mock_node_retrieval('uuid', self.uuid, exists=exists, status=200)
     people = MarketingSitePeople()
     result = people.update_or_publish_person(self.person)
     if exists:
         assert result == {}
     else:
         assert result == self.expected_node
예제 #12
0
    def create(self, request, *args, **kwargs):
        """ Create a new person. """
        person_data = request.data

        partner = request.site.partner
        person_data['partner'] = partner.id
        serializer = self.get_serializer(data=person_data)
        serializer.is_valid(raise_exception=True)

        if waffle.switch_is_active('publish_person_to_marketing_site'):
            try:
                marketing_person = MarketingSitePeople()
                response = marketing_person.publish_person(
                    partner, {
                        'given_name': serializer.validated_data['given_name'],
                        'family_name': serializer.validated_data['family_name']
                    })
                serializer.validated_data.pop('uuid')
                serializer.validated_data['uuid'] = response['uuid']

            except (PersonToMarketingException,
                    MarketingSiteAPIClientException):
                logger.exception(
                    'An error occurred while adding the person [%s]-[%s] to the marketing site.',
                    serializer.validated_data['given_name'],
                    serializer.validated_data['family_name'])
                return Response(
                    'Failed to add person data to the marketing site.',
                    status=status.HTTP_400_BAD_REQUEST)

            try:
                self.perform_create(serializer)
            except Exception:  # pylint: disable=broad-except
                logger.exception(
                    'An error occurred while adding the person [%s]-[%s]-[%s].',
                    serializer.validated_data['given_name'],
                    serializer.validated_data['family_name'], response['id'])
                marketing_person.delete_person(partner, response['id'])
                return Response('Failed to add person data.',
                                status=status.HTTP_400_BAD_REQUEST)

            headers = self.get_success_headers(serializer.data)
            return Response(serializer.data,
                            status=status.HTTP_201_CREATED,
                            headers=headers)

        return Response('publish_program_to_marketing_site is disabled.',
                        status=status.HTTP_400_BAD_REQUEST)
예제 #13
0
    def create(self, request, *args, **kwargs):
        """
        Create a person in discovery and also create a person node in drupal
        """
        person_data = request.data

        partner = request.site.partner
        person_data['partner'] = partner.id
        serializer = self.get_serializer(data=person_data)
        serializer.is_valid(raise_exception=True)

        try:
            self.perform_create(serializer)
        except Exception:  # pylint: disable=broad-except
            logger.exception(
                'An error occurred while adding the person [%s]-[%s] in discovery.',
                serializer.validated_data['given_name'], serializer.validated_data['family_name'],
            )
            return Response('Failed to add person data.', status=status.HTTP_400_BAD_REQUEST)

        try:
            if waffle.switch_is_active('publish_person_to_marketing_site'):
                MarketingSitePeople().publish_person(serializer.instance)
        except (PersonToMarketingException, MarketingSiteAPIClientException):
            serializer.instance.delete()
            logger.exception(
                'An error occurred while adding the person [%s]-[%s] to the marketing site.',
                serializer.validated_data['given_name'], serializer.validated_data['family_name']
            )
            return Response('Failed to add person data to the marketing site.', status=status.HTTP_400_BAD_REQUEST)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)
예제 #14
0
    def handle(self, *args, **options):
        config = DrupalPublishUuidConfig.get_solo()

        # Publish course runs
        if config.course_run_ids:
            course_run_ids = config.course_run_ids.split(',')
            course_runs = CourseRun.objects.filter(key__in=course_run_ids)
            for course_run in course_runs:
                publisher = CourseRunMarketingSitePublisher(
                    course_run.course.partner)
                publisher.publish_obj(course_run, include_uuid=True)

        # Publish people
        if config.push_people:
            publisher = MarketingSitePeople()
            for person in Person.objects.all():
                logger.info('Updating person node %s [%s].', person.slug,
                            person.uuid)
                try:
                    publisher.update_person(person)
                except (PersonToMarketingException,
                        MarketingSiteAPIClientException):
                    logger.exception(
                        'An error occurred while updating person %s on the marketing site.',
                        person.full_name,
                    )
예제 #15
0
    def update(self, request, *args, **kwargs):  # pylint: disable=unused-argument
        """
        Updates a person in discovery and the corresponding person node in drupal
        """
        person_data = request.data

        partner = request.site.partner
        person_data['partner'] = partner.id
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance,
                                         data=person_data,
                                         partial=partial)
        serializer.is_valid(raise_exception=True)

        if not waffle.switch_is_active('publish_person_to_marketing_site'):
            return Response('publish_person_to_marketing_site is disabled.',
                            status=status.HTTP_400_BAD_REQUEST)
        try:
            marketing_person = MarketingSitePeople()
            marketing_person.update_person(partner,
                                           serializer.validated_data['uuid'],
                                           self._get_person_data(serializer))

        except (PersonToMarketingException, MarketingSiteAPIClientException):
            logger.exception(
                'An error occurred while updating the person [%s]-[%s] on the marketing site.',
                serializer.validated_data['given_name'],
                serializer.validated_data['family_name'])
            return Response(
                'Failed to update person data on the marketing site.',
                status=status.HTTP_400_BAD_REQUEST)

        try:
            self.perform_update(serializer)
        except Exception:  # pylint: disable=broad-except
            logger.exception(
                'An error occurred while updating the person [%s]-[%s] in discovery.',
                serializer.validated_data['given_name'],
                serializer.validated_data['family_name'])
            return Response('Failed to update person data.',
                            status=status.HTTP_400_BAD_REQUEST)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_200_OK,
                        headers=headers)
    def delete_person(self, pinfo, commit=False):
        # Foreign keys to worry about:
        #
        # Just delete
        # - Position
        # - PersonSocialNetwork
        # - PersonWork
        #
        # Move to target
        # - Endorsement
        # - Program instructor_ordering (sortedm2m)
        # - CourseRun staff (sortedm2m)
        # - Publisher CourseRun staff (sortedm2m)

        logger.info(  # pylint: disable=logging-not-lazy
            '{} {}:\n'.format(_('Deleting') if commit else _('Would delete'), pinfo.person.uuid) +
            ' {}: {}\n'.format(_('Name'), pinfo.person.full_name) +
            ' {}: {}\n'.format(_('Endorsements'), pinfo.person.endorsement_set.count()) +
            ' {}: {}\n'.format(_('Programs'), pinfo.person.program_set.count()) +
            ' {}: {}\n'.format(_('Course Runs'), pinfo.person.courses_staffed.count()) +
            ' {}: {} ({})\n'.format(_('Target'), pinfo.target.full_name, pinfo.target.uuid)
        )
        if not commit:
            return

        # First, delete the person in the marketing site, if they exist there
        try:
            MarketingSitePeople().delete_person_by_uuid(pinfo.person.partner, pinfo.person.uuid)
        except MarketingSiteAPIClientException:
            # This will occur if the partner has no marketing site associated with it - not an error condition for
            # this management command and not something we need to tell user about for each person.
            pass

        # Move endorsements
        Endorsement.objects.filter(endorser=pinfo.person).update(endorser=pinfo.target)

        def filter_person(person):
            return pinfo.target if person == pinfo.person else person

        # Update programs
        for program in pinfo.person.program_set.all():
            if pinfo.target in program.instructor_ordering.all():
                continue
            new_instructors = [filter_person(instructor) for instructor in program.instructor_ordering.all()]
            program.instructor_ordering.set(new_instructors)

        # Update metadata course runs
        for course_run in pinfo.person.courses_staffed.all():
            if pinfo.target in course_run.staff.all():
                continue
            new_staff = [filter_person(staff) for staff in course_run.staff.all()]
            course_run.staff.set(new_staff)

        # And finally, actually delete the person
        pinfo.person.delete()
예제 #17
0
    def update(self, request, *args, **kwargs):  # pylint: disable=unused-argument
        """
        Updates a person in discovery and the corresponding person node in drupal
        """
        person_data = request.data

        partner = request.site.partner
        person_data['partner'] = partner.id
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance,
                                         data=person_data,
                                         partial=partial)
        serializer.is_valid(raise_exception=True)

        # Save a copy of the original data so we can revert to it if marketing update fails
        original_data = self.get_serializer(instance).data

        try:
            self.perform_update(serializer)
        except Exception:  # pylint: disable=broad-except
            logger.exception(
                'An error occurred while updating the person [%s]-[%s] in discovery.',
                serializer.validated_data['given_name'],
                serializer.validated_data['family_name'])
            return Response('Failed to update person data.',
                            status=status.HTTP_400_BAD_REQUEST)

        try:
            if waffle.switch_is_active('publish_person_to_marketing_site'):
                MarketingSitePeople().update_person(instance)
        except (PersonToMarketingException, MarketingSiteAPIClientException):
            # First, roll back to previous version of this person
            try:
                self.perform_update(
                    self.get_serializer(instance, data=original_data))
            except Exception:  # pylint: disable=broad-except
                pass  # ignore for now

            logger.exception(
                'An error occurred while updating the person [%s]-[%s] on the marketing site.',
                serializer.validated_data['given_name'],
                serializer.validated_data['family_name'])
            return Response(
                'Failed to update person data on the marketing site.',
                status=status.HTTP_400_BAD_REQUEST)

        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data,
                        status=status.HTTP_200_OK,
                        headers=headers)
예제 #18
0
 def test_update_node_failed(self):
     self.mock_api_client(200)
     self.mock_node_edit(500)
     people = MarketingSitePeople()
     with pytest.raises(PersonToMarketingException):
         people._update_node(self.api_client, self.node_id, {})  # pylint: disable=protected-access
예제 #19
0
 def test_create_node(self):
     self.mock_api_client(200)
     self.mock_node_create(self.expected_node, 201)
     people = MarketingSitePeople()
     data = people._create_node(self.api_client, {})  # pylint: disable=protected-access
     assert data == self.expected_node
예제 #20
0
 def test_delete_person_by_uuid(self):
     self.mock_api_client(200)
     self.mock_node_retrieval('uuid', self.uuid, status=200)
     self.mock_node_delete(200)
     people = MarketingSitePeople()
     people.delete_person_by_uuid(self.partner, self.uuid)
예제 #21
0
 def test_delete_person(self):
     self.mock_api_client(200)
     self.mock_node_delete(200)
     people = MarketingSitePeople()
     people.delete_person(self.partner, self.node_id)
예제 #22
0
 def test_person_create(self):
     self.mock_api_client(200)
     self.mock_node_create(self.expected_node, 201)
     people = MarketingSitePeople()
     result = people.publish_person(self.partner, self.data)
     self.assertEqual(result, self.expected_node)
예제 #23
0
 def test_person_create_failed(self):
     self.mock_api_client(200)
     self.mock_node_create({}, 500)
     people = MarketingSitePeople()
     with self.assertRaises(PersonToMarketingException):
         people.publish_person(self.partner, self.data)
예제 #24
0
 def test_get_node_id_from_uuid(self):
     self.mock_api_client(200)
     self.mock_node_retrieval('uuid', self.uuid, status=200)
     people = MarketingSitePeople()
     data = people._get_node_id_from_uuid(self.api_client, self.uuid)  # pylint: disable=protected-access
     assert data == self.node_id
예제 #25
0
 def test_get_node_id_from_uuid_failed(self):
     self.mock_api_client(200)
     self.mock_node_retrieval('uuid', self.uuid, status=500)
     people = MarketingSitePeople()
     with pytest.raises(PersonToMarketingException):
         people._get_node_id_from_uuid(self.api_client, self.uuid)  # pylint: disable=protected-access