Skip to content

Commit 0b5b425

Browse files
committed
[feature/PI-565-questionnaire_rethink] add more validation
1 parent c4c370f commit 0b5b425

File tree

2 files changed

+54
-13
lines changed

2 files changed

+54
-13
lines changed

src/layers/domain/core/questionnaire/tests/test_questionnaire_v3.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import json
22

33
import pytest
4-
from domain.core.enum import Status
5-
from domain.core.questionnaire.v3 import Questionnaire
4+
from domain.core.questionnaire.v3 import (
5+
Questionnaire,
6+
QuestionnaireResponseMissingValue,
7+
QuestionnaireResponseValidationError,
8+
)
69
from domain.core.timestamp import now
7-
from jsonschema import ValidationError as JsonSchemaValidationError
8-
from pydantic import ValidationError as PydanticValidationError
10+
from pydantic import ValidationError
911

1012
VALID_SCHEMA = {
1113
"$schema": "http://json-schema.org/draft-07/schema#",
@@ -51,13 +53,10 @@ def test_schema_validation_pass(data):
5153
name="foo", version="1", json_schema=json.dumps(VALID_SCHEMA)
5254
)
5355
response = questionnaire.validate(data=data)
54-
assert response.name == "foo"
55-
assert response.version == "1"
56+
assert response.questionnaire_name == "foo"
57+
assert response.questionnaire_version == "1"
5658
assert response.data == data
57-
assert response.status is Status.ACTIVE
5859
assert response.created_on.date() == now().date()
59-
assert response.updated_on is None
60-
assert response.deleted_on is None
6160

6261

6362
@pytest.mark.parametrize(
@@ -77,17 +76,31 @@ def test_schema_validation_fail(data):
7776
questionnaire = Questionnaire(
7877
name="foo", version="1", json_schema=json.dumps(VALID_SCHEMA)
7978
)
80-
with pytest.raises(JsonSchemaValidationError):
79+
with pytest.raises(QuestionnaireResponseValidationError):
80+
questionnaire.validate(data=data)
81+
82+
83+
@pytest.mark.parametrize(
84+
"data",
85+
[
86+
{"size": 1},
87+
{"colour": "white"},
88+
],
89+
)
90+
def test_schema_validation_missing_fail(data):
91+
questionnaire = Questionnaire(
92+
name="foo", version="1", json_schema=json.dumps(VALID_SCHEMA)
93+
)
94+
with pytest.raises(QuestionnaireResponseMissingValue):
8195
questionnaire.validate(data=data)
8296

8397

8498
@pytest.mark.parametrize(
8599
"schema",
86100
[
87-
{},
88101
INVALID_SCHEMA,
89102
],
90103
)
91104
def test_invalid_schema(schema):
92-
with pytest.raises(PydanticValidationError):
105+
with pytest.raises(ValidationError):
93106
Questionnaire(name="name", version="123", json_schema=json.dumps(schema))

src/layers/domain/core/questionnaire/v3.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
from domain.core.timestamp import now
77
from pydantic import Field, Json, validator
88

9+
REQUIRED = "required"
10+
11+
12+
class QuestionnaireResponseValidationError(Exception): ...
13+
14+
15+
class QuestionnaireResponseMissingValue(Exception): ...
16+
917

1018
class Questionnaire(BaseModel):
1119
name: str
@@ -21,15 +29,35 @@ def validate_json_schema(cls, json_schema):
2129
return json_schema
2230

2331
def validate(self, data) -> "QuestionnaireResponse":
24-
jsonschema.validate(instance=data, schema=self.json_schema)
32+
try:
33+
jsonschema.validate(instance=data, schema=self.json_schema)
34+
except jsonschema.ValidationError as error:
35+
*_, variable_name = error.schema_path
36+
exception_type = (
37+
QuestionnaireResponseMissingValue
38+
if variable_name == REQUIRED
39+
else QuestionnaireResponseValidationError
40+
)
41+
raise exception_type(
42+
f"Failed to validate data against '{self.id}': {error.message}"
43+
)
44+
2545
return QuestionnaireResponse(
2646
questionnaire_name=self.name, questionnaire_version=self.version, data=data
2747
)
2848

49+
@property
50+
def id(self) -> str:
51+
return f"{self.name}/{self.version}"
52+
2953

3054
class QuestionnaireResponse(BaseModel):
3155
id: UUID = Field(default_factory=uuid4)
3256
questionnaire_name: str
3357
questionnaire_version: str
3458
data: dict
3559
created_on: datetime = Field(default_factory=now)
60+
61+
@property
62+
def questionnaire_id(self) -> str:
63+
return f"{self.questionnaire_name}/{self.questionnaire_version}"

0 commit comments

Comments
 (0)