def radio_button(self): self.model_object.an_attribute = 2 choices = [ Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')) ] self.field = ChoiceField(choices) self.field.bind('an_attribute', self.model_object) self.widget = self.form.add_child( RadioButtonSelectInput(self.form, self.field)) radio_button = '<label>'\ '<input name="test-an_attribute" id="id-test-an_attribute-%s"%s '\ 'data-msg-pattern="an_attribute should be one of the following: 1|2" '\ '%s'\ 'form="test" pattern="(1|2)" '\ 'title="an_attribute should be one of the following: 1|2" '\ 'type="radio" value="%s">%s'\ '</label>' outer_div = '<div class="reahl-primitiveinput reahl-radio-button-input">%s</div>' buttons = (radio_button % ('1', '', '', '1', 'One')) +\ (radio_button % ('2', ' checked="checked"', '', '2', 'Two')) self.expected_html = outer_div % buttons self.field_controls_visibility = True
def test_marshalling_of_radio_button_select_input(web_fixture, input_fixture, field_scenario): """When a form is submitted, the value of the selected radio button is persisted.""" fixture = input_fixture choices = [Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two'))] fixture.field = field_scenario.field_class(choices) model_object = fixture.model_object model_object.an_attribute = field_scenario.default_domain_value wsgi_app = web_fixture.new_wsgi_app(child_factory=fixture.new_Form(input_widget_class=RadioButtonSelectInput).factory('myform')) web_fixture.reahl_server.set_app(wsgi_app) web_fixture.driver_browser.open('/') radio_one = XPath.input_labelled('One') radio_two = XPath.input_labelled('Two') # One is pre selected assert web_fixture.driver_browser.is_selected(radio_one) assert not web_fixture.driver_browser.is_selected(radio_two) # click on Two web_fixture.driver_browser.click(radio_two) assert not web_fixture.driver_browser.is_selected(radio_one) web_fixture.driver_browser.click(XPath.button_labelled('click me')) assert model_object.an_attribute == field_scenario.selected_domain_value
def test_unique_choices(fixture): """All choices must have unique values.""" duplicate_choices = [Choice(1, IntegerField(label='One')), Choice(1, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))] with expected(ProgrammerError, test='Duplicate choices are not allowed'): ChoiceField(duplicate_choices)
def radio_button(self): self.model_object.an_attribute = 2 choices = [ Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')) ] self.field = ChoiceField(choices) self.field.bind('an_attribute', self.model_object) self.widget = self.form.add_child( RadioButtonInput(self.form, self.field)) validations = html_escape( '{"validate": {"messages": {"pattern": "an_attribute should be one of the following: 1\|2"}}}' ) radio_button = r'<span class="reahl-radio-button">'\ r'<input name="an_attribute"%s form="test" pattern="\(1\|2\)" '\ r'title="an_attribute should be one of the following: 1\|2" '\ r'type="radio" value="%s" class="%s">%s'\ r'</span>' outer_div = r'<div class="reahl-radio-button-input">%s</div>' buttons = (radio_button % ('', '1', validations, 'One')) +\ (radio_button % (' checked="checked"', '2', validations, 'Two')) self.expected_html = outer_div % buttons self.field_controls_visibility = True
def events(self, events): events.an_event = Event(one_argument=IntegerField(required=True), another_argument=IntegerField(), unused_argument=IntegerField(), action=Action( self.do_something, ['one_argument'], dict(a_kwarg='another_argument')))
def test_marshalling_of_checkbox_select_input(web_fixture, checkbox_fixture): """CheckboxSelectInput is used to choose many things from a list.""" fixture = checkbox_fixture choices = [Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))] fixture.field = MultiChoiceField(choices) model_object = fixture.model_object model_object.an_attribute = [1] wsgi_app = web_fixture.new_wsgi_app(child_factory=fixture.new_Form(input_widget_class=CheckboxSelectInput).factory('myform')) web_fixture.reahl_server.set_app(wsgi_app) web_fixture.driver_browser.open('/') assert web_fixture.driver_browser.is_selected(XPath.input_labelled('One')) assert not web_fixture.driver_browser.is_selected(XPath.input_labelled('Two')) assert not web_fixture.driver_browser.is_selected(XPath.input_labelled('Three')) # Case: checkbox is submitted with form (ie checked) web_fixture.driver_browser.set_deselected(XPath.input_labelled('One')) web_fixture.driver_browser.set_selected(XPath.input_labelled('Two')) web_fixture.driver_browser.set_selected(XPath.input_labelled('Three')) web_fixture.driver_browser.click(XPath.button_labelled('click me')) assert model_object.an_attribute == [2, 3] assert fixture.checkbox.value == '2,3' assert not web_fixture.driver_browser.is_selected(XPath.input_labelled('One')) assert web_fixture.driver_browser.is_selected(XPath.input_labelled('Two')) assert web_fixture.driver_browser.is_selected(XPath.input_labelled('Three'))
def multi_value_empty_the_list(self): self.field = MultiChoiceField([Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))], default=[2], label='field') self.field_on_query_string = '{field_name}[]-' self.field_value_marshalled = [] self.field_value_as_string = ''
def multi_value_not_submitted(self): self.field = MultiChoiceField([Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))], default=[2], label='field') self.field_on_query_string = '' self.field_value_marshalled = [2] self.field_value_as_string = '2'
def fields(self, fields): fields.operand_a = IntegerField(label='A', required=True) fields.operand_b = IntegerField(label='B', required=True) fields.operator = ChoiceField([ Choice('plus', Field(label='+')), Choice('divide', Field(label='÷')) ], required=True)
def fields(self, fields): fields.percentage = IntegerField( label='Percentage', required=True, writable=lambda field: self.is_in_percentage) fields.amount = IntegerField(label='Amount', required=True, writable=lambda field: self.is_in_amount)
def fields(self, fields): fields.operandA = IntegerField(label='A') fields.operandB = ChoiceField([ Choice(4, IntegerField(label='4')), Choice(5, IntegerField(label='5')), Choice(6, IntegerField(label='6')) ], label='B')
def multi_value(self): self.field = MultiChoiceField([Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))], default=[], label='field') self.field_on_query_string = '{field_name}[]=1&{field_name}[]=3' self.field_value_marshalled = [1, 3] self.field_value_as_string = '1,3'
def fields(self, fields): choices = [ Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three')) ] fields.no_validation_exception_field = MultiChoiceField( choices, label='Make your invalid choice', default=[]) fields.validation_exception_field = MultiChoiceField( choices, label='Make your choice', default=[], required=True)
def fields(self, fields): fields.text_input_field = Field(label='A TextInput') fields.password_field = Field(label='A PasswordInput') fields.text_area_field = Field(label='A TextArea') fields.text_input_without_label = Field(label='A TextInput without a label') fields.cue_field = Field(label='A TextInput in a CueInput') fields.choice_field = ChoiceField([Choice(False, BooleanField(label='None selected')), ChoiceGroup('Numbers', [Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))]), ChoiceGroup('Colours', [Choice('r', Field(label='Red')), Choice('g', Field(label='Green'))]) ], label='A SelectInput') fields.multi_choice_field = MultiChoiceField([Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))], label='A SelectInput allowing multiple choices') fields.another_multi_choice_field = MultiChoiceField([Choice('a', Field(label='Newton')), Choice('b', Field(label='Archimedes')), Choice('c', Field(label='Einstein')), ], default=['a', 'c'], label='A CheckboxInput allowing multiple choices') fields.boolean_field = BooleanField(label='A CheckboxInput to toggle') fields.radio_choice_field = ChoiceField([Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))], label='A RadioButtonSelectInput') fields.fuzzy_date_field = DateField(label='A fuzzy TextInput for a Date')
def assemble(self): self.define_page(HTML5Page).use_layout(BasicPageLayout()) home = self.define_view('/', title='Home page') other_view = self.define_view('/page2', title='Page 2', view_class=ParameterisedView, event_argument1=IntegerField(required=True), view_argument=IntegerField(required=True)) home.set_slot('main', MyForm.factory('myform')) self.define_transition(model_object.events.an_event, home, other_view)
def __init__(self, view): super(ScoringDataPanel, self).__init__(view) class Row(object): def __init__(self, request): self.request = request self.criteria = { i.label: i for i in self.request.get_criteria() } def does_criterion_apply(self, criterion): return self.criteria[criterion.label].applies def value_for(self, criterion): return self.criteria[criterion.label].score @property def score_total(self): return self.request.score_total @property def name(self): return self.request.name @property def surname(self): return self.request.surname def make_column_value(criterion, view, row): return TextNode( view, ('yes' if row.does_criterion_apply(criterion) else 'no')) def make_score_column_value(criterion, view, row): return TextNode(view, str(row.value_for(criterion))) columns = [] columns.append(StaticColumn(IntegerField(label='Name'), 'name')) columns.append(StaticColumn(IntegerField(label='Surname'), 'surname')) for i in FundingRequest().get_criteria(): columns.append( DynamicColumn(i.label, functools.partial(make_column_value, i))) columns.append( DynamicColumn('#', functools.partial(make_score_column_value, i))) columns.append(StaticColumn(IntegerField(label='Total'), 'score_total')) rows = [Row(i) for i in FundingRequest.find_requests()] table = self.add_child( Table(view, caption_text='Financial Aid Applications')) table.use_layout(TableLayout(responsive=True, striped=True)) table.with_data(columns, rows)
def multi_choices(self): self.all_choices = [Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two')), Choice(3, IntegerField(label='Three'))] self.groups = [] self.choices = self.all_choices self.field = self.new_field(MultiChoiceField) self.valid_inputs = [('1',), ['1', '2']] self.input_to_value_map = {('1',): [1], ('1', '2'): [1,2]} self.expected_validation_constraint = MultiChoiceConstraint
def fields(self, fields): fields.agreed_to_terms = BooleanField(label='I agree to the terms and conditions') fields.new_or_existing = ChoiceField([Choice('new', Field(label='New')), Choice('existing', Field(label='Existing'))], label='Are you a new or existing investor?') fields.existing_account_number = IntegerField(label='Existing account number', required=True) fields.name = Field(label='Name', required=True) fields.surname = Field(label='Surname', required=True) fields.amount = IntegerField(label='Total amount', required=True) fields.amount_or_percentage = ChoiceField([Choice('amount', Field(label='Amount')), Choice('percentage', Field(label='Percentage'))], label='Allocate using', required=True)
def greater_than_constraint(self, fixture): other_field = IntegerField(label='other') greater_than_constraint = GreaterThanConstraint(other_field, '$label, $other_label') other_field.set_user_input('5', ignore_validation=True) #case: valid input with expected(NoException): greater_than_constraint.validate_parsed_value( 6 ) #case: invalid input with expected(GreaterThanConstraint): greater_than_constraint.validate_parsed_value( 5 )
def select_input_multi(self): self.model_object.an_attribute = [2] choices = [Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two'))] self.field = MultiChoiceField(choices) self.field.bind('an_attribute', self.model_object) self.widget = self.form.add_child(SelectInput(self.form, self.field)) options = '<option id="id-test-an_attribute-91--93--1" value="1">One</option><option id="id-test-an_attribute-91--93--2" selected="selected" value="2">Two</option>' self.expected_html = '<select name="test-an_attribute[]" id="id-test-an_attribute-91--93-" form="test" multiple="multiple" class="reahl-primitiveinput">%s</select>' % (options) self.field_controls_visibility = True
def test_smaller_than_constraint(fixture): other_field = IntegerField(label='other') smaller_than_constraint = SmallerThanConstraint(other_field, '$label, $other_label') other_field.set_user_input('5', ignore_validation=True) #case: valid input with expected(NoException): smaller_than_constraint.validate_parsed_value( 4 ) #case: invalid input with expected(SmallerThanConstraint): smaller_than_constraint.validate_parsed_value( 5 )
def __init__(self, view): super(QualifyDataPanel, self).__init__(view) class QualifyDataRow(object): def __init__(self, request): self.request = request self.funding_items = { i.label: i for i in self.request.get_funding_items() } def qualifies_for_amount(self, funding_item): return self.funding_items[funding_item.label].qualified_amount @property def score_total(self): return self.request.score_total @property def qualify_total(self): return self.request.qualify_total @property def name(self): return self.request.name @property def surname(self): return self.request.surname def make_column_value(funding_item, view, row): return TextNode(view, str(row.qualifies_for_amount(funding_item))) columns = [] columns.append(StaticColumn(IntegerField(label='Name'), 'name')) columns.append(StaticColumn(IntegerField(label='Surname'), 'surname')) columns.append(StaticColumn(IntegerField(label='Score'), 'score_total')) for i in FundingRequest().get_funding_items(): columns.append( DynamicColumn(i.label, functools.partial(make_column_value, i))) columns.append( StaticColumn(IntegerField(label='Total'), 'qualify_total')) rows = [QualifyDataRow(i) for i in FundingRequest.find_requests()] table = self.add_child(Table(view, caption_text='Qualifying amounts')) table.use_layout(TableLayout(responsive=True, striped=True)) table.with_data(columns, rows)
def checked_arguments(self, fixture): """A CheckedRemoteMethod checks and marshalls its parameters using Fields.""" def callable_object(anint=None, astring=None): fixture.method_kwargs = {'anint': anint, 'astring': astring} return '' remote_method = CheckedRemoteMethod('amethod', callable_object, MethodResult(), immutable=fixture.immutable, anint=IntegerField(), astring=Field()) wsgi_app = fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) if fixture.immutable: browser.open( '/_amethod_method?anint=5&astring=SupercalifraGilisticexpialidocious' ) else: browser.post('/_amethod_method', { 'anint': '5', 'astring': 'SupercalifraGilisticexpialidocious' }) vassert(fixture.method_kwargs == { 'anint': 5, 'astring': 'SupercalifraGilisticexpialidocious' })
def test_checked_arguments(web_fixture, remote_method_fixture, argument_scenarios): """A CheckedRemoteMethod checks and marshalls its parameters using Fields.""" fixture = argument_scenarios def callable_object(anint=None, astring=None): fixture.method_kwargs = {'anint': anint, 'astring': astring} return '' remote_method = CheckedRemoteMethod(web_fixture.view, 'amethod', callable_object, MethodResult(), idempotent=fixture.idempotent, anint=IntegerField(), astring=Field(), disable_csrf_check=True) wsgi_app = remote_method_fixture.new_wsgi_app(remote_method=remote_method) browser = Browser(wsgi_app) if fixture.idempotent: browser.open( '/_amethod_method?anint=5&astring=SupercalifraGilisticexpialidocious' ) else: browser.post('/_amethod_method', { 'anint': '5', 'astring': 'SupercalifraGilisticexpialidocious' }) assert fixture.method_kwargs == { 'anint': 5, 'astring': 'SupercalifraGilisticexpialidocious' }
def test_choices_disabled(web_fixture, checkbox_fixture, choice_type_scenario): """A choice that is not writable renders as disabled.""" fixture = checkbox_fixture choices = [Choice(1, IntegerField(label='One')), Choice(2, IntegerField(label='Two', writable=Allowed(False)))] fixture.field = MultiChoiceField(choices) model_object = fixture.model_object model_object.an_attribute = [1] wsgi_app = web_fixture.new_wsgi_app(child_factory=fixture.new_Form(input_widget_class=choice_type_scenario.input_type).factory('myform')) web_fixture.reahl_server.set_app(wsgi_app) web_fixture.driver_browser.open('/') assert web_fixture.driver_browser.is_element_enabled(choice_type_scenario.xpath_function_to_choice('One')) assert not web_fixture.driver_browser.is_element_enabled(choice_type_scenario.xpath_function_to_choice('Two'))
def __init__(self, view, address_book_ui): super().__init__(view) self.rows = QueryAsSequence(Session.query(Address).order_by( Address.id), map_function=lambda address: Row(address)) self.add_child(H(view, 1, text='Addresses')) def make_link_widget(view, row): return A.from_bookmark( view, address_book_ui.get_edit_bookmark(row.address, description='Edit')) columns = [ StaticColumn(Field(label='Name'), 'name', sort_key=Address.name), StaticColumn(EmailField(label='Email'), 'email_address', sort_key=Address.email_address), StaticColumn(IntegerField(label='Zip'), 'zip_code', sort_key=Address.zip_code), DynamicColumn('', make_link_widget) ] table_layout = TableLayout(striped=True) data_table = DataTable(view, columns, self.rows, caption_text='All my friends', summary='Summary for screen reader', table_layout=table_layout, css_id='address_data') self.add_child(data_table)
def events(self, events): events.an_event = Event( label='click me', action=Action(self.handle_event, ['one_argument', 'another_argument']), one_argument=IntegerField(), another_argument=Field())
def test_checkbox_input_restricted_to_use_with_boolean(web_fixture): """CheckboxInput is for toggling a true or false answer.""" model_object = web_fixture form = Form(web_fixture.view, 'test') # case: with BooleanField boolean_field = BooleanField(label='Boolean') boolean_field.bind('a_choice', model_object) with expected(NoException): CheckboxInput(form, boolean_field) # case: with disallowed field not_a_boolean_field = IntegerField(label='Other') not_a_boolean_field.bind('not_a_boolean', model_object) with expected(IsInstance): CheckboxInput(form, not_a_boolean_field)
def grouped_choices(self): self.all_choices = [Choice(1, IntegerField(label='One')), Choice('2', Field(label='Two'))] self.groups = [ChoiceGroup('', self.all_choices)] self.choices = self.groups self.valid_inputs = ['1', '2'] self.input_to_value_map = {'1': 1, '2': '2'} self.expected_validation_constraint = AllowedValuesConstraint
def fields(self, fields): fields.amount = IntegerField(label='Total amount', required=True) fields.amount_or_percentage = ChoiceField([ Choice('amount', Field(label='Amount')), Choice('percentage', Field(label='Percentage')) ], label='Allocate using', required=True)