From 239bf1390e1b7b108a918963267c26ce1967246a Mon Sep 17 00:00:00 2001 From: pengyuesheng Date: Tue, 8 Jan 2019 17:16:36 +0800 Subject: [PATCH] Show error if required fields are not filled when creating a port Change-Id: Ic91220cfc19d408d7361d716a3ed9309b394e158 Closes-Bug: #1810909 --- .../project/networks/ports/tests.py | 68 +++++++++++++++++++ .../project/networks/ports/workflows.py | 14 ++++ 2 files changed, 82 insertions(+) diff --git a/openstack_dashboard/dashboards/project/networks/ports/tests.py b/openstack_dashboard/dashboards/project/networks/ports/tests.py index ecb7857411..544f18d075 100644 --- a/openstack_dashboard/dashboards/project/networks/ports/tests.py +++ b/openstack_dashboard/dashboards/project/networks/ports/tests.py @@ -501,6 +501,74 @@ class NetworkPortTests(test.TestCase): self.mock_security_group_list.assert_called_once_with( test.IsHttpRequest(), tenant_id='1') + @test.create_mocks({api.neutron: ('network_get', + 'security_group_list', + 'is_extension_supported')}) + def test_port_create_post_designated_subnet(self): + network = self.networks.first() + port = self.ports.first() + self.mock_network_get.return_value = self.networks.first() + self._stub_is_extension_supported({'binding': False, + 'mac-learning': False, + 'port-security': False}) + self.mock_security_group_list.return_value = \ + self.security_groups.list() + form_data = {'network_id': port.network_id, + 'network_name': network.name, + 'name': port.name, + 'admin_state': port.admin_state_up, + 'device_id': port.device_id, + 'device_owner': port.device_owner, + 'specify_ip': 'subnet_id', + 'subnet_id': "", + 'mac_address': port.mac_address} + url = reverse('horizon:project:networks:addport', + args=[port.network_id]) + res = self.client.post(url, form_data) + self.assertFormErrors(res, 1) + self.assertContains(res, "This field is required.") + self._check_is_extension_supported({'binding': 1, + 'mac-learning': 1, + 'port-security': 1}) + self.mock_security_group_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id='1') + self.mock_network_get.assert_called_with(test.IsHttpRequest(), + network.id) + + @test.create_mocks({api.neutron: ('network_get', + 'security_group_list', + 'is_extension_supported')}) + def test_port_create_post_designated_fixed_ip(self): + network = self.networks.first() + port = self.ports.first() + self.mock_network_get.return_value = self.networks.first() + self._stub_is_extension_supported({'binding': False, + 'mac-learning': False, + 'port-security': False}) + self.mock_security_group_list.return_value = \ + self.security_groups.list() + form_data = {'network_id': port.network_id, + 'network_name': network.name, + 'name': port.name, + 'admin_state': port.admin_state_up, + 'device_id': port.device_id, + 'device_owner': port.device_owner, + 'specify_ip': 'fixed_ip', + 'fixed_ip': "", + 'mac_address': port.mac_address} + url = reverse('horizon:project:networks:addport', + args=[port.network_id]) + res = self.client.post(url, form_data) + self.assertFormErrors(res, 1) + self.assertContains(res, "This field is required.") + self._check_is_extension_supported({'binding': 1, + 'mac-learning': 1, + 'port-security': 1}) + self.mock_security_group_list.assert_called_once_with( + test.IsHttpRequest(), tenant_id='1') + self.mock_network_get.assert_called_with(test.IsHttpRequest(), + network.id) + def test_port_create_post_exception(self): self._test_port_create_post_exception() diff --git a/openstack_dashboard/dashboards/project/networks/ports/workflows.py b/openstack_dashboard/dashboards/project/networks/ports/workflows.py index 29924b44c7..b6e13047c4 100644 --- a/openstack_dashboard/dashboards/project/networks/ports/workflows.py +++ b/openstack_dashboard/dashboards/project/networks/ports/workflows.py @@ -201,6 +201,20 @@ class CreatePortInfoAction(workflows.Action): for subnet in network.subnets if isinstance(subnet, api.neutron.Subnet)] + def clean_subnet_id(self): + specify_ip = self.cleaned_data.get('specify_ip') + subnet_id = self.cleaned_data.get('subnet_id') + if specify_ip == "subnet_id" and not subnet_id: + raise forms.ValidationError(_("This field is required.")) + return subnet_id + + def clean_fixed_ip(self): + specify_ip = self.cleaned_data.get('specify_ip') + fixed_ip = self.cleaned_data.get('fixed_ip') + if specify_ip == "fixed_ip" and not fixed_ip: + raise forms.ValidationError(_("This field is required.")) + return fixed_ip + class Meta(object): name = _("Info") slug = 'create_info'