Beispiel #1
0
    def test_request_password_change(self):
        # Create and activate an account
        self.create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
        self.assertEqual(len(mail.outbox), 1)

        user = User.objects.get(username=self.USERNAME)
        activation_key = self.get_activation_key(user)
        activate_account(activation_key)

        request = RequestFactory().post('/password')
        request.user = Mock()
        request.site = SiteFactory()

        with patch('crum.get_current_request', return_value=request):
            # Request a password change
            request_password_change(self.EMAIL, self.IS_SECURE)

        # Verify that a new email message has been sent
        self.assertEqual(len(mail.outbox), 2)

        # Verify that the body of the message contains something that looks
        # like an activation link
        email_body = mail.outbox[0].body
        result = re.search(r'(?P<url>https?://[^\s]+)', email_body)
        self.assertIsNot(result, None)
Beispiel #2
0
    def test_decline(self):
        """ Verify the view reports an error if the transaction is only authorized pending review. """
        basket = self._create_valid_basket()
        data = self._generate_data(basket.id)
        order_number = OrderNumberGenerator().order_number_from_basket_id(
            self.site.siteconfiguration.partner,
            basket.id,
        )
        # This response has been pruned to only the needed data.
        self._prep_request_success(
            """{"links":{"_self":{"href":"/pts/v2/payments/6021683934456376603262","method":"GET"}},"id":"6021683934456376603262","status":"DECLINED","error_information":{"reason":"PROCESSOR_DECLINED","message":"Decline - General decline of the card. No other information provided by the issuing bank."},"client_reference_information":{"code":"%s"},"processor_information":{"transaction_id":"460282531937765","network_transaction_id":"460282531937765","response_code":"005","avs":{"code":"D","code_raw":"D"},"card_verification":{"result_code":"M","result_code_raw":"M"}},"payment_information":{"account_features":{"category":"F"}}}"""
            % order_number  # pylint: disable=line-too-long
        )
        response = self.client.post(self.path, data)

        assert response.status_code == 400
        assert response['content-type'] == JSON

        request = RequestFactory(SERVER_NAME='testserver.fake').post(
            self.path, data)
        request.site = self.site
        assert json.loads(
            response.content
        )['redirectTo'] == get_payment_microfrontend_or_basket_url(request)

        # Ensure the basket is frozen
        basket = Basket.objects.get(pk=basket.pk)
        self.assertEqual(basket.status, Basket.MERGED)
        assert Basket.objects.count() == 2
Beispiel #3
0
    def setUp(self):
        super(SiteMixin, self).setUp()

        # Set the domain used for all test requests
        domain = 'testserver.fake'
        self.client = self.client_class(SERVER_NAME=domain)

        Site.objects.get_current().delete()
        site_configuration = SiteConfigurationFactory(
            partner__name='edX',
            site__id=settings.SITE_ID,
            site__domain=domain,
            segment_key='fake_segment_key',
            oauth_settings={
                'SOCIAL_AUTH_EDX_OIDC_KEY': 'key',
                'SOCIAL_AUTH_EDX_OIDC_SECRET': 'secret'
            }
        )
        self.partner = site_configuration.partner
        self.site = site_configuration.site

        request = RequestFactory().get('')
        request.session = None
        request.site = self.site
        set_thread_variable('request', request)
    def test_listboard_filter_view(self):

        class SubjectVisitModelWrapper(ModelWrapper):
            model = 'edc_dashboard.subjectvisit'
            next_url_name = 'thenexturl'

        class MyListboardViewFilters(ListboardViewFilters):

            all = ListboardFilter(
                name='all',
                label='All',
                lookup={})

            scheduled = ListboardFilter(
                label='Scheduled',
                lookup={'reason': 'scheduled'})

            not_scheduled = ListboardFilter(
                label='Not Scheduled',
                exclude_filter=True,
                lookup={'reason': 'scheduled'})

        class MyView(ListboardFilterViewMixin, ListboardView):

            model = 'edc_dashboard.subjectvisit'
            listboard_url = 'listboard_url'
            listboard_template = 'listboard_template'
            listboard_filter_url = 'listboard_url'
            model_wrapper_cls = SubjectVisitModelWrapper
            listboard_view_filters = MyListboardViewFilters()

        start = datetime(2013, 5, 1, 12, 30)
        end = datetime(2013, 5, 10, 17, 15)
        for r in arrow.Arrow.range('day', start, end):
            SubjectVisit.objects.create(
                subject_identifier='1234',
                report_datetime=r.datetime,
                reason='missed')
        subject_visit = SubjectVisit.objects.create(
            subject_identifier='1234',
            report_datetime=get_utcnow(),
            reason='scheduled')
        request = RequestFactory().get('/?scheduled=scheduled')
        request.user = '******'
        request.site = Site.objects.get_current()
        request.url_name_data = {'listboard_url': 'listboard_url'}
        request.template_data = {'listboard_template': 'listboard.html'}
        template_response = MyView.as_view()(request=request)
        object_list = template_response.__dict__.get(
            'context_data').get('object_list')
        self.assertEqual(
            [wrapper.object.reason for wrapper in object_list
             if wrapper.object.pk == subject_visit.pk], [subject_visit.reason])
    def test_request_password_change_inactive_user(self):
        # Create an account, but do not activate it
        create_account(self.USERNAME, self.PASSWORD, self.EMAIL)

        request = RequestFactory().post('/password')
        request.user = Mock()
        request.site = SiteFactory()

        with patch('crum.get_current_request', return_value=request):
            request_password_change(self.EMAIL, self.IS_SECURE)

        # Verify that the activation email was still sent
        self.assertEqual(len(mail.outbox), 1)
Beispiel #6
0
    def test_order_number_for_basket_without_site(self):
        """ Verify the order number is linked to the default site, if the basket has no associated site. """
        site_configuration = SiteConfigurationFactory(site__domain='acme.fake', partner__name='ACME')
        site = site_configuration.site
        partner = site_configuration.partner
        basket = BasketFactory(site=None)

        request = RequestFactory().get('')
        request.session = None
        request.site = site

        with mock.patch('ecommerce.extensions.order.utils.get_current_request', mock.Mock(return_value=request)):
            self.assert_order_number_matches_basket(basket, partner)
Beispiel #7
0
    def test_order_number_for_basket_without_site(self):
        """ Verify the order number is linked to the default site, if the basket has no associated site. """
        site_configuration = SiteConfigurationFactory(site__domain='acme.fake', partner__name='ACME')
        site = site_configuration.site
        partner = site_configuration.partner
        basket = BasketFactory(site=None)

        request = RequestFactory().get('')
        request.session = None
        request.site = site

        with mock.patch('ecommerce.extensions.order.utils.get_current_request', mock.Mock(return_value=request)):
            self.assert_order_number_matches_basket(basket, partner)
    def test_listboard_filter_view(self):
        class SubjectVisitModelWrapper(ModelWrapper):
            model = "edc_dashboard.subjectvisit"
            next_url_name = "dashboard_url"

        class MyListboardViewFilters(ListboardViewFilters):
            all = ListboardFilter(name="all", label="All", lookup={})

            scheduled = ListboardFilter(label="Scheduled",
                                        lookup={"reason": "scheduled"})

            not_scheduled = ListboardFilter(
                label="Not Scheduled",
                exclude_filter=True,
                lookup={"reason": "scheduled"},
            )

        class MyView(ListboardFilterViewMixin, ListboardView):
            listboard_model = "edc_dashboard.subjectvisit"
            listboard_url = "listboard_url"
            listboard_template = "listboard_template"
            listboard_filter_url = "listboard_url"
            listboard_view_permission_codename = "edc_dashboard.view_my_listboard"
            model_wrapper_cls = SubjectVisitModelWrapper
            listboard_view_filters = MyListboardViewFilters()

        start = datetime(2013, 5, 1, 12, 30)
        end = datetime(2013, 5, 10, 17, 15)
        for r in arrow.Arrow.range("day", start, end):
            SubjectVisit.objects.create(subject_identifier="1234",
                                        report_datetime=r.datetime,
                                        reason="missed")
        subject_visit = SubjectVisit.objects.create(
            subject_identifier="1234",
            report_datetime=get_utcnow(),
            reason="scheduled")
        request = RequestFactory().get("/?scheduled=scheduled")
        request.user = self.user
        request.site = Site.objects.get_current()
        # request.url_name_data = {"listboard_url": "listboard_url"}
        request.template_data = {"listboard_template": "listboard.html"}
        template_response = MyView.as_view()(request=request)
        object_list = template_response.__dict__.get("context_data").get(
            "object_list")
        self.assertEqual(
            [
                wrapper.object.reason for wrapper in object_list
                if wrapper.object.pk == subject_visit.pk
            ],
            [subject_visit.reason],
        )
Beispiel #9
0
    def test_request_password_change(self):
        # Create and activate an account
        self.create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
        assert len(mail.outbox) == 1

        request = RequestFactory().post('/password')
        request.user = Mock()
        request.site = SiteFactory()

        with patch('crum.get_current_request', return_value=request):
            # Request a password change
            request_password_change(self.EMAIL, self.IS_SECURE)

        # Verify that a new email message has been sent
        assert len(mail.outbox) == 2

        # Verify that the body of the message contains something that looks
        # like an activation link
        email_body = mail.outbox[0].body
        result = re.search(r'(?P<url>https?://[^\s]+)', email_body)
        assert result is not None
Beispiel #10
0
    def test_request_password_change(self):
        # Create and activate an account
        activation_key = create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
        activate_account(activation_key)

        request = RequestFactory().post('/password')
        request.user = Mock()
        request.site = SiteFactory()

        with patch('crum.get_current_request', return_value=request):
            # Request a password change
            request_password_change(self.EMAIL, self.IS_SECURE)

        # Verify that one email message has been sent
        self.assertEqual(len(mail.outbox), 1)

        # Verify that the body of the message contains something that looks
        # like an activation link
        email_body = mail.outbox[0].body
        result = re.search(r'(?P<url>https?://[^\s]+)', email_body)
        self.assertIsNot(result, None)
Beispiel #11
0
    def test_authorized_pending_review_request_reversal_failed(self):
        """ Verify the view reports an error if the transaction is only authorized pending review. """
        basket = self._create_valid_basket()
        data = self._generate_data(basket.id)
        order_number = OrderNumberGenerator().order_number_from_basket_id(
            self.site.siteconfiguration.partner,
            basket.id,
        )
        # This response has been pruned to only the needed data.
        self._prep_request_success(
            """{"links":{"_self":{"href":"/pts/v2/payments/6038898237296087603031","method":"GET"}},"id":"6038898237296087603031","submit_time_utc":"2020-10-28T12:57:04Z","status":"AUTHORIZED_PENDING_REVIEW","error_information":{"reason":"AVS_FAILED","message":"Soft Decline - The authorization request was approved by the issuing bank but declined by CyberSource because it did not pass the Address Verification Service (AVS) check."},"client_reference_information":{"code":"%s"},"processor_information":{"approval_code":"028252","transaction_id":"580302466249046","network_transaction_id":"580302466249046","response_code":"000","avs":{"code":"N","code_raw":"N"},"card_verification":{"result_code":"M","result_code_raw":"M"}},"payment_information":{"account_features":{"category":"C"}},"order_information":{"amount_details":{"authorized_amount":"25.00","currency":"USD"}}}"""
            % order_number  # pylint: disable=line-too-long
        )
        self._prep_request_invalid(
            """{"submitTimeUtc":"2020-09-30T18:53:23Z","status":"INVALID_REQUEST","reason":"DUPLICATE_REQUEST","message":"Declined - The\u00a0merchantReferenceCode\u00a0sent with this authorization request matches the merchantReferenceCode of another authorization request that you sent in the last 15 minutes."}""",  # pylint: disable=line-too-long
            '6038898237296087603031')

        response = self.client.post(self.path, data)

        assert response.status_code == 400
        assert response['content-type'] == JSON

        request = RequestFactory(SERVER_NAME='testserver.fake').post(
            self.path, data)
        request.site = self.site
        assert json.loads(
            response.content
        )['redirectTo'] == get_payment_microfrontend_or_basket_url(request)

        # Ensure the basket is frozen
        basket = Basket.objects.get(pk=basket.pk)
        self.assertEqual(basket.status, Basket.MERGED)
        assert Basket.objects.count() == 2

        # Ensure that 2 requests were sent to cybersource
        assert self.mock_cybersource_request.call_count == 2

        # Ensure that 2 requests and 2 responses were recorded as PaymentProcessorResponses
        assert PaymentProcessorResponse.objects.all().count() == 4
Beispiel #12
0
    def test_for_non_staff_user_return_error(self):
        password = '******'
        user = EdlyUserFactory(password=password)
        site = SiteFactory(name=self.site_name)
        site_config = SiteConfigurationFactory(
            values={'address': self.site_address}, site=site)
        EdlySubOrganizationFactory(lms_site=site)
        request = RequestFactory()
        request.user = user
        request.site = site

        self.client.login(username=user.username, password=password)
        self.client.cookies.load({
            settings.EDLY_USER_INFO_COOKIE_NAME:
            cookies._get_edly_user_info_cookie_string(request)
        })
        url = reverse('redhouse_panel:redhouse_panel_api.v0:site',
                      kwargs={'pk': site.id})
        response = self.client.get(url, SERVER_NAME=site.domain)

        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
        self.assertEqual(response.data['detail'],
                         'You do not have permission to perform this action.')
Beispiel #13
0
    def setUp(self):
        super(SiteMixin, self).setUp()

        # Set the domain used for all test requests
        domain = 'testserver.fake'
        self.client = self.client_class(SERVER_NAME=domain)

        Site.objects.all().delete()
        site_configuration = SiteConfigurationFactory(
            partner__name='edX',
            site__id=settings.SITE_ID,
            site__domain=domain,
            segment_key='fake_segment_key',
            oauth_settings={
                'SOCIAL_AUTH_EDX_OIDC_KEY': 'key',
                'SOCIAL_AUTH_EDX_OIDC_SECRET': 'secret'
            })
        self.partner = site_configuration.partner
        self.site = site_configuration.site

        request = RequestFactory().get('')
        request.session = None
        request.site = self.site
        set_thread_variable('request', request)
Beispiel #14
0
 def dummy_request(self, user=None):
     request = RequestFactory().get('/')
     request.user = user or AnonymousUser()
     request.site = Site.objects.first()
     return request
Beispiel #15
0
 def dummy_request(self, user=None):
     request = RequestFactory().get('/')
     request.user = user or AnonymousUser()
     request.site = Site.objects.first()
     return request
Beispiel #16
0
    def create_coupon(
            self,
            title='Test coupon',
            price=100,
            client=None,
            partner=None,
            catalog=None,
            code='',
            benefit_value=100,
            note=None,
            max_uses=None,
            quantity=5
    ):
        """Helper method for creating a coupon.

        Arguments:
            title(str): Title of the coupon
            price(int): Price of the coupon
            partner(Partner): Partner used for creating a catalog
            catalog(Catalog): Catalog of courses for which the coupon applies
            code(str): Custom coupon code
            benefit_value(int): The voucher benefit value

        Returns:
            coupon (Coupon)

        """
        if partner is None:
            partner = PartnerFactory(name='Tester')
        if client is None:
            client, __ = BusinessClient.objects.get_or_create(name='Test Client')
        if catalog is None:
            catalog = Catalog.objects.create(partner=partner)
        if code is not '':
            quantity = 1
        data = {
            'partner': partner,
            'benefit_type': Benefit.PERCENTAGE,
            'benefit_value': benefit_value,
            'catalog': catalog,
            'end_date': datetime.date(2020, 1, 1),
            'code': code,
            'quantity': quantity,
            'start_date': datetime.date(2015, 1, 1),
            'voucher_type': Voucher.SINGLE_USE,
            'categories': [self.category],
            'note': note,
            'max_uses': max_uses,
        }

        coupon = CouponViewSet().create_coupon_product(
            title=title,
            price=price,
            data=data
        )

        request = RequestFactory()
        request.site = self.site
        request.user = factories.UserFactory()
        request.COOKIES = {}

        self.basket = prepare_basket(request, coupon)

        self.response_data = CouponViewSet().create_order_for_invoice(self.basket, coupon_id=coupon.id, client=client)
        coupon.client = client

        return coupon
Beispiel #17
0
    def handle(self, *args, **options):
        site_id = options.get('site_id')
        try:
            site = Site.objects.get(id=site_id)
        except Site.DoesNotExist:
            logger.exception('Site id %s does not exist', site_id)
            raise Exception

        try:
            site_configurations = SiteConfiguration.objects.get(site=site)
            configuration_helpers = site_configurations.edly_client_theme_branding_settings
            voucher_api_url = configuration_helpers.get(
                'LUMSXPAY_VOUCHER_API_URL')
            if not voucher_api_url:
                logger.exception(
                    'Cron Job of Update Payment Statuses is canceled due to no '
                    'LUMSXPAY_VOUCHER_API_URL in client theme branding')
                raise Exception
        except:
            logger.exception(
                'Site Configurations with side id %s does not exist', site_id)
            raise Exception

        try:
            unpaid_challan_baskets = BasketChallanVoucher.objects.filter(
                is_paid=False)
        except:
            logger.exception(
                'could not fetch the unpaid challan baskets from Database')
            raise Exception

        headers = {
            "Authorization":
            configuration_helpers.get('PAYMENT_AUTHORIZATION_KEY'),
            "Content-Type": "application/json"
        }

        paid_vouchers = []
        unpaid_vouchers = unpaid_challan_baskets.values_list('voucher_number',
                                                             flat=True)
        if unpaid_challan_baskets:
            for unpaid_vouchers_lst in list(
                    self.equal_divided_chunks(list(unpaid_vouchers),
                                              self.VOUCHERS_PER_REQUEST)):
                unpaid_vouchers_str = ','.join(unpaid_vouchers_lst)
                url = '{}/{}'.format(voucher_api_url, unpaid_vouchers_str)

                response = requests.get(url, headers=headers)
                if response.status_code == 200:
                    voucher_details = response.json()

                    voucher_data = voucher_details['data']
                    if not isinstance(voucher_details['data'], list):
                        voucher_data = [voucher_details['data']]

                    for voucher in voucher_data:
                        if voucher['paid_status'].lower() == 'paid':
                            paid_vouchers.append(voucher['voucher_id'])
                else:
                    logger.info('VOUCHER API doesnot return 200 OK')
                    return
        else:
            logger.info('No unpaid voucher found for update payment status')
            return

        if not paid_vouchers:
            logger.info('No voucher paid so exiting the job')
            return

        unpaid_basket_ids = unpaid_challan_baskets.filter(
            voucher_number__in=paid_vouchers).values_list('basket_id',
                                                          flat=True)

        paid_baskets = Basket.objects.filter(id__in=unpaid_basket_ids,
                                             status=Basket.OPEN)

        if not paid_baskets:
            logger.info(
                'ERROR: Basket corresponding to voucher does not exist')
            raise Exception

        for basket in paid_baskets:
            shipping_method = NoShippingRequired()
            shipping_charge = shipping_method.calculate(basket)
            basket.strategy = DefaultStrategy()
            order_total = OrderTotalCalculator().calculate(
                basket, shipping_charge)
            user = basket.owner
            billing_address = None
            request = RequestFactory()
            request.site = site
            request.user = user
            request.site.siteconfiguration = site_configurations
            set_thread_variable('request', request)
            order = EdxOrderPlacementMixin().handle_order_placement(
                order_number=basket.order_number,
                user=user,
                basket=basket,
                shipping_address=None,
                shipping_method=shipping_method,
                shipping_charge=shipping_charge,
                billing_address=billing_address,
                order_total=order_total,
                request=request)

            EdxOrderPlacementMixin().handle_post_order(order)
            challan_voucher_basket = BasketChallanVoucher.objects.filter(
                basket_id=basket.id)

            if len(challan_voucher_basket) > 1:
                logger.info(
                    'more than one basket exist with same id in challan table.'
                )
            elif challan_voucher_basket:
                challan_voucher_basket.update(is_paid=True)

        logger.info(
            'Successfully finished the cron job for updating the order payment'
        )
        return
Beispiel #18
0
    def create_coupon(self,
                      title='Test coupon',
                      price=100,
                      client=None,
                      partner=None,
                      catalog=None,
                      code='',
                      benefit_value=100,
                      note=None,
                      max_uses=None,
                      quantity=5):
        """Helper method for creating a coupon.

        Arguments:
            title(str): Title of the coupon
            price(int): Price of the coupon
            partner(Partner): Partner used for creating a catalog
            catalog(Catalog): Catalog of courses for which the coupon applies
            code(str): Custom coupon code
            benefit_value(int): The voucher benefit value

        Returns:
            coupon (Coupon)

        """
        if partner is None:
            partner = PartnerFactory(name='Tester')
        if client is None:
            client, __ = BusinessClient.objects.get_or_create(
                name='Test Client')
        if catalog is None:
            catalog = Catalog.objects.create(partner=partner)
        if code is not '':
            quantity = 1
        data = {
            'partner': partner,
            'benefit_type': Benefit.PERCENTAGE,
            'benefit_value': benefit_value,
            'catalog': catalog,
            'end_date': datetime.date(2020, 1, 1),
            'code': code,
            'quantity': quantity,
            'start_date': datetime.date(2015, 1, 1),
            'voucher_type': Voucher.SINGLE_USE,
            'categories': [self.category],
            'note': note,
            'max_uses': max_uses,
        }

        coupon = CouponViewSet().create_coupon_product(title=title,
                                                       price=price,
                                                       data=data)

        request = RequestFactory()
        request.site = self.site
        request.user = factories.UserFactory()
        request.COOKIES = {}

        self.basket = prepare_basket(request, coupon)

        self.response_data = CouponViewSet().create_order_for_invoice(
            self.basket, coupon_id=coupon.id, client=client)
        coupon.client = client

        return coupon