Skip to content

Commit 5f7827f

Browse files
committed
feat(resources): add captcha validation on request demo mutation
1 parent 66b2a41 commit 5f7827f

File tree

4 files changed

+64
-13
lines changed

4 files changed

+64
-13
lines changed

apps/resources/graphql/inputs.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
11
import strawberry
2-
import strawberry_django
3-
4-
from apps.resources.models import RequestDemo
52

63

74
@strawberry.input
@@ -14,10 +11,12 @@ class ContactRequestInput:
1411
captcha_code: str
1512

1613

17-
@strawberry_django.input(RequestDemo)
14+
@strawberry.input
1815
class RequestDemoInput:
19-
name: strawberry.auto
20-
email: strawberry.auto
21-
content: strawberry.auto
22-
national_society: strawberry.auto
16+
name: str
17+
email: str
18+
content: str
19+
national_society: str
2320
tool: int
21+
captcha_hashkey: str
22+
captcha_code: str

apps/resources/serializers.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,10 @@ def create(self, validated_data: dict[str, typing.Any]):
2929
return super().create(validated_data)
3030

3131

32-
class RequestDemoSerializer(serializers.ModelSerializer):
32+
class RequestDemoSerializer(CaptchaModelSerializer):
33+
captcha_code = serializers.CharField(write_only=True)
34+
captcha_hashkey = serializers.CharField(write_only=True)
35+
3336
tool = serializers.PrimaryKeyRelatedField(
3437
queryset=Tool.objects.all(),
3538
)
@@ -42,4 +45,12 @@ class Meta:
4245
"national_society",
4346
"content",
4447
"tool",
48+
"captcha_code",
49+
"captcha_hashkey",
4550
)
51+
52+
@typing.override
53+
def create(self, validated_data: dict[str, typing.Any]):
54+
validated_data.pop("captcha_code", None)
55+
validated_data.pop("captcha_hashkey", None)
56+
return super().create(validated_data)

apps/resources/tests/mutation_test.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,12 +165,18 @@ def _create_tool_demo_request_mutation(self, data: dict[str, str | int], **kwarg
165165
)
166166

167167
def test_create_tool_demo_request(self):
168+
captcha_key = CaptchaStore.generate_key()
169+
captcha_obj = CaptchaStore.objects.get(hashkey=captcha_key)
170+
captcha_code = captcha_obj.response
171+
168172
tool_demo_request_data = {
169173
"name": "John",
170174
"email": "john@test.com",
171175
"nationalSociety": "Test National Society",
172176
"content": "This is test content",
173177
"tool": self.tool.id,
178+
"captchaHashkey": captcha_key,
179+
"captchaCode": captcha_code,
174180
}
175181

176182
content = self._create_tool_demo_request_mutation(data=tool_demo_request_data)
@@ -190,3 +196,39 @@ def test_create_tool_demo_request(self):
190196
"pk": self.gID(demo_request.tool.pk),
191197
},
192198
}
199+
200+
def test_create_tool_demo_request_without_captcha(self):
201+
tool_demo_request_data = {
202+
"name": "John",
203+
"email": "john@test.com",
204+
"nationalSociety": "Test National Society",
205+
"content": "This is test content",
206+
"tool": self.tool.id,
207+
"captchaHashkey": "",
208+
"captchaCode": "",
209+
}
210+
211+
content = self._create_tool_demo_request_mutation(data=tool_demo_request_data)
212+
response = content["data"]["createDemoRequest"]
213+
214+
assert response["ok"] is False
215+
assert response["result"] is None
216+
217+
assert response["errors"] == [
218+
{
219+
"field": "captchaCode",
220+
"client_id": None,
221+
"messages": "This field may not be blank.",
222+
"object_errors": None,
223+
"array_errors": None,
224+
"pydantic_errors": None,
225+
},
226+
{
227+
"field": "captchaHashkey",
228+
"client_id": None,
229+
"messages": "This field may not be blank.",
230+
"object_errors": None,
231+
"array_errors": None,
232+
"pydantic_errors": None,
233+
},
234+
]

schema.graphql

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -280,15 +280,14 @@ type RecommendationResultTypeOffsetPaginated {
280280
results: [RecommendationResultType!]!
281281
}
282282

283-
"""
284-
Model representing contact where anyone can request the tool demo to the admins.
285-
"""
286283
input RequestDemoInput {
287284
name: String!
288285
email: String!
289-
content: String
286+
content: String!
290287
nationalSociety: String!
291288
tool: Int!
289+
captchaHashkey: String!
290+
captchaCode: String!
292291
}
293292

294293
"""

0 commit comments

Comments
 (0)