Reputation: 936
I have a function in my Django App that add a product to a favorite database. I need to write a test of it. Everything except the test runs perfect.
def add(request):
data = {'success': False}
if request.method=='POST':
product_id = request.POST.get('product_id')
sub_product_id = request.POST.get('sub_product_id')
user = request.user
sub_product = Product.objects.get(pk=int(sub_product_id))
original_product = Product.objects.get(pk=int(product_id))
p = SavedProduct(username= user, sub_product=sub_product, original_product = original_product)
p.save()
data['success'] = True
return JsonResponse(data)
My 'product' comes from an AJAX call and I get it from this HTML:
<div class='sub_button'>
<form class="add_btn" method='post'>
<input type="hidden" class="product_id" value="{{ product.id }}">
<input type="hidden" class="sub_product_id" value="{{ sub_product.id }}">
<button class='added btn'><i class='fas fa-save'></i></button>
</div>
And that AJAX call:
$(".row").on('click', '.sub_button', function(event) {
let addedBtn = $(this);
event.preventDefault();
event.stopPropagation();
var product_id = $(this).find('.product_id').val();
var sub_product_id = $(this).find('.sub_product_id').val();
var url = '/finder/add/';
$.ajax({
url: url,
type: "POST",
data:{
'product_id': product_id,
'sub_product_id': sub_product_id,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val()
},
datatype:'json',
success: function(data) {
if (data['success'])
addedBtn.hide();
}
});
});
My urls.py:
app_name = 'finder'
urlpatterns = [
path('add/', views.add, name='add'),
path('sear/', views.search, name='sear'),
path('sub/', views.sub, name='sub') ]
This is the test I am running:
class AddDeleteProduct(TestCase):
def setUp(self):
User.objects.create(username='Toto', email='[email protected]')
def test_add_product(self):
old_count = SavedProduct.objects.count()
payload = {'product_id': 12, 'sub_product_id': 22}
response = self.client.post(reverse('finder:add', kwargs=payload))
new_count = SavedProduct.objects.count()
self.assertEqual(new_count, old_count + 1)
But I get this error message:
Traceback (most recent call last):
File "/home/pi/Documents/P_11_before/Pur_Beurre_Reload/finder/tests.py", line 155, in test_add_product
response = self.client.post(reverse('finder:add', kwargs=payload))
File "/home/pi/.local/lib/python3.7/site-packages/django/urls/base.py", line 87, in reverse
return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
File "/home/pi/.local/lib/python3.7/site-packages/django/urls/resolvers.py", line 677, in _reverse_with_prefix
raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'add' with keyword arguments '{'product_id': 12, 'sub_product_id': 22}' not found. 1 pattern(s) tried: ['finder/add/$']
Upvotes: 0
Views: 1007
Reputation: 2046
What you need is to have input fields in your html template.
path('add/<int:product_id>/<int:sub_product_id>', ...)
def add(request):
data = {'success': False}
if request.method=='POST':
product_id = request.POST.get('product_id')
sub_product_id = request.POST.get('sub_product_id')
user = request.user
sub_product = Product.objects.get(pk=int(sub_product_id))
original_product = Product.objects.get(pk=int(product_id))
p = SavedProduct(username= user, sub_product=sub_product, original_product = original_product)
p.save()
data['success'] = True
return JsonResponse(data)
<div class='sub_button'>
<form class="add_btn" method='post'>
<input type="hidden" name="product_id" value="{{ product.id }}">
<input type="hidden" name="sub_product_id" value="{{ sub_product.id }}">
<button class='added btn'><i class='fas fa-save'></i></button>
</div>
class AddDeleteProduct(TestCase):
def setUp(self):
User.objects.create(username='Toto', email='[email protected]')
def test_add_product(self):
old_count = SavedProduct.objects.count()
payload = {'product_id': 12, 'sub_product_id': 22}
response = self.client.post(reverse('finder:add', kwargs=payload))
new_count = SavedProduct.objects.count()
self.assertEqual(new_count, old_count + 1)
Upvotes: 1