mirror of
https://github.com/retspen/webvirtcloud
synced 2026-11-11 04:36:48 +00:00
fix(instances): adding or deleting a flavor keeps the unfinished VM form
The create page's flavor dialog posted its forms the normal way, and the server sent a fresh page back: the VM's name, sizes, disk choices and MAC edits were lost, and a refused flavor left the page for a bare form. The dialog's forms are now posted from the page. The flavor views answer such a post with the presets and the dialog body, rendered from the same includes as the page, and the script swaps them in: a refused flavor shows its errors in the dialog, and the focus stays in it. A post without the script, or one whose request fails, still goes the normal way. Fixes #173 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9ec665cbca
commit
575077c8ac
6 changed files with 104 additions and 36 deletions
|
|
@ -201,6 +201,38 @@ class FlavorPresetTests(TestCase):
|
|||
self.assertEqual(actions[-1], reverse("instances:flavor_create"))
|
||||
|
||||
|
||||
class InPageFlavorTests(TestCase):
|
||||
"""The create page's flavor forms are sent from the page and get back its
|
||||
presets and flavor dialog, so the unfinished VM form stays."""
|
||||
|
||||
def setUp(self):
|
||||
self.flavor = Flavor.objects.create(label="wvc-test", memory=512, vcpu=1, disk=10)
|
||||
render_create_page(self) # logs in a superuser
|
||||
|
||||
def post(self, url, data=None):
|
||||
response = self.client.post(url, data or {}, HTTP_X_REQUESTED_WITH="XMLHttpRequest")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(list(response.context["messages"]), [])
|
||||
return html.fromstring(response.content)
|
||||
|
||||
def test_an_added_flavor_is_a_preset_and_a_dialog_row(self):
|
||||
reply = self.post(reverse("instances:flavor_create"), {"label": "big", "memory": 4096, "vcpu": 4, "disk": 40})
|
||||
self.assertEqual(reply.xpath("//*[@id='presets']//button/@data-label")[-2:], ["wvc-test", "big"])
|
||||
self.assertEqual(len(reply.xpath("//*[@id='flavors']//li")), Flavor.objects.count())
|
||||
self.assertEqual(reply.xpath("//*[@id='flavors']//input[@name='label']/@value"), [])
|
||||
|
||||
def test_a_refused_flavor_shows_its_errors_in_the_dialog(self):
|
||||
reply = self.post(reverse("instances:flavor_create"), {"label": "big", "memory": "", "vcpu": 4, "disk": 40})
|
||||
self.assertFalse(Flavor.objects.filter(label="big").exists())
|
||||
self.assertEqual(reply.xpath("//*[@id='flavors']//input[@name='label']/@value"), ["big"])
|
||||
self.assertTrue(reply.xpath("//*[@id='flavors']//input[@name='memory'][contains(@class, 'is-invalid')]"))
|
||||
|
||||
def test_a_deleted_flavor_leaves_the_presets(self):
|
||||
reply = self.post(reverse("instances:flavor_delete", args=[self.flavor.id]))
|
||||
self.assertNotIn("wvc-test", reply.xpath("//*[@id='presets']//button/@data-label"))
|
||||
self.assertNotIn("wvc-test", reply.xpath("//*[@id='flavors']//li//strong/text()"))
|
||||
|
||||
|
||||
class SubmittedListsTests(TestCase):
|
||||
"""The volumes and networks of a refused form come back with it."""
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue