test_payment_fake.py 3.49 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
"""
Tests for the fake payment page used in acceptance tests.
"""

from django.test import TestCase
from shoppingcart.processors.CyberSource import sign, verify_signatures, \
    CCProcessorSignatureException
from shoppingcart.tests.payment_fake import PaymentFakeView
from collections import OrderedDict


class PaymentFakeViewTest(TestCase):
    """
    Test that the fake payment view interacts
    correctly with the shopping cart.
    """

    CLIENT_POST_PARAMS = OrderedDict([
        ('match', 'on'),
        ('course_id', 'edx/999/2013_Spring'),
        ('amount', '25.00'),
        ('currency', 'usd'),
        ('orderPage_transactionType', 'sale'),
        ('orderNumber', '33'),
        ('merchantID', 'edx'),
        ('djch', '012345678912'),
        ('orderPage_version', 2),
        ('orderPage_serialNumber', '1234567890'),
    ])

    def setUp(self):
        super(PaymentFakeViewTest, self).setUp()

        # Reset the view state
        PaymentFakeView.PAYMENT_STATUS_RESPONSE = "success"

    def test_accepts_client_signatures(self):

        # Generate shoppingcart signatures
        post_params = sign(self.CLIENT_POST_PARAMS)

        # Simulate a POST request from the payment workflow
        # page to the fake payment page.
        resp = self.client.post(
            '/shoppingcart/payment_fake', dict(post_params)
        )

        # Expect that the response was successful
        self.assertEqual(resp.status_code, 200)

        # Expect that we were served the payment page
        # (not the error page)
        self.assertIn("Payment Form", resp.content)

    def test_rejects_invalid_signature(self):

        # Generate shoppingcart signatures
        post_params = sign(self.CLIENT_POST_PARAMS)

        # Tamper with the signature
        post_params['orderPage_signaturePublic'] = "invalid"

        # Simulate a POST request from the payment workflow
        # page to the fake payment page.
        resp = self.client.post(
            '/shoppingcart/payment_fake', dict(post_params)
        )

        # Expect that we got an error
        self.assertIn("Error", resp.content)

    def test_sends_valid_signature(self):

        # Generate shoppingcart signatures
        post_params = sign(self.CLIENT_POST_PARAMS)

        # Get the POST params that the view would send back to us
        resp_params = PaymentFakeView.response_post_params(post_params)

        # Check that the client accepts these
        try:
            verify_signatures(resp_params)

        except CCProcessorSignatureException:
            self.fail("Client rejected signatures.")

    def test_set_payment_status(self):

        # Generate shoppingcart signatures
        post_params = sign(self.CLIENT_POST_PARAMS)

        # Configure the view to fail payments
        resp = self.client.put(
            '/shoppingcart/payment_fake',
            data="failure", content_type='text/plain'
        )
        self.assertEqual(resp.status_code, 200)

        # Check that the decision is "REJECT"
        resp_params = PaymentFakeView.response_post_params(post_params)
        self.assertEqual(resp_params.get('decision'), 'REJECT')

        # Configure the view to accept payments
        resp = self.client.put(
            '/shoppingcart/payment_fake',
            data="success", content_type='text/plain'
        )
        self.assertEqual(resp.status_code, 200)

        # Check that the decision is "ACCEPT"
        resp_params = PaymentFakeView.response_post_params(post_params)
        self.assertEqual(resp_params.get('decision'), 'ACCEPT')