Merge branch 'release/2.0.2'

This commit is contained in:
Nathan Chapman 2022-10-31 17:21:51 -06:00
commit 0453741561
10 changed files with 464 additions and 220 deletions

View File

@ -7,10 +7,11 @@
"status": "unfulfilled",
"billing_address": null,
"shipping_address": 1,
"shipping_method": null,
"coupon": null,
"shipping_total": "9.55",
"subtotal_amount": "13.40",
"coupon_amount": "0.00",
"shipping_total": "9.55",
"total_amount": "22.95",
"weight": "0.0:oz",
"created_at": "2022-03-15T17:18:59.584Z",
"updated_at": "2022-03-15T17:18:59.584Z"
@ -23,10 +24,11 @@
"status": "unfulfilled",
"billing_address": null,
"shipping_address": 1,
"shipping_method": null,
"coupon": null,
"shipping_total": "9.55",
"subtotal_amount": "13.40",
"coupon_amount": "0.00",
"shipping_total": "9.55",
"total_amount": "22.95",
"weight": "0.0:oz",
"created_at": "2022-03-15T17:22:18.440Z",
"updated_at": "2022-03-15T17:22:18.440Z"
@ -39,10 +41,11 @@
"status": "unfulfilled",
"billing_address": null,
"shipping_address": 1,
"shipping_method": null,
"coupon": null,
"shipping_total": "9.55",
"subtotal_amount": "13.40",
"coupon_amount": "0.00",
"shipping_total": "9.55",
"total_amount": "22.95",
"weight": "0.0:oz",
"created_at": "2022-03-15T17:26:27.869Z",
"updated_at": "2022-03-15T17:26:27.869Z"
@ -52,78 +55,78 @@
"pk": 1,
"fields": {
"order": 1,
"product": 1,
"variant": 1,
"quantity": 2,
"quantity_fulfilled": 0,
"customer_note": "Whole Beans",
"customer_note": "Grind: Whole Beans; ",
"currency": "USD",
"unit_price": "13.40",
"tax_rate": "2.00"
"tax_rate": "0.00"
}
}, {
"model": "core.orderline",
"pk": 2,
"fields": {
"order": 1,
"product": 1,
"variant": 1,
"quantity": 1,
"quantity_fulfilled": 1,
"customer_note": "Espresso",
"customer_note": "Grind: Espresso; ",
"currency": "USD",
"unit_price": "13.40",
"tax_rate": "2.00"
"tax_rate": "0.00"
}
}, {
"model": "core.orderline",
"pk": 3,
"fields": {
"order": 2,
"product": 8,
"variant": 8,
"quantity": 1,
"quantity_fulfilled": 1,
"customer_note": "Whole Beans",
"customer_note": "Grind: Whole Beans; ",
"currency": "USD",
"unit_price": "13.40",
"tax_rate": "2.00"
"tax_rate": "0.00"
}
}, {
"model": "core.orderline",
"pk": 4,
"fields": {
"order": 2,
"product": 7,
"variant": 7,
"quantity": 1,
"quantity_fulfilled": 1,
"customer_note": "Cone Drip",
"customer_note": "Grind: Cone Drip; ",
"currency": "USD",
"unit_price": "13.40",
"tax_rate": "2.00"
"tax_rate": "0.00"
}
}, {
"model": "core.orderline",
"pk": 5,
"fields": {
"order": 3,
"product": 4,
"variant": 4,
"quantity": 1,
"quantity_fulfilled": 0,
"customer_note": "Percolator",
"customer_note": "Grind: Percolator; ",
"currency": "USD",
"unit_price": "13.40",
"tax_rate": "2.00"
"tax_rate": "0.00"
}
}, {
"model": "core.orderline",
"pk": 6,
"fields": {
"order": 3,
"product": 6,
"variant": 6,
"quantity": 1,
"quantity_fulfilled": 0,
"customer_note": "Whole Beans",
"customer_note": "Grind: Whole Beans; ",
"currency": "USD",
"unit_price": "13.40",
"tax_rate": "2.00"
"tax_rate": "0.00"
}
}
]

View File

@ -1,190 +1,387 @@
[{
"model": "core.productcategory",
"pk": 1,
"fields": {
"name": "Coffee",
"main_category": true
}
}, {
"model": "core.productcategory",
"pk": 2,
"fields": {
"name": "Merchandise",
"main_category": false
}
}, {
"model": "core.product",
"pk": 1,
"fields": {
"category": 1,
"name": "Ethiopia",
"description": "Spicy espresso reminiscent of Northern Italy, on the mild side. Perfect for espresso, and steamed milk drinks. Also, a full-bodied, earthy sweet drip or Americano. Contains organic beans from Indonesia, Africa and America.",
"sku": "23468",
"price": "13.40",
"weight": "16.0:oz",
"subtitle": "Dark Roast",
"description": "A wild and complex solid body dark roast with earthy, chocolate and fruit flavors. Organic Single origin.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 4,
"created_at": "2022-02-19T20:15:36.292Z",
"updated_at": "2022-03-28T17:29:26.300Z"
"updated_at": "2022-04-30T17:17:20.730Z"
}
}, {
"model": "core.product",
"pk": 2,
"fields": {
"category": 1,
"name": "Sumatra",
"description": "Dark heavy-bodied roast with a lingering chocolatey taste. Organic Single origin.",
"sku": "89765",
"price": "13.40",
"weight": "16.0:oz",
"subtitle": "Dark Roast (Low Acid)",
"description": "Dark Heavy bodied roast with a lingering chocolatey taste. Organic Single origin.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 3,
"created_at": "2022-02-19T20:15:59.741Z",
"updated_at": "2022-03-28T17:29:08.706Z"
"updated_at": "2022-04-30T17:16:57.956Z"
}
}, {
"model": "core.product",
"pk": 3,
"fields": {
"category": 1,
"name": "Pantomime",
"description": "Very Dark French Roast\r\nOur darkest drip. A blend of five different beans roasted two ways. Organic Africa, Indonesia, and South and Central America.",
"sku": "565656",
"price": "13.40",
"weight": "16.0:oz",
"subtitle": "Very Dark French Roast",
"description": "Our darkest drip. A blend of five different beans roasted two ways. Organic Africa, Indonesia, and South and Central America.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 1,
"created_at": "2022-02-23T17:59:00.711Z",
"updated_at": "2022-03-28T17:28:58.670Z"
"updated_at": "2022-04-30T17:15:27.422Z"
}
}, {
"model": "core.product",
"pk": 4,
"fields": {
"category": 1,
"name": "Decaf",
"description": "French Roast (Water Processed)\r\n\r\n“I cant believe its decaf!”. The best-tasting Swiss water process decaf we have developed over the past 30 years, for an unbelievable espresso or drip coffee. Organic Africa, Indonesia and South and Central America.",
"sku": "566565",
"price": "13.40",
"weight": "16.0:oz",
"subtitle": "French Roast (Water Processed)",
"description": "“I cant believe its decaf!” The best-tasting Swiss water process decaf we have developed over the past 30 years, for an unbelievable espresso or drip coffee. Organic Africa, Indonesia and South and Central America.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 2,
"created_at": "2022-02-23T17:59:32.099Z",
"updated_at": "2022-03-28T17:28:45.512Z"
"updated_at": "2022-05-13T03:22:32.755Z"
}
}, {
"model": "core.product",
"pk": 5,
"fields": {
"name": "Moka Java Blend",
"description": "Dark Roast\r\n\r\nA classic Moka Java style blend dark roasted with organic beans for a perfect body and sweetness with a hint of citrus.",
"sku": "56466",
"price": "13.40",
"weight": "16.0:oz",
"visible_in_listings": false,
"category": 1,
"name": "Moka Java Blend *New!",
"subtitle": "Dark Roast",
"description": "A classic Moka Java style blend dark roasted with organic beans for a perfect body and sweetness with a hint of citrus.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 5,
"created_at": "2022-02-23T18:05:41.742Z",
"updated_at": "2022-03-28T17:29:39.761Z"
"updated_at": "2022-07-01T15:10:28.050Z"
}
}, {
"model": "core.product",
"pk": 6,
"fields": {
"category": 1,
"name": "Loop d Loop",
"description": "Mild Dark Roast\r\n\r\nOur most popular blend reminiscent of Central Italy. A dark, chocolaty flavor perfect for espresso or drip. Its dark Vienna roast properties make it ideal for steamed milk drinks. Organic Indonesia, Africa and America.",
"sku": "53264",
"price": "13.40",
"weight": "16.0:oz",
"subtitle": "Medium Dark Roast",
"description": "Our most popular blend reminiscent of Central Italy. A dark, chocolaty flavor perfect for espresso or drip. Its dark Vienna roast properties make it ideal for steamed milk drinks. Organic Indonesia, Africa and America.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 6,
"created_at": "2022-02-23T18:06:09.881Z",
"updated_at": "2022-03-28T17:29:53.104Z"
"updated_at": "2022-04-30T17:17:35.868Z"
}
}, {
"model": "core.product",
"pk": 7,
"fields": {
"category": 1,
"name": "Dantes Tornado",
"description": "Medium Roast\r\n\r\nFull City spicy espresso roast reminiscent of Northern Italy, on the mild side. A full- bodied, earthy sweet drip or Americano. Organic Indonesia, Africa and America.",
"sku": "78945",
"price": "13.40",
"weight": "16.0:oz",
"subtitle": "Medium Roast",
"description": "Full City smooth espresso roast reminiscent of Northern Italy, on the mild side. A full-bodied, earthy sweet drip or Americano. Organic Indonesia, Africa and America.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 7,
"created_at": "2022-02-23T18:06:35.593Z",
"updated_at": "2022-03-28T17:30:11.445Z"
"updated_at": "2022-04-30T17:17:50.348Z"
}
}, {
"model": "core.product",
"pk": 8,
"fields": {
"category": 1,
"name": "Nicaragua",
"description": "Mild Roast\r\n\r\nOur mildest roast with sweet and fruity notes, containing organic beans from Nicaragua. Single origin.",
"sku": "12365",
"price": "13.40",
"weight": "16.0:oz",
"subtitle": "Mild Roast",
"description": "Our mildest roast with sweet and fruity notes, containing organic beans from Nicaragua. Single origin.",
"checkout_limit": 20,
"visible_in_listings": true,
"sorting": 8,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-03-28T17:30:20.941Z"
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"model": "core.product",
"pk": 9,
"fields": {
"category": 1,
"name": "Santa Rides Again",
"subtitle": "Dark Roast",
"description": "Combines the bright, fruity, wine-like flavors of African coffee with the syrupy sweetness of Indonesian coffee",
"checkout_limit": 20,
"visible_in_listings": false,
"sorting": 9,
"created_at": "2022-10-25T21:38:10.028Z",
"updated_at": "2022-10-25T21:38:10.028Z"
}
}, {
"model": "core.productvariant",
"pk": 1,
"fields": {
"product": 1,
"image": "products/images/slice2.png"
"name": "16 oz",
"sku": "23468",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"model": "core.productvariant",
"pk": 2,
"fields": {
"product": 2,
"image": "products/images/slice1.png"
"name": "16 oz",
"sku": "89765",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"model": "core.productvariant",
"pk": 3,
"fields": {
"product": 3,
"name": "16 oz",
"sku": "565656",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productvariant",
"pk": 4,
"fields": {
"product": 4,
"name": "16 oz",
"sku": "566565",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productvariant",
"pk": 5,
"fields": {
"product": 5,
"image": "products/images/moka_java.png"
"name": "16 oz",
"sku": "56466",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"model": "core.productvariant",
"pk": 6,
"fields": {
"product": 6,
"image": "products/images/loop_d_loop.png"
"name": "16 oz",
"sku": "53264",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"model": "core.productvariant",
"pk": 7,
"fields": {
"product": 7,
"image": "products/images/dantes_tornado.png"
"name": "16 oz",
"sku": "78945",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"model": "core.productvariant",
"pk": 8,
"fields": {
"product": 8,
"image": "products/images/nicaragua.png"
"name": "16 oz",
"sku": "12365",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"pk": 15,
"model": "core.productvariant",
"pk": 9,
"fields": {
"product": 3,
"image": "products/images/pantomime_800.png"
"product": 9,
"name": "16 oz",
"sku": "56856",
"price": "15.00",
"weight": "16.0:oz",
"track_inventory": false,
"stock": null,
"created_at": "2022-02-23T18:06:57.624Z",
"updated_at": "2022-04-30T17:18:05.413Z"
}
}, {
"model": "core.productphoto",
"pk": 16,
"model": "core.productoption",
"pk": 1,
"fields": {
"product": 3,
"image": "products/images/pantomime_beans.png"
"name": "Grind",
"options": "[\"Whole Beans\",\"Espresso\",\"Cone Drip\",\"Basket Drip\",\"French Press\",\"Stovetop Espresso (Moka Pot)\",\"AeroPress\",\"Percolator\",\"BLTC cafe pour over\"]",
"products": [1, 2, 3, 4, 5, 6, 7, 8, 9]
}
}, {
"model": "core.productphoto",
"pk": 18,
"pk": 62,
"fields": {
"product": 2,
"image": "products/images/pantomime_beans_J2bFBiH.png"
"image": "products/images/sumatra_800_bA3nujk.png"
}
}, {
"model": "core.productphoto",
"pk": 19,
"pk": 63,
"fields": {
"product": 2,
"image": "products/images/sumatra_beans.png"
}
}, {
"model": "core.productphoto",
"pk": 70,
"fields": {
"product": 4,
"image": "products/images/decaf_800.png"
}
}, {
"model": "core.productphoto",
"pk": 20,
"pk": 74,
"fields": {
"product": 1,
"image": "products/images/ethiopia_800.png"
}
}, {
"model": "core.productphoto",
"pk": 75,
"fields": {
"product": 1,
"image": "products/images/ethiopia_beans.png"
}
}, {
"model": "core.productphoto",
"pk": 76,
"fields": {
"product": 6,
"image": "products/images/loop_800.png"
}
}, {
"model": "core.productphoto",
"pk": 77,
"fields": {
"product": 6,
"image": "products/images/loop_beans.png"
}
}, {
"model": "core.productphoto",
"pk": 78,
"fields": {
"product": 7,
"image": "products/images/dante_800_5hLaNEe.png"
}
}, {
"model": "core.productphoto",
"pk": 79,
"fields": {
"product": 7,
"image": "products/images/dante_beans.png"
}
}, {
"model": "core.productphoto",
"pk": 80,
"fields": {
"product": 8,
"image": "products/images/nicaragua_800.png"
}
}, {
"model": "core.productphoto",
"pk": 81,
"fields": {
"product": 8,
"image": "products/images/nicaragua_beans.png"
}
}, {
"model": "core.productphoto",
"pk": 82,
"fields": {
"product": 3,
"image": "products/images/pantomime_800.png"
}
}, {
"model": "core.productphoto",
"pk": 83,
"fields": {
"product": 3,
"image": "products/images/pantomime_beans.png"
}
}, {
"model": "core.productphoto",
"pk": 84,
"fields": {
"product": 4,
"image": "products/images/pantomime_beans_Lo0hJRx.png"
"image": "products/images/decaf_beans.png"
}
}, {
"model": "core.productphoto",
"pk": 124,
"fields": {
"product": 5,
"image": "products/images/mokajava_800.png"
}
}, {
"model": "core.productphoto",
"pk": 125,
"fields": {
"product": 5,
"image": "products/images/mokajava_beans.png"
}
}]

View File

@ -31,19 +31,19 @@ class AddressTests(StaticLiveServerTestCase):
'Checkout | Port Townsend Roasting Co.'
)
full_name_input = self.browser.find_element_by_name("full_name")
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 = 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 = self.browser.find_element(By.NAME, 'street_address_1')
street_address_1_input.send_keys('1579')
city_input = self.browser.find_element_by_name('city')
city_input = self.browser.find_element(By.NAME, 'city')
city_input.send_keys('Logan')
state_select = select = Select(self.browser.find_element_by_name('state'))
state_select = select = Select(self.browser.find_element(By.NAME, 'state'))
state_select.select_by_value('UT')
postal_code_input = self.browser.find_element_by_name('postal_code')
postal_code_input = self.browser.find_element(By.NAME, 'postal_code')
postal_code_input.send_keys('37461')
self.browser.find_element_by_xpath('//input[@value="Continue"]').click()
self.browser.find_element(By.XPATH, '//input[@value="Continue"]').click()
# try:
# WebDriverWait(self.browser, 4).until(
# EC.presence_of_element_located((By.CLASS_NAME, 'errorlist'))
@ -52,9 +52,7 @@ class AddressTests(StaticLiveServerTestCase):
# self.browser.quit()
self.assertEqual(
self.browser.find_element_by_css_selector(
'.errorlist li'
).text,
self.browser.find_element(By.CSS_SELECTOR, '.errorlist li').text,
'USPS: Address Not Found.'
)
@ -65,19 +63,19 @@ class AddressTests(StaticLiveServerTestCase):
'Checkout | Port Townsend Roasting Co.'
)
full_name_input = self.browser.find_element_by_name("full_name")
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 = 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 = 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 = 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 = 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 = self.browser.find_element(By.NAME, 'postal_code')
postal_code_input.send_keys('99801')
self.browser.find_element_by_xpath('//input[@value="Continue"]').click()
self.browser.find_element(By.XPATH, '//input[@value="Continue"]').click()
# try:
# WebDriverWait(self.browser, 4).until(
# EC.presence_of_element_located((By.CLASS_NAME, 'errorlist'))

View File

@ -33,11 +33,11 @@ class CouponTests(StaticLiveServerTestCase):
def login(self):
self.browser.get('%s%s' % (self.live_server_url, '/accounts/login/'))
username_input = self.browser.find_element_by_name("login")
username_input = self.browser.find_element(By.NAME, "login")
username_input.send_keys('john@example.com')
password_input = self.browser.find_element_by_name("password")
password_input = self.browser.find_element(By.NAME, "password")
password_input.send_keys('Bf25XBdP4vdt2X9L')
self.browser.find_element_by_xpath('//input[@value="Login"]').click()
self.browser.find_element(By.XPATH, '//input[@value="Login"]').click()
def test_driver_has_session(self):
self.browser.get(self.live_server_url)
@ -47,19 +47,21 @@ class CouponTests(StaticLiveServerTestCase):
def test_apply_coupon_to_order_for_non_registered_user(self):
# Add item to cart
self.browser.get(self.live_server_url + '/products/1/')
self.browser.find_element_by_xpath(
self.browser.find_element(
By.XPATH,
'//input[@value="Add to cart"]'
).click()
self.assertEqual(
self.browser.find_element_by_class_name('cart__count').text,
self.browser.find_element(By.CLASS_NAME, 'cart__count').text,
'1'
)
# Add coupon code
coupon_input = self.browser.find_element_by_id('id_code')
coupon_input = self.browser.find_element(By.ID, 'id_code')
coupon_input.send_keys('MAY2022')
self.browser.find_element_by_xpath('//input[@value="Apply"]').click()
self.browser.find_element_by_xpath(
self.browser.find_element(By.XPATH, '//input[@value="Apply"]').click()
self.browser.find_element(
By.XPATH,
'//a[contains(text(), "Proceed to Checkout")]'
).click()
@ -68,23 +70,24 @@ class CouponTests(StaticLiveServerTestCase):
self.browser.title,
'Checkout | Port Townsend Roasting Co.'
)
full_name_input = self.browser.find_element_by_name("full_name")
full_name_input = self.browser.find_element(By.NAME, "full_name")
full_name_input.send_keys('Peter Templer')
email_input = self.browser.find_element_by_id('id_email')
email_input = self.browser.find_element(By.ID, 'id_email')
email_input.send_keys('peter@example.com')
street_address_1_input = self.browser.find_element_by_name(
street_address_1_input = self.browser.find_element(
By.NAME,
'street_address_1'
)
street_address_1_input.send_keys('1579 Talon Dr')
city_input = self.browser.find_element_by_name('city')
city_input = self.browser.find_element(By.NAME, 'city')
city_input.send_keys('Logan')
state_select = select = Select(
self.browser.find_element_by_name('state')
self.browser.find_element(By.NAME, 'state')
)
state_select.select_by_value('UT')
postal_code_input = self.browser.find_element_by_name('postal_code')
postal_code_input = self.browser.find_element(By.NAME, 'postal_code')
postal_code_input.send_keys('84321')
self.browser.find_element_by_xpath(
self.browser.find_element(By.XPATH,
'//input[@value="Continue"]'
).click()
@ -95,26 +98,27 @@ class CouponTests(StaticLiveServerTestCase):
# Check there is not an exception
with self.assertRaises(NoSuchElementException):
self.browser.find_element_by_css_selector(
self.browser.find_element(
By.CSS_SELECTOR,
'.messages p'
).text
def test_apply_used_coupon_to_order_returns_message(self):
# Add item to cart
self.browser.get(self.live_server_url + '/products/1/')
self.browser.find_element_by_xpath(
self.browser.find_element(By.XPATH,
'//input[@value="Add to cart"]'
).click()
self.assertEqual(
self.browser.find_element_by_class_name('cart__count').text,
self.browser.find_element(By.CLASS_NAME, 'cart__count').text,
'1'
)
# Add coupon code
coupon_input = self.browser.find_element_by_id('id_code')
coupon_input = self.browser.find_element(By.ID, 'id_code')
coupon_input.send_keys('MAY2022')
self.browser.find_element_by_xpath('//input[@value="Apply"]').click()
self.browser.find_element_by_xpath(
self.browser.find_element(By.XPATH, '//input[@value="Apply"]').click()
self.browser.find_element(By.XPATH,
'//a[contains(text(), "Proceed to Checkout")]'
).click()
@ -123,23 +127,25 @@ class CouponTests(StaticLiveServerTestCase):
self.browser.title,
'Checkout | Port Townsend Roasting Co.'
)
full_name_input = self.browser.find_element_by_name("full_name")
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 = self.browser.find_element(By.ID, 'id_email')
email_input.send_keys('contact@nathanjchapman.com')
street_address_1_input = self.browser.find_element_by_name(
street_address_1_input = self.browser.find_element(
By.NAME,
'street_address_1'
)
street_address_1_input.send_keys('1579 Talon Dr')
city_input = self.browser.find_element_by_name('city')
city_input = self.browser.find_element(By.NAME, 'city')
city_input.send_keys('Logan')
state_select = select = Select(
self.browser.find_element_by_name('state')
self.browser.find_element(By.NAME, 'state')
)
state_select.select_by_value('UT')
postal_code_input = self.browser.find_element_by_name('postal_code')
postal_code_input = self.browser.find_element(By.NAME, 'postal_code')
postal_code_input.send_keys('84321')
self.browser.find_element_by_xpath(
self.browser.find_element(
By.XPATH,
'//input[@value="Continue"]'
).click()
@ -148,7 +154,8 @@ class CouponTests(StaticLiveServerTestCase):
'Checkout | Port Townsend Roasting Co.'
)
message_text = self.browser.find_element_by_css_selector(
message_text = self.browser.find_element(
By.CSS_SELECTOR,
'.messages p'
).text
self.assertEqual(

View File

@ -3,6 +3,7 @@ import time
from selenium.webdriver.firefox.webdriver import WebDriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
@ -22,13 +23,13 @@ class HomeTests(StaticLiveServerTestCase):
def test_home_page_has_product_list(self):
self.login()
self.assertTrue(
self.browser.find_element_by_css_selector('.product__list')
self.browser.find_element(By.CSS_SELECTOR, '.product__list')
)
def login(self):
self.browser.get('%s%s' % (self.live_server_url, '/accounts/login/'))
username_input = self.browser.find_element_by_name("login")
username_input = self.browser.find_element(By.NAME, "login")
username_input.send_keys('john@example.com')
password_input = self.browser.find_element_by_name("password")
password_input = self.browser.find_element(By.NAME, "password")
password_input.send_keys('Bf25XBdP4vdt2X9L')
self.browser.find_element_by_xpath('//input[@value="Login"]').click()
self.browser.find_element(By.XPATH, '//input[@value="Login"]').click()

View File

@ -11,22 +11,25 @@ class RequestFaker:
'description': 'Coffee',
'amount': {
'currency_code': 'USD',
'value': '13.40',
'value': '45.20',
'breakdown': {
'item_total': {'currency_code': 'USD', 'value': '13.40'},
'shipping': {'currency_code': 'USD', 'value': '0.00'},
'item_total': {'currency_code': 'USD', 'value': '40.20'},
'shipping': {'currency_code': 'USD', 'value': '5.00'},
'tax_total': {'currency_code': 'USD', 'value': '0'},
'discount': {'currency_code': 'USD', 'value': '0'},
},
},
'items': [
{
'name': 'Decaf: 1 x Whole Beans, 2 x Percolator',
'description': '',
'unit_amount': {'currency_code': 'USD', 'value': '13.40'},
'quantity': '3',
}
],
'items': [{
'name': 'Decaf: 16 oz',
'description': 'Medium Roast',
'unit_amount': {'currency_code': 'USD', 'value': '13.40'},
'quantity': '1'
}, {
'name': 'Decaf: 16 oz',
'description': 'Medium Roast',
'unit_amount': {'currency_code': 'USD', 'value': '13.40'},
'quantity': '2'
}],
'shipping': {
'method': 'US POSTAL SERVICE',
'address': {

View File

@ -9,7 +9,7 @@ from paypalcheckoutsdk.orders import OrdersCreateRequest, OrdersCaptureRequest
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment
from accounts.models import User, Address
from core.models import Product, Order
from core.models import Product, ProductVariant, Order
from core import CoffeeGrind
from storefront.views import OrderCreateView
from storefront.cart import Cart
@ -26,12 +26,18 @@ class CartTest(TestCase):
password='peterspassword321'
)
cls.product = Product.objects.create(
name='Dante\'s Tornado',
name="Dante's Tornado",
subtitle='Medium Roast',
description='Coffee',
sku='23987',
checkout_limit=10,
visible_in_listings=True
)
cls.variant = ProductVariant.objects.create(
product=cls.product,
name='16 oz',
sku='234987',
price=13.4,
weight=Weight(oz=16),
visible_in_listings=True
)
cls.order = Order.objects.create(
customer=cls.customer,
@ -63,20 +69,24 @@ class CartTest(TestCase):
cart.add(
request,
product=self.product,
quantity=1,
grind=CoffeeGrind.WHOLE,
update_quantity=False
item={
'options': {'Grind': 'Whole Beans'},
'price_total': 13.4,
'quantity': 1,
'variant': 1
}
)
cart.add(
request,
product=self.product,
quantity=1,
grind=CoffeeGrind.ESPRESSO,
update_quantity=False
item={
'options': {'Grind': 'Espresso'},
'price_total': 13.4,
'quantity': 1,
'variant': 1
}
)
for item in cart.cart.values():
self.assertTrue('variations' in item, item)
for item in cart.cart:
self.assertTrue('variant' in item, item)
def test_add_item_to_cart(self):
cart_detail_url = reverse('storefront:cart-detail')
@ -87,14 +97,16 @@ class CartTest(TestCase):
cart = Cart(request)
cart.add(
request,
product=self.product,
quantity=1,
grind=CoffeeGrind.WHOLE,
update_quantity=False
item={
'options': {'Grind': 'Whole Beans'},
'price_total': 13.4,
'quantity': 1,
'variant': 1
}
)
self.assertEqual(
cart.cart[f'{self.product.id}']['variations'][CoffeeGrind.WHOLE]['quantity'],
cart.cart[0]['quantity'],
1
)
self.assertEqual(len(cart), 1)
@ -102,26 +114,30 @@ class CartTest(TestCase):
self.assertEqual(cart.get_total_price(), Decimal('13.4'))
cart.add(
request,
product=self.product,
quantity=1,
grind=CoffeeGrind.WHOLE,
update_quantity=False
item={
'options': {'Grind': 'Whole Beans'},
'price_total': 13.4,
'quantity': 1,
'variant': 1
}
)
self.assertEqual(
cart.cart[f'{self.product.id}']['variations'][CoffeeGrind.WHOLE]['quantity'],
cart.cart[0]['quantity'],
2
)
self.assertEqual(len(cart), 2)
cart.add(
request,
product=self.product,
quantity=3,
grind=CoffeeGrind.ESPRESSO,
update_quantity=False
item={
'options': {'Grind': 'Espresso'},
'price_total': 40.2,
'quantity': 3,
'variant': 1
}
)
self.assertEqual(
cart.cart[f'{self.product.id}']['variations'][CoffeeGrind.ESPRESSO]['quantity'],
cart.cart[1]['quantity'],
3
)
self.assertEqual(len(cart), 5)
@ -136,25 +152,30 @@ class CartTest(TestCase):
cart = Cart(request)
cart.add(
request,
product=self.product,
quantity=3,
grind=CoffeeGrind.WHOLE,
update_quantity=False
item={
'options': {'Grind': 'Whole Beans'},
'price_total': 40.2,
'quantity': 3,
'variant': 1
}
)
self.assertEqual(
cart.cart[f'{self.product.id}']['variations'][CoffeeGrind.WHOLE]['quantity'],
cart.cart[0]['quantity'],
3
)
cart.add(
request,
product=self.product,
quantity=1,
grind=CoffeeGrind.WHOLE,
item={
'options': {'Grind': 'Whole Beans'},
'price_total': 13.4,
'quantity': 1,
'variant': 0
},
update_quantity=True
)
self.assertEqual(
cart.cart[f'{self.product.id}']['variations'][CoffeeGrind.WHOLE]['quantity'],
cart.cart[0]['quantity'],
1
)
@ -167,13 +188,15 @@ class CartTest(TestCase):
cart = Cart(request)
cart.add(
request,
product=self.product,
quantity=3,
grind=CoffeeGrind.WHOLE,
update_quantity=False
item={
'options': {'Grind': 'Whole Beans'},
'price_total': 40.2,
'quantity': 3,
'variant': 1
}
)
self.assertEqual(len(cart), 3)
cart.remove(self.product, CoffeeGrind.WHOLE)
cart.remove(0)
self.assertEqual(len(cart), 0)
def test_cart_get_total_weight(self):
@ -185,9 +208,11 @@ class CartTest(TestCase):
cart = Cart(request)
cart.add(
request,
product=self.product,
quantity=3,
grind=CoffeeGrind.WHOLE,
update_quantity=False
item={
'options': {'Grind': 'Whole Beans'},
'price_total': 40.2,
'quantity': 3,
'variant': 1
}
)
self.assertEqual(cart.get_total_weight(), Decimal(48))
self.assertEqual(cart.get_total_weight(), 3)

View File

@ -10,7 +10,7 @@ from paypalcheckoutsdk.orders import OrdersCreateRequest, OrdersCaptureRequest
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment
from accounts.models import User, Address
from core.models import Product, Order
from core.models import Product, ProductVariant, Order
from core import CoffeeGrind
from storefront.views import OrderCreateView
from storefront.cart import Cart
@ -26,12 +26,18 @@ class CreateOrderTest(TestCase):
def setUpTestData(cls):
cls.product = Product.objects.create(
name='Decaf',
subtitle='Medium Roast',
description='Coffee',
sku='23987',
price=Decimal('13.40'),
weight=Weight(oz=16),
checkout_limit=10,
visible_in_listings=True
)
cls.variant = ProductVariant.objects.create(
product=cls.product,
name='16 oz',
sku='234987',
price=13.4,
weight=Weight(oz=16),
)
def setUp(self):
self.client = Client()
@ -44,24 +50,28 @@ class CreateOrderTest(TestCase):
cart = Cart(request)
cart.add(
request,
product=self.product,
quantity=1,
grind=CoffeeGrind.WHOLE,
update_quantity=False
item={
'options': {'Grind': 'Whole Beans'},
'price_total': '13.40',
'quantity': 1,
'variant': self.variant.pk
}
)
cart.add(
request,
product=self.product,
quantity=2,
grind=CoffeeGrind.PERCOLATOR,
update_quantity=False
item={
'options': {'Grind': 'Percolator'},
'price_total': '26.80',
'quantity': 2,
'variant': self.variant.pk
}
)
params = {
'items': cart,
'total_price': '13.40',
'item_total': '13.40',
'total_price': '45.20',
'item_total': '40.20',
'discount': '0',
'shipping_price': '0.00',
'shipping_price': '5.00',
'tax_total': '0',
'shipping_method': 'US POSTAL SERVICE',
'shipping_address': {

View File

@ -9,14 +9,14 @@ from paypalcheckoutsdk.orders import OrdersCreateRequest, OrdersCaptureRequest
from paypalcheckoutsdk.core import PayPalHttpClient, SandboxEnvironment
from accounts.models import User, Address
from core.models import Product, Order, Coupon
from core.models import Product, ProductVariant, Order, Coupon
from core import CoffeeGrind
from storefront.forms import AddressForm, OrderCreateForm
from storefront.views import (
CartView, CartAddProductView, CartUpdateProductView, CouponApplyView,
ProductListView, ProductDetailView,
CheckoutAddressView, OrderCreateView,
paypal_order_transaction_capture, paypal_webhook_endpoint,
paypal_order_transaction_capture,
PaymentDoneView, PaymentCanceledView,
CustomerDetailView, CustomerUpdateView, OrderDetailView,
CustomerAddressCreateView, CustomerAddressUpdateView,
@ -70,10 +70,9 @@ class OrderCreateViewTest(TestCase):
cls.customer = User.objects.get(pk=1)
cls.product = Product.objects.create(
name="Dante's Tornado",
subtitle='Medium Roast',
description='Coffee',
sku='23987',
price=13.4,
weight=Weight(oz=16),
checkout_limit=10,
visible_in_listings=True
)
cls.order = Order.objects.create(

View File

@ -3,5 +3,6 @@
{% block content %}
<article class="error-view">
<h1>400 Bad request</h1>
<p>If you're seeing this page, clear your cache to fix the issue.</p>
</article>
{% endblock %}