display boolean and json parameters in stack launch form
Horizon fails to render boolean and json parameters properly in the stack launch form, instead of rendering these fields it renders a duplicate of the previous field. Change-Id: Idb2fcf4b52578951fb578138a80529eefc140d1a Closes-Bug: 1360495
This commit is contained in:
parent
fe5adf7693
commit
ad9c303504
|
@ -294,6 +294,7 @@ class CreateStackForm(forms.SelfHandlingForm):
|
|||
# no parameter groups, so no way to determine order
|
||||
params_in_order = params.items()
|
||||
for param_key, param in params_in_order:
|
||||
field = None
|
||||
field_key = self.param_prefix + param_key
|
||||
field_args = {
|
||||
'initial': param.get('Default', None),
|
||||
|
@ -310,7 +311,7 @@ class CreateStackForm(forms.SelfHandlingForm):
|
|||
field_args['choices'] = choices
|
||||
field = forms.ChoiceField(**field_args)
|
||||
|
||||
elif param_type in ('CommaDelimitedList', 'String'):
|
||||
elif param_type in ('CommaDelimitedList', 'String', 'Json'):
|
||||
if 'MinLength' in param:
|
||||
field_args['min_length'] = int(param['MinLength'])
|
||||
field_args['required'] = param.get('MinLength', 0) > 0
|
||||
|
@ -327,7 +328,14 @@ class CreateStackForm(forms.SelfHandlingForm):
|
|||
field_args['max_value'] = int(param['MaxValue'])
|
||||
field = forms.IntegerField(**field_args)
|
||||
|
||||
self.fields[field_key] = field
|
||||
# heat-api currently returns the boolean type in lowercase
|
||||
# (see https://bugs.launchpad.net/heat/+bug/1361448)
|
||||
# so for better compatibility both are checked here
|
||||
elif param_type in ('Boolean', 'boolean'):
|
||||
field = forms.BooleanField(**field_args)
|
||||
|
||||
if field:
|
||||
self.fields[field_key] = field
|
||||
|
||||
@sensitive_variables('password')
|
||||
def handle(self, request, data):
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
import json
|
||||
import re
|
||||
|
||||
import django
|
||||
from django.conf import settings
|
||||
from django.core import exceptions
|
||||
from django.core.urlresolvers import reverse
|
||||
|
@ -440,6 +441,132 @@ class StackTests(test.TestCase):
|
|||
flags=re.DOTALL)
|
||||
self.assertRegexpMatches(res.content.decode('utf-8'), regex)
|
||||
|
||||
@test.create_stubs({api.heat: ('stack_create', 'template_validate')})
|
||||
def test_launch_stack_parameter_types(self):
|
||||
template = {
|
||||
'data': ('heat_template_version: 2013-05-23\n'
|
||||
'parameters:\n'
|
||||
' param1:\n'
|
||||
' type: string\n'
|
||||
' param2:\n'
|
||||
' type: number\n'
|
||||
' param3:\n'
|
||||
' type: json\n'
|
||||
' param4:\n'
|
||||
' type: comma_delimited_list\n'
|
||||
' param5:\n'
|
||||
' type: boolean\n'),
|
||||
'validate': {
|
||||
"Description": "No description",
|
||||
"Parameters": {
|
||||
"param1": {
|
||||
"Type": "String",
|
||||
"NoEcho": "false",
|
||||
"Description": "",
|
||||
"Label": "param1"
|
||||
},
|
||||
"param2": {
|
||||
"Type": "Number",
|
||||
"NoEcho": "false",
|
||||
"Description": "",
|
||||
"Label": "param2"
|
||||
},
|
||||
"param3": {
|
||||
"Type": "Json",
|
||||
"NoEcho": "false",
|
||||
"Description": "",
|
||||
"Label": "param3"
|
||||
},
|
||||
"param4": {
|
||||
"Type": "CommaDelimitedList",
|
||||
"NoEcho": "false",
|
||||
"Description": "",
|
||||
"Label": "param4"
|
||||
},
|
||||
"param5": {
|
||||
"Type": "Boolean",
|
||||
"NoEcho": "false",
|
||||
"Description": "",
|
||||
"Label": "param5"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
stack = self.stacks.first()
|
||||
|
||||
api.heat.template_validate(IsA(http.HttpRequest),
|
||||
template=template['data']) \
|
||||
.AndReturn(template['validate'])
|
||||
|
||||
api.heat.stack_create(IsA(http.HttpRequest),
|
||||
stack_name=stack.stack_name,
|
||||
timeout_mins=60,
|
||||
disable_rollback=True,
|
||||
template=template['data'],
|
||||
parameters={'param1': 'some string',
|
||||
'param2': 42,
|
||||
'param3': '{"key": "value"}',
|
||||
'param4': 'a,b,c',
|
||||
'param5': True},
|
||||
password='password')
|
||||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
url = reverse('horizon:project:stacks:select_template')
|
||||
res = self.client.get(url)
|
||||
self.assertTemplateUsed(res, 'project/stacks/select_template.html')
|
||||
|
||||
form_data = {'template_source': 'raw',
|
||||
'template_data': template['data'],
|
||||
'method': forms.TemplateForm.__name__}
|
||||
res = self.client.post(url, form_data)
|
||||
self.assertTemplateUsed(res, 'project/stacks/create.html')
|
||||
|
||||
# ensure the fields were rendered correctly
|
||||
self.assertContains(res, '<input class="form-control" '
|
||||
'id="id___param_param1" '
|
||||
'name="__param_param1" '
|
||||
'type="text" />', html=True)
|
||||
if django.VERSION >= (1, 6):
|
||||
self.assertContains(res, '<input class="form-control" '
|
||||
'id="id___param_param2" '
|
||||
'name="__param_param2" '
|
||||
'type="number" />', html=True)
|
||||
else:
|
||||
self.assertContains(res, '<input class="form-control" '
|
||||
'id="id___param_param2" '
|
||||
'name="__param_param2" '
|
||||
'type="text" />', html=True)
|
||||
self.assertContains(res, '<input class="form-control" '
|
||||
'id="id___param_param3" '
|
||||
'name="__param_param3" '
|
||||
'type="text" />', html=True)
|
||||
self.assertContains(res, '<input class="form-control" '
|
||||
'id="id___param_param4" '
|
||||
'name="__param_param4" '
|
||||
'type="text" />', html=True)
|
||||
self.assertContains(res, '<input id="id___param_param5" '
|
||||
'name="__param_param5" '
|
||||
'type="checkbox" />', html=True)
|
||||
|
||||
# post some sample data and make sure it validates
|
||||
url = reverse('horizon:project:stacks:launch')
|
||||
form_data = {'template_source': 'raw',
|
||||
'template_data': template['data'],
|
||||
'password': 'password',
|
||||
'parameters': json.dumps(template['validate']),
|
||||
'stack_name': stack.stack_name,
|
||||
"timeout_mins": 60,
|
||||
"disable_rollback": True,
|
||||
"__param_param1": "some string",
|
||||
"__param_param2": 42,
|
||||
"__param_param3": '{"key": "value"}',
|
||||
"__param_param4": "a,b,c",
|
||||
"__param_param5": True,
|
||||
'method': forms.CreateStackForm.__name__}
|
||||
res = self.client.post(url, form_data)
|
||||
self.assertRedirectsNoFollow(res, INDEX_URL)
|
||||
|
||||
@test.create_stubs({api.heat: ('stack_update', 'stack_get',
|
||||
'template_get', 'template_validate')})
|
||||
def test_edit_stack_template(self):
|
||||
|
|
Loading…
Reference in New Issue