From ce54e287a7a23a42921c59d1f5d844958ad04ca2 Mon Sep 17 00:00:00 2001 From: Benjamin Bertrand <benjamin.bertrand@esss.se> Date: Tue, 29 Jan 2019 15:11:02 +0100 Subject: [PATCH] Catch exception raised by Unique Validator The MAC field has both a Regexp and Unique validators. In wtforms, the validation doesn't stop on the first error (all validators are run). In case of invalid mac address, the Unique validator makes a request to the database that raises a DataError. This exception has to be catched. JIRA INFRA-777 #action In Progress --- app/validators.py | 2 ++ tests/functional/test_web.py | 52 ++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/app/validators.py b/app/validators.py index 0248e7a..575bc87 100644 --- a/app/validators.py +++ b/app/validators.py @@ -80,6 +80,8 @@ class Unique(object): raise ValidationError(self.message) except sa.orm.exc.NoResultFound: pass + except sa.exc.DataError as e: + raise ValidationError(f"DBAPIError: {e.orig}") class UniqueAccrossModels: diff --git a/tests/functional/test_web.py b/tests/functional/test_web.py index 757e5e9..820a667 100644 --- a/tests/functional/test_web.py +++ b/tests/functional/test_web.py @@ -327,9 +327,11 @@ def test_create_host(client, domain_factory, network_factory, device_type): logout(client) # Success with user_prod user login(client, "user_prod", "userprod") - response = client.post(f"/network/hosts/create", data=form) - assert response.status_code == 302 + response = client.post(f"/network/hosts/create", data=form, follow_redirects=True) + assert response.status_code == 200 # The host was created + assert b"created!" in response.data + assert b"View host" in response.data host = models.Host.query.filter_by(name=name).first() assert host is not None assert host.interfaces[0].ip == ip @@ -337,6 +339,52 @@ def test_create_host(client, domain_factory, network_factory, device_type): assert host.interfaces[0].name == name +def test_create_host_invalid_fields( + session, client, domain_factory, network_factory, device_type +): + domain = domain_factory(name="prod.example.org") + network = network_factory( + address="192.168.1.0/24", + first_ip="192.168.1.10", + last_ip="192.168.1.250", + domain=domain, + ) + name = "myhost" + ip = "192.168.1.11" + mac = "02:42:42:45:3c:89" + form = { + "network_id": network.id, + "name": name, + "device_type_id": device_type.id, + "ip": ip, + "mac": mac, + "description": "test", + "ansible_vars": "", + "ansible_groups": [], + "tags": [], + "random_mac": False, + "cnames_string": "", + } + login(client, "user_prod", "userprod") + # Invalid mac + data = form.copy() + data["mac"] = "ea:ea:60:45:a8:96:se" + response = client.post(f"/network/hosts/create", data=data, follow_redirects=True) + assert response.status_code == 200 + assert b"Register new host" in response.data + assert b"Invalid MAC address" in response.data + # An exception was raised during validation (on Select in the Unique Validator), + # so we need to rollback. + session.rollback() + # Invalid hostname + data = form.copy() + data["name"] = "invalid_host" + response = client.post(f"/network/hosts/create", data=data, follow_redirects=True) + assert response.status_code == 200 + assert b"Register new host" in response.data + assert b"Invalid input" in response.data + + def test_create_interface( client, host_factory, domain_factory, network_factory, interface_factory ): -- GitLab