Adding more tests, finding more errors - again!
This commit is contained in:
parent
2ce2205bd3
commit
c69bf46255
|
@ -17,7 +17,7 @@ class OrderQuerySet(QuerySet):
|
|||
return self.filter(cancelled=False)
|
||||
|
||||
def open(self):
|
||||
return self.filter(open__isnull=True)
|
||||
return self.filter(open__isnull=False)
|
||||
|
||||
def paid(self):
|
||||
return self.filter(paid=True)
|
||||
|
|
|
@ -5,7 +5,7 @@ from psycopg2.extras import DateTimeTZRange
|
|||
|
||||
from shop.forms import OrderProductRelationForm
|
||||
from utils.factories import UserFactory
|
||||
from .factories import ProductFactory, OrderProductRelationFactory
|
||||
from .factories import ProductFactory, OrderProductRelationFactory, OrderFactory
|
||||
|
||||
|
||||
class ProductAvailabilityTest(TestCase):
|
||||
|
@ -111,7 +111,12 @@ class TestProductDetailView(TestCase):
|
|||
self.product = ProductFactory()
|
||||
self.path = reverse("shop:product_detail", kwargs={"slug": self.product.slug})
|
||||
|
||||
def test_product_is_available(self):
|
||||
def test_product_is_available_for_anonymous_user(self):
|
||||
response = self.client.get(self.path)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_product_is_available_for_logged_in_user(self):
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(self.path)
|
||||
|
||||
|
@ -180,3 +185,100 @@ class TestProductDetailView(TestCase):
|
|||
self.product.category.save()
|
||||
response = self.client.get(self.path)
|
||||
self.assertEquals(response.status_code, 404)
|
||||
|
||||
|
||||
class TestOrderDetailView(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.user = UserFactory()
|
||||
self.order = OrderFactory(user=self.user)
|
||||
self.path = reverse('shop:order_detail', kwargs={'pk': self.order.pk})
|
||||
|
||||
# We are using a formset which means we have to include some "management form" data.
|
||||
self.base_form_data = {
|
||||
'form-TOTAL_FORMS': '1',
|
||||
'form-INITIAL_FORMS': '1',
|
||||
'form-MAX_NUM_FORMS': '',
|
||||
}
|
||||
|
||||
def test_redirects_when_no_products(self):
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(self.path)
|
||||
self.assertEquals(response.status_code, 302)
|
||||
self.assertRedirects(response, reverse('shop:index'))
|
||||
|
||||
def test_redirects_when_cancelled(self):
|
||||
self.client.force_login(self.user)
|
||||
|
||||
OrderProductRelationFactory(order=self.order)
|
||||
|
||||
self.order.cancelled = True
|
||||
self.order.save()
|
||||
|
||||
response = self.client.get(self.path)
|
||||
|
||||
self.assertEquals(response.status_code, 302)
|
||||
self.assertRedirects(response, reverse('shop:index'))
|
||||
|
||||
def test_remove_product(self):
|
||||
self.client.force_login(self.user)
|
||||
|
||||
OrderProductRelationFactory(order=self.order)
|
||||
orp = OrderProductRelationFactory(order=self.order)
|
||||
|
||||
order = orp.order
|
||||
|
||||
data = self.base_form_data
|
||||
data['remove_product'] = orp.pk
|
||||
|
||||
response = self.client.post(self.path, data=data)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
||||
order.refresh_from_db()
|
||||
|
||||
self.assertEquals(order.products.count(), 1)
|
||||
|
||||
def test_remove_last_product_cancels_order(self):
|
||||
self.client.force_login(self.user)
|
||||
|
||||
orp = OrderProductRelationFactory(order=self.order)
|
||||
|
||||
order = orp.order
|
||||
|
||||
data = self.base_form_data
|
||||
data['remove_product'] = orp.pk
|
||||
|
||||
response = self.client.post(self.path, data=data)
|
||||
self.assertEquals(response.status_code, 302)
|
||||
self.assertRedirects(response, reverse('shop:index'))
|
||||
|
||||
order.refresh_from_db()
|
||||
|
||||
self.assertTrue(order.cancelled)
|
||||
|
||||
def test_cancel_order(self):
|
||||
self.client.force_login(self.user)
|
||||
|
||||
orp = OrderProductRelationFactory(order=self.order)
|
||||
order = orp.order
|
||||
|
||||
data = self.base_form_data
|
||||
data['cancel_order'] = None
|
||||
|
||||
response = self.client.post(self.path, data=data)
|
||||
self.assertEquals(response.status_code, 302)
|
||||
self.assertRedirects(response, reverse('shop:index'))
|
||||
|
||||
order.refresh_from_db()
|
||||
|
||||
self.assertTrue(order.cancelled)
|
||||
|
||||
|
||||
class TestOrderListView(TestCase):
|
||||
|
||||
def test_order_list_view_as_logged_in(self):
|
||||
user = UserFactory()
|
||||
self.client.force_login(user)
|
||||
path = reverse('shop:order_list')
|
||||
response = self.client.get(path)
|
||||
self.assertEquals(response.status_code, 200)
|
||||
|
|
|
@ -224,16 +224,18 @@ class ProductDetailView(FormView, DetailView):
|
|||
|
||||
def get_form_kwargs(self):
|
||||
kwargs = super().get_form_kwargs()
|
||||
kwargs['instance'] = self.opr
|
||||
if hasattr(self, 'opr'):
|
||||
kwargs['instance'] = self.opr
|
||||
return kwargs
|
||||
|
||||
def get_initial(self):
|
||||
if self.opr:
|
||||
if hasattr(self, 'opr'):
|
||||
return {'quantity': self.opr.quantity}
|
||||
return super().get_initial()
|
||||
return None
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
if hasattr(self.opr, 'order'):
|
||||
# If the OrderProductRelation already exists it has a primary key in the database
|
||||
if self.request.user.is_authenticated and self.opr.pk:
|
||||
kwargs['already_in_order'] = True
|
||||
|
||||
return super().get_context_data(**kwargs)
|
||||
|
@ -241,7 +243,10 @@ class ProductDetailView(FormView, DetailView):
|
|||
def dispatch(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
|
||||
self.opr = None
|
||||
if not self.object.category.public:
|
||||
# this product is not publicly available
|
||||
raise Http404("Product not found")
|
||||
|
||||
if self.request.user.is_authenticated:
|
||||
try:
|
||||
self.opr = OrderProductRelation.objects.get(
|
||||
|
@ -255,31 +260,23 @@ class ProductDetailView(FormView, DetailView):
|
|||
quantity=1,
|
||||
)
|
||||
|
||||
if not self.object.category.public:
|
||||
# this product is not publicly available
|
||||
raise Http404("Product not found")
|
||||
|
||||
return super(ProductDetailView, self).dispatch(
|
||||
request, *args, **kwargs
|
||||
)
|
||||
|
||||
def form_valid(self, form):
|
||||
product = self.get_object()
|
||||
quantity = form.cleaned_data.get('quantity')
|
||||
opr = form.save(commit=False)
|
||||
|
||||
if not hasattr(self.opr, 'order'):
|
||||
self.opr.order = Order.objects.create(
|
||||
user=self.request.user,
|
||||
)
|
||||
if not opr.pk:
|
||||
opr.order, _ = Order.objects.get_or_create(user=self.request.user, open=True, cancelled=False)
|
||||
|
||||
self.opr.quantity = quantity
|
||||
self.opr.save()
|
||||
opr.save()
|
||||
|
||||
messages.info(
|
||||
self.request,
|
||||
'{}x {} has been added to your order.'.format(
|
||||
quantity,
|
||||
product.name
|
||||
opr.quantity,
|
||||
opr.product.name
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -329,7 +326,7 @@ class OrderDetailView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureOrderH
|
|||
return HttpResponseRedirect(reverse_lazy('shop:index'))
|
||||
|
||||
# Then see if the user is cancelling the order.
|
||||
if 'cancel_order' in request.POST:
|
||||
elif 'cancel_order' in request.POST:
|
||||
order.mark_as_cancelled()
|
||||
messages.info(request, 'Order cancelled!')
|
||||
return HttpResponseRedirect(reverse_lazy('shop:index'))
|
||||
|
@ -338,66 +335,67 @@ class OrderDetailView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureOrderH
|
|||
# so from now on we do stuff that require us to check stock.
|
||||
# We use a formset for this to be able to display exactly
|
||||
# which product is not in stock if that is the case.
|
||||
formset = OrderProductRelationFormSet(
|
||||
request.POST,
|
||||
queryset=OrderProductRelation.objects.filter(order=order),
|
||||
)
|
||||
|
||||
# If the formset is not valid it means that we cannot fulfill the order, so return and inform the user.
|
||||
if not formset.is_valid():
|
||||
messages.error(
|
||||
request,
|
||||
"Some of the products you are ordering are out of stock. Review the order and try again."
|
||||
)
|
||||
return self.render_to_response(
|
||||
self.get_context_data(order_product_formset=formset)
|
||||
else:
|
||||
formset = OrderProductRelationFormSet(
|
||||
request.POST,
|
||||
queryset=OrderProductRelation.objects.filter(order=order),
|
||||
)
|
||||
|
||||
# No stock issues, proceed to check if the user is updating the order.
|
||||
if 'update_order' in request.POST:
|
||||
# We have already made sure the formset is valid, so just save it to update quantities.
|
||||
formset.save()
|
||||
|
||||
order.customer_comment = request.POST.get('customer_comment') or ''
|
||||
order.invoice_address = request.POST.get('invoice_address') or ''
|
||||
order.save()
|
||||
|
||||
# Then at last see if the user is paying for the order.
|
||||
payment_method = request.POST.get('payment_method')
|
||||
if payment_method in order.PAYMENT_METHODS:
|
||||
if not request.POST.get('accept_terms'):
|
||||
messages.error(request, "You need to accept the general terms and conditions before you can continue!")
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy('shop:order_detail', kwargs={'pk': order.pk})
|
||||
# If the formset is not valid it means that we cannot fulfill the order, so return and inform the user.
|
||||
if not formset.is_valid():
|
||||
messages.error(
|
||||
request,
|
||||
"Some of the products you are ordering are out of stock. Review the order and try again."
|
||||
)
|
||||
return self.render_to_response(
|
||||
self.get_context_data(order_product_formset=formset)
|
||||
)
|
||||
|
||||
# Set payment method and mark the order as closed
|
||||
order.payment_method = payment_method
|
||||
order.open = None
|
||||
order.customer_comment = request.POST.get('customer_comment') or ''
|
||||
order.invoice_address = request.POST.get('invoice_address') or ''
|
||||
order.save()
|
||||
# No stock issues, proceed to check if the user is updating the order.
|
||||
if 'update_order' in request.POST:
|
||||
# We have already made sure the formset is valid, so just save it to update quantities.
|
||||
formset.save()
|
||||
|
||||
reverses = {
|
||||
Order.CREDIT_CARD: reverse_lazy(
|
||||
'shop:epay_form',
|
||||
kwargs={'pk': order.id}
|
||||
),
|
||||
Order.BLOCKCHAIN: reverse_lazy(
|
||||
'shop:coinify_pay',
|
||||
kwargs={'pk': order.id}
|
||||
),
|
||||
Order.BANK_TRANSFER: reverse_lazy(
|
||||
'shop:bank_transfer',
|
||||
kwargs={'pk': order.id}
|
||||
),
|
||||
Order.CASH: reverse_lazy(
|
||||
'shop:cash',
|
||||
kwargs={'pk': order.id}
|
||||
)
|
||||
}
|
||||
order.customer_comment = request.POST.get('customer_comment') or ''
|
||||
order.invoice_address = request.POST.get('invoice_address') or ''
|
||||
order.save()
|
||||
|
||||
return HttpResponseRedirect(reverses[payment_method])
|
||||
# Then at last see if the user is paying for the order.
|
||||
payment_method = request.POST.get('payment_method')
|
||||
if payment_method in order.PAYMENT_METHODS:
|
||||
if not request.POST.get('accept_terms'):
|
||||
messages.error(request, "You need to accept the general terms and conditions before you can continue!")
|
||||
return HttpResponseRedirect(
|
||||
reverse_lazy('shop:order_detail', kwargs={'pk': order.pk})
|
||||
)
|
||||
|
||||
# Set payment method and mark the order as closed
|
||||
order.payment_method = payment_method
|
||||
order.open = None
|
||||
order.customer_comment = request.POST.get('customer_comment') or ''
|
||||
order.invoice_address = request.POST.get('invoice_address') or ''
|
||||
order.save()
|
||||
|
||||
reverses = {
|
||||
Order.CREDIT_CARD: reverse_lazy(
|
||||
'shop:epay_form',
|
||||
kwargs={'pk': order.id}
|
||||
),
|
||||
Order.BLOCKCHAIN: reverse_lazy(
|
||||
'shop:coinify_pay',
|
||||
kwargs={'pk': order.id}
|
||||
),
|
||||
Order.BANK_TRANSFER: reverse_lazy(
|
||||
'shop:bank_transfer',
|
||||
kwargs={'pk': order.id}
|
||||
),
|
||||
Order.CASH: reverse_lazy(
|
||||
'shop:cash',
|
||||
kwargs={'pk': order.id}
|
||||
)
|
||||
}
|
||||
|
||||
return HttpResponseRedirect(reverses[payment_method])
|
||||
|
||||
return super(OrderDetailView, self).get(request, *args, **kwargs)
|
||||
|
||||
|
|
Loading…
Reference in a new issue