diff --git a/src/core/usps.py b/src/core/usps.py index c4e60df..0e42e71 100644 --- a/src/core/usps.py +++ b/src/core/usps.py @@ -3,9 +3,10 @@ import requests import xmltodict from lxml import etree -from usps import USPSApi +from usps import USPSApi as USPSApiBase -class USPSApiWithRate(USPSApi): + +class USPSApi(USPSApiBase): urls = { 'tracking': 'TrackV2{test}&XML={xml}', 'label': 'eVS{test}&XML={xml}', diff --git a/src/functional_tests/test_address.py b/src/functional_tests/test_address.py index 2a85ca9..5608809 100644 --- a/src/functional_tests/test_address.py +++ b/src/functional_tests/test_address.py @@ -1,4 +1,6 @@ -import os, time +import os +import time + from selenium.webdriver.firefox.webdriver import WebDriver from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select @@ -8,6 +10,7 @@ from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from django.contrib.staticfiles.testing import StaticLiveServerTestCase + class AddressTests(StaticLiveServerTestCase): fixtures = ['products.json'] @@ -54,3 +57,35 @@ class AddressTests(StaticLiveServerTestCase): ).text, 'USPS: Address Not Found.' ) + + def test_address_is_url_safe(self): + self.browser.get(self.live_server_url + '/checkout/address/') + self.assertEqual( + self.browser.title, + 'Checkout | Port Townsend Roasting Co.' + ) + + full_name_input = self.browser.find_element_by_name("full_name") + full_name_input.send_keys('John Doe') + email_input = self.browser.find_element_by_id('id_email') + email_input.send_keys('john@example.com') + street_address_1_input = self.browser.find_element_by_name('street_address_1') + street_address_1_input.send_keys('4031 N Douglas HWY #B') + city_input = self.browser.find_element_by_name('city') + city_input.send_keys('Juneau') + state_select = select = Select(self.browser.find_element_by_name('state')) + state_select.select_by_value('AK') + postal_code_input = self.browser.find_element_by_name('postal_code') + postal_code_input.send_keys('99801') + self.browser.find_element_by_xpath('//input[@value="Continue to Payment"]').click() + # try: + # WebDriverWait(self.browser, 4).until( + # EC.presence_of_element_located((By.CLASS_NAME, 'errorlist')) + # ) + # finally: + # self.browser.quit() + + self.assertRegex( + self.browser.current_url, + '^http://localhost:[0-9]*/checkout/$' + ) diff --git a/src/storefront/cart.py b/src/storefront/cart.py index c14db29..3a113f2 100644 --- a/src/storefront/cart.py +++ b/src/storefront/cart.py @@ -8,7 +8,7 @@ from django.shortcuts import redirect, reverse from django.urls import reverse_lazy from core.models import Product, OrderLine, Coupon -from core.usps import USPSApiWithRate +from core.usps import USPSApi from core import ( DiscountValueType, VoucherType, @@ -125,7 +125,7 @@ class Cart: usps_rate_request = self.build_usps_rate_request() except TypeError as e: return Decimal('0.00') - usps = USPSApiWithRate(settings.USPS_USER_ID, test=True) + usps = USPSApi(settings.USPS_USER_ID, test=True) try: validation = usps.get_rate(usps_rate_request) diff --git a/src/storefront/forms.py b/src/storefront/forms.py index d1623ab..32dab3c 100644 --- a/src/storefront/forms.py +++ b/src/storefront/forms.py @@ -1,6 +1,7 @@ import logging import json from requests import ConnectionError +from urllib.parse import quote from django import forms from django.conf import settings from django.core.mail import EmailMessage @@ -74,12 +75,12 @@ class AddressForm(forms.Form): def clean(self): cleaned_data = super().clean() address = Address( - name=cleaned_data.get('full_name'), - address_1=cleaned_data.get('street_address_1'), - address_2=cleaned_data.get('street_address_2'), - city=cleaned_data.get('city'), - state=cleaned_data.get('state'), - zipcode=cleaned_data.get('postal_code') + name=quote(cleaned_data.get('full_name')), + address_1=quote(cleaned_data.get('street_address_1')), + address_2=quote(cleaned_data.get('street_address_2')), + city=quote(cleaned_data.get('city')), + state=quote(cleaned_data.get('state')), + zipcode=quote(cleaned_data.get('postal_code')) ) usps = USPSApi(settings.USPS_USER_ID, test=True) diff --git a/src/storefront/payments.py b/src/storefront/payments.py index 46365fb..1d806ae 100644 --- a/src/storefront/payments.py +++ b/src/storefront/payments.py @@ -3,7 +3,9 @@ import sys import json import logging -from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment, LiveEnvironment +from paypalcheckoutsdk.core import ( + PayPalHttpClient, SandboxEnvironment, LiveEnvironment +) from paypalcheckoutsdk.orders import OrdersCreateRequest, OrdersCaptureRequest from paypalhttp.serializers.json_serializer import Json @@ -91,19 +93,14 @@ class CreateOrder(PayPalClient): processed_items = [ { # Shows within upper-right dropdown during payment approval - "name": f'{item["product"]}: ' - ", ".join( - [ - next( - ( - f"{value['quantity']} x {v[1]}" - for i, v in enumerate(CoffeeGrind.GRIND_CHOICES) - if v[0] == key - ), - None, - ) - for key, value in item["variations"].items() - ] + "name": f'{item["product"]}: ' + ', '.join([ + next(( + f"{value['quantity']} x {v[1]}" + for i, v in enumerate(CoffeeGrind.GRIND_CHOICES) + if v[0] == key + ), + None, + ) for key, value in item["variations"].items()] )[:100], # Item details will also be in the completed paypal.com # transaction view diff --git a/src/storefront/tests/__init__.py b/src/storefront/tests/__init__.py index 3a9ddea..6f5eb66 100644 --- a/src/storefront/tests/__init__.py +++ b/src/storefront/tests/__init__.py @@ -21,8 +21,8 @@ class RequestFaker: }, 'items': [ { - 'name': 'Decaf', - 'description': '1 x Whole Beans, 2 x Percolator', + 'name': 'Decaf: 1 x Whole Beans, 2 x Percolator', + 'description': '', 'unit_amount': {'currency_code': 'USD', 'value': '13.40'}, 'quantity': '3', } diff --git a/src/storefront/tests/test_payments.py b/src/storefront/tests/test_payments.py index 1f4d059..d0f396a 100644 --- a/src/storefront/tests/test_payments.py +++ b/src/storefront/tests/test_payments.py @@ -20,6 +20,7 @@ from . import RequestFaker logger = logging.getLogger(__name__) + class CreateOrderTest(TestCase): @classmethod def setUpTestData(cls): @@ -35,7 +36,6 @@ class CreateOrderTest(TestCase): def setUp(self): self.client = Client() - def test_build_request_body(self): product_list_url = reverse('storefront:product-list') response = self.client.get(product_list_url, follow=True)