Skip to content

Commit

Permalink
Merge pull request #339 from praekeltfoundation/forms-year-of-birth
Browse files Browse the repository at this point in the history
Add year of birth question type
  • Loading branch information
DevChima authored Jun 25, 2024
2 parents 435a719 + 3df46cf commit 047b2f4
Show file tree
Hide file tree
Showing 5 changed files with 280 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add version number to distinguish question sets
- Add Freetext question type for forms
- Add Integer question with min and max values
- Add Year of Birth type question type
### Changed
- Increased SMS limit to 459 characters
Expand Down
247 changes: 247 additions & 0 deletions home/migrations/0071_alter_assessment_questions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
# Generated by Django 4.2.11 on 2024-06-25 06:58

from django.db import migrations
import wagtail.blocks
import wagtail.fields


class Migration(migrations.Migration):

dependencies = [
("home", "0070_alter_assessment_questions"),
]

operations = [
migrations.AlterField(
model_name="assessment",
name="questions",
field=wagtail.fields.StreamField(
[
(
"categorical_question",
wagtail.blocks.StructBlock(
[
(
"question",
wagtail.blocks.TextBlock(
help_text="The question to ask the user"
),
),
(
"explainer",
wagtail.blocks.TextBlock(
help_text="Explainer message which tells the user why we need this question",
required=False,
),
),
(
"error",
wagtail.blocks.TextBlock(
help_text="Error message for this question if we don't understand the input",
required=False,
),
),
(
"answers",
wagtail.blocks.ListBlock(
wagtail.blocks.StructBlock(
[
(
"answer",
wagtail.blocks.TextBlock(
help_text="The choice shown to the user for this option"
),
),
(
"score",
wagtail.blocks.FloatBlock(
help_text="How much to add to the total score if this answer is chosen"
),
),
(
"semantic_id",
wagtail.blocks.TextBlock(
help_text="Semantic ID for this answer"
),
),
]
)
),
),
]
),
),
(
"age_question",
wagtail.blocks.StructBlock(
[
(
"question",
wagtail.blocks.TextBlock(
help_text="The question to ask the user"
),
),
(
"explainer",
wagtail.blocks.TextBlock(
help_text="Explainer message which tells the user why we need this question",
required=False,
),
),
(
"error",
wagtail.blocks.TextBlock(
help_text="Error message for this question if we don't understand the input",
required=False,
),
),
]
),
),
(
"multiselect_question",
wagtail.blocks.StructBlock(
[
(
"question",
wagtail.blocks.TextBlock(
help_text="The question to ask the user"
),
),
(
"explainer",
wagtail.blocks.TextBlock(
help_text="Explainer message which tells the user why we need this question",
required=False,
),
),
(
"error",
wagtail.blocks.TextBlock(
help_text="Error message for this question if we don't understand the input",
required=False,
),
),
(
"answers",
wagtail.blocks.ListBlock(
wagtail.blocks.StructBlock(
[
(
"answer",
wagtail.blocks.TextBlock(
help_text="The choice shown to the user for this option"
),
),
(
"score",
wagtail.blocks.FloatBlock(
help_text="How much to add to the total score if this answer is chosen"
),
),
(
"semantic_id",
wagtail.blocks.TextBlock(
help_text="Semantic ID for this answer"
),
),
]
)
),
),
]
),
),
(
"freetext_question",
wagtail.blocks.StructBlock(
[
(
"question",
wagtail.blocks.TextBlock(
help_text="The question to ask the user"
),
),
(
"explainer",
wagtail.blocks.TextBlock(
help_text="Explainer message which tells the user why we need this question",
required=False,
),
),
]
),
),
(
"integer_question",
wagtail.blocks.StructBlock(
[
(
"question",
wagtail.blocks.TextBlock(
help_text="The question to ask the user"
),
),
(
"explainer",
wagtail.blocks.TextBlock(
help_text="Explainer message which tells the user why we need this question",
required=False,
),
),
(
"error",
wagtail.blocks.TextBlock(
help_text="Error message for this question if we don't understand the input",
required=False,
),
),
(
"min",
wagtail.blocks.IntegerBlock(
help_text="The minimum value that can be entered",
required=False,
),
),
(
"max",
wagtail.blocks.IntegerBlock(
help_text="The maximum value that can be entered",
required=False,
),
),
]
),
),
(
"year_of_birth_question",
wagtail.blocks.StructBlock(
[
(
"question",
wagtail.blocks.TextBlock(
help_text="The question to ask the user"
),
),
(
"explainer",
wagtail.blocks.TextBlock(
help_text="Explainer message which tells the user why we need this question",
required=False,
),
),
(
"error",
wagtail.blocks.TextBlock(
help_text="Error message for this question if we don't understand the input",
required=False,
),
),
]
),
),
],
use_json_field=True,
),
),
]
5 changes: 5 additions & 0 deletions home/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,10 @@ class IntegerQuestionBlock(BaseQuestionBlock):
answers = None


class YearofBirthQuestionBlock(BaseQuestionBlock):
answers = None


class AssessmentTag(TaggedItemBase):
content_object = ParentalKey(
"Assessment", on_delete=models.CASCADE, related_name="tagged_items"
Expand Down Expand Up @@ -1409,6 +1413,7 @@ class Assessment(DraftStateMixin, RevisionMixin, index.Indexed, ClusterableModel
("multiselect_question", MultiselectQuestionBlock()),
("freetext_question", FreeTextQuestionBlock()),
("integer_question", IntegerQuestionBlock()),
("year_of_birth_question", YearofBirthQuestionBlock()),
],
use_json_field=True,
)
Expand Down
1 change: 1 addition & 0 deletions home/tests/import-export-data/multiple_assessments.csv
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Health Assessment,categorical_question,checker,health-assessment,v1.0,en,high-in
Health Assessment,categorical_question,checker,health-assessment,v1.0,en,high-inflection,4.0,medium-score,2.0,low-score,"Sorry, we didn't quite get that.",How high is your temperature?,We need to know this for a proper risk assessment,Please choose the option that matches your answer.,,,"Between 37.5C and 38C,Between 38.1C and 40C,Between 40.1C and 41.1C","3.0,2.0,1.0","test-1,test-2,test-3"
Freetext Test,freetext_question,Free-text,freetext-test,v1.0,en,high-inflection,5.0,medium-score,3.0,low-score,Generic error message,Did you find the information useful,We need to know if the information was useful,,,,,,
Integer Type Question,integer_question,integer-type-question,integer-type-question,v1.0,en,high-inflection,5.0,medium-score,3.0,low-score,This is a generic error,How much do you weigh in kilograms?,We need to test integer type questions,Sorry your min and max weight should be between 40 and 500kg.,40,500,,,
Year of Birth,year_of_birth_question,year-of-birth,year-of-birth,v1.0,en,high-inflection,5.0,medium-score,3.0,low-score,This is a generic error,What's your year of birth,We need to know some things,Your year of birth must be between {current_year} and {lower_bound},,,,,
26 changes: 26 additions & 0 deletions home/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
MultiselectQuestionBlock,
OrderedContentSet,
PageView,
YearofBirthQuestionBlock,
)

from .page_builder import (
Expand Down Expand Up @@ -1434,6 +1435,21 @@ def create_test_data(self):
integer_question_block_value,
)
)
year_of_birth_question_block = YearofBirthQuestionBlock()
year_of_birth_question_block_value = year_of_birth_question_block.to_python(
{
"question": "What's your year of birth?",
"error": "You entered an invalid year of birth",
"explainer": "We need to know some things",
"answers": None,
}
)
self.assessment.questions.append(
(
"year_of_birth_question",
year_of_birth_question_block_value,
)
)
self.assessment.save()

def test_assessment_endpoint(self, uclient):
Expand Down Expand Up @@ -1558,6 +1574,16 @@ def test_assessment_endpoint(self, uclient):
"max": 500,
"answers": [],
}
assert content["results"][0]["questions"][5] == {
"id": self.assessment.questions[5].id,
"question_type": "year_of_birth_question",
"question": "What's your year of birth?",
"explainer": "We need to know some things",
"error": "You entered an invalid year of birth",
"min": None,
"max": None,
"answers": [],
}

def test_assessment_detail_endpoint(self, uclient):
response = uclient.get(f"/api/v2/assessment/{self.assessment.id}/")
Expand Down

0 comments on commit 047b2f4

Please sign in to comment.