Merge branch 'release/1.3.10'

This commit is contained in:
Nathan Chapman 2022-05-21 08:35:15 -06:00
commit 0a32eec8d6
11 changed files with 495 additions and 35 deletions

View File

@ -4,7 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [1.3.10] - 2022-05-21
### Added
- Tests for almost all storefront views, exposing a couple of inconsistencies
### Fixed
- CustomerAddressUpdateView `test_func()` throwing error because addresses don't have a `customer` object
- PaymentCanceled misspelled template name
## [1.3.7] - 2022-05-19
### Added

View File

@ -4,6 +4,7 @@ from django.contrib.auth.models import AbstractUser
from . import STATE_CHOICES
class Address(models.Model):
first_name = models.CharField(max_length=256, blank=True)
last_name = models.CharField(max_length=256, blank=True)
@ -20,6 +21,7 @@ class Address(models.Model):
def __str__(self):
return f'{self.street_address_1}{self.city}'
class User(AbstractUser):
addresses = models.ManyToManyField(
Address, blank=True, related_name="user_addresses"

View File

@ -3,7 +3,7 @@
"model": "core.order",
"pk": 1,
"fields": {
"customer": null,
"customer": 1,
"status": "unfulfilled",
"billing_address": null,
"shipping_address": 1,
@ -19,7 +19,7 @@
"model": "core.order",
"pk": 2,
"fields": {
"customer": null,
"customer": 1,
"status": "unfulfilled",
"billing_address": null,
"shipping_address": 1,
@ -35,7 +35,7 @@
"model": "core.order",
"pk": 3,
"fields": {
"customer": null,
"customer": 2,
"status": "unfulfilled",
"billing_address": null,
"shipping_address": 1,

View File

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View File

View File

@ -0,0 +1,37 @@
from decimal import Decimal
from django.test import TestCase
from measurement.measures import Weight
from core.models import (
Product,
ProductPhoto,
Coupon,
ShippingMethod,
Order,
Transaction,
OrderLine,
TrackingNumber,
)
class ProductModelTest(TestCase):
@classmethod
def setUpTestData(cls):
Product.objects.create(
name='Pantomime',
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.',
sku='565656',
price=Decimal('15.00'),
weight=Weight(oz=16),
visible_in_listings=True,
sorting=1,
)
def test_get_absolute_url(self):
product = Product.objects.get(pk=1)
self.assertEqual(
product.get_absolute_url(),
'/dashboard/products/1/'
)

View File

View File

@ -12,13 +12,42 @@ from accounts.models import User, Address
from core.models import Product, Order, Coupon
from core import CoffeeGrind
from storefront.forms import AddressForm, OrderCreateForm
from storefront.views import OrderCreateView, CheckoutAddressView
from storefront.views import (
CartView, CartAddProductView, CartUpdateProductView, CouponApplyView,
ProductListView, ProductDetailView,
CheckoutAddressView, OrderCreateView,
paypal_order_transaction_capture, paypal_webhook_endpoint,
PaymentDoneView, PaymentCanceledView,
CustomerDetailView, CustomerUpdateView, OrderDetailView,
CustomerAddressCreateView, CustomerAddressUpdateView,
AboutView, FairTradeView, ReviewListView, ContactFormView,
)
from storefront.cart import Cart
logger = logging.getLogger(__name__)
class CheckoutAddressViewTests(TestCase):
class CartViewTest(TestCase):
fixtures = ['products.json']
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/cart/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:cart-detail'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:cart-detail'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/cart_detail.html')
class CheckoutAddressViewTest(TestCase):
def setUp(self):
self.client = Client()
@ -33,7 +62,7 @@ class CheckoutAddressViewTests(TestCase):
self.assertTrue(isinstance(response.context['form'], AddressForm))
class OrderCreateViewTests(TestCase):
class OrderCreateViewTest(TestCase):
fixtures = ['accounts.json', 'coupons.json']
@classmethod
@ -54,8 +83,6 @@ class OrderCreateViewTests(TestCase):
def setUp(self):
self.client = Client()
def test_used_coupon_creates_error_on_checkout(self):
session = self.client.session
session['shipping_address'] = {
'first_name': 'Nathan',
@ -67,6 +94,27 @@ class OrderCreateViewTests(TestCase):
'state': 'UT',
'postal_code': '84341'
}
session.save()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/checkout/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('storefront:order-create')
)
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(
reverse('storefront:order-create')
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/order_form.html')
def test_used_coupon_creates_error_on_checkout(self):
session = self.client.session
session['coupon_code'] = 'MAY2022'
session.save()
@ -76,3 +124,323 @@ class OrderCreateViewTests(TestCase):
self.assertTrue(self.client.session.get('shipping_address'))
self.assertTemplateUsed(response, 'storefront/order_form.html')
self.assertContains(response, 'Coupon already used', status_code=200)
class ProductListViewTest(TestCase):
fixtures = ['products.json']
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:product-list'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:product-list'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/product_list.html')
class ProductDetailViewTest(TestCase):
fixtures = ['products.json']
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/products/1/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('storefront:product-detail', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(
reverse('storefront:product-detail', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/product_detail.html')
class CheckoutAddressViewTest(TestCase):
fixtures = ['products.json']
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/checkout/address/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:checkout-address'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:checkout-address'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/checkout_address.html')
class OrderCreateViewTest(TestCase):
fixtures = ['products.json']
def setUp(self):
self.client = Client()
class PaymentDoneViewTest(TestCase):
fixtures = ['products.json']
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/done/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:payment-done'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:payment-done'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/payment_done.html')
class PaymentCanceledViewTest(TestCase):
fixtures = ['products.json']
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/canceled/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:payment-canceled'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:payment-canceled'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/payment_canceled.html')
class CustomerDetailViewTest(TestCase):
fixtures = ['products.json', 'accounts.json']
def setUp(self):
self.client = Client()
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/customers/1/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('storefront:customer-detail', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(
reverse('storefront:customer-detail', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/customer_detail.html')
class CustomerUpdateViewTest(TestCase):
fixtures = ['products.json', 'accounts.json']
def setUp(self):
self.client = Client()
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/customers/1/update/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('storefront:customer-update', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(
reverse('storefront:customer-update', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/customer_form.html')
class OrderDetailViewTest(TestCase):
fixtures = ['products.json', 'accounts.json', 'orders.json']
def setUp(self):
self.client = Client()
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/customers/1/orders/1/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('storefront:order-detail', kwargs={'pk': 1, 'order_pk': 1})
)
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(
reverse('storefront:order-detail', kwargs={'pk': 1, 'order_pk': 1})
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/order_detail.html')
class CustomerAddressCreateViewTest(TestCase):
fixtures = ['products.json', 'accounts.json']
def setUp(self):
self.client = Client()
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/customers/1/addresses/new/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('storefront:customer-address-create', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(
reverse('storefront:customer-address-create', kwargs={'pk': 1})
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(
response, 'storefront/address_create_form.html'
)
class CustomerAddressUpdateViewTest(TestCase):
fixtures = ['products.json', 'accounts.json']
def setUp(self):
self.client = Client()
self.user = User.objects.get(pk=1)
self.client.force_login(self.user)
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/customers/1/addresses/1/update/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(
reverse('storefront:address-update', kwargs={
'pk': 1, 'address_pk': 1
})
)
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(
reverse('storefront:address-update', kwargs={
'pk': 1, 'address_pk': 1}
)
)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/address_form.html')
class AboutViewTest(TestCase):
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/about/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:about'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:about'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/about.html')
class FairTradeViewTest(TestCase):
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/fair-trade/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:fair-trade'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:fair-trade'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/fairtrade.html')
class ReviewListViewTest(TestCase):
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/reviews/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:reviews'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:reviews'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/reviews.html')
class ContactFormViewTest(TestCase):
def setUp(self):
self.client = Client()
def test_view_url_exists_at_desired_location(self):
response = self.client.get('/contact/')
self.assertEqual(response.status_code, 200)
def test_view_url_accessible_by_name(self):
response = self.client.get(reverse('storefront:contact'))
self.assertEqual(response.status_code, 200)
def test_view_uses_correct_template(self):
response = self.client.get(reverse('storefront:contact'))
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'storefront/contact_form.html')

View File

@ -11,30 +11,80 @@ urlpatterns = [
path('products/<int:pk>/', include([
path('', views.ProductDetailView.as_view(), name='product-detail'),
])),
path('cart/', views.CartView.as_view(), name='cart-detail'),
path('cart/<int:pk>/add/', views.CartAddProductView.as_view(), name='cart-add'),
path('cart/<int:pk>/update/<slug:grind>/', views.CartUpdateProductView.as_view(), name='cart-update'),
path('cart/<int:pk>/remove/<slug:grind>/', views.cart_remove_product_view, name='cart-remove'),
path('coupon/apply/', views.CouponApplyView.as_view(), name='coupon-apply'),
path('paypal/order/<slug:transaction_id>/capture/', views.paypal_order_transaction_capture, name='paypal-capture'),
path('paypal/webhooks/', views.paypal_webhook_endpoint, name='paypal-webhook'),
path('checkout/address/', views.CheckoutAddressView.as_view(), name='checkout-address'),
path(
'cart/<int:pk>/add/',
views.CartAddProductView.as_view(),
name='cart-add'
),
path(
'cart/<int:pk>/update/<slug:grind>/',
views.CartUpdateProductView.as_view(),
name='cart-update',
),
path(
'cart/<int:pk>/remove/<slug:grind>/',
views.cart_remove_product_view,
name='cart-remove',
),
path(
'coupon/apply/',
views.CouponApplyView.as_view(),
name='coupon-apply'
),
path(
'paypal/order/<slug:transaction_id>/capture/',
views.paypal_order_transaction_capture,
name='paypal-capture',
),
path(
'paypal/webhooks/',
views.paypal_webhook_endpoint,
name='paypal-webhook'
),
path(
'checkout/address/',
views.CheckoutAddressView.as_view(),
name='checkout-address',
),
path('checkout/', views.OrderCreateView.as_view(), name='order-create'),
path('done/', views.PaymentDoneView.as_view(), name='payment-done'),
path('canceled/', views.PaymentCanceledView.as_view(), name='payment-canceled'),
path(
'canceled/',
views.PaymentCanceledView.as_view(),
name='payment-canceled'
),
path('customers/<int:pk>/', include([
path('', views.CustomerDetailView.as_view(), name='customer-detail'),
path('update/', views.CustomerUpdateView.as_view(), name='customer-update'),
# path('delete/', views.CustomerDeleteView.as_view(), name='customer-delete'),
path('orders/<int:order_pk>/', views.OrderDetailView.as_view(), name='order-detail'),
path('addresses/new/', views.CustomerAddressCreateView.as_view(), name='customer-address-create'),
path('addresses/<int:address_pk>/update/', views.CustomerAddressUpdateView.as_view(), name='address-update'),
])),
path(
'',
views.CustomerDetailView.as_view(),
name='customer-detail'
),
path(
'update/',
views.CustomerUpdateView.as_view(),
name='customer-update',
),
# path(
# 'delete/',
# views.CustomerDeleteView.as_view(),
# name='customer-delete'
# ),
path(
'orders/<int:order_pk>/',
views.OrderDetailView.as_view(),
name='order-detail',
),
path(
'addresses/new/',
views.CustomerAddressCreateView.as_view(),
name='customer-address-create',
),
path(
'addresses/<int:address_pk>/update/',
views.CustomerAddressUpdateView.as_view(),
name='address-update',
)
]))
]

View File

@ -422,7 +422,7 @@ class CustomerAddressUpdateView(
raise_exception = True
def test_func(self):
return self.request.user.pk == self.get_object().customer.pk
return self.request.user.pk == self.kwargs['pk']
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)