def setUp(self):
        super().setUp()
        self.pk_generator = itertools.count(1)

        stored_site, created = Site.objects.get_or_create(  # pylint: disable=unused-variable
            domain='example.com')
        self.default_partner = Partner.objects.create(site=stored_site,
                                                      name='edX',
                                                      short_code='edx')

        SeatType.objects.all().delete()
        ProgramType.objects.all().delete()

        self.partner = PartnerFactory(name='Test')
        self.organization = OrganizationFactory(partner=self.partner)
        self.seat_type_verified = SeatTypeFactory(name='Verified',
                                                  slug='verified')
        self.program_type_masters = ProgramTypeFactory(
            name='Masters',
            name_t='Masters',
            slug='masters',
            applicable_seat_types=[self.seat_type_verified])
        self.program_type_masters_translation = self.program_type_masters.translations.all(
        )[0]

        self.program_type_mm = ProgramTypeFactory(
            name='MicroMasters',
            name_t='MicroMasters',
            slug='micromasters',
            applicable_seat_types=[self.seat_type_verified])
        self.program_type_mm_translation = self.program_type_mm.translations.all(
        )[0]

        self.course = CourseFactory(
            partner=self.partner, authoring_organizations=[self.organization])
        self.course_run = CourseRunFactory(course=self.course)
        self.program = ProgramFactory(
            type=self.program_type_masters,
            partner=self.partner,
            authoring_organizations=[self.organization])
        self.course_mm = CourseFactory(
            partner=self.partner, authoring_organizations=[self.organization])
        self.course_run_mm = CourseRunFactory(course=self.course)
        self.program_mm = ProgramFactory(
            type=self.program_type_mm,
            partner=self.partner,
            authoring_organizations=[self.organization],
            courses=[self.course_mm])
        self.curriculum = CurriculumFactory(program=self.program)
        self.curriculum_course_membership = CurriculumCourseMembershipFactory(
            course=self.course, curriculum=self.curriculum)
        self.curriculum_program_membership = CurriculumProgramMembershipFactory(
            program=self.program_mm, curriculum=self.curriculum)

        self.program_2 = ProgramFactory(
            type=self.program_type_masters,
            partner=self.partner,
            authoring_organizations=[self.organization])

        self._mock_oauth_request()
Example #2
0
 def setUp(self):
     super().setUp()
     self.partner = PartnerFactory(lms_url='http://127.0.0.1:8000')
     self.mock_access_token()
     with mock.patch(
             'course_discovery.apps.course_metadata.data_loaders.configured_jwt_decode_handler',
             return_value={'preferred_username': '******'},
     ):
         self.loader = self.loader_class(self.partner, self.api_url)
Example #3
0
 def setUp(self):
     super(PersonViewSetTests, self).setUp()
     self.user = UserFactory(is_staff=True, is_superuser=True)
     self.client.force_authenticate(self.user)
     self.person = PersonFactory()
     self.organization = OrganizationFactory()
     # DEFAULT_PARTNER_ID is used explicitly here to avoid issues with differences in
     # auto-incrementing behavior across databases. Otherwise, it's not safe to assume
     # that the partner created here will always have id=DEFAULT_PARTNER_ID.
     self.partner = PartnerFactory(id=settings.DEFAULT_PARTNER_ID)
 def setUp(self):
     super(PersonViewSetTests, self).setUp()
     self.user = UserFactory(is_staff=True, is_superuser=True)
     self.client.force_authenticate(self.user)
     self.person = PersonFactory()
     PositionFactory(person=self.person)
     self.organization = OrganizationFactory()
     # DEFAULT_PARTNER_ID is used explicitly here to avoid issues with differences in
     # auto-incrementing behavior across databases. Otherwise, it's not safe to assume
     # that the partner created here will always have id=DEFAULT_PARTNER_ID.
     self.partner = PartnerFactory(id=settings.DEFAULT_PARTNER_ID)
     toggle_switch('publish_person_to_marketing_site', True)
     self.expected_node = {
         'resource': 'node',
         ''
         'id': '28691',
         'uuid': '18d5542f-fa80-418e-b416-455cfdeb4d4e',
         'uri': 'https://stage.edx.org/node/28691'
     }
Example #5
0
 def setUp(self):
     super(CourseRunViewSetTests, self).setUp()
     self.user = UserFactory(is_staff=True, is_superuser=True)
     self.client.force_authenticate(self.user)
     self.partner = PartnerFactory()
     self.course_run = CourseRunFactory(course__partner=self.partner)
     self.course_run_2 = CourseRunFactory(course__partner=self.partner)
     self.refresh_index()
     self.request = APIRequestFactory().get('/')
     self.request.user = self.user
 def setUp(self):
     super().setUp()
     self.partner = PartnerFactory(short_code="testx")
     self.organization = OrganizationFactory(partner=self.partner,
                                             name="testx")
     self.logo = mock.MagicMock(spec=File, name="logo")
     self.logo.name = "logo"
     self.certificate_logo = mock.MagicMock(spec=File,
                                            name="certificate_logo")
     self.certificate_logo.name = "certificate_logo"
     self.banner_image = mock.MagicMock(spec=File, name="banner_image")
     self.banner_image.name = "banner image"
Example #7
0
 def setUp(self):
     super(CourseRunViewSetTests, self).setUp()
     self.user = UserFactory(is_staff=True, is_superuser=True)
     self.client.force_authenticate(self.user)
     # DEFAULT_PARTNER_ID is used explicitly here to avoid issues with differences in
     # auto-incrementing behavior across databases. Otherwise, it's not safe to assume
     # that the partner created here will always have id=DEFAULT_PARTNER_ID.
     self.partner = PartnerFactory(id=settings.DEFAULT_PARTNER_ID)
     self.course_run = CourseRunFactory(course__partner=self.partner)
     self.course_run_2 = CourseRunFactory(course__partner=self.partner)
     self.refresh_index()
     self.request = APIRequestFactory().get('/')
     self.request.user = self.user
 def setUp(self):
     super().setUp()
     self.partner = PartnerFactory()
     self.command_args = [f'--partner_code={self.partner.short_code}']
Example #9
0
 def setUp(self):
     super(DataLoaderTestMixin, self).setUp()
     self.partner = PartnerFactory(lms_url='http://127.0.0.1:8000')
     self.loader = self.loader_class(self.partner, self.api_url)
     self.mock_access_token()
Example #10
0
 def setUp(self):
     super(DataLoaderTestMixin, self).setUp()
     self.partner = PartnerFactory()
     self.loader = self.loader_class(self.partner, self.api_url)
     self.mock_access_token()
class PersonViewSetTests(SerializationMixin, APITestCase):
    """ Tests for the person resource. """
    people_list_url = reverse('api:v1:person-list')

    def setUp(self):
        super(PersonViewSetTests, self).setUp()
        self.user = UserFactory(is_staff=True, is_superuser=True)
        self.client.force_authenticate(self.user)
        self.person = PersonFactory()
        PositionFactory(person=self.person)
        self.organization = OrganizationFactory()
        # DEFAULT_PARTNER_ID is used explicitly here to avoid issues with differences in
        # auto-incrementing behavior across databases. Otherwise, it's not safe to assume
        # that the partner created here will always have id=DEFAULT_PARTNER_ID.
        self.partner = PartnerFactory(id=settings.DEFAULT_PARTNER_ID)
        toggle_switch('publish_person_to_marketing_site', True)
        self.expected_node = {
            'resource': 'node',
            ''
            'id': '28691',
            'uuid': '18d5542f-fa80-418e-b416-455cfdeb4d4e',
            'uri': 'https://stage.edx.org/node/28691'
        }

    def test_create_with_authentication(self):
        """ Verify endpoint successfully creates a person. """
        with mock.patch.object(MarketingSitePeople,
                               'publish_person',
                               return_value=self.expected_node):
            response = self.client.post(self.people_list_url,
                                        self._person_data(),
                                        format='json')
            self.assertEqual(response.status_code, 201)

        data = self._person_data()
        person = Person.objects.last()
        self.assertDictEqual(response.data, self.serialize_person(person))
        self.assertEqual(person.given_name, data['given_name'])
        self.assertEqual(person.family_name, data['family_name'])
        self.assertEqual(person.bio, data['bio'])
        self.assertEqual(person.position.title, data['position']['title'])
        self.assertEqual(person.position.organization, self.organization)
        self.assertEqual(
            sorted([work.value for work in person.person_works.all()]),
            sorted(data['works']))
        self.assertEqual(
            sorted([social.value for social in person.person_networks.all()]),
            sorted([
                data['urls']['facebook'], data['urls']['twitter'],
                data['urls']['blog']
            ]))

    def test_create_without_drupal_client_settings(self):
        """ Verify that if credentials are missing api will return the error. """
        self.partner.marketing_site_api_username = None
        self.partner.save()
        data = self._person_data()

        with LogCapture(people_logger.name) as log_capture:
            response = self.client.post(self.people_list_url,
                                        self._person_data(),
                                        format='json')
            self.assertEqual(response.status_code, 400)
            log_capture.check((
                people_logger.name, 'ERROR',
                'An error occurred while adding the person [{}]-[{}] to the marketing site.'
                .format(data['given_name'], data['family_name'])))

    def test_create_with_api_exception(self):
        """ Verify that after creating drupal page if serializer fail due to any error, message
        will be logged and drupal page will be deleted. """

        data = self._person_data()
        with mock.patch.object(MarketingSitePeople,
                               'publish_person',
                               return_value=self.expected_node):
            with mock.patch(
                    'course_discovery.apps.api.v1.views.people.PersonViewSet.perform_create',
                    side_effect=IntegrityError):
                with mock.patch.object(MarketingSitePeople,
                                       'delete_person',
                                       return_value=None):
                    with LogCapture(people_logger.name) as log_capture:
                        response = self.client.post(self.people_list_url,
                                                    self._person_data(),
                                                    format='json')
                        self.assertEqual(response.status_code, 400)
                        log_capture.check((
                            people_logger.name, 'ERROR',
                            'An error occurred while adding the person [{}]-[{}]-[{}].'
                            .format(data['given_name'], data['family_name'],
                                    self.expected_node['id'])))

    def test_create_without_authentication(self):
        """ Verify authentication is required when creating a person. """
        self.client.logout()
        Person.objects.all().delete()

        response = self.client.post(self.people_list_url, {}, format='json')
        self.assertEqual(response.status_code, 403)
        self.assertEqual(Person.objects.count(), 0)

    def test_get(self):
        """ Verify the endpoint returns the details for a single person. """
        url = reverse('api:v1:person-detail',
                      kwargs={'uuid': self.person.uuid})

        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, self.serialize_person(self.person))

    def test_list(self):
        """ Verify the endpoint returns a list of all people. """
        response = self.client.get(self.people_list_url)
        self.assertEqual(response.status_code, 200)
        self.assertListEqual(
            response.data['results'],
            self.serialize_person(Person.objects.all(), many=True))

    def test_create_without_waffle_switch(self):
        """ Verify endpoint shows error message if waffle switch is disabled. """
        toggle_switch('publish_person_to_marketing_site', False)
        response = self.client.post(self.people_list_url,
                                    self._person_data(),
                                    format='json')
        self.assertEqual(response.status_code, 400)

    def _person_data(self):
        return {
            'given_name': "Robert",
            'family_name': "Ford",
            'bio': "The maze is not for him.",
            'position': {
                'title': "Park Director",
                'organization': self.organization.id
            },
            'works': ["Delores", "Teddy", "Maive"],
            'urls': {
                'facebook': 'http://www.facebook.com/hopkins',
                'twitter': 'http://www.twitter.com/hopkins',
                'blog': 'http://www.blog.com/hopkins'
            }
        }

    def test_update(self):
        """Verify that people data can be updated using endpoint."""
        url = reverse('api:v1:person-detail',
                      kwargs={'uuid': self.person.uuid})

        data = {
            'given_name': "updated",
            'family_name': "name",
            'bio': "updated bio",
            'position': {
                'title': "new title",
                'organization': self.organization.id
            },
            'works': ["new", "added"],
            'urls': {
                'facebook': 'http://www.facebook.com/new',
                'twitter': 'http://www.twitter.com/new',
            }
        }

        response = self.client.patch(url, data, format='json')
        self.assertEqual(response.status_code, 200)

        updated_person = Person.objects.get(id=self.person.id)

        self.assertEqual(updated_person.given_name, data['given_name'])
        self.assertEqual(updated_person.family_name, data['family_name'])
        self.assertEqual(updated_person.bio, data['bio'])
        self.assertEqual(updated_person.position.title,
                         data['position']['title'])
        self.assertEqual(updated_person.person_works.all()[0].value,
                         data['works'][0])
        self.assertEqual(updated_person.person_works.all()[1].value,
                         data['works'][1])
        self.assertEqual(
            updated_person.person_networks.get(type='facebook').value,
            data['urls']['facebook'])
        self.assertEqual(
            updated_person.person_networks.get(type='twitter').value,
            data['urls']['twitter'])
        self.assertFalse(
            updated_person.person_networks.filter(type='blog').exists())
Example #12
0
 def setUp(self):
     super(CreateTestProgramCommandTests, self).setUp()
     self.partner = PartnerFactory()
     self.command_args = [
         '--partner_code={}'.format(self.partner.short_code)
     ]
Example #13
0
 def setUp(self):
     super(DataLoaderTestMixin, self).setUp()
     self.partner = PartnerFactory()
     self.loader = self.loader_class(self.partner, self.api_url,
                                     ACCESS_TOKEN, ACCESS_TOKEN_TYPE)