Skip to content

Commit

Permalink
Update a schema to demonstrate minimum/maximum supports floats (#1277)
Browse files Browse the repository at this point in the history
  • Loading branch information
VirajP1002 authored Jan 18, 2024
1 parent 524abde commit 67ce919
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 21 deletions.
25 changes: 14 additions & 11 deletions app/jinja_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,18 +250,21 @@ def get_min_max_value_width(
"""
This function gets the minimum and maximum value accepted for a question.
Which then allows us to use that value to set the width of the textbox to suit that min and max.
"""

if (
answer.get(min_max, {})
and isinstance(answer[min_max]["value"], Mapping)
and answer[min_max]["value"].get("source") == "answers"
):
schema: QuestionnaireSchema = g.get("schema")
identifier = answer[min_max]["value"].get("identifier")
return schema.min_and_max_map[identifier][min_max]
return len(str(answer.get(min_max, {}).get("value", default_value)))
If the min or max for the answer is a value source but not an "answers" source, such as a calculated or grand calculated summary,
use the length of the default value for the min and max width, as the actual min and max width cannot currently be determined
"""
min_max_value = answer.get(min_max, {})
if min_max_value and isinstance(answer[min_max]["value"], Mapping):
if answer[min_max]["value"].get("source") == "answers":
schema: QuestionnaireSchema = g.get("schema")
identifier = answer[min_max]["value"]["identifier"]
return schema.min_and_max_map[identifier][min_max]
return len(str(default_value))

# Factor out the decimals as it's accounted for in get_width_for_number
result = int(min_max_value.get("value", default_value))
return len(str(result))


@blueprint.app_template_filter()
Expand Down
6 changes: 4 additions & 2 deletions app/questionnaire/questionnaire_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from collections import defaultdict
from copy import deepcopy
from dataclasses import dataclass
from decimal import Decimal
from functools import cached_property
from typing import Any, Generator, Iterable, Literal, Mapping, Sequence, TypeAlias

Expand Down Expand Up @@ -167,8 +168,9 @@ def _create_min_max_map(
for answer in answers:
value = answer.get(min_max, {}).get("value")

if isinstance(value, float | int):
value_length = len(str(value))
if isinstance(value, float | int | Decimal):
# Factor out the decimals as it's accounted for in jinja_filters.py
value_length = len(str(int(value)))

longest_value_length = max(longest_value_length, value_length)

Expand Down
4 changes: 2 additions & 2 deletions app/translations/messages.pot
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-01-02 14:50+0000\n"
"POT-Creation-Date: 2024-01-02 11:59+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
Expand Down Expand Up @@ -41,7 +41,7 @@ msgstr ""
msgid "%(from_date)s to %(to_date)s"
msgstr ""

#: app/jinja_filters.py:731
#: app/jinja_filters.py:734
#: templates/partials/summary/collapsible-summary.html:27
#: templates/partials/summary/summary.html:25
msgid "No answer provided"
Expand Down
6 changes: 3 additions & 3 deletions schemas/test/en/test_metadata_routing.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"type": "string"
},
{
"name": "flag_1",
"name": "boolean_flag",
"type": "boolean"
},
{
Expand Down Expand Up @@ -63,10 +63,10 @@
"when": {
"==": [
{
"identifier": "flag_1",
"identifier": "boolean_flag",
"source": "metadata"
},
"true"
true
]
}
},
Expand Down
4 changes: 2 additions & 2 deletions schemas/test/en/test_numbers.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
"type": "Number",
"decimal_places": 2,
"minimum": {
"value": -1000
"value": -1000.98
},
"maximum": {
"value": 1000
Expand All @@ -65,7 +65,7 @@
"value": 1001
},
"maximum": {
"value": 10000
"value": 10000.98
}
}
],
Expand Down
2 changes: 1 addition & 1 deletion tests/app/forms/test_questionnaire_form.py
Original file line number Diff line number Diff line change
Expand Up @@ -1489,7 +1489,7 @@ def test_answer_errors_are_interpolated(app, data_stores):
form.validate()
answer_errors = form.answer_errors("set-minimum")
assert (
schema.error_messages["NUMBER_TOO_SMALL"] % {"min": "-1,000"}
schema.error_messages["NUMBER_TOO_SMALL"] % {"min": "-1,000.98"}
in answer_errors
)

Expand Down
15 changes: 15 additions & 0 deletions tests/functional/spec/numbers.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,22 @@ describe("Number validation", () => {
before(async () => {
await browser.openQuestionnaire("test_numbers.json");
});

describe("Given I am completing the test numbers questionnaire,", () => {
it("When a minimum value with decimals is used and I enter a value less than the minimum, Then the error message includes the minimum value with the decimals values", async () => {
await $(SetMinMax.setMinimum()).setValue(-1000.99);
await $(SetMinMax.setMaximum()).setValue(1000);
await click(SetMinMax.submit());
await expect(await $(SetMinMax.errorNumber(1)).getText()).toBe("Enter an answer more than or equal to -1,000.98");
});

it("When a maximum value with decimals is used and I enter a value greater than the maximum, Then the error message includes the minimum value with the decimal values", async () => {
await $(SetMinMax.setMinimum()).setValue(100);
await $(SetMinMax.setMaximum()).setValue(10000.99);
await click(SetMinMax.submit());
await expect(await $(SetMinMax.errorNumber(1)).getText()).toBe("Enter an answer less than or equal to 10,000.98");
});

it("When I am on the set minimum and maximum page, Then each field has a label", async () => {
await expect(await $(SetMinMax.setMinimumLabelDescription()).getText()).toBe("This is a description of the minimum value");
await expect(await $(SetMinMax.setMaximumLabelDescription()).getText()).toBe("This is a description of the maximum value");
Expand Down

0 comments on commit 67ce919

Please sign in to comment.