Happy with test cases

main
Thu Trang Pham 2020-11-06 01:10:14 -08:00
parent 081aec4821
commit c6a44f6426
5 changed files with 116 additions and 47 deletions

2
Makefile 100644
View File

@ -0,0 +1,2 @@
run:
./tests/manage.py runserver

View File

@ -52,7 +52,7 @@ class AdminConfirmMixin:
def changeform_view(self, request, object_id=None, form_url="", extra_context=None):
if request.method == "POST":
if (not object_id and "_confirm_add" in request.POST) or (object_id and "_confirm_change"):
if (not object_id and "_confirm_add" in request.POST) or (object_id and "_confirm_change" in request.POST):
return self._change_confirmation_view(request, object_id, form_url, extra_context)
extra_context = {
@ -68,6 +68,7 @@ class AdminConfirmMixin:
TO_FIELD_VAR, request.GET.get(TO_FIELD_VAR)
)
if to_field and not self.to_field_allowed(request, to_field):
print("OKAY WHAT")
raise DisallowedModelAdminToField(
"The field %s cannot be referenced." % to_field
)
@ -115,8 +116,8 @@ class AdminConfirmMixin:
if field.has_changed(initial_value, new_value) and initial_value != new_value:
changed_data[name] = [initial_value, new_value]
changed_confirmation_fields = set(self.get_confirmation_fields(request, obj)) & set(changed_data.keys())
self.message_user(request, changed_confirmation_fields)
changed_confirmation_fields = set(self.get_confirmation_fields(
request, obj)) & set(changed_data.keys())
if not bool(changed_confirmation_fields):
# No confirmation required for changed fields, continue to save
return super()._changeform_view(request, object_id, form_url, extra_context)

View File

@ -1,69 +1,135 @@
from unittest import mock
from requests import Request
from django.test import TestCase
from django.test import TestCase, RequestFactory
from django.contrib.auth.models import User
from django.contrib.admin.sites import AdminSite
from tests.market.admin import ItemAdmin, InventoryAdmin, ShopAdmin
from tests.market.models import Item
from tests.factories import ItemFactory, InventoryFactory, ShopFactory
from tests.market.admin import ItemAdmin
from tests.market.models import Item, Inventory
from django.urls import reverse
from tests.factories import ItemFactory, ShopFactory
class TestAdminConfirmMixin(TestCase):
@mock.patch('django.contrib.admin.options.changeform_view')
def test_add_without_confirm(self, mock_super):
ItemAdmin.confirm_add = None
admin = ItemAdmin(Item, AdminSite())
request = Request('POST', 'url', data={'name': 'name', 'price': 2.0, 'currency': Item.VALID_CURRENCIES[0]})
@classmethod
def setUpTestData(cls):
cls.superuser = User.objects.create_superuser(
username='super', email='super@email.org', password='pass')
confirmation_template = admin.render_change_confirmation(request, context={}).template_name
# object_id = None for adding
actual_template = admin.changeform_view(request).template_name
mock_super.assert_called_once()
self.assertNotEqual(confirmation_template, actual_template)
def setUp(self):
self.client.force_login(self.superuser)
self.factory = RequestFactory()
def test_change_with_no_options(self):
def test_get_add_without_confirm_add(self):
response = self.client.get(reverse('admin:market_item_add'))
self.assertFalse(response.context_data.get('confirm_add'))
self.assertNotIn('_confirm_add', response.rendered_content)
def test_get_add_with_confirm_add(self):
response = self.client.get(reverse('admin:market_inventory_add'))
self.assertTrue(response.context_data.get('confirm_add'))
self.assertIn('_confirm_add', response.rendered_content)
def test_with_confirm_change(self):
pass
def test_get_change_without_confirm_change(self):
response = self.client.get(reverse('admin:market_shop_add'))
self.assertFalse(response.context_data.get('confirm_change'))
self.assertNotIn('_confirm_change', response.rendered_content)
def test_with_confirm_add(self):
pass
def test_get_change_with_confirm_change(self):
response = self.client.get(reverse('admin:market_inventory_add'))
self.assertTrue(response.context_data.get('confirm_change'))
self.assertIn('_confirm_change', response.rendered_content)
def test_post_add_without_confirm_add(self):
data = {'name': 'name', 'price': 2.0,
'currency': Item.VALID_CURRENCIES[0]}
response = self.client.post(reverse('admin:market_item_add'), data)
# Redirects to item changelist and item is added
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, '/admin/market/item/')
self.assertEqual(Item.objects.count(), 1)
def test_post_add_with_confirm_add(self):
item = ItemFactory()
shop = ShopFactory()
data = {'shop': shop.id, 'item': item.id,
'quantity': 5, '_confirm_add': True}
response = self.client.post(
reverse('admin:market_inventory_add'), data)
# Ensure not redirected (confirmation page does not redirect)
self.assertEqual(response.status_code, 200)
expected_templates = [
'admin/market/inventory/change_confirmation.html',
'admin/market/change_confirmation.html',
'admin/change_confirmation.html'
]
self.assertEqual(response.template_name, expected_templates)
form_data = {'shop': str(shop.id), 'item': str(
item.id), 'quantity': str(5)}
self.assertEqual(
response.context_data['form_data'], form_data)
for k, v in form_data.items():
self.assertIn(
f'<input type="hidden" name="{ k }" value="{ v }">', response.rendered_content)
# Should not have been added yet
self.assertEqual(Inventory.objects.count(), 0)
def test_post_change_with_confirm_change(self):
item = ItemFactory(name='item')
data = {'name': 'name', 'price': 2.0,
'currency': Item.VALID_CURRENCIES[0], '_confirm_change': True}
response = self.client.post(
f'/admin/market/item/{item.id}/change/', data)
# Ensure not redirected (confirmation page does not redirect)
self.assertEqual(response.status_code, 200)
expected_templates = [
'admin/market/item/change_confirmation.html',
'admin/market/change_confirmation.html',
'admin/change_confirmation.html'
]
self.assertEqual(response.template_name, expected_templates)
form_data = {'name': 'name', 'price': str(2.0),
'currency': Item.VALID_CURRENCIES[0][0]}
self.assertEqual(
response.context_data['form_data'], form_data)
for k, v in form_data.items():
self.assertIn(
f'<input type="hidden" name="{ k }" value="{ v }">', response.rendered_content)
# Hasn't changed item yet
item.refresh_from_db()
self.assertEqual(item.name, 'item')
def test_post_change_without_confirm_change(self):
shop = ShopFactory(name='bob')
data = {'name': 'sally'}
response = self.client.post(
f'/admin/market/shop/{shop.id}/change/', data)
# Redirects to changelist
print(response)
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, '/admin/market/shop/')
# Shop has changed
shop.refresh_from_db()
self.assertEqual(shop.name, 'sally')
def test_get_confirmation_fields_should_default_if_not_set(self):
expected_fields = [f.name for f in Item._meta.fields if f.name != 'id']
ItemAdmin.confirmation_fields = None
admin = ItemAdmin(Item, AdminSite())
actual_fields = admin.get_confirmation_fields(Request('GET', 'url'))
actual_fields = admin.get_confirmation_fields(self.factory.request())
self.assertEqual(expected_fields, actual_fields)
def test_get_confirmation_fields_if_set(self):
expected_fields = ['name', 'currency']
ItemAdmin.confirmation_fields = expected_fields
admin = ItemAdmin(Item, AdminSite())
actual_fields = admin.get_confirmation_fields(Request('GET', 'url'))
actual_fields = admin.get_confirmation_fields(self.factory.request())
self.assertEqual(expected_fields, actual_fields)
def test_custom_template(self):
expected_template = 'my_custom_template.html'
ItemAdmin.confirmation_template = expected_template
admin = ItemAdmin(Item, AdminSite())
actual_template = admin.render_change_confirmation(Request('POST', 'url'), context={}).template_name
actual_template = admin.render_change_confirmation(
self.factory.request(), context={}).template_name
self.assertEqual(expected_template, actual_template)
class TestAdminConfirmMixinConfirmChange(TestCase):
pass
class TestAdminConfirmMixinConfirmAdd(TestCase):
pass
class TestAdminConfirmMixinConfirmChangeWithFields(TestCase):
pass
class TestAdminConfirmMixinConfirmChangeWithFields(TestCase):
pass

View File

@ -1,6 +1,6 @@
import factory
from random import choice
from random import choice, randint
from tests.market.models import Item, Shop, Inventory
@ -10,7 +10,7 @@ class ItemFactory(factory.django.DjangoModelFactory):
model = Item
name = factory.Faker('name')
price = factory.Faker('price')
price = factory.LazyAttribute(lambda _: randint(5, 500))
currency = factory.LazyAttribute(lambda _: choice(Item.VALID_CURRENCIES))

View File

@ -23,4 +23,4 @@ class ShopAdmin(AdminConfirmMixin, admin.ModelAdmin):
admin.site.register(Item, ItemAdmin)
admin.site.register(Inventory, InventoryAdmin)
admin.site.register(Shop, ShopAdmin)
admin.site.register(Shop, ShopAdmin)