django-admin-confirm-briq/admin_confirm/tests/unit/test_confirmation_using_fil...

921 lines
33 KiB
Python

"""
Ensure that files are saved during confirmation
Without file changes, Django is relied on
With file changes, we cache the object, save it with
the files if new, or add files to existing obj and save
Then send the rest of the changes to Django to handle
This is arguably the most we fiddle with the Django request
Thus we should test it extensively
"""
from admin_confirm.utils import format_cache_key
from admin_confirm.file_cache import FileCache
import time
from unittest import mock
from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.cache import cache
from admin_confirm.tests.helpers import AdminConfirmTestCase
from admin_confirm.constants import CACHE_KEYS, CONFIRMATION_RECEIVED
from tests.market.admin import ItemAdmin
from tests.market.models import Item, Shop
from tests.factories import ItemFactory, ShopFactory
class TestConfirmationUsingFileCache(AdminConfirmTestCase):
def setUp(self):
# Load the Change Item Page
ItemAdmin.confirm_change = True
ItemAdmin.fields = ["name", "price", "file", "image", "currency"]
ItemAdmin.save_as = True
ItemAdmin.save_as_continue = True
self.image_path = "screenshot.png"
f = SimpleUploadedFile(
name="test_file.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
i = SimpleUploadedFile(
name="test_image.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
self.item = ItemFactory(name="Not name", file=f, image=i)
return super().setUp()
def test_save_as_continue_true_should_not_redirect_to_changelist(self):
item = self.item
# Load the Change Item Page
ItemAdmin.save_as_continue = True
# Upload new image and remove file
i2 = SimpleUploadedFile(
name="test_image2.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"file": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_saveasnew": True,
}
# Set cache
cache_item = Item(
name=data["name"],
price=data["price"],
currency=data["currency"],
image=i2,
)
file_cache = FileCache()
file_cache.set(format_cache_key(model="Item", field="image"), i2)
cache.set(CACHE_KEYS["object"], cache_item)
cache.set(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertIn("You may edit it again below.", message)
# Should not have redirected to changelist
self.assertEqual(response.url, f"/admin/market/item/{self.item.id + 1}/change/")
# Should not have changed existing item
item.refresh_from_db()
self.assertEqual(item.name, "Not name")
self.assertEqual(item.file.name.count("test_file"), 1)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertFalse(new_item.file)
self.assertEqual(new_item.image.name.count("test_image2"), 1)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_save_as_continue_false_should_redirect_to_changelist(self):
item = self.item
# Load the Change Item Page
ItemAdmin.save_as_continue = False
# Upload new image and remove file
i2 = SimpleUploadedFile(
name="test_image2.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"file": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_saveasnew": True,
}
# Set cache
cache_item = Item(
name=data["name"],
price=data["price"],
currency=data["currency"],
image=i2,
)
file_cache = FileCache()
file_cache.set(format_cache_key(model="Item", field="image"), i2)
cache.set(CACHE_KEYS["object"], cache_item)
cache.set(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
item.refresh_from_db()
self.assertEqual(item.name, "Not name")
self.assertEqual(item.file.name.count("test_file"), 1)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertFalse(new_item.file)
self.assertEqual(new_item.image.name.count("test_image2"), 1)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_saveasnew_without_any_file_changes_should_save_new_instance_without_files(
self,
):
item = self.item
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"file": "",
"image": "",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_saveasnew": True,
}
# Set cache
cache_item = Item(
name=data["name"],
price=data["price"],
currency=data["currency"],
)
cache.set(CACHE_KEYS["object"], cache_item)
cache.set(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertIn("You may edit it again below.", message)
# Should not have redirected to changelist
self.assertEqual(response.url, f"/admin/market/item/{self.item.id + 1}/change/")
# Should not have changed existing item
item.refresh_from_db()
self.assertEqual(item.name, "Not name")
self.assertEqual(item.file.name.count("test_file"), 1)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
# In Django (by default), the save as new does not transfer over the files
self.assertFalse(new_item.file)
self.assertFalse(new_item.image)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_add_with_upload_file_should_save_new_instance_with_files(self):
# Upload new file
f2 = SimpleUploadedFile(
name="test_file2.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
# Request.POST
data = {
"name": "name",
"price": 2.0,
"image": "",
"file": f2,
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_add": True,
"_save": True,
}
# Set cache
cache_item = Item(
name=data["name"], price=data["price"], currency=data["currency"], file=f2
)
cache.set(CACHE_KEYS["object"], cache_item)
cache.set(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_add"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post("/admin/market/item/add/", data=data)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should not have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
self.item.refresh_from_db()
self.assertEqual(self.item.name, "Not name")
self.assertEqual(self.item.file.name.count("test_file"), 1)
self.assertEqual(self.item.image.name.count("test_image2"), 0)
self.assertEqual(self.item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=self.item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertIsNotNone(new_item.file)
self.assertFalse(new_item.image)
self.assertRegex(new_item.file.name, r"test_file2.*\.jpg$")
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_add_without_cached_post_should_save_new_instance_with_file(self):
# Upload new file
f2 = SimpleUploadedFile(
name="test_file2.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
# Request.POST
data = {
"name": "name",
"price": 2.0,
"image": "",
"file": f2,
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_add": True,
"_save": True,
}
# Set cache
cache_item = Item(
name=data["name"], price=data["price"], currency=data["currency"], file=f2
)
cache.set(CACHE_KEYS["object"], cache_item)
# Make sure there's no post cached post
cache.delete(CACHE_KEYS["post"])
# Click "Yes, I'm Sure"
del data["_confirm_add"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post("/admin/market/item/add/", data=data)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should not have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
self.item.refresh_from_db()
self.assertEqual(self.item.name, "Not name")
self.assertEqual(self.item.file.name.count("test_file"), 1)
self.assertEqual(self.item.image.name.count("test_image2"), 0)
self.assertEqual(self.item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=self.item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertFalse(new_item.image)
# Able to save the cached file since cached object was there even though cached post was not
self.assertRegex(new_item.file.name, r"test_file2.*\.jpg$")
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_add_without_cached_object_should_save_new_instance_but_not_have_file(self):
# Request.POST
data = {
"name": "name",
"price": 2.0,
"image": "",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_add": True,
"_save": True,
}
# Make sure there's no post cached obj
cache.delete(CACHE_KEYS["object"])
cache.set(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_add"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post("/admin/market/item/add/", data=data)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should not have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
self.item.refresh_from_db()
self.assertEqual(self.item.name, "Not name")
self.assertEqual(self.item.file.name.count("test_file"), 1)
self.assertEqual(self.item.image.name.count("test_image2"), 0)
self.assertEqual(self.item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=self.item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertFalse(new_item.image)
# FAILED to save the file, because cached item was not there
self.assertFalse(new_item.file)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_add_without_any_cache_should_save_new_instance_but_not_have_file(self):
# Request.POST
data = {
"name": "name",
"price": 2.0,
"image": "",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_add": True,
"_save": True,
}
# Make sure there's no cache
cache.delete(CACHE_KEYS["object"])
cache.delete(CACHE_KEYS["post"])
# Click "Yes, I'm Sure"
del data["_confirm_add"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post("/admin/market/item/add/", data=data)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should not have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
self.item.refresh_from_db()
self.assertEqual(self.item.name, "Not name")
self.assertEqual(self.item.file.name.count("test_file"), 1)
self.assertEqual(self.item.image.name.count("test_image2"), 0)
self.assertEqual(self.item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=self.item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertFalse(new_item.image)
# FAILED to save the file, because cached item was not there
self.assertFalse(new_item.file)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_change_without_cached_post_should_save_file_changes(self):
item = self.item
# Load the Change Item Page
ItemAdmin.save_as_continue = False
# Upload new image and remove file
i2 = SimpleUploadedFile(
name="test_image2.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"image": i2,
"file": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_saveasnew": True,
}
# Set cache
cache_item = Item(
name=data["name"],
price=data["price"],
currency=data["currency"],
image=i2,
)
file_cache = FileCache()
file_cache.set(format_cache_key(model="Item", field="image"), i2)
cache.set(CACHE_KEYS["object"], cache_item)
# Ensure no cached post
cache.delete(CACHE_KEYS["post"])
# Click "Yes, I'm Sure"
del data["_confirm_change"]
# Image would have been in FILES and not in POST
del data["image"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
item.refresh_from_db()
self.assertEqual(item.name, "Not name")
self.assertEqual(item.file.name.count("test_file"), 1)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
# Should have cleared `file` since clear was selected
self.assertFalse(new_item.file)
self.assertIsNotNone(new_item.image)
# Saved cached file from cached obj even if cached post was missing
self.assertIn("test_image2", new_item.image.name)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_change_without_cached_object_should_save_but_without_file_changes(self):
item = self.item
# Load the Change Item Page
ItemAdmin.save_as_continue = False
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"file": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_saveasnew": True,
}
# Ensure no cached obj
cache.delete(CACHE_KEYS["object"])
cache.set(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
item.refresh_from_db()
self.assertEqual(item.name, "Not name")
self.assertEqual(item.file.name.count("test_file"), 1)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertFalse(new_item.file)
# FAILED to save image
self.assertFalse(new_item.image)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_change_without_any_cache_should_save_but_not_have_file_changes(self):
item = self.item
# Load the Change Item Page
ItemAdmin.save_as_continue = False
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"file": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_saveasnew": True,
}
# Ensure no cache
cache.delete(CACHE_KEYS["object"])
cache.delete(CACHE_KEYS["post"])
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/2/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should not have changed existing item
item.refresh_from_db()
self.assertEqual(item.name, "Not name")
self.assertEqual(item.file.name.count("test_file"), 1)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have saved new item
self.assertEqual(Item.objects.count(), 2)
new_item = Item.objects.filter(id=item.id + 1).first()
self.assertIsNotNone(new_item)
self.assertEqual(new_item.name, data["name"])
self.assertEqual(new_item.price, data["price"])
self.assertEqual(new_item.currency, data["currency"])
self.assertFalse(new_item.file)
# FAILED to save image
self.assertFalse(new_item.image)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_change_without_changing_file_should_save_changes(self):
item = self.item
# Load the Change Item Page
ItemAdmin.save_as_continue = False
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"file": "",
"image": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_save": True,
}
# Set cache
cache_item = Item(
name=data["name"],
price=data["price"],
currency=data["currency"],
)
cache.get(CACHE_KEYS["object"], cache_item)
cache.get(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/1/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should have changed existing item
self.assertEqual(Item.objects.count(), 1)
item.refresh_from_db()
self.assertEqual(item.name, "name")
# Should have cleared if requested
self.assertFalse(item.file.name)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
@mock.patch("admin_confirm.admin.CACHE_TIMEOUT", 1)
def test_old_cache_should_not_be_used(self):
item = self.item
# Upload new image and remove file
i2 = SimpleUploadedFile(
name="test_image2.jpg",
content=open(self.image_path, "rb").read(),
content_type="image/jpeg",
)
# Click "Save And Continue"
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"image": i2,
"file": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_continue": True,
}
response = self.client.post(f"/admin/market/item/{item.id}/change/", data=data)
# Should be shown confirmation page
self._assertSubmitHtml(
rendered_content=response.rendered_content,
save_action="_continue",
multipart_form=True,
)
# Should have cached the unsaved item
cached_item = cache.get(CACHE_KEYS["object"])
self.assertIsNotNone(cached_item)
# Should not have saved the changes yet
self.assertEqual(Item.objects.count(), 1)
item.refresh_from_db()
self.assertEqual(item.name, "Not name")
self.assertIsNotNone(item.file)
self.assertIsNotNone(item.image)
# Wait for cache to time out
time.sleep(1)
# Check that it did time out
cached_item = cache.get(CACHE_KEYS["object"])
self.assertIsNone(cached_item)
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data["image"] = ""
data[CONFIRMATION_RECEIVED] = True
response = self.client.post(f"/admin/market/item/{item.id}/change/", data=data)
# Should not have redirected to changelist
self.assertEqual(response.url, f"/admin/market/item/{item.id}/change/")
# Should have saved item
self.assertEqual(Item.objects.count(), 1)
saved_item = Item.objects.all().first()
self.assertEqual(saved_item.name, data["name"])
self.assertEqual(saved_item.price, data["price"])
self.assertEqual(saved_item.currency, data["currency"])
self.assertFalse(saved_item.file)
# SHOULD not have saved image since it was in the old cache
self.assertNotIn("test_image2", saved_item.image)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_cache_with_incorrect_model_should_not_be_used(self):
item = self.item
# Load the Change Item Page
ItemAdmin.save_as_continue = False
# Request.POST
data = {
"id": item.id,
"name": "name",
"price": 2.0,
"file": "",
"file-clear": "on",
"currency": Item.VALID_CURRENCIES[0][0],
"_confirm_change": True,
"_save": True,
}
# Set cache to incorrect model
cache_obj = Shop(name="ShopName")
cache.set(CACHE_KEYS["object"], cache_obj)
cache.set(CACHE_KEYS["post"], data)
# Click "Yes, I'm Sure"
del data["_confirm_change"]
data[CONFIRMATION_RECEIVED] = True
with mock.patch.object(ItemAdmin, "message_user") as message_user:
response = self.client.post(
f"/admin/market/item/{self.item.id}/change/", data=data
)
# Should show message to user with correct obj and path
message_user.assert_called_once()
message = message_user.call_args[0][1]
self.assertIn("/admin/market/item/1/change/", message)
self.assertIn(data["name"], message)
self.assertNotIn("You may edit it again below.", message)
# Should have redirected to changelist
self.assertEqual(response.url, "/admin/market/item/")
# Should have changed existing item
self.assertEqual(Item.objects.count(), 1)
item.refresh_from_db()
self.assertEqual(item.name, "name")
# Should have cleared if requested
self.assertFalse(item.file.name)
self.assertEqual(item.image.name.count("test_image2"), 0)
self.assertEqual(item.image.name.count("test_image"), 1)
# Should have cleared cache
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))
def test_form_without_files_should_not_use_cache(self):
cache.delete_many(CACHE_KEYS.values())
shop = ShopFactory()
# Click "Save And Continue"
data = {
"id": shop.id,
"name": "name",
"_confirm_change": True,
"_continue": True,
}
response = self.client.post(f"/admin/market/shop/{shop.id}/change/", data=data)
# Should be shown confirmation page
self._assertSubmitHtml(
rendered_content=response.rendered_content, save_action="_continue"
)
# Should not have set cache since not multipart form
for key in CACHE_KEYS.values():
self.assertIsNone(cache.get(key))