Esempio n. 1
0
class ServicesTests(APITestCase):
    def setUp(self):
        self.user = UserFactory()
        self.payment_profile = PaymentProfile.objects.create(
            name="Test profile",
            owner=self.user,
            external_api_id="123",
            external_api_url="https://api.test.paysafe.com/customervault/v1/"
            "profiles/",
        )

        self.order = Order.objects.create(
            user=self.user,
            transaction_date=timezone.now(),
            authorization_id=1,
            settlement_id=1,
            reference_number=751,
        )

        self.coupon = Coupon.objects.create(
            value=13,
            code="ABCDEFGH",
            start_time=LOCAL_TIMEZONE.localize(datetime.now() -
                                               timedelta(weeks=5)),
            end_time=LOCAL_TIMEZONE.localize(datetime.now() +
                                             timedelta(weeks=5)),
            max_use=100,
            max_use_per_user=2,
            details="Any package for clients",
            owner=self.user,
        )
        self.package_type = ContentType.objects.get_for_model(Package)
        self.package = Package.objects.create(
            name="extreme_package",
            details="100 reservations package",
            available=True,
            price=600,
            reservations=100,
        )
        self.package_2 = Package.objects.create(
            name="extreme_package",
            details="100 reservations package",
            available=True,
            price=400,
            reservations=100,
        )
        self.package_most_exp_product = Package.objects.create(
            name="extreme_package",
            details="100 reservations package",
            available=True,
            price=9999,
            reservations=100,
        )
        self.package_less_exp_product = Package.objects.create(
            name="extreme_package",
            details="100 reservations package",
            available=True,
            price=1,
            reservations=100,
        )
        self.coupon.applicable_product_types.add(self.package_type)

        self.order_line = OrderLine.objects.create(
            order=self.order,
            quantity=1,
            content_type=self.package_type,
            object_id=self.package.id)
        self.order_line_2 = OrderLine.objects.create(
            order=self.order,
            quantity=1,
            content_type=self.package_type,
            object_id=self.package_2.id)

    @responses.activate
    def test_get_external_payment_profile(self):
        """
        Ensure we can get a user's external payment profile.
        """
        responses.add(
            responses.GET,
            "http://example.com/customervault/v1/profiles/123?fields=cards",
            json=SAMPLE_PROFILE_RESPONSE,
            status=200)

        response = get_external_payment_profile(
            self.payment_profile.external_api_id)

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(json.loads(response.content), SAMPLE_PROFILE_RESPONSE)

    @responses.activate
    def test_create_external_payment_profile(self):
        """
        Ensure we can create a user's external payment profile.
        """
        responses.add(responses.POST,
                      "http://example.com/customervault/v1/profiles/",
                      json=SAMPLE_PROFILE_RESPONSE,
                      status=201)
        response = create_external_payment_profile(self.user)

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(json.loads(response.content), SAMPLE_PROFILE_RESPONSE)

    @responses.activate
    def test_update_external_card(self):
        """
        Ensure we can update a user's card.
        """
        responses.add(
            responses.PUT,
            "http://example.com/customervault/v1/profiles/123/cards/456",
            json=SAMPLE_PROFILE_RESPONSE,
            status=200)
        response = update_external_card(
            self.payment_profile.external_api_id,
            SAMPLE_PROFILE_RESPONSE['cards'][0]['id'],
            SINGLE_USE_TOKEN,
        )

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(json.loads(response.content), SAMPLE_PROFILE_RESPONSE)

    @responses.activate
    def test_delete_external_card(self):
        """
        Ensure we can delete a user's card.
        """
        responses.add(
            responses.DELETE,
            "http://example.com/customervault/v1/profiles/123/cards/456",
            json='',
            status=204)
        response = delete_external_card(
            self.payment_profile.external_api_id,
            SAMPLE_PROFILE_RESPONSE['cards'][0]['id'],
        )

        self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

    @responses.activate
    def test_create_external_card(self):
        """
        Ensure we can create a new card for a user.
        """
        responses.add(
            responses.POST,
            "http://example.com/customervault/v1/profiles/123/cards/",
            json=SAMPLE_PROFILE_RESPONSE,
            status=200)
        response = create_external_card(
            self.payment_profile.external_api_id,
            SINGLE_USE_TOKEN,
        )

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(json.loads(response.content), SAMPLE_PROFILE_RESPONSE)

    @responses.activate
    def test_charge_payment(self):
        """
        Ensure we can charge a user.
        """
        responses.add(
            responses.POST,
            "http://example.com/cardpayments/v1/accounts/0123456789/auths/",
            json=SAMPLE_PROFILE_RESPONSE,
            status=200)
        response = charge_payment(1000, PAYMENT_TOKEN, "123")

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(json.loads(response.content), SAMPLE_PROFILE_RESPONSE)

    @responses.activate
    def test_unknown_external_api_exception(self):
        """
        Ensure we catch unhandled errors of the external API.
        """
        responses.add(
            responses.POST,
            "http://example.com/cardpayments/v1/accounts/0123456789/auths/",
            json=UNKNOWN_EXCEPTION,
            status=400)
        responses.add(
            responses.POST,
            "http://example.com/customervault/v1/profiles/123/cards/",
            json=UNKNOWN_EXCEPTION,
            status=400)
        responses.add(
            responses.PUT,
            "http://example.com/customervault/v1/profiles/123/cards/456",
            json=UNKNOWN_EXCEPTION,
            status=400)
        responses.add(responses.POST,
                      "http://example.com/customervault/v1/profiles/",
                      json=UNKNOWN_EXCEPTION,
                      status=400)
        responses.add(
            responses.GET,
            "http://example.com/customervault/v1/profiles/123?fields=cards",
            json=UNKNOWN_EXCEPTION,
            status=400)
        self.assertRaises(PaymentAPIError, charge_payment, 1000, PAYMENT_TOKEN,
                          "123")
        self.assertRaises(PaymentAPIError, create_external_card,
                          self.payment_profile.external_api_id,
                          SINGLE_USE_TOKEN)
        self.assertRaises(PaymentAPIError, update_external_card,
                          self.payment_profile.external_api_id,
                          SAMPLE_PROFILE_RESPONSE['cards'][0]['id'],
                          SINGLE_USE_TOKEN)
        self.assertRaises(PaymentAPIError, create_external_payment_profile,
                          self.user)
        self.assertRaises(PaymentAPIError, get_external_payment_profile,
                          self.payment_profile.external_api_id)

    @responses.activate
    def test_known_external_api_exception(self):
        """
        Ensure we catch and handle some errors of the external API.
        """
        responses.add(
            responses.POST,
            "http://example.com/cardpayments/v1/accounts/0123456789/auths/",
            json=SAMPLE_INVALID_PAYMENT_TOKEN,
            status=400)
        responses.add(
            responses.POST,
            "http://example.com/customervault/v1/profiles/123/cards/",
            json=SAMPLE_INVALID_PAYMENT_TOKEN,
            status=400)
        responses.add(
            responses.PUT,
            "http://example.com/customervault/v1/profiles/123/cards/456",
            json=SAMPLE_INVALID_PAYMENT_TOKEN,
            status=400)
        responses.add(responses.POST,
                      "http://example.com/customervault/v1/profiles/",
                      json=SAMPLE_INVALID_PAYMENT_TOKEN,
                      status=400)
        responses.add(
            responses.GET,
            "http://example.com/customervault/v1/profiles/123?fields=cards",
            json=SAMPLE_INVALID_PAYMENT_TOKEN,
            status=400)
        self.assertRaises(PaymentAPIError, charge_payment, 1000, PAYMENT_TOKEN,
                          "123")
        self.assertRaises(PaymentAPIError, create_external_card,
                          self.payment_profile.external_api_id,
                          SINGLE_USE_TOKEN)
        self.assertRaises(PaymentAPIError, update_external_card,
                          self.payment_profile.external_api_id,
                          SAMPLE_PROFILE_RESPONSE['cards'][0]['id'],
                          SINGLE_USE_TOKEN)
        self.assertRaises(PaymentAPIError, create_external_payment_profile,
                          self.user)
        self.assertRaises(PaymentAPIError, get_external_payment_profile,
                          self.payment_profile.external_api_id)

    def test_validate_coupon_for_order_with_most_exp_product(self):

        self.user.faculty = "Random faculty"
        self.user.student_number = "Random code"
        self.user.academic_program_code = "Random code"
        self.user.save()

        order_line_most_exp_product = OrderLine.objects.create(
            order=self.order,
            quantity=1,
            content_type=self.package_type,
            object_id=self.package_most_exp_product.id)
        order_line_les_exp_product = OrderLine.objects.create(
            order=self.order,
            quantity=1,
            content_type=self.package_type,
            object_id=self.package_less_exp_product.id)

        coupon_info = validate_coupon_for_order(self.coupon, self.order)

        error = coupon_info.get('error')

        self.assertIsNone(error)

        coupon_info_order_line = coupon_info.get('orderline')
        self.assertIsNotNone(coupon_info_order_line)
        self.assertEqual(coupon_info_order_line.id,
                         order_line_most_exp_product.id)
class ObtainTemporaryAuthTokenTests(APITestCase):

    def setUp(self):
        self.client = APIClient()
        self.user = UserFactory()
        self.user.set_password('Test123!')
        self.user.save()
        self.url = reverse('token_api')

    def test_authenticate_username(self):
        """
        Ensure we can authenticate on the platform.
        """
        data = {
            'username': self.user.username,
            'password': '******'
        }

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token = TemporaryToken.objects.get(
            user__username=self.user.username,
        )
        self.assertContains(response, token)

    def test_authenticate_email(self):
        """
        Ensure we can authenticate on the platform.
        """
        data = {
            'username': self.user.email,
            'password': '******'
        }

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token = TemporaryToken.objects.get(
            user__username=self.user.username,
        )
        self.assertContains(response, token)

    def test_authenticate_expired_token(self):
        """
        Ensure we can authenticate on the platform when token is expired.
        """
        data = {
            'username': self.user.username,
            'password': '******'
        }

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token_old = TemporaryToken.objects.get(
            user__username=self.user.username,
        )
        token_old.expire()

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

        token_new = TemporaryToken.objects.get(
            user__username=self.user.username,
        )

        self.assertNotContains(response, token_old)
        self.assertContains(response, token_new)

    def test_authenticate_bad_password(self):
        """
        Ensure we can't authenticate with a wrong password'
        """
        data = {
            'username': self.user.username,
            'password': '******'  # No caps on the first letter
        }

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__username='******'
        ).count()
        self.assertEqual(0, tokens)

    def test_authenticate_bad_username(self):
        """
        Ensure we can't authenticate with a wrong username
        """
        data = {
            'username': '******',  # Forget the `h` in `John`
            'password': '******'
        }

        response = self.client.post(self.url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__username='******'
        ).count()
        self.assertEqual(0, tokens)

    def test_authenticate_inactive(self):
        """
        Ensure we can't authenticate if user is inactive
        """
        data = {
            'username': self.user.username,
            'password': '******'
        }

        User.objects.filter(id=self.user.id).update(is_active=False)

        response = self.client.post(self.url, data, format='json')

        content = {
            "non_field_errors": [
                "Unable to log in with provided credentials."
                ]
            }

        self.assertEqual(json.loads(response.content), content)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__username=self.user.username
        ).count()
        self.assertEqual(0, tokens)

    def test_authenticate_missing_parameter(self):
        """
        Ensure we can't authenticate if "username" or "password" are not
        provided.
        """
        response = self.client.post(self.url, {}, format='json')

        content = {
            'password': ['This field is required.'],
            'username': ['This field is required.']
        }

        self.assertEqual(json.loads(response.content), content)
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        tokens = TemporaryToken.objects.filter(
            user__username=self.user.username
        ).count()
        self.assertEqual(0, tokens)