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)
|
return self.filter(cancelled=False)
|
||||||
|
|
||||||
def open(self):
|
def open(self):
|
||||||
return self.filter(open__isnull=True)
|
return self.filter(open__isnull=False)
|
||||||
|
|
||||||
def paid(self):
|
def paid(self):
|
||||||
return self.filter(paid=True)
|
return self.filter(paid=True)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from psycopg2.extras import DateTimeTZRange
|
||||||
|
|
||||||
from shop.forms import OrderProductRelationForm
|
from shop.forms import OrderProductRelationForm
|
||||||
from utils.factories import UserFactory
|
from utils.factories import UserFactory
|
||||||
from .factories import ProductFactory, OrderProductRelationFactory
|
from .factories import ProductFactory, OrderProductRelationFactory, OrderFactory
|
||||||
|
|
||||||
|
|
||||||
class ProductAvailabilityTest(TestCase):
|
class ProductAvailabilityTest(TestCase):
|
||||||
|
@ -111,7 +111,12 @@ class TestProductDetailView(TestCase):
|
||||||
self.product = ProductFactory()
|
self.product = ProductFactory()
|
||||||
self.path = reverse("shop:product_detail", kwargs={"slug": self.product.slug})
|
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)
|
self.client.force_login(self.user)
|
||||||
response = self.client.get(self.path)
|
response = self.client.get(self.path)
|
||||||
|
|
||||||
|
@ -180,3 +185,100 @@ class TestProductDetailView(TestCase):
|
||||||
self.product.category.save()
|
self.product.category.save()
|
||||||
response = self.client.get(self.path)
|
response = self.client.get(self.path)
|
||||||
self.assertEquals(response.status_code, 404)
|
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):
|
def get_form_kwargs(self):
|
||||||
kwargs = super().get_form_kwargs()
|
kwargs = super().get_form_kwargs()
|
||||||
kwargs['instance'] = self.opr
|
if hasattr(self, 'opr'):
|
||||||
|
kwargs['instance'] = self.opr
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_initial(self):
|
def get_initial(self):
|
||||||
if self.opr:
|
if hasattr(self, 'opr'):
|
||||||
return {'quantity': self.opr.quantity}
|
return {'quantity': self.opr.quantity}
|
||||||
return super().get_initial()
|
return None
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
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
|
kwargs['already_in_order'] = True
|
||||||
|
|
||||||
return super().get_context_data(**kwargs)
|
return super().get_context_data(**kwargs)
|
||||||
|
@ -241,7 +243,10 @@ class ProductDetailView(FormView, DetailView):
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
self.object = self.get_object()
|
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:
|
if self.request.user.is_authenticated:
|
||||||
try:
|
try:
|
||||||
self.opr = OrderProductRelation.objects.get(
|
self.opr = OrderProductRelation.objects.get(
|
||||||
|
@ -255,31 +260,23 @@ class ProductDetailView(FormView, DetailView):
|
||||||
quantity=1,
|
quantity=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not self.object.category.public:
|
|
||||||
# this product is not publicly available
|
|
||||||
raise Http404("Product not found")
|
|
||||||
|
|
||||||
return super(ProductDetailView, self).dispatch(
|
return super(ProductDetailView, self).dispatch(
|
||||||
request, *args, **kwargs
|
request, *args, **kwargs
|
||||||
)
|
)
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
product = self.get_object()
|
opr = form.save(commit=False)
|
||||||
quantity = form.cleaned_data.get('quantity')
|
|
||||||
|
|
||||||
if not hasattr(self.opr, 'order'):
|
if not opr.pk:
|
||||||
self.opr.order = Order.objects.create(
|
opr.order, _ = Order.objects.get_or_create(user=self.request.user, open=True, cancelled=False)
|
||||||
user=self.request.user,
|
|
||||||
)
|
|
||||||
|
|
||||||
self.opr.quantity = quantity
|
opr.save()
|
||||||
self.opr.save()
|
|
||||||
|
|
||||||
messages.info(
|
messages.info(
|
||||||
self.request,
|
self.request,
|
||||||
'{}x {} has been added to your order.'.format(
|
'{}x {} has been added to your order.'.format(
|
||||||
quantity,
|
opr.quantity,
|
||||||
product.name
|
opr.product.name
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -329,7 +326,7 @@ class OrderDetailView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureOrderH
|
||||||
return HttpResponseRedirect(reverse_lazy('shop:index'))
|
return HttpResponseRedirect(reverse_lazy('shop:index'))
|
||||||
|
|
||||||
# Then see if the user is cancelling the order.
|
# 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()
|
order.mark_as_cancelled()
|
||||||
messages.info(request, 'Order cancelled!')
|
messages.info(request, 'Order cancelled!')
|
||||||
return HttpResponseRedirect(reverse_lazy('shop:index'))
|
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.
|
# 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
|
# We use a formset for this to be able to display exactly
|
||||||
# which product is not in stock if that is the case.
|
# which product is not in stock if that is the case.
|
||||||
formset = OrderProductRelationFormSet(
|
else:
|
||||||
request.POST,
|
formset = OrderProductRelationFormSet(
|
||||||
queryset=OrderProductRelation.objects.filter(order=order),
|
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)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# No stock issues, proceed to check if the user is updating the order.
|
# If the formset is not valid it means that we cannot fulfill the order, so return and inform the user.
|
||||||
if 'update_order' in request.POST:
|
if not formset.is_valid():
|
||||||
# We have already made sure the formset is valid, so just save it to update quantities.
|
messages.error(
|
||||||
formset.save()
|
request,
|
||||||
|
"Some of the products you are ordering are out of stock. Review the order and try again."
|
||||||
order.customer_comment = request.POST.get('customer_comment') or ''
|
)
|
||||||
order.invoice_address = request.POST.get('invoice_address') or ''
|
return self.render_to_response(
|
||||||
order.save()
|
self.get_context_data(order_product_formset=formset)
|
||||||
|
|
||||||
# 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
|
# No stock issues, proceed to check if the user is updating the order.
|
||||||
order.payment_method = payment_method
|
if 'update_order' in request.POST:
|
||||||
order.open = None
|
# We have already made sure the formset is valid, so just save it to update quantities.
|
||||||
order.customer_comment = request.POST.get('customer_comment') or ''
|
formset.save()
|
||||||
order.invoice_address = request.POST.get('invoice_address') or ''
|
|
||||||
order.save()
|
|
||||||
|
|
||||||
reverses = {
|
order.customer_comment = request.POST.get('customer_comment') or ''
|
||||||
Order.CREDIT_CARD: reverse_lazy(
|
order.invoice_address = request.POST.get('invoice_address') or ''
|
||||||
'shop:epay_form',
|
order.save()
|
||||||
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])
|
# 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)
|
return super(OrderDetailView, self).get(request, *args, **kwargs)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue