Coverage for website/registrations/tests/test_views.py: 100.00%

453 statements  

« prev     ^ index     » next       coverage.py v7.6.7, created at 2025-08-14 10:31 +0000

1from unittest import mock 

2from unittest.mock import MagicMock, Mock 

3 

4from django.conf import settings 

5from django.contrib.auth import get_user_model 

6from django.core import mail 

7from django.http import HttpResponse 

8from django.template.defaultfilters import floatformat 

9from django.test import RequestFactory, TestCase, override_settings 

10from django.urls import reverse 

11from django.utils import timezone 

12 

13from freezegun import freeze_time 

14 

15from members.models import Member, Membership, Profile 

16from registrations import views 

17from registrations.models import Entry, Reference, Registration, Renewal 

18from registrations.views import RenewalFormView 

19 

20 

21def _get_mock_user(is_staff=False, is_authenticated=False, perms=None): 

22 user = mock.MagicMock() 

23 user.pk = 1 

24 user.is_staff = is_staff 

25 user.is_authenticated = is_authenticated 

26 

27 user.is_superuser = False 

28 user.user_permissions = perms 

29 user.has_perm = lambda x: x in perms 

30 

31 return user 

32 

33 

34class EntryAdminViewTest(TestCase): 

35 fixtures = ["members.json"] 

36 

37 @classmethod 

38 def setUpTestData(cls): 

39 cls.admin = Member.objects.get(pk=2) 

40 cls.admin.is_superuser = True 

41 cls.admin.save() 

42 

43 cls.member = Member.objects.get(pk=1) 

44 cls.member.email = "test@example.com" 

45 cls.member.save() 

46 

47 cls.membership = cls.member.membership_set.first() 

48 cls.membership.until = "2023-09-01" 

49 cls.membership.save() 

50 

51 cls.registration = Registration.objects.create( 

52 first_name="John", 

53 last_name="Doe", 

54 email="johndoe@example.com", 

55 programme="computingscience", 

56 student_number="s1234567", 

57 starting_year=2014, 

58 address_street="Heyendaalseweg 135", 

59 address_street2="", 

60 address_postal_code="6525AJ", 

61 address_city="Nijmegen", 

62 address_country="NL", 

63 phone_number="06123456789", 

64 birthday=timezone.now().replace(year=1990, day=1).date(), 

65 length=Entry.MEMBERSHIP_YEAR, 

66 contribution=7.5, 

67 membership_type=Membership.MEMBER, 

68 status=Entry.STATUS_REVIEW, 

69 ) 

70 

71 cls.renewal = Renewal.objects.create( 

72 member=cls.member, 

73 length=Entry.MEMBERSHIP_YEAR, 

74 membership_type=Membership.MEMBER, 

75 status=Entry.STATUS_REVIEW, 

76 contribution=7.5, 

77 ) 

78 

79 def setUp(self): 

80 self.client.force_login(self.admin) 

81 

82 @mock.patch("registrations.services.revert_registration") 

83 @mock.patch("registrations.services.reject_registration") 

84 @mock.patch("registrations.services.accept_registration") 

85 def test_registration_actions(self, mock_accept, mock_reject, mock_revert): 

86 url = reverse("registrations:admin-process", args=(self.registration.pk,)) 

87 

88 with self.subTest("accept"): 

89 self.client.post(url, data={"action": "accept"}) 

90 mock_accept.assert_called_once_with(self.registration, actor=self.admin) 

91 

92 with self.subTest("reject"): 

93 self.client.post(url, data={"action": "reject"}) 

94 mock_reject.assert_called_once_with(self.registration, actor=self.admin) 

95 

96 mail.outbox = [] 

97 with self.subTest("resend"): 

98 self.client.post(url, data={"action": "resend"}) 

99 self.assertEqual(len(mail.outbox), 1) 

100 

101 with self.subTest("revert"): 

102 self.client.post(url, data={"action": "revert"}) 

103 mock_revert.assert_called_once_with(self.registration, actor=self.admin) 

104 

105 with self.subTest("accept with non-unique email"): 

106 mock_accept.reset_mock() 

107 self.registration.email = self.member.email 

108 self.registration.save() 

109 self.client.post(url, data={"action": "accept"}) 

110 mock_accept.assert_not_called() 

111 

112 @mock.patch("registrations.services.revert_renewal") 

113 @mock.patch("registrations.services.reject_renewal") 

114 @mock.patch("registrations.services.accept_renewal") 

115 def test_renewal_actions(self, mock_accept, mock_reject, mock_revert): 

116 url = reverse("registrations:admin-process", args=(self.renewal.pk,)) 

117 

118 with self.subTest("accept"): 

119 self.client.post(url, data={"action": "accept"}) 

120 mock_accept.assert_called_once_with(self.renewal, actor=self.admin) 

121 

122 with self.subTest("reject"): 

123 self.client.post(url, data={"action": "reject"}) 

124 mock_reject.assert_called_once_with(self.renewal, actor=self.admin) 

125 

126 with self.subTest("resend"): 

127 response = self.client.post(url, data={"action": "resend"}, follow=True) 

128 self.assertContains(response, "Cannot resend renewal") 

129 self.assertEqual(len(mail.outbox), 0) 

130 

131 with self.subTest("revert"): 

132 self.client.post(url, data={"action": "revert"}) 

133 mock_revert.assert_called_once_with(self.renewal, actor=self.admin) 

134 

135 

136class ConfirmEmailViewTest(TestCase): 

137 @classmethod 

138 def setUpTestData(cls): 

139 cls.registration = Registration.objects.create( 

140 first_name="John", 

141 last_name="Doe", 

142 email="johndoe@example.com", 

143 programme="computingscience", 

144 student_number="s1234567", 

145 starting_year=2014, 

146 address_street="Heyendaalseweg 135", 

147 address_street2="", 

148 address_postal_code="6525AJ", 

149 address_city="Nijmegen", 

150 address_country="NL", 

151 phone_number="06123456789", 

152 birthday=timezone.now().replace(year=1990, day=1).date(), 

153 length=Entry.MEMBERSHIP_YEAR, 

154 contribution=7.5, 

155 membership_type=Membership.MEMBER, 

156 status=Entry.STATUS_CONFIRM, 

157 ) 

158 

159 def test_incorrect_uuid(self): 

160 response = self.client.get( 

161 reverse( 

162 "registrations:confirm-email", 

163 args=["11111111-2222-3333-4444-555555555555"], 

164 ) 

165 ) 

166 self.assertEqual(response.status_code, 404) 

167 

168 def test_confirm_email(self): 

169 with self.subTest("Member registration."): 

170 response = self.client.get( 

171 reverse("registrations:confirm-email", args=[self.registration.pk]) 

172 ) 

173 

174 self.assertContains(response, "Your email address has been confirmed.") 

175 self.registration.refresh_from_db() 

176 self.assertEqual(self.registration.status, Entry.STATUS_REVIEW) 

177 self.assertEqual(len(mail.outbox), 1) 

178 

179 self.registration.status = Entry.STATUS_CONFIRM 

180 self.registration.membership_type = Membership.BENEFACTOR 

181 self.registration.save() 

182 mail.outbox = [] 

183 

184 with self.subTest("Benefactor registration."): 

185 response = self.client.get( 

186 reverse( 

187 "registrations:confirm-email", 

188 args=[self.registration.pk], 

189 ) 

190 ) 

191 

192 self.assertContains(response, "Your email address has been confirmed.") 

193 self.registration.refresh_from_db() 

194 self.assertEqual(self.registration.status, Entry.STATUS_REVIEW) 

195 self.assertEqual(len(mail.outbox), 2) 

196 

197 self.registration.status = Entry.STATUS_CONFIRM 

198 self.registration.no_references = True 

199 self.registration.save() 

200 mail.outbox = [] 

201 

202 with self.subTest("Benefacor that doesn't need references."): 

203 response = self.client.get( 

204 reverse("registrations:confirm-email", args=[self.registration.pk]), 

205 follow=True, 

206 ) 

207 

208 self.assertContains(response, "Your email address has been confirmed.") 

209 self.registration.refresh_from_db() 

210 self.assertEqual(self.registration.status, Entry.STATUS_REVIEW) 

211 self.assertEqual(len(mail.outbox), 1) 

212 

213 def test_already_confirmed(self): 

214 self.registration.status = Entry.STATUS_REVIEW 

215 self.registration.save() 

216 

217 with self.subTest("In review."): 

218 response = self.client.get( 

219 reverse("registrations:confirm-email", args=[self.registration.pk]) 

220 ) 

221 

222 self.assertContains(response, "Your email address has been confirmed.") 

223 self.assertEqual(len(mail.outbox), 0) 

224 

225 self.registration.status = Entry.STATUS_ACCEPTED 

226 self.registration.save() 

227 

228 with self.subTest("Reviewed."): 

229 response = self.client.get( 

230 reverse("registrations:confirm-email", args=[self.registration.pk]) 

231 ) 

232 self.assertEqual(response.status_code, 404) 

233 self.assertEqual(len(mail.outbox), 0) 

234 

235 

236class BecomeAMemberViewTest(TestCase): 

237 def setUp(self): 

238 self.view = views.BecomeAMemberView() 

239 

240 def test_get_context_data(self): 

241 context = self.view.get_context_data() 

242 self.assertEqual(len(context), 3) 

243 self.assertEqual( 

244 context["year_fees"], 

245 floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_YEAR], 2), 

246 ) 

247 self.assertEqual( 

248 context["study_fees"], 

249 floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_STUDY], 2), 

250 ) 

251 

252 

253class BaseRegistrationFormViewTest(TestCase): 

254 def setUp(self): 

255 self.rf = RequestFactory() 

256 self.view = views.BaseRegistrationFormView() 

257 

258 @override_settings(GOOGLE_PLACES_API_KEY="hello") 

259 def test_get_context_data(self): 

260 self.view.request = self.rf.post("/") 

261 context = self.view.get_context_data() 

262 self.assertEqual(len(context), 5) 

263 self.assertEqual( 

264 context["year_fees"], 

265 floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_YEAR], 2), 

266 ) 

267 self.assertEqual( 

268 context["study_fees"], 

269 floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_STUDY], 2), 

270 ) 

271 self.assertEqual(context["google_api_key"], "hello") 

272 

273 @mock.patch("django.views.generic.FormView.get") 

274 def test_get(self, super_get): 

275 super_get.return_value = HttpResponse(status=200) 

276 

277 request = self.rf.get("/") 

278 request.user = _get_mock_user(is_authenticated=False) 

279 request.member = request.user 

280 response = self.view.get(request) 

281 self.assertEqual(response.status_code, 200) 

282 

283 request = self.rf.get("/") 

284 request.user = _get_mock_user(is_authenticated=True) 

285 request.member = request.user 

286 response = self.view.get(request) 

287 self.assertEqual(response.status_code, 302) 

288 self.assertEqual(response.url, reverse("registrations:renew")) 

289 

290 @mock.patch("registrations.emails.send_registration_email_confirmation") 

291 def test_form_valid(self, send_mail): 

292 mock_form = MagicMock() 

293 

294 return_value = self.view.form_valid(mock_form) 

295 

296 mock_form.save.assert_called_once_with() 

297 self.assertEqual(return_value.status_code, 302) 

298 self.assertEqual(return_value.url, reverse("registrations:register-success")) 

299 

300 send_mail.assert_called_once_with(mock_form.instance) 

301 

302 

303class MemberRegistrationFormViewTest(TestCase): 

304 def setUp(self): 

305 self.rf = RequestFactory() 

306 self.view = views.MemberRegistrationFormView() 

307 

308 @override_settings( 

309 THALIA_PAY_ENABLED_PAYMENT_METHOD=True, THALIA_PAY_FOR_NEW_MEMBERS=True 

310 ) 

311 def test_get_context_data_tpay_enabled(self): 

312 context = self.view.get_context_data(form=MagicMock()) 

313 self.assertTrue(context["tpay_enabled"]) 

314 

315 @override_settings( 

316 THALIA_PAY_ENABLED_PAYMENT_METHOD=False, THALIA_PAY_FOR_NEW_MEMBERS=False 

317 ) 

318 def test_get_context_data_tpay_disabled(self): 

319 context = self.view.get_context_data(form=MagicMock()) 

320 self.assertFalse(context["tpay_enabled"]) 

321 

322 @mock.patch("django.views.generic.FormView.post") 

323 def test_post(self, super_post): 

324 request = self.rf.post("/") 

325 request.user = _get_mock_user() 

326 request.member = request.user 

327 request.member.pk = 2 

328 self.view.request = request 

329 

330 self.view.post(request) 

331 

332 request = super_post.call_args[0][0] 

333 self.assertEqual(request.POST["membership_type"], Membership.MEMBER) 

334 

335 

336class BenefactorRegistrationFormViewTest(TestCase): 

337 def setUp(self): 

338 self.rf = RequestFactory() 

339 self.view = views.BenefactorRegistrationFormView() 

340 

341 @override_settings( 

342 THALIA_PAY_ENABLED_PAYMENT_METHOD=True, THALIA_PAY_FOR_NEW_MEMBERS=True 

343 ) 

344 def test_get_context_data_tpay_enabled(self): 

345 context = self.view.get_context_data(form=MagicMock()) 

346 self.assertTrue(context["tpay_enabled"]) 

347 

348 @override_settings( 

349 THALIA_PAY_ENABLED_PAYMENT_METHOD=False, THALIA_PAY_FOR_NEW_MEMBERS=False 

350 ) 

351 def test_get_context_data_tpay_disabled(self): 

352 context = self.view.get_context_data(form=MagicMock()) 

353 self.assertFalse(context["tpay_enabled"]) 

354 

355 @mock.patch("django.views.generic.FormView.post") 

356 def test_post(self, super_post): 

357 request = self.rf.post("/", {}) 

358 request.user = _get_mock_user() 

359 request.member = request.user 

360 request.member.pk = 2 

361 self.view.request = request 

362 

363 with self.subTest("No iCIS employee"): 

364 self.view.post(request) 

365 

366 request = super_post.call_args[0][0] 

367 self.assertEqual(request.POST["membership_type"], Membership.BENEFACTOR) 

368 self.assertEqual(request.POST["length"], Entry.MEMBERSHIP_YEAR) 

369 self.assertEqual(request.POST["remarks"], "") 

370 

371 request = self.rf.post("/", {"icis_employee": True}) 

372 request.user = _get_mock_user() 

373 request.member = request.user 

374 request.member.pk = 2 

375 self.view.request = request 

376 

377 with self.subTest("An iCIS employee"): 

378 self.view.post(request) 

379 

380 request = super_post.call_args[0][0] 

381 self.assertEqual(request.POST["membership_type"], Membership.BENEFACTOR) 

382 self.assertEqual(request.POST["length"], Entry.MEMBERSHIP_YEAR) 

383 self.assertEqual(request.POST["remarks"], "Registered as iCIS employee") 

384 

385 

386class RenewalFormViewTest(TestCase): 

387 def setUp(self): 

388 self.rf = RequestFactory() 

389 self.view = views.RenewalFormView() 

390 

391 def test_get_context_data(self): 

392 membership = Membership(pk=2, type=Membership.MEMBER) 

393 self.view.request = MagicMock() 

394 

395 with mock.patch("members.models.Membership.objects") as _membership_qs: 

396 Membership.objects.filter().exists.return_value = True 

397 

398 with mock.patch("registrations.models.Renewal.objects") as _renewal_qs: 

399 Renewal.objects.filter().last.return_value = None 

400 

401 context = self.view.get_context_data(form=MagicMock()) 

402 self.assertEqual(len(context), 8) 

403 self.assertEqual( 

404 context["year_fees"], 

405 floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_YEAR], 2), 

406 ) 

407 self.assertEqual( 

408 context["study_fees"], 

409 floatformat(settings.MEMBERSHIP_PRICES[Entry.MEMBERSHIP_STUDY], 2), 

410 ) 

411 self.assertEqual(context["was_member"], True) 

412 

413 Membership.objects.filter().exists.return_value = False 

414 context = self.view.get_context_data(form=MagicMock()) 

415 self.assertEqual(context["was_member"], False) 

416 

417 with self.subTest("With latest membership"): 

418 self.view.request.member.latest_membership = membership 

419 

420 context = self.view.get_context_data(form=MagicMock()) 

421 self.assertEqual(context["latest_membership"], membership) 

422 

423 with self.subTest("Without latest membership"): 

424 self.view.request.member.latest_membership = None 

425 

426 context = self.view.get_context_data(form=MagicMock()) 

427 self.assertEqual(context["latest_membership"], None) 

428 

429 with self.subTest("With renewal"): 

430 renewal = Renewal.objects.create( 

431 member=self.view.request.member, status=Entry.STATUS_ACCEPTED 

432 ) 

433 Renewal.objects.filter().last.return_value = renewal 

434 

435 context = self.view.get_context_data(form=MagicMock()) 

436 self.assertEqual(context["latest_renewal"], renewal) 

437 

438 def test_get_form(self): 

439 self.view.request = self.rf.get("/") 

440 

441 self.view.request.member = None 

442 form = self.view.get_form() 

443 self.assertFalse(Entry.MEMBERSHIP_YEAR in form.fields["length"].choices) 

444 

445 self.view.request.member = MagicMock() 

446 self.view.request.member.latest_membership = None 

447 form = self.view.get_form() 

448 self.assertFalse(Entry.MEMBERSHIP_YEAR in form.fields["length"].choices) 

449 

450 self.view.request.member.latest_membership = Membership(until=None) 

451 form = self.view.get_form() 

452 self.assertFalse(Entry.MEMBERSHIP_YEAR in form.fields["length"].choices) 

453 

454 self.view.request.member.latest_membership = Membership( 

455 until=timezone.now().date() 

456 ) 

457 form = self.view.get_form() 

458 self.assertEqual(Entry.MEMBERSHIP_YEAR, form.fields["length"].choices[1][0]) 

459 

460 @mock.patch("django.views.generic.FormView.post") 

461 def test_post(self, super_post): 

462 with mock.patch("members.models.Membership.objects"): 

463 Membership.objects.filter().exists.return_value = False 

464 with self.subTest("Member type"): 

465 request = self.rf.post("/", {"membership_type": Membership.MEMBER}) 

466 request.member = MagicMock() 

467 request.member.pk = 2 

468 self.view.request = request 

469 request.member.latest_membership.study_long = False 

470 

471 self.view.post(request) 

472 

473 request = super_post.call_args[0][0] 

474 self.assertEqual(request.POST["member"], 2) 

475 self.assertEqual(request.POST["remarks"], "") 

476 self.assertEqual(request.POST["no_references"], True) 

477 

478 with self.subTest("Forced benefactor type"): 

479 request = self.rf.post("/", {"membership_type": Membership.MEMBER}) 

480 request.member = MagicMock() 

481 request.member.pk = 2 

482 self.view.request = request 

483 

484 request.member.latest_membership.type = Membership.BENEFACTOR 

485 self.view.post(request) 

486 

487 request = super_post.call_args[0][0] 

488 self.assertEqual(request.POST["member"], 2) 

489 self.assertEqual(request.POST["membership_type"], Membership.BENEFACTOR) 

490 self.assertEqual(request.POST["length"], Entry.MEMBERSHIP_YEAR) 

491 self.assertEqual(request.POST["no_references"], False) 

492 

493 with self.subTest("Detects old memberships"): 

494 request = self.rf.post("/", {"membership_type": Membership.BENEFACTOR}) 

495 request.member = MagicMock() 

496 request.member.pk = 2 

497 self.view.request = request 

498 

499 Membership.objects.filter().exists.return_value = True 

500 self.view.post(request) 

501 request = super_post.call_args[0][0] 

502 self.assertEqual( 

503 request.POST["remarks"], "Was a Thalia member in the past." 

504 ) 

505 self.assertEqual(request.POST["no_references"], True) 

506 

507 with self.subTest("Adds iCIS remark"): 

508 request = self.rf.post( 

509 "/", 

510 {"membership_type": Membership.BENEFACTOR, "icis_employee": True}, 

511 ) 

512 request.member = MagicMock() 

513 request.member.pk = 2 

514 self.view.request = request 

515 

516 Membership.objects.filter().exists.return_value = False 

517 self.view.post(request) 

518 request = super_post.call_args[0][0] 

519 self.assertEqual( 

520 request.POST["remarks"], "Registered as iCIS employee." 

521 ) 

522 self.assertEqual(request.POST["no_references"], True) 

523 

524 @mock.patch("registrations.emails.send_references_information_message") 

525 @mock.patch("registrations.emails.send_new_renewal_board_message") 

526 def test_form_valid(self, board_mail, references_mail): 

527 mock_form = Mock(spec=RenewalFormView) 

528 member = Member( 

529 email="test@example.org", 

530 first_name="John", 

531 last_name="Doe", 

532 profile=Profile(), 

533 ) 

534 

535 renewal = Renewal(pk=0, member=member) 

536 mock_form.save = MagicMock(return_value=renewal) 

537 

538 with self.subTest("No references required"): 

539 renewal.no_references = True 

540 return_value = self.view.form_valid(mock_form) 

541 board_mail.assert_called_once_with(renewal) 

542 self.assertFalse(references_mail.called) 

543 

544 self.assertEqual(return_value.status_code, 302) 

545 self.assertEqual(return_value.url, reverse("registrations:renew-success")) 

546 

547 board_mail.reset_mock() 

548 

549 with self.subTest("References required"): 

550 renewal.no_references = False 

551 return_value = self.view.form_valid(mock_form) 

552 board_mail.assert_called_once_with(renewal) 

553 references_mail.assert_called_once_with(renewal) 

554 

555 self.assertEqual(return_value.status_code, 302) 

556 self.assertEqual(return_value.url, reverse("registrations:renew-success")) 

557 

558 

559class NewYearRenewalFormViewTest(TestCase): 

560 fixtures = ["members.json"] 

561 

562 @classmethod 

563 def setUpTestData(cls): 

564 cls.member = Member.objects.get(pk=1) 

565 cls.member.profile.is_minimized = False 

566 cls.member.profile.save() 

567 

568 cls.membership = Membership.objects.create( 

569 user=cls.member, 

570 type=Membership.MEMBER, 

571 since=timezone.datetime(year=2022, month=9, day=1).date(), 

572 until=timezone.datetime(year=2023, month=9, day=1).date(), 

573 study_long=True, 

574 ) 

575 

576 def setUp(self): 

577 self.client.force_login(self.member) 

578 

579 @freeze_time("2023-08-01") 

580 def test_prolong_membership_in_august(self): 

581 response = self.client.post( 

582 reverse("registrations:renew-studylong"), 

583 data={"privacy_policy": True, "extension": True}, 

584 ) 

585 self.assertRedirects(response, reverse("registrations:renew-studylong-success")) 

586 self.membership.refresh_from_db() 

587 

588 self.assertEqual( 

589 self.membership.until, timezone.datetime(year=2024, month=9, day=1).date() 

590 ) 

591 

592 @freeze_time("2023-07-31") 

593 def test_cannot_prolong_membership_before_august_or_when_minimized(self): 

594 response = self.client.post( 

595 reverse("registrations:renew-studylong"), 

596 data={"privacy_policy": True, "extension": True}, 

597 ) 

598 self.assertRedirects(response, reverse("registrations:renew")) 

599 

600 profile = self.member.profile 

601 profile.student_number = None 

602 profile.phone_number = None 

603 profile.address_street = None 

604 profile.address_street2 = None 

605 profile.address_postal_code = None 

606 profile.address_city = None 

607 profile.address_country = None 

608 profile.birthday = None 

609 profile.emergency_contact_phone_number = None 

610 profile.emergency_contact = None 

611 profile.is_minimized = True 

612 self.member.profile.save() 

613 

614 with freeze_time("2023-08-01"): 

615 response = self.client.post( 

616 reverse("registrations:renew-studylong"), 

617 data={"privacy_policy": True, "extension": True}, 

618 ) 

619 

620 self.assertRedirects(response, reverse("registrations:renew")) 

621 

622 @freeze_time("2023-09-01") 

623 def test_prolong_membership_in_september(self): 

624 response = self.client.post( 

625 reverse("registrations:renew-studylong"), 

626 data={"privacy_policy": True, "extension": True}, 

627 ) 

628 self.assertRedirects(response, reverse("registrations:renew-studylong-success")) 

629 self.membership.refresh_from_db() 

630 self.assertEqual( 

631 self.membership.until, timezone.datetime(year=2024, month=9, day=1).date() 

632 ) 

633 

634 

635@override_settings(SUSPEND_SIGNALS=True) 

636class ReferenceCreateViewTest(TestCase): 

637 """Test for the ReferenceCreateView.""" 

638 

639 fixtures = ["members.json"] 

640 

641 @classmethod 

642 def setUpTestData(cls): 

643 cls.login_user = Member.objects.filter(last_name="Wiggers").first() 

644 cls.registration = Registration.objects.create( 

645 first_name="John", 

646 last_name="Doe", 

647 email="johndoe@example.com", 

648 programme="computingscience", 

649 student_number="s1234567", 

650 starting_year=2014, 

651 address_street="Heyendaalseweg 135", 

652 address_street2="", 

653 address_postal_code="6525AJ", 

654 address_city="Nijmegen", 

655 address_country="NL", 

656 phone_number="06123456789", 

657 birthday=timezone.now().replace(year=1990, day=1), 

658 length=Entry.MEMBERSHIP_YEAR, 

659 contribution=7.50, 

660 membership_type=Membership.BENEFACTOR, 

661 status=Entry.STATUS_CONFIRM, 

662 ) 

663 cls.new_user = get_user_model().objects.create_user( 

664 username="username", first_name="Johnny", last_name="Test" 

665 ) 

666 cls.renewal = Renewal.objects.create( 

667 length=Entry.MEMBERSHIP_YEAR, 

668 contribution=7.50, 

669 membership_type=Membership.BENEFACTOR, 

670 status=Entry.STATUS_CONFIRM, 

671 member=cls.new_user, 

672 ) 

673 

674 def setUp(self): 

675 self.rf = RequestFactory() 

676 self.view = views.ReferenceCreateView() 

677 self.client.force_login(self.login_user) 

678 

679 def test_not_logged_in(self): 

680 """ 

681 If there is no logged-in user they should redirect 

682 to the authentication page 

683 """ 

684 self.client.logout() 

685 

686 response = self.client.get( 

687 reverse("registrations:reference", args=(self.registration.pk,)), 

688 follow=True, 

689 ) 

690 self.assertEqual(200, response.status_code) 

691 self.assertEqual( 

692 [ 

693 ( 

694 "/user/account/login/?next=" 

695 + reverse("registrations:reference", args=(self.registration.pk,)), 

696 302, 

697 ) 

698 ], 

699 response.redirect_chain, 

700 ) 

701 

702 def test_not_a_current_member(self): 

703 """ 

704 If the logged-in user is not a member they should not be able to visit 

705 this page 

706 """ 

707 self.client.logout() 

708 self.client.force_login(self.new_user) 

709 

710 response = self.client.get( 

711 reverse("registrations:reference", args=(self.registration.pk,)) 

712 ) 

713 self.assertEqual(403, response.status_code) 

714 

715 def test_entry_does_not_exist(self): 

716 """If the registration/renewal does not exist a 404 should be shown.""" 

717 response = self.client.get( 

718 reverse( 

719 "registrations:reference", 

720 args=("00000000-0000-0000-0000-000000000000",), 

721 ) 

722 ) 

723 self.assertEqual(404, response.status_code) 

724 

725 def test_entry_no_references_required(self): 

726 """ 

727 If the registration/renewal does not require references 

728 a 404 should be shown 

729 """ 

730 self.registration.no_references = True 

731 self.registration.save() 

732 

733 response = self.client.get( 

734 reverse("registrations:reference", args=(self.registration.pk,)) 

735 ) 

736 self.assertEqual(404, response.status_code) 

737 

738 def test_entry_no_benefactor(self): 

739 """ 

740 If the registration/renewal is not a the benefactor type 

741 a 404 should be shown 

742 """ 

743 self.registration.membership_type = Membership.MEMBER 

744 self.registration.save() 

745 

746 response = self.client.get( 

747 reverse("registrations:reference", args=(self.registration.pk,)) 

748 ) 

749 self.assertEqual(404, response.status_code) 

750 

751 def test_entry_shows_info(self): 

752 """ 

753 If everything is alright the info and submission buttons should 

754 be shown 

755 """ 

756 with self.subTest("Registration"): 

757 response = self.client.get( 

758 reverse("registrations:reference", args=(self.registration.pk,)) 

759 ) 

760 self.assertEqual(200, response.status_code) 

761 self.assertEqual("John Doe", response.context["name"]) 

762 self.assertEqual(False, response.context["success"]) 

763 self.assertContains( 

764 response, "<strong>John Doe</strong> wants to become a benefactor" 

765 ) 

766 

767 with self.subTest("Renewal"): 

768 response = self.client.get( 

769 reverse("registrations:reference", args=(self.renewal.pk,)) 

770 ) 

771 self.assertEqual(200, response.status_code) 

772 self.assertEqual("Johnny Test", response.context["name"]) 

773 self.assertEqual(False, response.context["success"]) 

774 self.assertContains( 

775 response, "<strong>Johnny Test</strong> wants to become a benefactor" 

776 ) 

777 

778 def test_entry_saves_correctly(self): 

779 """ 

780 If a entry is saved it should redirect to the success page 

781 which should show the right content. And the Reference object 

782 should be saved. 

783 """ 

784 response = self.client.post( 

785 reverse("registrations:reference", args=(self.registration.pk,)), 

786 follow=True, 

787 ) 

788 self.assertEqual(200, response.status_code) 

789 self.assertEqual( 

790 [ 

791 ( 

792 reverse( 

793 "registrations:reference-success", args=(self.registration.pk,) 

794 ), 

795 302, 

796 ) 

797 ], 

798 response.redirect_chain, 

799 ) 

800 self.assertEqual("John Doe", response.context["name"]) 

801 self.assertEqual(True, response.context["success"]) 

802 self.assertContains(response, "Your reference has been saved.") 

803 

804 self.assertTrue( 

805 Reference.objects.filter( 

806 member=self.login_user, entry=self.registration 

807 ).exists() 

808 ) 

809 

810 def test_entry_reference_exists(self): 

811 """ 

812 If there is already a reference for an entry then the page should 

813 show an error and not redirect. 

814 """ 

815 Reference.objects.create(member=self.login_user, entry=self.registration) 

816 

817 response = self.client.post( 

818 reverse("registrations:reference", args=(self.registration.pk,)), 

819 follow=True, 

820 ) 

821 self.assertEqual(200, response.status_code) 

822 self.assertEqual([], response.redirect_chain) 

823 self.assertEqual( 

824 {"__all__": ["You've already given a reference for this person."]}, 

825 response.context["form"].errors, 

826 ) 

827 self.assertEqual(False, response.context["success"]) 

828 self.assertContains( 

829 response, "You&#x27;ve already given a reference for this person." 

830 )