Skip to content

Commit

Permalink
feat(caluma_form): add min/max_date to date question
Browse files Browse the repository at this point in the history
  • Loading branch information
MitanOmar authored and open-dynaMIX committed Oct 6, 2023
1 parent 70e875c commit 77916a9
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 2 deletions.
3 changes: 3 additions & 0 deletions caluma/caluma_form/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,9 @@ class QuestionFactory(DjangoModelFactory):
)
calc_dependents = []

min_date = None
max_date = None

# action button question
action = Maybe(
"is_action_button",
Expand Down
24 changes: 24 additions & 0 deletions caluma/caluma_form/models.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import uuid
from functools import wraps

import dateutil.parser
from django.contrib.postgres.fields import ArrayField
from django.contrib.postgres.indexes import GinIndex
from django.core.serializers.json import DjangoJSONEncoder, json
from django.db import models, transaction
from django.utils.functional import cached_property
from localized_fields.fields import LocalizedField, LocalizedTextField
Expand Down Expand Up @@ -220,6 +222,28 @@ def min_value(self):
def min_value(self, value):
self.configuration["min_value"] = value

@property
def max_date(self):
if (max_date := self.configuration.get("max_date")) and max_date:
return dateutil.parser.parse(json.loads(max_date)).date()

@max_date.setter
def max_date(self, value):
self.configuration["max_date"] = (
json.dumps(value, cls=DjangoJSONEncoder) if value is not None else None
)

@property
def min_date(self):
if (min_date := self.configuration.get("min_date")) and min_date:
return dateutil.parser.parse(json.loads(min_date)).date()

@min_date.setter
def min_date(self, value):
self.configuration["min_date"] = (
json.dumps(value, cls=DjangoJSONEncoder) if value is not None else None
)

@property
def action(self):
return self.configuration.get("action")
Expand Down
2 changes: 2 additions & 0 deletions caluma/caluma_form/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ class Meta:

class DateQuestion(QuestionQuerysetMixin, FormDjangoObjectType):
hint_text = graphene.String()
min_date = graphene.Date()
max_date = graphene.Date()
default_answer = graphene.Field("caluma.caluma_form.schema.DateAnswer")

class Meta:
Expand Down
18 changes: 17 additions & 1 deletion caluma/caluma_form/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,12 +240,28 @@ class Meta(SaveQuestionSerializer.Meta):


class SaveDateQuestionSerializer(SaveQuestionSerializer):
min_date = DateField("%Y-%m-%d", required=False, allow_null=True)
max_date = DateField("%Y-%m-%d", required=False, allow_null=True)

def validate(self, data):
if (
(min_date := data.get("min_date"))
and (max_date := data.get("max_date"))
and max_date < min_date
):
raise exceptions.ValidationError(
f"max_value {max_date} is smaller than {min_date}"
)

data["type"] = models.Question.TYPE_DATE
return super().validate(data)

class Meta(SaveQuestionSerializer.Meta):
fields = SaveQuestionSerializer.Meta.fields + ["hint_text"]
fields = SaveQuestionSerializer.Meta.fields + [
"hint_text",
"min_date",
"max_date",
]


class SaveQuestionOptionsMixin(object):
Expand Down
114 changes: 114 additions & 0 deletions caluma/caluma_form/tests/__snapshots__/test_question.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,120 @@
}),
})
# ---
# name: test_save_date_question[False-date-2022-01-31-2022-12-31-True]
dict({
'saveDateQuestion': dict({
'clientMutationId': 'testid',
'question': dict({
'__typename': 'DateQuestion',
'defaultAnswer': None,
'hintText': '',
'id': 'RGF0ZVF1ZXN0aW9uOmVudmlyb25tZW50YWwtdGVu',
'label': 'Bonnie Moreno',
'maxDate': '2022-12-31',
'meta': dict({
}),
'minDate': '2022-01-31',
'slug': 'environmental-ten',
}),
}),
})
# ---
# name: test_save_date_question[False-date-2022-01-31-None-True]
dict({
'saveDateQuestion': dict({
'clientMutationId': 'testid',
'question': dict({
'__typename': 'DateQuestion',
'defaultAnswer': None,
'hintText': '',
'id': 'RGF0ZVF1ZXN0aW9uOmVudmlyb25tZW50YWwtdGVu',
'label': 'Bonnie Moreno',
'maxDate': None,
'meta': dict({
}),
'minDate': '2022-01-31',
'slug': 'environmental-ten',
}),
}),
})
# ---
# name: test_save_date_question[False-date-None-2022-12-31-True]
dict({
'saveDateQuestion': dict({
'clientMutationId': 'testid',
'question': dict({
'__typename': 'DateQuestion',
'defaultAnswer': None,
'hintText': '',
'id': 'RGF0ZVF1ZXN0aW9uOmVudmlyb25tZW50YWwtdGVu',
'label': 'Bonnie Moreno',
'maxDate': '2022-12-31',
'meta': dict({
}),
'minDate': None,
'slug': 'environmental-ten',
}),
}),
})
# ---
# name: test_save_date_question[True-date-2022-01-31-2022-12-31-True]
dict({
'saveDateQuestion': dict({
'clientMutationId': 'testid',
'question': dict({
'__typename': 'DateQuestion',
'defaultAnswer': None,
'hintText': '',
'id': 'RGF0ZVF1ZXN0aW9uOmVudmlyb25tZW50YWwtdGVu',
'label': 'Bonnie Moreno',
'maxDate': '2022-12-31',
'meta': dict({
}),
'minDate': '2022-01-31',
'slug': 'environmental-ten',
}),
}),
})
# ---
# name: test_save_date_question[True-date-2022-01-31-None-True]
dict({
'saveDateQuestion': dict({
'clientMutationId': 'testid',
'question': dict({
'__typename': 'DateQuestion',
'defaultAnswer': None,
'hintText': '',
'id': 'RGF0ZVF1ZXN0aW9uOmVudmlyb25tZW50YWwtdGVu',
'label': 'Bonnie Moreno',
'maxDate': None,
'meta': dict({
}),
'minDate': '2022-01-31',
'slug': 'environmental-ten',
}),
}),
})
# ---
# name: test_save_date_question[True-date-None-2022-12-31-True]
dict({
'saveDateQuestion': dict({
'clientMutationId': 'testid',
'question': dict({
'__typename': 'DateQuestion',
'defaultAnswer': None,
'hintText': '',
'id': 'RGF0ZVF1ZXN0aW9uOmVudmlyb25tZW50YWwtdGVu',
'label': 'Bonnie Moreno',
'maxDate': '2022-12-31',
'meta': dict({
}),
'minDate': None,
'slug': 'environmental-ten',
}),
}),
})
# ---
# name: test_save_dynamic_choice_question[dynamic_choice-False]
dict({
'saveDynamicChoiceQuestion': dict({
Expand Down
78 changes: 77 additions & 1 deletion caluma/caluma_form/tests/test_question.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import pytest
from django.utils.timezone import datetime

from caluma.caluma_core.relay import extract_global_id
from caluma.caluma_core.tests import (
Expand Down Expand Up @@ -369,7 +370,6 @@ def test_save_textarea_question(db, question, answer, schema_executor):
}
}
"""

question.default_answer = answer
question.hint_text = "test"
question.save()
Expand All @@ -389,6 +389,82 @@ def test_save_textarea_question(db, question, answer, schema_executor):
assert result.data["saveTextareaQuestion"]["question"]["hintText"] == "test"


@pytest.mark.parametrize(
"question__type, min_date, max_date, success",
[
(models.Question.TYPE_DATE, "2022-01-31", "2022-12-31", True),
(models.Question.TYPE_DATE, "2022-01-31", None, True),
(models.Question.TYPE_DATE, None, "2022-12-31", True),
(models.Question.TYPE_DATE, "2022-12-01", "2022-01-31", False),
],
)
@pytest.mark.parametrize("existing_values", [False, True])
def test_save_date_question(
db,
snapshot,
question,
success,
schema_executor,
min_date,
max_date,
existing_values,
):
query = """
mutation SaveDateQuestion($input: SaveDateQuestionInput!) {
saveDateQuestion(input: $input) {
question {
id
slug
label
meta
__typename
... on DateQuestion {
minDate
maxDate
hintText
defaultAnswer {
value
}
}
}
clientMutationId
}
}
"""

if max_date:
question.max_date = datetime.strptime(max_date, "%Y-%m-%d").date()
if min_date:
question.min_date = datetime.strptime(min_date, "%Y-%m-%d").date()

inp = {
"input": extract_serializer_input_fields(
serializers.SaveDateQuestionSerializer, question
)
}

if existing_values:
question.save()

result = schema_executor(query, variable_values=inp)
assert not bool(result.errors) == success
if not success:
return

snapshot.assert_match(result.data)

question.refresh_from_db()
if not min_date:
assert question.min_date is None
else:
assert question.min_date == datetime.strptime(min_date, "%Y-%m-%d").date()

if not max_date:
assert question.max_date is None
else:
assert question.max_date == datetime.strptime(max_date, "%Y-%m-%d").date()


@pytest.mark.parametrize(
"question__type,question__configuration,answer__value,success",
[
Expand Down
4 changes: 4 additions & 0 deletions caluma/tests/__snapshots__/test_schema.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -818,6 +818,8 @@

"""The ID of the object"""
id: ID!
minDate: Date
maxDate: Date
}

"""
Expand Down Expand Up @@ -2376,6 +2378,8 @@
meta: JSONString
isArchived: Boolean
hintText: String
minDate: Date
maxDate: Date
clientMutationId: String
}

Expand Down

0 comments on commit 77916a9

Please sign in to comment.