Skip to content

Commit

Permalink
Support new supplementary lists property (#213)
Browse files Browse the repository at this point in the history
* Support new supplementary lists property

* Enforce unique supplementary lists

* Improve list collector error message
  • Loading branch information
katie-gardner authored Sep 11, 2023
1 parent eaf7b4d commit cf3286d
Show file tree
Hide file tree
Showing 11 changed files with 1,896 additions and 46 deletions.
2 changes: 1 addition & 1 deletion app/error_messages.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
DUMB_QUOTES_FOUND = "Found dumb quotes(s) in schema text"
INVALID_WHITESPACE_FOUND = "Found invalid white space(s) in schema text"
DUPLICATE_ID_FOUND = "Duplicate id found"
FOR_LIST_NEVER_POPULATED = "for_list is not populated by any ListCollector blocks"
FOR_LIST_NEVER_POPULATED = "for_list is not populated by any ListCollector blocks or supplementary data sources"
MULTIPLE_LIST_COLLECTORS_WITH_SUMMARY_ENABLED = "Section cannot have multiple list collectors that populate the same list when summary with items are enabled."
MULTIPLE_LIST_COLLECTORS = "Section cannot contain multiple ListCollector blocks with a summary showing non-item answers"
RELATED_ANSWERS_NOT_IN_LIST_COLLECTOR = (
Expand Down
4 changes: 4 additions & 0 deletions app/validators/blocks/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
from app.validators.blocks.grand_calculated_summary_block_validator import (
GrandCalculatedSummaryBlockValidator,
)
from app.validators.blocks.list_collector_content_validator import (
ListCollectorContentValidator,
)
from app.validators.blocks.list_collector_driving_question_validator import (
ListCollectorDrivingQuestionValidator,
)
Expand All @@ -23,6 +26,7 @@ def get_block_validator(block, questionnaire_schema):
"GrandCalculatedSummary": GrandCalculatedSummaryBlockValidator,
"PrimaryPersonListCollector": PrimaryPersonListCollectorValidator,
"ListCollector": ListCollectorValidator,
"ListCollectorContent": ListCollectorContentValidator,
"ListCollectorDrivingQuestion": ListCollectorDrivingQuestionValidator,
"RelationshipCollector": RelationshipCollectorValidator,
}
Expand Down
22 changes: 22 additions & 0 deletions app/validators/blocks/list_collector_content_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from app.error_messages import FOR_LIST_NEVER_POPULATED
from app.validators.blocks.block_validator import BlockValidator


class ListCollectorContentValidator(BlockValidator):
def validate(self):
super().validate()
self.validate_for_list_is_valid()
return self.errors

def validate_for_list_is_valid(self):
"""
Verifies that the list for the list collector content block is either:
1) Populated by a standard list collector - OR
2) In the supplementary data lists property so populated by supplementary data
"""
list_name = self.block["for_list"]
if list_name not in self.questionnaire_schema.list_names:
self.add_error(
FOR_LIST_NEVER_POPULATED,
list_name=list_name,
)
22 changes: 14 additions & 8 deletions app/validators/blocks/list_collector_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,9 @@ class ListCollectorValidator(BlockValidator, ValidateListCollectorQuestionsMixin
NO_RADIO_FOR_LIST_COLLECTOR_REMOVE = (
"The list collector remove block does not contain a Radio answer type"
)
LIST_COLLECTOR_ADD_EDIT_IDS_DONT_MATCH = (
"The list collector block contains an add block and edit block"
" with different answer ids"
)
NON_UNIQUE_ANSWER_ID_FOR_LIST_COLLECTOR_ADD = (
"Multiple list collectors populate a list using different "
"answer_ids in the add block"
)
LIST_COLLECTOR_FOR_SUPPLEMENTARY_LIST_IS_INVALID = "Non content list collectors cannot be for a list which comes from supplementary data"
LIST_COLLECTOR_ADD_EDIT_IDS_DONT_MATCH = "The list collector block contains an add block and edit block with different answer ids"
NON_UNIQUE_ANSWER_ID_FOR_LIST_COLLECTOR_ADD = "Multiple list collectors populate a list using different answer_ids in the add block"
NON_SINGLE_REPEATING_BLOCKS_LIST_COLLECTOR = "List may only have one List Collector, if the List Collector features Repeating Blocks"

def validate(self):
Expand Down Expand Up @@ -61,6 +56,7 @@ def validate(self):
self.validate_list_collector_answer_ids(self.block)
self.validate_other_list_collectors()
self.validate_single_repeating_blocks_list_collector()
self.validate_not_for_supplementary_list()
except KeyError as e:
self.add_error(self.LIST_COLLECTOR_KEY_MISSING, key=e)

Expand All @@ -83,6 +79,16 @@ def validate_list_collector_answer_ids(self, block):
self.LIST_COLLECTOR_ADD_EDIT_IDS_DONT_MATCH, block_id=block["id"]
)

def validate_not_for_supplementary_list(self):
"""
Standard list collectors cannot be used for a supplementary list, as these may not be edited
"""
if self.block["for_list"] in self.questionnaire_schema.supplementary_lists:
self.add_error(
self.LIST_COLLECTOR_FOR_SUPPLEMENTARY_LIST_IS_INVALID,
list_name=self.block["for_list"],
)

def validate_other_list_collectors(self):
list_name = self.block["for_list"]
add_answer_ids = self.questionnaire_schema.get_all_answer_ids(
Expand Down
6 changes: 5 additions & 1 deletion app/validators/questionnaire_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,13 @@ def __init__(self, schema):
self.groups_by_id = {group["id"]: group for group in self.groups}
self.group_ids = list(self.groups_by_id.keys())

self.list_names = jp.match(
self.supplementary_lists = jp.match(
"$..supplementary_data.lists[*]", self.schema
)
self.list_collector_names = jp.match(
'$..blocks[?(@.type=="ListCollector")].for_list', self.schema
)
self.list_names = self.list_collector_names + self.supplementary_lists

self._answers_with_context = {}

Expand Down
16 changes: 16 additions & 0 deletions schemas/questionnaire_v1.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,22 @@
"description": {
"$ref": "common_definitions.json#/non_empty_string"
},
"supplementary_data": {
"type": "object",
"description": "A object containing the lists which come from supplementary data",
"properties": {
"lists": {
"type": "array",
"minItems": 1,
"items": {
"$ref": "common_definitions.json#/non_empty_string"
},
"uniqueItems": true
}
},
"required": ["lists"],
"additionalProperties": false
},
"theme": {
"enum": [
"business",
Expand Down
Loading

0 comments on commit cf3286d

Please sign in to comment.