This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import json
|
||||
from io import BytesIO
|
||||
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.files.base import ContentFile
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from PIL import Image
|
||||
|
||||
from shop.models import Product, ProductImage, ProductVariant
|
||||
from shop.tests.mixins import CreateProductsMixin
|
||||
|
||||
|
||||
class TestBackofficeHtmxContract(TestCase, CreateProductsMixin):
|
||||
def setUp(self):
|
||||
self.superuser = User.objects.create_superuser('vader', 'vader@empire.com', 'ihatesand')
|
||||
self.client.force_login(self.superuser)
|
||||
self.product = self.create_product()
|
||||
|
||||
def test_htmx_get_create_form_returns_fragment_not_full_page(self):
|
||||
response = self.client.get(reverse('backoffice:product_create'), HTTP_HX_REQUEST='true')
|
||||
assert response.status_code == 200
|
||||
body = response.content.decode()
|
||||
assert '<html' not in body
|
||||
assert 'Añadir producto' in body
|
||||
|
||||
def test_htmx_create_success_returns_204_and_triggers_modal_close_and_refresh(self):
|
||||
response = self.client.post(
|
||||
reverse('backoffice:product_create'),
|
||||
{
|
||||
'sku': 'HTMX-1',
|
||||
'name': 'Producto htmx',
|
||||
'description': '',
|
||||
'stock': '0',
|
||||
'categories': [],
|
||||
'tags': [],
|
||||
},
|
||||
HTTP_HX_REQUEST='true',
|
||||
)
|
||||
assert response.status_code == 204
|
||||
trigger = json.loads(response['HX-Trigger'])
|
||||
assert trigger == {'backoffice:modal-close': True, 'backoffice:list-changed': True}
|
||||
assert Product.objects.filter(sku='HTMX-1').exists()
|
||||
|
||||
def test_htmx_create_invalid_returns_200_with_errors_not_204(self):
|
||||
response = self.client.post(
|
||||
reverse('backoffice:product_create'),
|
||||
{'sku': '', 'name': '', 'description': '', 'stock': '0', 'categories': [], 'tags': []},
|
||||
HTTP_HX_REQUEST='true',
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert 'HX-Trigger' not in response
|
||||
|
||||
def test_non_htmx_create_still_redirects(self):
|
||||
response = self.client.post(
|
||||
reverse('backoffice:product_create'),
|
||||
{
|
||||
'sku': 'PLAIN-1',
|
||||
'name': 'Producto normal',
|
||||
'description': '',
|
||||
'stock': '0',
|
||||
'categories': [],
|
||||
'tags': [],
|
||||
},
|
||||
)
|
||||
assert response.status_code == 302
|
||||
assert 'HX-Trigger' not in response
|
||||
|
||||
def test_htmx_variant_create_triggers_refresh(self):
|
||||
size_m = self.create_attribute_value('Talla', 'M')
|
||||
|
||||
response = self.client.post(
|
||||
reverse('backoffice:product_variant_create', args=[self.product.pk]),
|
||||
{'sku': 'HTMX-V1', 'stock': '5', 'attribute_values': [size_m.pk]},
|
||||
HTTP_HX_REQUEST='true',
|
||||
)
|
||||
assert response.status_code == 204
|
||||
trigger = json.loads(response['HX-Trigger'])
|
||||
assert trigger['backoffice:modal-close'] is True
|
||||
assert trigger['backoffice:list-changed'] is True
|
||||
assert ProductVariant.objects.filter(sku='HTMX-V1').exists()
|
||||
|
||||
def test_htmx_variant_delete_stays_and_refreshes(self):
|
||||
size_m = self.create_attribute_value('Talla', 'M')
|
||||
variant = self.create_product_variant(self.product, sku='HTMX-V2', attribute_values=[size_m])
|
||||
|
||||
response = self.client.post(
|
||||
reverse('backoffice:product_variant_delete', args=[variant.pk]), HTTP_HX_REQUEST='true'
|
||||
)
|
||||
assert response.status_code == 204
|
||||
assert 'HX-Redirect' not in response
|
||||
trigger = json.loads(response['HX-Trigger'])
|
||||
assert trigger['backoffice:list-changed'] is True
|
||||
assert not ProductVariant.objects.filter(pk=variant.pk).exists()
|
||||
|
||||
def test_htmx_image_upload_triggers_refresh(self):
|
||||
image = Image.new('RGB', (64, 64), '#ACACAC')
|
||||
buffer = BytesIO()
|
||||
image.save(fp=buffer, format='WEBP')
|
||||
file = ContentFile(buffer.getvalue(), name='test.webp')
|
||||
|
||||
response = self.client.post(
|
||||
reverse('backoffice:product_image_create', args=[self.product.pk]),
|
||||
{'original': file},
|
||||
format='multipart',
|
||||
HTTP_HX_REQUEST='true',
|
||||
)
|
||||
assert response.status_code == 204
|
||||
trigger = json.loads(response['HX-Trigger'])
|
||||
assert trigger == {'backoffice:modal-close': True, 'backoffice:list-changed': True}
|
||||
assert ProductImage.objects.filter(product=self.product).exists()
|
||||
|
||||
def test_htmx_product_delete_uses_hx_redirect_instead_of_trigger(self):
|
||||
product = self.create_product(sku='HTMX-DEL')
|
||||
|
||||
response = self.client.post(reverse('backoffice:product_delete', args=[product.pk]), HTTP_HX_REQUEST='true')
|
||||
assert response.status_code == 200
|
||||
assert response['HX-Redirect'] == reverse('backoffice:product_list')
|
||||
assert 'HX-Trigger' not in response
|
||||
assert not Product.objects.filter(pk=product.pk).exists()
|
||||
|
||||
def test_htmx_list_self_refresh_returns_fragment(self):
|
||||
response = self.client.get(reverse('backoffice:product_list'), HTTP_HX_REQUEST='true')
|
||||
assert response.status_code == 200
|
||||
body = response.content.decode()
|
||||
assert '<html' not in body
|
||||
assert 'id="backoffice-list"' in body
|
||||
|
||||
def test_htmx_product_detail_self_refresh_returns_fragment(self):
|
||||
response = self.client.get(reverse('backoffice:product_detail', args=[self.product.pk]), HTTP_HX_REQUEST='true')
|
||||
assert response.status_code == 200
|
||||
body = response.content.decode()
|
||||
assert '<html' not in body
|
||||
assert 'id="backoffice-detail"' in body
|
||||
Reference in New Issue
Block a user