Skip to content

Commit a512d77

Browse files
authored
test: write tests for htmx widget initialization
1 parent 1c2e5da commit a512d77

File tree

8 files changed

+626
-1
lines changed

8 files changed

+626
-1
lines changed

tests/templates/test_htmx.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>HTMX</title>
7+
{{ media }}
8+
</head>
9+
<body hx-headers='{"X-CSRFToken": "{{ csrf_token }}"}'>
10+
11+
<button
12+
hx-get="{% if destination %}{{ destination }}{% else %}/test-htmx-image-widget/required/{% endif %}"
13+
hx-target="this"
14+
hx-swap="outerHTML"
15+
hx-trigger="click"
16+
type="button"
17+
class="btn-load"
18+
>
19+
Load
20+
</button>
21+
22+
<script src="https://unpkg.com/htmx.org@1.9.12"></script>
23+
</body>
24+
</html>

tests/templates/test_htmx_widget.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<form
2+
hx-post="/{{ post_url }}/{% if instance %}{{ instance.pk }}/{% endif %}"
3+
hx-target="this"
4+
hx-swap="outerHTML"
5+
enctype="multipart/form-data"
6+
id="my-widget-form"
7+
>
8+
{% if messages %}
9+
<ul class="messagelist">
10+
{% for message in messages %}
11+
<li class="{{ message.tags }}">{{ message }}</li>
12+
{% endfor %}
13+
</ul>
14+
{% endif %}
15+
16+
{{ form }}
17+
18+
<button class="btn-submit" type="submit">Submit</button>
19+
</form>

tests/tests_functional/htmx/__init__.py

Whitespace-only changes.
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
from django.core.files import File
2+
from django.test.utils import tag
3+
4+
from tests import models, test_case
5+
6+
7+
@tag("functional", "functional_widget", "widget", "htmx")
8+
class HTMXWidgetOptionalTestCase(test_case.IUWTestCase):
9+
def goto_add_page(self):
10+
self.page.goto(
11+
f"{self.live_server_url}/test-htmx/?destination=/test-htmx-image-widget/optional/"
12+
)
13+
14+
def goto_change_page(self):
15+
item = self.init_item()
16+
self.page.goto(
17+
f"{self.live_server_url}/test-htmx/?destination=/test-htmx-image-widget/optional/{item.pk}/"
18+
)
19+
return item
20+
21+
def init_item(self):
22+
item = models.TestNonRequired()
23+
with open(self.image1, "rb") as f:
24+
item.image.save("image.png", File(f), False)
25+
item.save()
26+
return item
27+
28+
def load_widget(self):
29+
button = self.page.query_selector(".btn-load")
30+
button.click()
31+
self.wait(0.4)
32+
33+
def test_empty_marker_click(self):
34+
self.goto_add_page()
35+
self.load_widget()
36+
37+
with self.assert_input_file_clicked(
38+
input_selector=".iuw-root input[type=file]"
39+
):
40+
empty_marker = self.find_empty_marker()
41+
self.assertTrue(empty_marker.is_visible())
42+
empty_marker.click()
43+
44+
def test_non_required_file_input(self):
45+
self.assertEqual(models.TestNonRequired.objects.count(), 0)
46+
self.goto_add_page()
47+
self.load_widget()
48+
49+
form_row = self.page.query_selector(".iuw-root")
50+
preview = self.find_widget_preview(form_row)
51+
self.assertFalse(preview.is_visible())
52+
53+
file_input = form_row.query_selector("input[type=file]")
54+
file_input.set_input_files(self.image1)
55+
56+
preview = self.find_widget_preview(form_row)
57+
self.assertIsNotNone(preview)
58+
59+
img = preview.query_selector("img")
60+
preview_button = self.find_preview_icon()
61+
delete_button = self.find_delete_icon()
62+
self.assertTrue(preview.is_visible())
63+
self.assertIsNotNone(img)
64+
self.assertIsNotNone(preview_button)
65+
self.assertIsNotNone(delete_button)
66+
67+
self.submit_form("#my-widget-form")
68+
self.assert_success_message()
69+
70+
items = models.TestNonRequired.objects.all()
71+
self.assertEqual(len(items), 1)
72+
self.assertIsNotNone(items[0].image)
73+
74+
def test_remove_button_with_non_saved_image(self):
75+
self.assertEqual(models.TestNonRequired.objects.count(), 0)
76+
self.goto_add_page()
77+
self.load_widget()
78+
79+
form_row = self.page.query_selector(".iuw-root")
80+
file_input = form_row.query_selector("input[type=file]")
81+
file_input.set_input_files(self.image2)
82+
83+
preview = self.find_widget_preview(form_row)
84+
self.assertIsNotNone(preview)
85+
delete_button = self.find_delete_icon(preview)
86+
delete_button.click()
87+
88+
preview = self.find_widget_preview(form_row)
89+
self.assertFalse(preview.is_visible())
90+
91+
def test_image_with_database_data(self):
92+
item = self.goto_change_page()
93+
self.load_widget()
94+
95+
root = self.page.query_selector(".iuw-root")
96+
97+
preview = self.find_widget_preview(root)
98+
self.assertIsNotNone(preview)
99+
self.assertEqual(root.get_attribute("data-raw"), item.image.url)
100+
101+
empty_marker = self.find_empty_marker(root)
102+
self.assertFalse(empty_marker.is_visible())
103+
104+
img = preview.query_selector("img")
105+
preview_button = self.find_preview_icon(preview)
106+
delete_button = self.find_delete_icon(preview)
107+
self.assertTrue(preview.is_visible())
108+
self.assertIsNotNone(img)
109+
self.assertTrue(item.image.url in img.get_attribute("src"))
110+
self.assertIsNotNone(preview_button)
111+
self.assertIsNotNone(delete_button)
112+
113+
def test_delete_saved_image(self):
114+
self.goto_change_page()
115+
self.load_widget()
116+
117+
form_row = self.page.query_selector(".iuw-root")
118+
checkbox = form_row.query_selector("[type=checkbox]")
119+
preview = self.find_widget_preview(form_row)
120+
self.assertIsNotNone(preview)
121+
122+
self.assertFalse(checkbox.is_checked())
123+
124+
delete_button = self.find_delete_icon(preview)
125+
delete_button.click()
126+
127+
preview = self.find_widget_preview(form_row)
128+
self.assertFalse(preview.is_visible())
129+
130+
self.assertTrue(checkbox.is_checked())
131+
132+
self.submit_form("#my-widget-form")
133+
self.assert_success_message()
134+
135+
items = models.TestNonRequired.objects.all()
136+
self.assertEqual(len(items), 1)
137+
self.assertFalse(bool(items[0].image))
138+
139+
def test_click_on_the_preview_image(self):
140+
self.goto_add_page()
141+
self.load_widget()
142+
143+
form_row = self.page.query_selector(".iuw-root")
144+
preview = self.find_widget_preview(form_row)
145+
self.assertFalse(preview.is_visible())
146+
file_input = form_row.query_selector("input[type=file]")
147+
file_input.set_input_files(self.image1)
148+
149+
with self.assert_input_file_clicked(
150+
input_selector=".iuw-root input[type=file]"
151+
):
152+
preview = self.find_widget_preview(form_row)
153+
self.assertIsNotNone(preview)
154+
img = preview.query_selector("img")
155+
img.click()
156+
157+
def test_click_on_the_preview_button(self):
158+
self.goto_add_page()
159+
self.load_widget()
160+
161+
form_row = self.page.query_selector(".iuw-root")
162+
preview = self.find_widget_preview(form_row)
163+
self.assertFalse(preview.is_visible())
164+
file_input = form_row.query_selector("input[type=file]")
165+
file_input.set_input_files(self.image2)
166+
167+
preview = self.find_widget_preview(form_row)
168+
self.assertIsNotNone(preview)
169+
preview_img = preview.query_selector("img")
170+
preview_button = self.find_preview_icon(form_row)
171+
preview_button.click()
172+
173+
self.assert_preview_modal(preview_img)
174+
175+
def test_click_on_the_preview_button_and_image_on_modal(self):
176+
self.goto_add_page()
177+
self.load_widget()
178+
179+
form_row = self.page.query_selector(".iuw-root")
180+
preview = self.find_widget_preview(form_row)
181+
self.assertFalse(preview.is_visible())
182+
183+
file_input = form_row.query_selector("input[type=file]")
184+
file_input.set_input_files(self.image2)
185+
186+
preview = self.find_widget_preview(form_row)
187+
self.assertIsNotNone(preview)
188+
preview_img = preview.query_selector("img")
189+
preview_button = self.find_preview_icon(form_row)
190+
preview_button.click()
191+
192+
self.assert_preview_modal(preview_img)
193+
preview_modal = self.get_preview_modal()
194+
img = preview_modal.query_selector("img")
195+
img.click()
196+
197+
self.wait(0.5)
198+
self.assertEqual(preview_modal.get_attribute("class"), "iuw-modal visible")
199+
200+
def test_click_on_the_preview_button_and_close_on_modal(self):
201+
self.goto_add_page()
202+
self.load_widget()
203+
204+
form_row = self.page.query_selector(".iuw-root")
205+
preview = self.find_widget_preview(form_row)
206+
self.assertFalse(preview.is_visible())
207+
208+
file_input = form_row.query_selector("input[type=file]")
209+
file_input.set_input_files(self.image2)
210+
211+
preview = self.find_widget_preview(form_row)
212+
self.assertIsNotNone(preview)
213+
preview_img = preview.query_selector("img")
214+
preview_button = self.find_preview_icon(form_row)
215+
preview_button.click()
216+
217+
self.assert_preview_modal(preview_img)
218+
self.assert_preview_modal_close()
219+
220+
def test_drop_label_leave(self):
221+
self.goto_add_page()
222+
self.load_widget()
223+
224+
root = self.page.query_selector(".iuw-root")
225+
drop_label = self.find_drop_label()
226+
227+
self.assertFalse(drop_label.is_visible())
228+
229+
data_transfer = self.page.evaluate_handle("() => new DataTransfer()")
230+
root.dispatch_event("dragenter", {"dataTransfer": data_transfer})
231+
self.wait(0.5)
232+
233+
self.assertTrue(drop_label.is_visible())
234+
235+
root.dispatch_event("dragleave", {"dataTransfer": data_transfer})
236+
self.wait(0.5)
237+
238+
self.assertFalse(drop_label.is_visible())
239+
240+
def test_drop_label_drop(self):
241+
self.goto_add_page()
242+
self.load_widget()
243+
244+
root = self.page.query_selector(".iuw-root")
245+
drop_label = self.find_drop_label()
246+
247+
self.assertFalse(drop_label.is_visible())
248+
249+
data_transfer = self.page.evaluate_handle("() => new DataTransfer()")
250+
root.dispatch_event("dragenter", {"dataTransfer": data_transfer})
251+
self.wait(0.5)
252+
253+
self.assertTrue(drop_label.is_visible())
254+
255+
root.dispatch_event("drop", {"dataTransfer": data_transfer})
256+
self.wait(0.5)
257+
258+
self.assertFalse(drop_label.is_visible())
259+
260+
def test_drop_label_end(self):
261+
self.goto_add_page()
262+
self.load_widget()
263+
264+
root = self.page.query_selector(".iuw-root")
265+
drop_label = self.find_drop_label()
266+
267+
self.assertFalse(drop_label.is_visible())
268+
269+
data_transfer = self.page.evaluate_handle("() => new DataTransfer()")
270+
root.dispatch_event("dragenter", {"dataTransfer": data_transfer})
271+
self.wait(0.5)
272+
273+
self.assertTrue(drop_label.is_visible())
274+
275+
root.dispatch_event("dragend", {"dataTransfer": data_transfer})
276+
self.wait(0.5)
277+
278+
self.assertFalse(drop_label.is_visible())

0 commit comments

Comments
 (0)