示例#1
0
    def test_create_case_for_course_salesforce_case_id_not_set_salesforce_id_set(
            self):
        course = CourseFactoryNoSignals(
            partner=self.salesforce_config.partner,
            salesforce_id='TestSalesforceId',
        )
        official_course = CourseFactoryNoSignals(
            partner=self.salesforce_config.partner,
            draft_version=course,
        )

        return_value = {'id': 'SomeSalesforceId'}

        with mock.patch(self.salesforce_path) as mock_salesforce:
            mock_salesforce().Case.create.return_value = return_value
            util = SalesforceUtil(self.salesforce_config.partner)
            util.create_case_for_course(course)
            mock_salesforce().Case.create.assert_called_with({
                'Course__c':
                course.salesforce_id,
                'Status':
                'Open',
                'Origin':
                'Publisher',
                'Subject':
                '{} Comments'.format(course.title),
                'Description':
                'This case is required to be Open for the Publisher comment service.',
                'RecordTypeId':
                self.salesforce_config.case_record_type_id,
            })
            assert course.salesforce_case_id == return_value.get('id')
            assert official_course.salesforce_case_id == return_value.get('id')
示例#2
0
    def test_wrapper_salesforce_os_error_calls_login(self):
        """
        Tests the wrapper when an OSError exception is thrown.
        The first exception thrown will trigger a re-login, the second will
        throw an exception as we don't want infinite retries.
        """
        course = CourseFactoryNoSignals(
            partner=self.salesforce_config.partner,
            salesforce_id='TestSalesforceId',
            salesforce_case_id='TestSalesforceCaseId',
        )

        with mock.patch(self.salesforce_util_path + '._query',
                        side_effect=OSError('Test Error')):
            with mock.patch(self.salesforce_path) as mock_salesforce:
                with mock.patch(
                        'course_discovery.apps.course_metadata.salesforce.logger'
                ) as mock_logger:
                    util = SalesforceUtil(self.salesforce_config.partner)
                    # Any method that has the decorator
                    with pytest.raises(OSError):
                        util.get_comments_for_course(course)
                    # 2 calls, one for initialization, one for login before exception
                    assert len(mock_salesforce.call_args_list) == 2
                    mock_logger.warning.assert_called_with(
                        'An OSError occurred while attempting to call get_comments_for_course for {}'
                        .format(str(course)))
示例#3
0
    def test_create_course_salesforce_id_not_set(self):
        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner)
        organization = OrganizationFactoryNoSignals(
            key='edX',
            partner=self.salesforce_config.partner,
            salesforce_id='Test')
        course.authoring_organizations.add(organization)
        partner = self.salesforce_config.partner

        return_value = {'id': 'SomeSalesforceId'}

        with mock.patch(self.salesforce_path) as mock_salesforce:
            mock_salesforce().Course__c.create.return_value = return_value
            util = SalesforceUtil(self.salesforce_config.partner)
            util.create_course(course)
            mock_salesforce().Course__c.create.assert_called_with({
                'Course_Name__c':
                course.title,
                'Link_to_Publisher__c':
                '{url}/courses/{uuid}'.format(
                    url=partner.publisher_url.strip('/'), uuid=course.uuid)
                if partner.publisher_url else None,
                'Link_to_Admin_Portal__c':
                '{url}/admin/course_metadata/course/{id}/change/'.format(
                    url=partner.site.domain.strip('/'), id=course.id)
                if partner.site.domain else None,
                'Course_Key__c':
                course.key,
                'Publisher_Organization__c':
                organization.salesforce_id,
            })
            assert course.salesforce_id == return_value.get('id')
示例#4
0
    def test_create_course_run_salesforce_id_not_set(self):
        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_id='TestSalesforceId')
        course_run = CourseRunFactoryNoSignals(course=course)
        partner = self.salesforce_config.partner

        return_value = {'id': 'SomeSalesforceId'}

        with mock.patch(self.salesforce_path) as mock_salesforce:
            mock_salesforce().Course_Run__c.create.return_value = return_value
            util = SalesforceUtil(self.salesforce_config.partner)
            util.create_course_run(course_run)
            mock_salesforce().Course_Run__c.create.assert_called_with({
                'Course__c':
                course_run.course.salesforce_id,
                'Link_to_Admin_Portal__c':
                '{url}/admin/course_metadata/courserun/{id}/change/'.format(
                    url=partner.site.domain.strip('/'), id=course_run.id),
                'Course_Start_Date__c':
                course_run.start.isoformat(),
                'Course_End_Date__c':
                course_run.end.isoformat(),
                'Publisher_Status__c':
                'Live',  # Expected return value from _get_equivalent_status
                'Course_Run_Name__c':
                course_run.title,
                'Expected_Go_Live_Date__c':
                None,
                'Course_Number__c':
                course_run.key,
                # Expected return value from _get_equivalent_ofac_review_decision
                'OFAC_Review_Decision__c':
                'OFAC Enabled',
            })
            assert course_run.salesforce_id == return_value.get('id')
示例#5
0
    def test_create_comment_for_course_case_salesforce_case_id_not_set(self):
        create_case_path = self.salesforce_util_path + '.create_case_for_course'

        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_id='TestSalesforceId')
        user = UserFactory()

        body = 'Test body'

        # Need to modify state of the instance passed in
        def new_create_course_case(self, instance):  # pylint: disable=unused-argument
            instance.salesforce_case_id = 'SomeSalesforceId'
            instance.save()

        with mock.patch(self.salesforce_path) as mock_salesforce:
            with mock.patch(create_case_path, new=new_create_course_case):
                util = SalesforceUtil(self.salesforce_config.partner)
                assert course.salesforce_case_id is None
                util.create_comment_for_course_case(course, user, body)
                mock_salesforce().FeedItem.create.assert_called_with({
                    'ParentId':
                    course.salesforce_case_id,
                    'Body':
                    util.format_user_comment_body(user, body, None)
                })
                assert course.salesforce_case_id is not None
示例#6
0
    def test_wrapper_salesforce_expired_session_calls_login(self):
        """
        Tests the wrapper when a SalesforceExpiredSession is thrown.
        The first exception thrown will trigger a re-login, the second will
        throw an exception as we don't want infinite retries.
        """
        course = CourseFactoryNoSignals(
            partner=self.salesforce_config.partner,
            salesforce_id='TestSalesforceId',
            salesforce_case_id='TestSalesforceCaseId',
        )

        with mock.patch(self.salesforce_util_path + '._query',
                        side_effect=SalesforceExpiredSession(
                            url='Test',
                            status=401,
                            resource_name='Test',
                            content='Test')):
            with mock.patch(self.salesforce_path) as mock_salesforce:
                util = SalesforceUtil(self.salesforce_config.partner)
                # Any method that has the decorator
                with pytest.raises(SalesforceExpiredSession):
                    util.get_comments_for_course(course)
                # 2 calls, one for initialization, one for login before exception
                assert len(mock_salesforce.call_args_list) == 2
示例#7
0
    def test_format_and_parse(self):
        user = UserFactory()
        body = 'This is a test body.'
        course_run_key = 'course-v1:testX+TestX+Test'

        with mock.patch(self.salesforce_path):
            util = SalesforceUtil(self.salesforce_config.partner)
            formatted_message = util.format_user_comment_body(
                user, body, course_run_key)
            expected_formatted_message = '[User]\n{}\n\n[Course Run]\n{}\n\n[Body]\n{}'.format(
                '{} {} ({})'.format(user.first_name, user.last_name,
                                    user.username), course_run_key, body)
            assert formatted_message == expected_formatted_message
            parsed_message = util._parse_user_comment_body(  # pylint: disable=protected-access
                {'Body': formatted_message})
            parsed_user = parsed_message.get('user')
            assert parsed_user.get('username') == user.username
            # Below 3 will always be None for a matched comment
            assert parsed_user.get('email') is None
            assert parsed_user.get('first_name') is None
            assert parsed_user.get('last_name') is None

            assert parsed_message.get('course_run_key') == course_run_key
            assert parsed_message.get('comment') == body
            user.first_name = ''
            user.last_name = ''
            user.save()

            formatted_message = util.format_user_comment_body(
                user, body, course_run_key)
            expected_formatted_message = '[User]\n{}\n\n[Course Run]\n{}\n\n[Body]\n{}'.format(
                '{}'.format(user.username), course_run_key, body)
            assert formatted_message == expected_formatted_message
示例#8
0
    def test_get_comments_for_course_case_id_not_set(self):
        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_id='TestSalesforceId')

        with mock.patch(self.salesforce_path):
            util = SalesforceUtil(self.salesforce_config.partner)
            comments = util.get_comments_for_course(course)
            assert comments == []
示例#9
0
 def test_soql_escape(self):
     with mock.patch(self.salesforce_path):
         util = SalesforceUtil(self.salesforce_config.partner)
         escaped_string = util.soql_escape(r"Some 'test' \string")
         self.assertEqual(
             escaped_string,
             r"Some \'test\' \\string",
         )
示例#10
0
    def test_create_case_for_course_salesforce_case_id_set(self):
        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_case_id='Test')

        with mock.patch(self.salesforce_path) as mock_salesforce:
            util = SalesforceUtil(self.salesforce_config.partner)
            util.create_case_for_course(course)
            mock_salesforce().Case.create.assert_not_called()
示例#11
0
 def test_singleton(self):
     new_config = SalesforceConfigurationFactory()
     with mock.patch(self.salesforce_path):
         # Instantiate these twice for the same partner, verify only one instance is created each
         SalesforceUtil(self.salesforce_config.partner)
         SalesforceUtil(self.salesforce_config.partner)
         SalesforceUtil(new_config.partner)
         SalesforceUtil(new_config.partner)
     assert len(SalesforceUtil.instances) == 2
示例#12
0
    def test_create_course_run_salesforce_id_set(self):
        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_id='Test')
        course_run = CourseRunFactoryNoSignals(course=course,
                                               salesforce_id='Test')

        with mock.patch(self.salesforce_path) as mock_salesforce:
            util = SalesforceUtil(self.salesforce_config.partner)
            util.create_course_run(course_run)
            mock_salesforce().Course_Run__c.create.assert_not_called()
示例#13
0
    def test_create_account_salesforce_id_set(self):
        organization = OrganizationFactoryNoSignals(
            key='edX',
            partner=self.salesforce_config.partner,
            salesforce_id='Test')

        with mock.patch(self.salesforce_path) as mock_salesforce:
            util = SalesforceUtil(self.salesforce_config.partner)
            util.create_publisher_organization(organization)

            mock_salesforce(
            ).Publisher_Organization__c.create.assert_not_called()
示例#14
0
    def test_update_course_run(self, salesforce_id):
        """Test Cases: updating course run with a salesforce_id, with no salesforce_id"""
        course_run = CourseRunFactory()
        course_run.salesforce_id = salesforce_id

        with mock.patch(self.salesforce_path) as mock_salesforce:
            with mock.patch(self.salesforce_util_path +
                            '.create_course_run') as mock_create:
                util = SalesforceUtil(self.salesforce_config.partner)
                util.update_course_run(course_run)
                if salesforce_id:
                    mock_salesforce().Course_Run__c.update.assert_called()
                else:
                    mock_salesforce().Course_Run__c.update.assert_not_called()
                    mock_create.assert_called()
示例#15
0
    def test_update_publisher_organization(self, salesforce_id):
        """Test Cases: updating organization with a salesforce_id, with no salesforce_id"""
        organization = OrganizationFactoryNoSignals(
            partner=self.salesforce_config.partner,
            salesforce_id=salesforce_id)

        with mock.patch(self.salesforce_path) as mock_salesforce:
            util = SalesforceUtil(self.salesforce_config.partner)
            util.update_publisher_organization(organization)
            if salesforce_id:
                mock_salesforce(
                ).Publisher_Organization__c.update.assert_called()
            else:
                mock_salesforce(
                ).Publisher_Organization__c.update.assert_not_called()
示例#16
0
 def test_wrapper_salesforce_without_client_raises_not_configured_exception(
         self):
     """
     Tests the wrapper when no config is found but a query is run
     """
     course = CourseFactoryNoSignals(
         partner=self.salesforce_config.partner,
         salesforce_id='TestSalesforceId',
         salesforce_case_id='TestSalesforceCaseId',
     )
     with mock.patch(self.salesforce_path):
         util = SalesforceUtil(self.salesforce_config.partner)
         SalesforceUtil.instances[
             self.salesforce_config.partner].client = None
         # Any method that has the decorator
         with pytest.raises(SalesforceNotConfiguredException):
             util.get_comments_for_course(course)
示例#17
0
    def test_create_course_run_course_salesforce_id_not_set(self):
        create_course_path = self.salesforce_util_path + '.create_course'

        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner)
        course_run = CourseRunFactoryNoSignals(course=course)
        partner = self.salesforce_config.partner

        return_value = {'id': 'SomeSalesforceId'}

        # Need to modify state of the instance passed in
        def new_create_course(self, instance):  # pylint: disable=unused-argument
            instance.salesforce_id = 'SomeSalesforceId'
            instance.save()

        with mock.patch(self.salesforce_path) as mock_salesforce:
            with mock.patch(create_course_path, new=new_create_course):
                mock_salesforce(
                ).Course_Run__c.create.return_value = return_value
                util = SalesforceUtil(self.salesforce_config.partner)
                assert course.salesforce_id is None
                util.create_course_run(course_run)
                mock_salesforce().Course_Run__c.create.assert_called_with({
                    'Course__c':
                    course_run.course.salesforce_id,
                    'Link_to_Admin_Portal__c':
                    '{url}/admin/course_metadata/courserun/{id}/change/'.
                    format(url=partner.site, id=course_run.id),
                    'Course_Start_Date__c':
                    course_run.start.isoformat(),
                    'Course_End_Date__c':
                    course_run.end.isoformat(),
                    'Publisher_Status__c':
                    'Live',  # Expected return value from _get_equivalent_status
                    'Course_Run_Name__c':
                    course_run.title,
                    'Expected_Go_Live_Date__c':
                    None,
                    'Course_Number__c':
                    course_run.key,
                    # Expected return value from _get_equivalent_ofac_review_decision
                    'OFAC_Review_Decision__c':
                    'OFAC Enabled',
                })
            assert course.salesforce_id is not None
            assert course_run.salesforce_id == return_value.get('id')
示例#18
0
    def test_create_account_salesforce_id_not_set(self):
        organization = OrganizationFactoryNoSignals(
            key='edX', partner=self.salesforce_config.partner)

        return_value = {'id': 'SomeSalesforceId'}

        with mock.patch(self.salesforce_path) as mock_salesforce:
            mock_salesforce(
            ).Publisher_Organization__c.create.return_value = return_value
            util = SalesforceUtil(self.salesforce_config.partner)
            util.create_publisher_organization(organization)
            mock_salesforce(
            ).Publisher_Organization__c.create.assert_called_with({
                'Organization_Name__c':
                organization.name,
                'Organization_Key__c':
                organization.key,
            })
            assert organization.salesforce_id == return_value.get('id')
示例#19
0
    def test_create_course_organization_salesforce_id_not_set(self):
        create_pub_org_path = (self.salesforce_util_path +
                               '.create_publisher_organization')

        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner)
        organization = OrganizationFactoryNoSignals(
            key='edX', partner=self.salesforce_config.partner)
        course.authoring_organizations.add(organization)
        partner = self.salesforce_config.partner

        return_value = {'id': 'SomeSalesforceId'}

        # Need to modify state of the instance passed in
        def new_create_organization(self, instance):  # pylint: disable=unused-argument
            instance.salesforce_id = 'SomeSalesforceId'
            instance.save()

        with mock.patch(self.salesforce_path) as mock_salesforce:
            with mock.patch(create_pub_org_path, new=new_create_organization):
                mock_salesforce().Course__c.create.return_value = return_value
                util = SalesforceUtil(self.salesforce_config.partner)
                assert organization.salesforce_id is None
                util.create_course(course)
                organization.refresh_from_db()
                mock_salesforce().Course__c.create.assert_called_with({
                    'Course_Name__c':
                    course.title,
                    'Link_to_Publisher__c':
                    '{url}/courses/{uuid}'.format(
                        url=partner.publisher_url.strip('/'), uuid=course.uuid)
                    if partner.publisher_url else None,
                    'Link_to_Admin_Portal__c':
                    '{url}/admin/course_metadata/course/{id}/change/'.format(
                        url=partner.site.domain.strip('/'), id=course.id)
                    if partner.site.domain else None,
                    'Course_Key__c':
                    course.key,
                    'Publisher_Organization__c':
                    organization.salesforce_id,
                })

                assert organization.salesforce_id is not None
                assert course.salesforce_id == return_value.get('id')
示例#20
0
    def test_create_comment_for_course_case_raises_exceptions(self):
        create_case_path = self.salesforce_util_path + '.create_case_for_course'

        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_id='TestSalesforceId')
        user = UserFactory()

        body = 'Test body'

        # Need to modify state of the instance passed in and make it None to simulate an error
        def new_create_course_case(self, instance):  # pylint: disable=unused-argument
            instance.salesforce_case_id = None
            instance.save()

        with mock.patch(self.salesforce_path):
            with mock.patch(create_case_path, new=new_create_course_case):
                util = SalesforceUtil(self.salesforce_config.partner)
                assert course.salesforce_case_id is None
                with pytest.raises(SalesforceMissingCaseException):
                    util.create_comment_for_course_case(course, user, body)
示例#21
0
    def test_create_comment_for_course_case_salesforce_case_id_set(self):
        create_case_path = self.salesforce_util_path + '.create_case_for_course'

        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_case_id='TestSalesforceId')
        user = UserFactory()

        body = 'Test body'

        with mock.patch(self.salesforce_path) as mock_salesforce:
            with mock.patch(create_case_path) as mock_create_case_for_course:
                util = SalesforceUtil(self.salesforce_config.partner)
                util.create_comment_for_course_case(course, user, body)
                mock_salesforce().FeedItem.create.assert_called_with({
                    'ParentId':
                    course.salesforce_case_id,
                    'Body':
                    util.format_user_comment_body(user, body, None)
                })
                mock_create_case_for_course.assert_not_called()
示例#22
0
    def test_create_case_for_course_salesforce_case_id_not_set_salesforce_id_not_set(
            self):
        create_course_path = self.salesforce_util_path + '.create_course'

        self.salesforce_config.case_record_type_id = 'TestId'

        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner)

        return_value = {'id': 'SomeSalesforceId'}

        # Need to modify state of the instance passed in
        def new_create_course(self, instance):  # pylint: disable=unused-argument
            instance.salesforce_id = 'SomeSalesforceId'
            instance.save()

        with mock.patch(self.salesforce_path) as mock_salesforce:
            with mock.patch(create_course_path, new=new_create_course):
                mock_salesforce().Case.create.return_value = return_value
                util = SalesforceUtil(self.salesforce_config.partner)
                self.assertIsNone(course.salesforce_id)
                util.create_case_for_course(course)
                mock_salesforce().Case.create.assert_called_with({
                    'Course__c':
                    course.salesforce_id,
                    'Status':
                    'Open',
                    'Origin':
                    'Publisher',
                    'Subject':
                    '{} Comments'.format(course.title),
                    'Description':
                    'This case is required to be Open for the Publisher comment service.',
                    'RecordTypeId':
                    self.salesforce_config.case_record_type_id,
                })
                self.assertIsNotNone(course.salesforce_id)
                self.assertEqual(course.salesforce_case_id,
                                 return_value.get('id'))
示例#23
0
    def test_login(self):
        # Update the config to reflect what we'll run locally
        self.salesforce_config.security_token = ''
        self.salesforce_config.save()

        with mock.patch(self.salesforce_path) as mock_salesforce:
            with mock.patch(
                    'course_discovery.apps.course_metadata.salesforce.requests'
            ) as mock_requests:
                SalesforceUtil(self.salesforce_config.partner)
                mock_salesforce.assert_called_with(
                    session=mock_requests.Session(),
                    **{
                        'username': self.salesforce_config.username,
                        'password': self.salesforce_config.password,
                        'organizationId':
                        self.salesforce_config.organization_id,
                        'security_token': '',
                        'domain': 'test',
                    })
示例#24
0
    def test_get_comments_for_course_case_id_set(self):
        user = UserFactory()
        query_path = self.salesforce_util_path + '._query'

        course = CourseFactoryNoSignals(partner=self.salesforce_config.partner,
                                        salesforce_case_id='TestSalesforceId')

        return_value = {
            'records': [
                {
                    'CreatedBy': {
                        'Username': user.username
                    },
                    'CreatedDate':
                    '2000-01-01',
                    'Body':
                    ('[User]\n{}\n\n'
                     '[Course Run]\ncourse-v1:testX+TestX+Test\n\n'
                     '[Body]\nThis is a formatted test message.').format(
                         user.username),
                },
                {
                    'CreatedBy': {
                        'Username': '******'
                    },
                    'CreatedDate': '2000-01-01',
                    'Body':
                    'This is an internal user comment without formatting.'
                },
            ]
        }

        with mock.patch(self.salesforce_path):
            with mock.patch(query_path,
                            return_value=return_value) as mock_query:
                util = SalesforceUtil(self.salesforce_config.partner)
                comments = util.get_comments_for_course(course)
                mock_query.assert_called_with(
                    "SELECT CreatedDate,Body,CreatedBy.Username,CreatedBy.Email,CreatedBy.FirstName,CreatedBy.LastName "
                    "FROM FeedItem WHERE ParentId='{}' AND IsDeleted=FALSE ORDER BY CreatedDate ASC"
                    .format(course.salesforce_case_id))
                assert comments == [{
                    'user': {
                        'username': user.username,
                        'email': user.email,
                        'first_name': user.first_name,
                        'last_name': user.last_name
                    },
                    'course_run_key': 'course-v1:testX+TestX+Test',
                    'comment': 'This is a formatted test message.',
                    'created': '2000-01-01'
                }, {
                    'user': {
                        'username': '******',
                        'email': None,
                        'first_name': None,
                        'last_name': None
                    },
                    'course_run_key': None,
                    'comment':
                    'This is an internal user comment without formatting.',
                    'created': '2000-01-01'
                }]
示例#25
0
def get_salesforce_util(partner):
    try:
        return SalesforceUtil(partner)
    except SalesforceConfiguration.DoesNotExist:
        return None
示例#26
0
 def _get_salesforce_util_or_404(partner):
     try:
         return SalesforceUtil(partner)
     except SalesforceConfiguration.DoesNotExist:
         raise Http404