Coverage for /home/marco/Code/django-simple-captcha/captcha/tests/tests.py: 91.53%

338 statements  

« prev     ^ index     » next       coverage.py v7.6.5, created at 2024-11-15 09:22 +0100

1import datetime 

2import json 

3import os 

4import re 

5from io import BytesIO 

6from unittest.mock import call, patch 

7 

8from PIL import Image 

9from testfixtures import LogCapture 

10 

11import django 

12from django.core import management 

13from django.core.exceptions import ImproperlyConfigured 

14from django.test import TestCase, override_settings 

15from django.urls import reverse 

16from django.utils import timezone 

17from django.utils.translation import gettext_lazy 

18 

19from captcha.conf import settings 

20from captcha.models import CaptchaStore 

21 

22 

23@override_settings(ROOT_URLCONF="captcha.tests.urls") 

24class CaptchaCase(TestCase): 

25 def setUp(self): 

26 self.stores = {} 

27 self.__current_settings_dictionary = settings.CAPTCHA_WORDS_DICTIONARY 

28 self.__current_settings_punctuation = settings.CAPTCHA_PUNCTUATION 

29 

30 tested_helpers = [ 

31 "captcha.helpers.math_challenge", 

32 "captcha.helpers.random_char_challenge", 

33 "captcha.helpers.unicode_challenge", 

34 ] 

35 if os.path.exists("/usr/share/dict/words"): 35 ↛ 36line 35 didn't jump to line 36 because the condition on line 35 was never true

36 settings.CAPTCHA_WORDS_DICTIONARY = "/usr/share/dict/words" 

37 settings.CAPTCHA_PUNCTUATION = ";-,." 

38 tested_helpers.append("captcha.helpers.word_challenge") 

39 tested_helpers.append( 

40 "captcha.helpers.huge_words_and_punctuation_challenge" 

41 ) 

42 for helper in tested_helpers: 

43 challenge, response = settings._callable_from_string(helper)() 

44 ( 

45 self.stores[helper.rsplit(".", 1)[-1].replace("_challenge", "_store")], 

46 _, 

47 ) = CaptchaStore.objects.get_or_create( 

48 challenge=challenge, response=response 

49 ) 

50 challenge, response = settings.get_challenge()() 

51 self.stores["default_store"], _ = CaptchaStore.objects.get_or_create( 

52 challenge=challenge, response=response 

53 ) 

54 self.default_store = self.stores["default_store"] 

55 

56 def tearDown(self): 

57 settings.CAPTCHA_WORDS_DICTIONARY = self.__current_settings_dictionary 

58 settings.CAPTCHA_PUNCTUATION = self.__current_settings_punctuation 

59 

60 def _assertFormError(self, response, form_name, *args, **kwargs): 

61 self.assertFormError(response.context.get(form_name), *args, **kwargs) 

62 

63 def __extract_hash_and_response(self, r): 

64 hash_ = re.findall(r'value="([0-9a-f]+)"', str(r.content))[0] 

65 response = CaptchaStore.objects.get(hashkey=hash_).response 

66 return hash_, response 

67 

68 def test_image(self): 

69 for key in [store.hashkey for store in self.stores.values()]: 

70 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

71 self.assertEqual(response.status_code, 200) 

72 self.assertTrue(response.has_header("content-type")) 

73 self.assertEqual(response["content-type"], "image/png") 

74 

75 def test_audio(self): 

76 if not settings.CAPTCHA_FLITE_PATH: 76 ↛ 78line 76 didn't jump to line 78 because the condition on line 76 was always true

77 return 

78 for key in ( 

79 self.stores.get("math_store").hashkey, 

80 self.stores.get("math_store").hashkey, 

81 self.default_store.hashkey, 

82 ): 

83 response = self.client.get(reverse("captcha-audio", kwargs=dict(key=key))) 

84 self.assertEqual(response.status_code, 200) 

85 self.assertTrue(response.ranged_file.size > 1024) 

86 self.assertTrue(response.has_header("content-type")) 

87 self.assertEqual(response["content-type"], "audio/wav") 

88 

89 def test_form_submit(self): 

90 r = self.client.get(reverse("captcha-test")) 

91 self.assertEqual(r.status_code, 200) 

92 hash_, response = self.__extract_hash_and_response(r) 

93 

94 r = self.client.post( 

95 reverse("captcha-test"), 

96 dict( 

97 captcha_0=hash_, 

98 captcha_1=response, 

99 subject="xxx", 

100 sender="asasd@asdasd.com", 

101 ), 

102 ) 

103 self.assertEqual(r.status_code, 200) 

104 self.assertTrue(str(r.content).find("Form validated") > 0) 

105 

106 r = self.client.post( 

107 reverse("captcha-test"), 

108 dict( 

109 captcha_0=hash_, 

110 captcha_1=response, 

111 subject="xxx", 

112 sender="asasd@asdasd.com", 

113 ), 

114 ) 

115 self.assertEqual(r.status_code, 200) 

116 self.assertFalse(str(r.content).find("Form validated") > 0) 

117 

118 def test_modelform(self): 

119 r = self.client.get(reverse("captcha-test-model-form")) 

120 self.assertEqual(r.status_code, 200) 

121 hash_, response = self.__extract_hash_and_response(r) 

122 

123 r = self.client.post( 

124 reverse("captcha-test-model-form"), 

125 dict( 

126 captcha_0=hash_, 

127 captcha_1=response, 

128 subject="xxx", 

129 sender="asasd@asdasd.com", 

130 ), 

131 ) 

132 self.assertEqual(r.status_code, 200) 

133 self.assertTrue(str(r.content).find("Form validated") > 0) 

134 

135 r = self.client.post( 

136 reverse("captcha-test-model-form"), 

137 dict( 

138 captcha_0=hash_, 

139 captcha_1=response, 

140 subject="xxx", 

141 sender="asasd@asdasd.com", 

142 ), 

143 ) 

144 self.assertEqual(r.status_code, 200) 

145 self.assertFalse(str(r.content).find("Form validated") > 0) 

146 

147 def test_wrong_submit(self): 

148 for urlname in ("captcha-test", "captcha-test-model-form"): 

149 r = self.client.get(reverse(urlname)) 

150 self.assertEqual(r.status_code, 200) 

151 r = self.client.post( 

152 reverse(urlname), 

153 dict( 

154 captcha_0="abc", 

155 captcha_1="wrong response", 

156 subject="xxx", 

157 sender="asasd@asdasd.com", 

158 ), 

159 ) 

160 self._assertFormError(r, "form", "captcha", gettext_lazy("Invalid CAPTCHA")) 

161 

162 def test_deleted_expired(self): 

163 self.default_store.expiration = timezone.now() - datetime.timedelta(minutes=5) 

164 self.default_store.save() 

165 hash_ = self.default_store.hashkey 

166 r = self.client.post( 

167 reverse("captcha-test"), 

168 dict( 

169 captcha_0=hash_, 

170 captcha_1=self.default_store.response, 

171 subject="xxx", 

172 sender="asasd@asdasd.com", 

173 ), 

174 ) 

175 

176 self.assertEqual(r.status_code, 200) 

177 self.assertFalse("Form validated" in str(r.content)) 

178 

179 # expired -> deleted 

180 try: 

181 CaptchaStore.objects.get(hashkey=hash_) 

182 self.fail() 

183 except Exception: 

184 pass 

185 

186 def test_custom_error_message(self): 

187 r = self.client.get(reverse("captcha-test-custom-error-message")) 

188 self.assertEqual(r.status_code, 200) 

189 # Wrong answer 

190 r = self.client.post( 

191 reverse("captcha-test-custom-error-message"), 

192 dict(captcha_0="abc", captcha_1="wrong response"), 

193 ) 

194 self._assertFormError(r, "form", "captcha", "TEST CUSTOM ERROR MESSAGE") 

195 # empty answer 

196 r = self.client.post( 

197 reverse("captcha-test-custom-error-message"), 

198 dict(captcha_0="abc", captcha_1=""), 

199 ) 

200 self._assertFormError( 

201 r, "form", "captcha", gettext_lazy("This field is required.") 

202 ) 

203 

204 def test_repeated_challenge(self): 

205 CaptchaStore.objects.create(challenge="xxx", response="xxx") 

206 try: 

207 CaptchaStore.objects.create(challenge="xxx", response="xxx") 

208 except Exception: 

209 self.fail() 

210 

211 @patch("captcha.tests.tests.random_color_challenge") 

212 def test_custom_letters_color(self, color_challenge_func_mock): 

213 color_challenge_func_mock.return_value = "#ffffff" 

214 _current_captcha_challenge_func = settings.CAPTCHA_CHALLENGE_FUNCT 

215 

216 settings.CAPTCHA_LETTER_COLOR_FUNCT = ( 

217 "captcha.tests.tests.random_color_challenge" 

218 ) 

219 settings.CAPTCHA_CHALLENGE_FUNCT = "captcha.tests.tests.random_char_challenge" 

220 

221 challenge, response = settings.get_challenge()() 

222 _store, _ = CaptchaStore.objects.get_or_create( 

223 challenge=challenge, response=response 

224 ) 

225 

226 _response = self.client.get( 

227 reverse("captcha-image", kwargs=dict(key=_store.hashkey)) 

228 ) 

229 assert _response.status_code == 200 

230 

231 _calls = [] 

232 for index, char in enumerate(challenge): 

233 _calls.append(call(index, challenge)) 

234 color_challenge_func_mock.assert_has_calls(_calls, any_order=True) 

235 

236 settings.CAPTCHA_LETTER_COLOR_FUNCT = None 

237 settings.CAPTCHA_CHALLENGE_FUNCT = _current_captcha_challenge_func 

238 

239 def test_repeated_challenge_form_submit(self): 

240 __current_challange_function = settings.CAPTCHA_CHALLENGE_FUNCT 

241 for urlname in ("captcha-test", "captcha-test-model-form"): 

242 settings.CAPTCHA_CHALLENGE_FUNCT = "captcha.tests.trivial_challenge" 

243 

244 r1 = self.client.get(reverse(urlname)) 

245 r2 = self.client.get(reverse(urlname)) 

246 self.assertEqual(r1.status_code, 200) 

247 self.assertEqual(r2.status_code, 200) 

248 if re.findall(r'value="([0-9a-f]+)"', str(r1.content)): 248 ↛ 251line 248 didn't jump to line 251 because the condition on line 248 was always true

249 hash_1 = re.findall(r'value="([0-9a-f]+)"', str(r1.content))[0] 

250 else: 

251 self.fail() 

252 

253 if re.findall(r'value="([0-9a-f]+)"', str(r2.content)): 253 ↛ 256line 253 didn't jump to line 256 because the condition on line 253 was always true

254 hash_2 = re.findall(r'value="([0-9a-f]+)"', str(r2.content))[0] 

255 else: 

256 self.fail() 

257 try: 

258 store_1 = CaptchaStore.objects.get(hashkey=hash_1) 

259 store_2 = CaptchaStore.objects.get(hashkey=hash_2) 

260 except Exception: 

261 self.fail() 

262 

263 self.assertTrue(store_1.pk != store_2.pk) 

264 self.assertTrue(store_1.response == store_2.response) 

265 self.assertTrue(hash_1 != hash_2) 

266 

267 r1 = self.client.post( 

268 reverse(urlname), 

269 dict( 

270 captcha_0=hash_1, 

271 captcha_1=store_1.response, 

272 subject="xxx", 

273 sender="asasd@asdasd.com", 

274 ), 

275 ) 

276 self.assertEqual(r1.status_code, 200) 

277 self.assertTrue(str(r1.content).find("Form validated") > 0) 

278 

279 try: 

280 store_2 = CaptchaStore.objects.get(hashkey=hash_2) 

281 except Exception: 

282 self.fail() 

283 

284 r2 = self.client.post( 

285 reverse(urlname), 

286 dict( 

287 captcha_0=hash_2, 

288 captcha_1=store_2.response, 

289 subject="xxx", 

290 sender="asasd@asdasd.com", 

291 ), 

292 ) 

293 self.assertEqual(r2.status_code, 200) 

294 self.assertTrue(str(r2.content).find("Form validated") > 0) 

295 settings.CAPTCHA_CHALLENGE_FUNCT = __current_challange_function 

296 

297 def test_custom_generator(self): 

298 r = self.client.get(reverse("test_custom_generator")) 

299 hash_, response = self.__extract_hash_and_response(r) 

300 self.assertEqual(response, "111111") 

301 

302 def test_refresh_view(self): 

303 r = self.client.get( 

304 reverse("captcha-refresh"), HTTP_X_REQUESTED_WITH="XMLHttpRequest" 

305 ) 

306 try: 

307 new_data = json.loads(str(r.content, encoding="ascii")) 

308 self.assertTrue("image_url" in new_data) 

309 self.assertTrue("audio_url" in new_data) 

310 except Exception: 

311 self.fail() 

312 

313 def test_content_length(self): 

314 for key in [store.hashkey for store in self.stores.values()]: 

315 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

316 self.assertTrue(response.has_header("content-length")) 

317 self.assertTrue(response["content-length"].isdigit()) 

318 self.assertTrue(int(response["content-length"])) 

319 

320 def test_test_mode_issue15(self): 

321 __current_test_mode_setting = settings.CAPTCHA_TEST_MODE 

322 settings.CAPTCHA_TEST_MODE = False 

323 r = self.client.get(reverse("captcha-test")) 

324 self.assertEqual(r.status_code, 200) 

325 r = self.client.post( 

326 reverse("captcha-test"), 

327 dict( 

328 captcha_0="abc", 

329 captcha_1="wrong response", 

330 subject="xxx", 

331 sender="asasd@asdasd.com", 

332 ), 

333 ) 

334 self._assertFormError(r, "form", "captcha", gettext_lazy("Invalid CAPTCHA")) 

335 

336 settings.CAPTCHA_TEST_MODE = True 

337 # Test mode, only 'PASSED' is accepted 

338 r = self.client.get(reverse("captcha-test")) 

339 self.assertEqual(r.status_code, 200) 

340 r = self.client.post( 

341 reverse("captcha-test"), 

342 dict( 

343 captcha_0="abc", 

344 captcha_1="wrong response", 

345 subject="xxx", 

346 sender="asasd@asdasd.com", 

347 ), 

348 ) 

349 self._assertFormError(r, "form", "captcha", gettext_lazy("Invalid CAPTCHA")) 

350 

351 r = self.client.get(reverse("captcha-test")) 

352 self.assertEqual(r.status_code, 200) 

353 r = self.client.post( 

354 reverse("captcha-test"), 

355 dict( 

356 captcha_0="abc", 

357 captcha_1="passed", 

358 subject="xxx", 

359 sender="asasd@asdasd.com", 

360 ), 

361 ) 

362 self.assertTrue(str(r.content).find("Form validated") > 0) 

363 settings.CAPTCHA_TEST_MODE = __current_test_mode_setting 

364 

365 def test_get_version(self): 

366 import captcha 

367 

368 captcha.get_version() 

369 

370 def test_missing_value(self): 

371 r = self.client.get(reverse("captcha-test-non-required")) 

372 self.assertEqual(r.status_code, 200) 

373 hash_, response = self.__extract_hash_and_response(r) 

374 

375 # Empty response is okay when required is False 

376 r = self.client.post( 

377 reverse("captcha-test-non-required"), 

378 dict(subject="xxx", sender="asasd@asdasd.com"), 

379 ) 

380 self.assertEqual(r.status_code, 200) 

381 self.assertTrue(str(r.content).find("Form validated") > 0) 

382 

383 # But a valid response is okay, too 

384 r = self.client.get(reverse("captcha-test-non-required")) 

385 self.assertEqual(r.status_code, 200) 

386 hash_, response = self.__extract_hash_and_response(r) 

387 

388 r = self.client.post( 

389 reverse("captcha-test-non-required"), 

390 dict( 

391 captcha_0=hash_, 

392 captcha_1=response, 

393 subject="xxx", 

394 sender="asasd@asdasd.com", 

395 ), 

396 ) 

397 self.assertEqual(r.status_code, 200) 

398 self.assertTrue(str(r.content).find("Form validated") > 0) 

399 

400 def test_autocomplete_off(self): 

401 r = self.client.get(reverse("captcha-test")) 

402 captcha_input = ( 

403 '<input type="text" name="captcha_1" autocomplete="off" ' 

404 'spellcheck="false" autocorrect="off" ' 

405 'autocapitalize="off" id="id_captcha_1" required />' 

406 ) 

407 if django.VERSION >= (5, 0): 407 ↛ 414line 407 didn't jump to line 414 because the condition on line 407 was always true

408 captcha_input = ( 

409 '<input type="text" name="captcha_1" autocomplete="off" ' 

410 'spellcheck="false" autocorrect="off" ' 

411 'autocapitalize="off" id="id_captcha_1" ' 

412 "required />" 

413 ) 

414 self.assertContains(r, captcha_input, html=True) 

415 

416 def test_issue201_autocomplete_off_on_hiddeninput(self): 

417 r = self.client.get(reverse("captcha-test")) 

418 

419 # Inspect the response context to find out the captcha key. 

420 key = r.context["form"]["captcha"].field.widget._key 

421 

422 # Assety that autocomplete=off is set on the hidden captcha field. 

423 if django.VERSION >= (5, 0): 423 ↛ 434line 423 didn't jump to line 434 because the condition on line 423 was always true

424 self.assertInHTML( 

425 ( 

426 f'<input type="hidden" name="captcha_0" value="{key}" ' 

427 'id="id_captcha_0" autocomplete="off" ' 

428 "required />" 

429 ), 

430 str(r.content), 

431 ) 

432 

433 else: 

434 self.assertInHTML( 

435 ( 

436 f'<input type="hidden" name="captcha_0" value="{key}" ' 

437 'id="id_captcha_0" autocomplete="off" required />' 

438 ), 

439 str(r.content), 

440 ) 

441 

442 def test_transparent_background(self): 

443 __current_test_mode_setting = settings.CAPTCHA_BACKGROUND_COLOR 

444 settings.CAPTCHA_BACKGROUND_COLOR = "transparent" 

445 for key in [store.hashkey for store in self.stores.values()]: 

446 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

447 self.assertEqual(response.status_code, 200) 

448 self.assertTrue(response.has_header("content-type")) 

449 self.assertEqual(response["content-type"], "image/png") 

450 

451 settings.CAPTCHA_BACKGROUND_COLOR = __current_test_mode_setting 

452 

453 def test_expired_captcha_returns_410(self): 

454 for key in [store.hashkey for store in self.stores.values()]: 

455 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

456 self.assertEqual(response.status_code, 200) 

457 CaptchaStore.objects.filter(hashkey=key).delete() 

458 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

459 self.assertEqual(response.status_code, 410) 

460 

461 def test_id_prefix(self): 

462 r = self.client.get(reverse("captcha-test-id-prefix")) 

463 self.assertTrue( 

464 '<label for="form1_id_captcha1_1">Captcha1:</label>' in str(r.content) 

465 ) 

466 self.assertTrue('id="form1_id_captcha1_1"' in str(r.content)) 

467 self.assertTrue( 

468 '<label for="form2_id_captcha2_1">Captcha2:</label>' in str(r.content) 

469 ) 

470 self.assertTrue('id="form2_id_captcha2_1"' in str(r.content)) 

471 

472 def test_image_size(self): 

473 __current_test_mode_setting = settings.CAPTCHA_IMAGE_SIZE 

474 for key in [store.hashkey for store in self.stores.values()]: 

475 settings.CAPTCHA_IMAGE_SIZE = (201, 97) 

476 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

477 self.assertEqual(response.status_code, 200) 

478 self.assertTrue(response.has_header("content-type")) 

479 self.assertEqual(response["content-type"], "image/png") 

480 self.assertEqual(Image.open(BytesIO(response.content)).size, (201, 97)) 

481 

482 settings.CAPTCHA_IMAGE_SIZE = __current_test_mode_setting 

483 

484 def test_multiple_fonts(self): 

485 vera = os.path.join(os.path.dirname(__file__), "..", "fonts", "Vera.ttf") 

486 __current_test_mode_setting = settings.CAPTCHA_FONT_PATH 

487 settings.CAPTCHA_FONT_PATH = vera 

488 

489 for key in [store.hashkey for store in self.stores.values()]: 

490 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

491 self.assertEqual(response.status_code, 200) 

492 self.assertEqual(response["content-type"], "image/png") 

493 

494 settings.CAPTCHA_FONT_PATH = [vera, vera, vera] 

495 for key in [store.hashkey for store in self.stores.values()]: 

496 response = self.client.get(reverse("captcha-image", kwargs=dict(key=key))) 

497 self.assertEqual(response.status_code, 200) 

498 self.assertEqual(response["content-type"], "image/png") 

499 

500 settings.CAPTCHA_FONT_PATH = False 

501 for key in [store.hashkey for store in self.stores.values()]: 

502 try: 

503 response = self.client.get( 

504 reverse("captcha-image", kwargs=dict(key=key)) 

505 ) 

506 self.fail() 

507 except ImproperlyConfigured: 

508 pass 

509 

510 settings.CAPTCHA_FONT_PATH = __current_test_mode_setting 

511 

512 def test_math_challenge(self): 

513 __current_test_mode_setting = settings.CAPTCHA_MATH_CHALLENGE_OPERATOR 

514 settings.CAPTCHA_MATH_CHALLENGE_OPERATOR = "~" 

515 helper = "captcha.helpers.math_challenge" 

516 challenge, response = settings._callable_from_string(helper)() 

517 

518 while settings.CAPTCHA_MATH_CHALLENGE_OPERATOR not in challenge: 

519 challenge, response = settings._callable_from_string(helper)() 

520 

521 self.assertEqual( 

522 response, 

523 str( 

524 eval( 

525 challenge.replace(settings.CAPTCHA_MATH_CHALLENGE_OPERATOR, "*")[ 

526 :-1 

527 ] 

528 ) 

529 ), 

530 ) 

531 settings.CAPTCHA_MATH_CHALLENGE_OPERATOR = __current_test_mode_setting 

532 

533 def test_get_from_pool(self): 

534 __current_test_get_from_pool_setting = settings.CAPTCHA_GET_FROM_POOL 

535 __current_test_get_from_pool_timeout_setting = ( 

536 settings.CAPTCHA_GET_FROM_POOL_TIMEOUT 

537 ) 

538 __current_test_timeout_setting = settings.CAPTCHA_TIMEOUT 

539 settings.CAPTCHA_GET_FROM_POOL = True 

540 settings.CAPTCHA_GET_FROM_POOL_TIMEOUT = 5 

541 settings.CAPTCHA_TIMEOUT = 90 

542 CaptchaStore.objects.all().delete() # Delete objects created during SetUp 

543 POOL_SIZE = 10 

544 CaptchaStore.create_pool(count=POOL_SIZE) 

545 self.assertEqual(CaptchaStore.objects.count(), POOL_SIZE) 

546 pool = CaptchaStore.objects.values_list("hashkey", flat=True) 

547 random_pick = CaptchaStore.pick() 

548 self.assertIn(random_pick, pool) 

549 # pick() should not create any extra captcha 

550 self.assertEqual(CaptchaStore.objects.count(), POOL_SIZE) 

551 settings.CAPTCHA_GET_FROM_POOL = __current_test_get_from_pool_setting 

552 settings.CAPTCHA_GET_FROM_POOL_TIMEOUT = ( 

553 __current_test_get_from_pool_timeout_setting 

554 ) 

555 settings.CAPTCHA_TIMEOUT = __current_test_timeout_setting 

556 

557 def test_captcha_create_pool(self): 

558 CaptchaStore.objects.all().delete() # Delete objects created during SetUp 

559 POOL_SIZE = 10 

560 management.call_command("captcha_create_pool", pool_size=POOL_SIZE, verbosity=0) 

561 self.assertEqual(CaptchaStore.objects.count(), POOL_SIZE) 

562 

563 def test_empty_pool_fallback(self): 

564 __current_test_get_from_pool_setting = settings.CAPTCHA_GET_FROM_POOL 

565 settings.CAPTCHA_GET_FROM_POOL = True 

566 CaptchaStore.objects.all().delete() # Delete objects created during SetUp 

567 with LogCapture() as log: 

568 CaptchaStore.pick() 

569 log.check( 

570 ("captcha.models", "ERROR", "Couldn't get a captcha from pool, generating") 

571 ) 

572 self.assertEqual(CaptchaStore.objects.count(), 1) 

573 settings.CAPTCHA_GET_FROM_POOL = __current_test_get_from_pool_setting 

574 

575 def test_serializer(self): 

576 r = self.client.post( 

577 reverse("captcha-test-serializer"), 

578 dict( 

579 captcha_code=self.default_store.response, 

580 captcha_hashkey=self.default_store.hashkey, 

581 ), 

582 ) 

583 self.assertEqual(r.status_code, 200) 

584 

585 def test_wrong_serializer(self): 

586 r = self.client.post( 

587 reverse("captcha-test-serializer"), 

588 dict( 

589 captcha_code="xxx", 

590 captcha_hashkey="wrong hash", 

591 ), 

592 ) 

593 self.assertEqual(r.status_code, 400) 

594 self.assertEqual(json.loads(r.content), {"error": "Invalid CAPTCHA"}) 

595 

596 def test_model_serializer(self): 

597 r = self.client.post( 

598 reverse("captcha-test-model-serializer"), 

599 dict( 

600 captcha_code=self.default_store.response, 

601 captcha_hashkey=self.default_store.hashkey, 

602 subject="xxx", 

603 sender="asasd@asdasd.com", 

604 ), 

605 ) 

606 self.assertEqual(r.status_code, 200) 

607 

608 def test_wrong_model_serializer(self): 

609 r = self.client.post( 

610 reverse("captcha-test-model-serializer"), 

611 dict( 

612 captcha_code="xxx", 

613 captcha_hashkey="wrong hash", 

614 subject="xxx", 

615 sender="asasd@asdasd.com", 

616 ), 

617 ) 

618 self.assertEqual(r.status_code, 400) 

619 self.assertEqual(json.loads(r.content), {"error": "Invalid CAPTCHA"}) 

620 

621 

622def trivial_challenge(): 

623 return "trivial", "trivial" 

624 

625 

626def random_color_challenge(index, string): 

627 return "#ffffff" 

628 

629 

630def random_char_challenge(): 

631 chars = "abcdefghijklmnopqrstuvwxyz" 

632 ret = chars[: settings.CAPTCHA_LENGTH] 

633 return ret.upper(), ret