def test_markdown_characters_in_jinja_tags(self): assert TemplateField(u'Title:\nnumber {{ number._value }}') assert TemplateField(u'Title:\nnumber {{ number["value"] }}') assert TemplateField(u'Title:\nnumber {{ number|join(".") }}') assert TemplateField( u"Title:\n{% if name == 'context' %}template {{ name }}{% endif %}" )
def test_render_question(framework, question_id, question_set, question): brief_msg = "Brief questions must be single-line since they're used as <title>s: frameworks/{}/questions/{}/{}.yml" for field_name, field in question.items(): if isinstance(field, TemplateField): rendered_field = field.render( QUESTION_SET_CONTEXT.get(question_set)) rendered_md = TemplateField(field.source, markdown=True).render( QUESTION_SET_CONTEXT.get(question_set)) rendered_text = TemplateField(field.source, markdown=False).render( QUESTION_SET_CONTEXT.get(question_set)) assert rendered_field is not None assert ( strip_paragraph_wrapper( rendered_md) == strip_paragraph_wrapper(rendered_field) ), "Single-line field probably contains markdown: frameworks/{}/questions/{}/{}.yml".format( framework, question_set, question_id) if field.markdown and question_set in [ 'briefs', 'brief-responses' ] and field_name == 'question': assert strip_paragraph_wrapper( rendered_field) != rendered_text, brief_msg.format( framework, question_set, question_id)
def test_content_metadata_list_field_does_not_render_template_fields(self): metadata = ContentMetadata( {'nested': [TemplateField('Name'), TemplateField('{{ name }}')]}) assert metadata.nested == [ TemplateField('Name'), TemplateField('{{ name }}') ]
def test_question_fields_are_templated_on_access_if_filter_wasnt_called(self): question = self.question( name=TemplateField("Name {{ name }}"), question=TemplateField("Question"), ) with pytest.raises(ContentTemplateError): question.name assert question.question == "Question"
def test_content_message_list_field_returns_rendered_fields( self, filter_inplace_allowed): message = ContentMessage( {'nested': [TemplateField('Name'), TemplateField('{{ name }}')]}) assert message.filter( { 'name': 'Other' }, inplace_allowed=filter_inplace_allowed).nested == [ 'Name', 'Other' ]
def test_fields_without_template_tags_are_unchanged(self): section = ContentSection(slug='section', name=TemplateField('Section'), description=TemplateField('just a string'), prefill=True, editable=False, edit_questions=False, questions=[Question({})]) assert section.filter({}).name == 'Section' assert section.filter({}).description == 'just a string' assert section.filter({}).prefill is True
def test_question_without_template_tags_are_unchanged(self): question = self.question( name=TemplateField("Name"), question=TemplateField("Question"), hint=TemplateField("Hint"), question_advice=TemplateField("Advice") ).filter(self.context()) assert question.name == "Name" assert question.question == "Question" assert question.hint == "Hint" assert question.question_advice == "Advice"
def test_section_description_is_templated(self): section = ContentSection( slug='section', name=TemplateField('Section one'), prefill=False, editable=False, edit_questions=False, questions=[Question({})], description=TemplateField("This is the {{ name }} section")) assert section.filter({ 'name': 'first' }).description == 'This is the first section'
def test_question_followup_get_data(self): section = ContentSection(slug='section', name=TemplateField('Section one'), prefill=False, editable=False, edit_questions=False, questions=[ Question({ 'id': 'q1', 'followup': { 'q2': [False] }, 'type': 'boolean' }), Question({ 'id': 'q2', 'type': 'boolean' }) ]).filter({}) assert section.get_data(MultiDict([('q1', 'false')])) == {'q1': False} assert section.get_data(MultiDict([('q1', 'true')])) == { 'q1': True, 'q2': None } assert section.get_data(MultiDict([('q1', 'false'), ('q2', 'true')])) == { 'q1': False, 'q2': True } assert section.get_data(MultiDict([('q1', 'true'), ('q2', 'true')])) == { 'q1': True, 'q2': None }
def test_getting_a_multiquestion_as_a_section_preserves_value_of_context_attribute( self): multiquestion_data = { "id": "example", "slug": "example", "question": "Example question", "type": "multiquestion", "questions": [{ "id": "example2", "type": "text", }, { "id": "example3", "type": "number", }] } section = ContentSection(slug='section', name=TemplateField('Section'), prefill=True, editable=False, edit_questions=False, questions=[Multiquestion(multiquestion_data)]) assert section.get_question_as_section('example')._context is None assert section.filter({ 'context': 'context1' }).get_question_as_section('example')._context == { 'context': 'context1' }
def test_is_empty(self): questions = [ Question({ 'id': 'q1', 'name': 'q1', 'type': 'unknown' }), Question({ 'id': 'q2', 'name': 'q2', 'type': 'unknown' }) ] # note that id and type are required as this function indirectly calls QuestionSummary.value section = ContentSection(slug='section', name=TemplateField('Section'), prefill=False, editable=False, edit_questions=False, questions=questions) answered = section.summary({'q1': 'a1', 'q2': 'a2'}) assert not answered.is_empty half_answered = section.summary({'q1': 'a1', 'q2': ''}) assert not half_answered.is_empty not_answered = section.summary({'q1': '', 'q2': ''}) assert not_answered.is_empty
def test_content_message_template_field_with_context(self): message = ContentMessage({'name': TemplateField("Field {{ name }}")}) with pytest.raises(ContentTemplateError): assert message.name assert message.filter({'name': 'one'}).name == 'Field one'
def test_unused_template_variables_are_ignored(self): field = TemplateField(u'template {{ name }}') assert field.render({ 'name': 'context', 'lot': 'lot' }) == u'template context'
def question(self, **kwargs): data = { "id": "example", "type": "radios", "options": [ {"label": "Wrong label", "value": "value", "description": TemplateField("some description" " [markup](links)")}, {"label": "Option label", "value": "value1"}, {"label": "Wrong label", "value": "value2"}, ], "validations": [ {"name": "answer_required", "message": TemplateField("You have to answer the question")} ] } data.update(kwargs) return ContentQuestion(data)
def test_content_message_list_field_returns_content_messages(self): message = ContentMessage({ 'nested': [{ 'name': 'Name' }, { 'name': TemplateField('{{ name }}') }] }) assert message.filter({ 'name': 'Other' }).nested == [ ContentMessage({'name': 'Name'}, {'name': 'Other'}), ContentMessage({'name': TemplateField('{{ name }}')}, {'name': 'Other'}) ] assert message.filter({'name': 'Other'}).nested[1].name == 'Other'
def test_filtering_a_section_with_a_description_template(self, filter_inplace_allowed, lot, expected_description): section = ContentSection( slug='section', name=TemplateField('Section one'), prefill=False, editable=False, edit_questions=False, questions=[Question({})], description=TemplateField( "description for {% if lot == 'digital-specialists' %}specialists{% else %}outcomes{% endif %}" ) ) assert section.filter( {"lot": lot}, inplace_allowed=filter_inplace_allowed, ).description == expected_description
def test_nested_content_message_preserves_context(self): message = ContentMessage( {'nested': { 'name': TemplateField('Nested {{ name }}') }}) assert message.filter({ 'name': "message" }).nested.name == 'Nested message'
def test_get_templatable_section_attributes_calls_render(self): section = ContentSection( slug='section', name=TemplateField( '{% if True %}Section one{% else %}Section two{% endif %}'), prefill=True, editable=False, edit_questions=False, questions=[Question({})], description=TemplateField( "description for {% if lot == 'digital-specialists' %}specialists{% else %}outcomes{% endif %}" )) assert section.name == 'Section one' with pytest.raises(ContentTemplateError): section.description assert section.slug == 'section'
def test_section_description_is_not_set(self): section = ContentSection(slug='section', name=TemplateField('Section one'), prefill=False, editable=False, edit_questions=False, questions=[Question({})]) assert section.filter({}).description is None
def test_question_fields_without_template_tags_are_unchanged(self): section = ContentSection(slug='section', name=TemplateField('Section'), prefill=False, editable=False, edit_questions=False, questions=[Question({'name': 'Question'})]) assert section.filter({}).questions[0].name == 'Question'
def test_section_name_is_templated(self): section = ContentSection(slug='section', name=TemplateField('Section {{ name }}'), prefill=True, editable=False, edit_questions=False, questions=[Question({})]) assert section.filter({'name': 'one'}).name == 'Section one'
def test_filtering_a_section_with_a_description_template(self): section = ContentSection( slug='section', name=TemplateField('Section one'), prefill=False, editable=False, edit_questions=False, questions=[Question({})], description=TemplateField( "description for {% if lot == 'digital-specialists' %}specialists{% else %}outcomes{% endif %}" )) assert section.filter({ "lot": "digital-specialists" }).description == "description for specialists" assert section.filter({ "lot": "digital-outcomes" }).description == "description for outcomes"
def test_not_all_fields_are_templated(self): section = ContentSection(slug='# {{ section }}', name=TemplateField('Section'), prefill=True, editable=False, edit_questions=False, questions=[Question({})]) assert section.filter({}).slug == '# {{ section }}'
def test_jinja_in_field_variables_is_not_evaluated_with_safe(self): env = Environment(autoescape=True) template_string = "This is a {{ name }} template" rendered_field = TemplateField(template_string).render( {'name': '{{ context }}'}) final_template = env.from_string('{{ rendered_field|safe }}').render( {'rendered_field': rendered_field}) assert final_template == 'This is a {{ context }} template'
def test_html_in_content_is_not_escaped_with_safe(self): env = Environment(autoescape=True) template_string = "This *is* a {{ name }} <em>template</em>\n" rendered_field = TemplateField(template_string).render( {'name': 'context'}) final_template = env.from_string('{{ rendered_field|safe }}').render( {'rendered_field': rendered_field}) assert final_template == '<p class="govuk-body">This <em>is</em> a context <em>template</em></p>'
def test_html_in_field_variables_is_escaped_with_safe(self): env = Environment(autoescape=True) template_string = "This is a {{ name }} template" rendered_field = TemplateField(template_string).render( {'name': '<em>context</em>'}) final_template = env.from_string('{{ rendered_field|safe }}').render( {'rendered_field': rendered_field}) assert final_template == 'This is a <em>context</em> template'
def test_missing_context_variable_raises_an_error(self): section = ContentSection(slug='section', name=TemplateField('Section {{ name }}'), prefill=False, editable=False, edit_questions=False, questions=[Question({})]) with pytest.raises(ContentTemplateError): section.filter({}).name
def test_question_fields_are_templated(self): question = self.question( name=TemplateField("Name {{ name }}"), question=TemplateField("Question {{ question }}"), hint=TemplateField("Hint {{ hint }}"), question_advice=TemplateField("Advice {{ advice }}") ).filter(self.context({ "name": "zero", "question": "one", "hint": "two", "advice": "three" })) assert question.name == "Name zero" assert question.question == "Question one" assert question.hint == "Hint two" assert question.question_advice == "Advice three" assert question.get_source('name') == "Name {{ name }}" assert question.get_source('question') == "Question {{ question }}"
def test_markdown_strings_govuk_classes(self): field = TemplateField(u'##A Heading\n\n' u'Some paragraph\n\n' u' * Some\n' u' * List\n\n' u'And\n\n' u'1. Some other\n' u'2. [Ordered](http://example.com)\n' u'3. List & such') assert field.render() == """<h2 class="govuk-heading-m">A Heading</h2>
def test_content_message_list_field_returns_content_messages( self, filter_inplace_allowed): message = ContentMessage({ 'nested': [{ 'name': 'Name' }, { 'name': TemplateField('{{ name }}') }] }) nested = message.filter({ 'name': 'Other' }, inplace_allowed=filter_inplace_allowed).nested assert nested == [ ContentMessage({'name': 'Name'}, {'name': 'Other'}), ContentMessage({'name': TemplateField('{{ name }}')}, {'name': 'Other'}) ] assert nested[1].name == 'Other'