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

256 statements  

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

1from django.contrib.auth import get_user_model 

2from django.core.exceptions import ValidationError 

3from django.test import TestCase, override_settings 

4from django.utils import timezone 

5from django.utils.translation import gettext_lazy as _ 

6 

7from freezegun import freeze_time 

8 

9from members.models import Member, Membership, Profile 

10from registrations import payables 

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

12 

13 

14@override_settings(SUSPEND_SIGNALS=True) 

15class EntryTest(TestCase): 

16 fixtures = ["members.json"] 

17 

18 @classmethod 

19 def setUpTestData(cls): 

20 cls.registration = Registration.objects.create( 

21 first_name="John", 

22 last_name="Doe", 

23 email="johndoe@example.com", 

24 programme="computingscience", 

25 starting_year=2014, 

26 address_street="Heyendaalseweg 135", 

27 address_street2="", 

28 address_postal_code="6525AJ", 

29 address_city="Nijmegen", 

30 address_country="NL", 

31 phone_number="06123456789", 

32 birthday=timezone.now().replace(year=1990), 

33 length=Entry.MEMBERSHIP_YEAR, 

34 membership_type=Membership.MEMBER, 

35 status=Entry.STATUS_CONFIRM, 

36 ) 

37 cls.member = Member.objects.filter(last_name="Wiggers").first() 

38 cls.renewal = Renewal( 

39 member=cls.member, 

40 length=Entry.MEMBERSHIP_STUDY, 

41 membership_type=Membership.MEMBER, 

42 ) 

43 

44 def setUp(self) -> None: 

45 payables.register() 

46 

47 def test_str(self): 

48 entry = Entry(registration=self.registration) 

49 self.assertEqual( 

50 str(entry), 

51 "{} {} ({})".format( # noqa: UP032 

52 self.registration.first_name, 

53 self.registration.last_name, 

54 self.registration.email, 

55 ), 

56 ) 

57 

58 entry = Entry(renewal=self.renewal) 

59 self.assertEqual( 

60 str(entry), 

61 f"{self.member.first_name} {self.member.last_name} ({self.member.email})", 

62 ) 

63 

64 @freeze_time("2019-01-01") 

65 def test_save(self): 

66 entry = Entry(length=Entry.MEMBERSHIP_YEAR, registration=self.registration) 

67 

68 entry.status = Entry.STATUS_ACCEPTED 

69 test_value = timezone.now().replace(year=1996) 

70 entry.updated_at = test_value 

71 

72 with self.subTest("Accepted should not update `updated_at`"): 

73 entry.save() 

74 self.assertEqual(entry.updated_at, test_value) 

75 

76 entry.status = Entry.STATUS_REJECTED 

77 

78 with self.subTest("Rejected should not update `updated_at`"): 

79 entry.save() 

80 self.assertEqual(entry.updated_at, test_value) 

81 

82 entry.status = Entry.STATUS_REVIEW 

83 

84 with self.subTest("Review should update `updated_at`"): 

85 entry.save() 

86 self.assertNotEqual(entry.updated_at, test_value) 

87 

88 entry.length = Entry.MEMBERSHIP_STUDY 

89 

90 with self.subTest("Type `Member` should not change length"): 

91 entry.save() 

92 self.assertEqual(entry.length, Entry.MEMBERSHIP_STUDY) 

93 

94 entry.membership_type = Membership.BENEFACTOR 

95 

96 def test_clean(self): 

97 entry = Entry(registration=self.registration) 

98 

99 entry.contribution = None 

100 entry.length = Entry.MEMBERSHIP_YEAR 

101 entry.membership_type = Membership.BENEFACTOR 

102 

103 with self.subTest("Type `Benefactor` should require contribution"): 

104 with self.assertRaises(ValidationError): 

105 entry.clean() 

106 entry.contribution = 7.5 

107 entry.clean() 

108 

109 with self.subTest("Type `Benefactor` should require year length"): 

110 entry.length = Entry.MEMBERSHIP_STUDY 

111 with self.assertRaises(ValidationError): 

112 entry.clean() 

113 

114 

115@override_settings(SUSPEND_SIGNALS=True) 

116@freeze_time("2019-01-01") 

117class RegistrationTest(TestCase): 

118 """Tests registrations.""" 

119 

120 @classmethod 

121 def setUpTestData(cls): 

122 cls.registration = Registration.objects.create( 

123 first_name="John", 

124 last_name="Doe", 

125 email="johndoe@example.com", 

126 programme="computingscience", 

127 starting_year=2014, 

128 address_street="Heyendaalseweg 135", 

129 address_street2="", 

130 address_postal_code="6525AJ", 

131 address_city="Nijmegen", 

132 address_country="NL", 

133 phone_number="06123456789", 

134 student_number="s1234567", 

135 birthday=timezone.now().replace(year=1990), 

136 length=Entry.MEMBERSHIP_YEAR, 

137 membership_type=Membership.MEMBER, 

138 status=Entry.STATUS_CONFIRM, 

139 contribution=7.5, 

140 ) 

141 

142 def setUp(self): 

143 self.registration.refresh_from_db() 

144 

145 def test_str(self): 

146 self.assertEqual( 

147 str(self.registration), 

148 "{} {} ({})".format( # noqa: UP032 

149 self.registration.first_name, 

150 self.registration.last_name, 

151 self.registration.email, 

152 ), 

153 ) 

154 

155 def test_get_full_name(self): 

156 self.assertEqual( 

157 self.registration.get_full_name(), 

158 f"{self.registration.first_name} {self.registration.last_name}", 

159 ) 

160 

161 def test_full_clean_works(self): 

162 self.registration.full_clean() 

163 

164 def test_clean_works(self): 

165 self.registration.clean() 

166 

167 def test_unique_email_user(self): 

168 self.registration.clean() 

169 user = get_user_model().objects.create_user("johnnydoe", "johndoe@example.com") 

170 

171 with self.assertRaises(ValidationError): 

172 self.registration.clean() 

173 

174 user.delete() 

175 self.registration.clean() 

176 Registration.objects.create( 

177 length=Entry.MEMBERSHIP_YEAR, 

178 first_name="John", 

179 last_name="Doe", 

180 birthday=timezone.now().replace(year=1990), 

181 email="johndoe@example.com", 

182 ) 

183 

184 with self.assertRaises(ValidationError): 

185 self.registration.clean() 

186 

187 def test_require_past_birthday(self): 

188 registration = Registration.objects.create( 

189 length=Entry.MEMBERSHIP_YEAR, 

190 first_name="John", 

191 last_name="Doe", 

192 birthday=timezone.now().date() + timezone.timedelta(weeks=52), 

193 ) 

194 

195 with self.assertRaises(ValidationError): 

196 registration.clean() 

197 

198 def test_unique_student_number_user(self): 

199 self.registration.student_number = "s1234567" 

200 self.registration.clean() 

201 

202 user = get_user_model().objects.create_user("johnnydoe", "johndoe2@example.com") 

203 Profile.objects.create(user=user, student_number="s1234567") 

204 

205 with self.assertRaises(ValidationError): 

206 self.registration.clean() 

207 

208 user.delete() 

209 self.registration.clean() 

210 Registration.objects.create( 

211 length=Entry.MEMBERSHIP_YEAR, 

212 first_name="John", 

213 last_name="Doe", 

214 birthday=timezone.now().replace(year=1990), 

215 student_number="s1234567", 

216 ) 

217 

218 with self.assertRaises(ValidationError): 

219 self.registration.clean() 

220 

221 def test_require_student_number_members(self): 

222 with self.subTest("No student number entered"): 

223 self.registration.student_number = None 

224 with self.assertRaisesMessage( 

225 ValidationError, "{'student_number': ['This field is required.']}" 

226 ): 

227 self.registration.clean() 

228 

229 with self.subTest("Type is benefactor"): 

230 self.registration.student_number = None 

231 self.registration.membership_type = Membership.BENEFACTOR 

232 self.registration.contribution = 7.5 

233 self.registration.clean() 

234 

235 def test_unique_username_user(self): 

236 self.registration.username = "johndoe" 

237 self.registration.clean() 

238 

239 get_user_model().objects.create_user("johndoe", "johndoe@example.com") 

240 

241 with self.assertRaises(ValidationError): 

242 self.registration.clean() 

243 

244 def test_require_programme_members(self): 

245 self.registration.programme = None 

246 with self.assertRaisesMessage( 

247 ValidationError, "{'programme': ['This field is required.']}" 

248 ): 

249 self.registration.clean() 

250 self.registration.membership_type = Membership.BENEFACTOR 

251 self.registration.contribution = 7.5 

252 self.registration.clean() 

253 

254 def test_require_starting_year_members(self): 

255 self.registration.starting_year = None 

256 with self.assertRaisesMessage( 

257 ValidationError, "{'starting_year': ['This field is required.']}" 

258 ): 

259 self.registration.clean() 

260 self.registration.membership_type = Membership.BENEFACTOR 

261 self.registration.contribution = 7.5 

262 self.registration.clean() 

263 

264 def test_require_bank_details(self): 

265 self.registration.direct_debit = True 

266 

267 with self.assertRaises(ValidationError): 

268 self.registration.clean() 

269 

270 self.registration.iban = "BE91ABNA0417164300" 

271 

272 with self.assertRaises(ValidationError): 

273 self.registration.clean() 

274 

275 self.registration.initials = "J" 

276 

277 with self.assertRaises(ValidationError): 

278 self.registration.clean() 

279 

280 self.registration.signature = "base64,png" 

281 

282 with self.assertRaises(ValidationError): 

283 self.registration.clean() 

284 

285 self.registration.bic = "ADSGBEBZ" 

286 

287 self.registration.clean() 

288 

289 def test_generate_default_username(self): 

290 registration = Registration(first_name="John", last_name="Doe") 

291 

292 self.assertEqual(registration._generate_default_username(), "jdoe") 

293 

294 registration.last_name = ( 

295 "famgtjbblvpcxpebclsjfamgtjbblvpcxpebcl" 

296 "sjfamgtjbblvpcxpebclsjfamgtjbblvpcxpeb" 

297 "clsjfamgtjbblvpcxpebclsjfamgtjbblvpcxp" 

298 "ebclsjfamgtjbblvpcxpebclsjfamgtjbblvpc" 

299 "xpebclsj" 

300 ) 

301 

302 self.assertEqual( 

303 registration._generate_default_username(), 

304 "jfamgtjbblvpcxpebclsjfamgtjbblvpcxpebclsjf" 

305 "amgtjbblvpcxpebclsjfamgtjbblvpcxpebclsjfam" 

306 "gtjbblvpcxpebclsjfamgtjbblvpcxpebclsjfamgt" 

307 "jbblvpcxpebclsjfamgtjbbl", 

308 ) 

309 

310 possibilities = [ 

311 ("Bram", "in 't Zandt", "bintzandt"), 

312 ("Astrid", "van der Jagt", "avanderjagt"), 

313 ("Bart", "van den Boom", "bvandenboom"), 

314 ("Richard", "van Ginkel", "rvanginkel"), 

315 ("Edwin", "de Koning", "edekoning"), 

316 ("Martijn", "de la Cosine", "mdelacosine"), 

317 ("Robert", "Hissink Muller", "rhissinkmuller"), 

318 ("Robert", "Al-Malak", "ralmalak"), 

319 ("Arthur", "Domelé", "adomele"), 

320 ("Ben", "Brücker", "bbrucker"), 

321 ] 

322 

323 for first_name, last_name, username in possibilities: 

324 (registration._generate_default_username(),) 

325 self.assertEqual( 

326 Registration( 

327 first_name=first_name, last_name=last_name 

328 )._generate_default_username(), 

329 username, 

330 ) 

331 

332 def test_get_username(self): 

333 self.assertEqual( 

334 Registration(first_name="John", last_name="Doe").get_username(), 

335 "jdoe", 

336 ) 

337 self.assertEqual( 

338 Registration( 

339 first_name="John", last_name="Doe", username="johnny" 

340 ).get_username(), 

341 "johnny", 

342 ) 

343 

344 def test_check_user_is_unique(self): 

345 user = get_user_model().objects.create_user( 

346 "johnnydoe", "johnnydoe@example.com" 

347 ) 

348 

349 registration = Registration.objects.create( 

350 first_name="John", 

351 last_name="Doe", 

352 email="johndoe@example.com", 

353 programme="computingscience", 

354 student_number="s1234567", 

355 starting_year=2014, 

356 address_street="Heyendaalseweg 135", 

357 address_street2="", 

358 address_postal_code="6525AJ", 

359 address_city="Nijmegen", 

360 address_country="NL", 

361 phone_number="06123456789", 

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

363 length=Entry.MEMBERSHIP_YEAR, 

364 contribution=7.5, 

365 membership_type=Membership.MEMBER, 

366 status=Entry.STATUS_CONFIRM, 

367 ) 

368 

369 self.assertEqual(registration.check_user_is_unique(), True) 

370 

371 user.username = "jdoe" 

372 user.save() 

373 

374 self.assertEqual(registration.check_user_is_unique(), False) 

375 

376 user.username = "johnnydoe" 

377 user.email = "johndoe@example.com" 

378 user.save() 

379 

380 self.assertEqual(registration.check_user_is_unique(), False) 

381 

382 user.username = "jdoe" 

383 user.email = "unique@example.com" 

384 user.save() 

385 

386 registration.username = "unique_username" 

387 

388 self.assertEqual(registration.check_user_is_unique(), True) 

389 

390 def test_foreign_bankaccount_without_bic(self): 

391 self.registration.initials = "J" 

392 self.registration.signature = "base64,png" 

393 self.registration.iban = "XX91ABNA0123456789" 

394 self.registration.bic = "" 

395 self.registration.clean() 

396 

397 

398@override_settings(SUSPEND_SIGNALS=True) 

399@freeze_time("2019-01-01") 

400class RenewalTest(TestCase): 

401 fixtures = ["members.json"] 

402 

403 def setUp(self): 

404 self.member = Member.objects.filter(last_name="Wiggers").first() 

405 self.renewal = Renewal( 

406 member=self.member, 

407 length=Entry.MEMBERSHIP_STUDY, 

408 contribution=8, 

409 membership_type=Membership.MEMBER, 

410 ) 

411 

412 def test_str(self): 

413 self.assertEqual( 

414 str(self.renewal), 

415 f"{self.member.first_name} {self.member.last_name} ({self.member.email})", 

416 ) 

417 

418 def test_save(self): 

419 self.renewal.pk = 2 

420 self.renewal.status = Entry.STATUS_ACCEPTED 

421 self.renewal.save() 

422 

423 self.assertEqual(self.renewal.status, Entry.STATUS_ACCEPTED) 

424 

425 self.renewal.pk = None 

426 self.renewal.save() 

427 

428 self.assertEqual(self.renewal.status, Entry.STATUS_REVIEW) 

429 

430 def test_clean_works(self): 

431 self.member.membership_set.all().delete() 

432 self.renewal.clean() 

433 

434 def test_existing_renewal_in_review(self): 

435 Renewal.objects.create( 

436 member=self.member, 

437 length=Entry.MEMBERSHIP_STUDY, 

438 membership_type=Membership.MEMBER, 

439 ) 

440 

441 with self.assertRaises(ValidationError): 

442 self.renewal.clean() 

443 

444 try: 

445 self.renewal.clean() 

446 except ValidationError as e: 

447 self.assertEqual( 

448 e.message, _("You already have a renewal request queued for review.") 

449 ) 

450 

451 def test_not_within_renew_period(self): 

452 membership = self.member.latest_membership 

453 membership.until = timezone.now().date() + timezone.timedelta(days=32) 

454 membership.save() 

455 

456 self.renewal.length = Entry.MEMBERSHIP_YEAR 

457 

458 with self.assertRaises(ValidationError): 

459 self.renewal.clean() 

460 

461 try: 

462 self.renewal.clean() 

463 except ValidationError as e: 

464 self.assertCountEqual( 

465 e.error_dict, 

466 { 

467 "length": "You cannot renew your membership at this moment.", 

468 }, 

469 ) 

470 

471 def test_within_renew_period(self): 

472 self.renewal.length = Entry.MEMBERSHIP_YEAR 

473 

474 membership = self.member.latest_membership 

475 membership.until = timezone.now().date() + timezone.timedelta(days=31) 

476 membership.save() 

477 

478 self.renewal.clean() 

479 

480 def test_benefactor_no_study_length(self): 

481 self.renewal.length = Entry.MEMBERSHIP_STUDY 

482 self.renewal.membership_type = Membership.BENEFACTOR 

483 membership = self.member.latest_membership 

484 membership.until = timezone.now().date() 

485 membership.save() 

486 

487 with self.assertRaises(ValidationError): 

488 self.renewal.clean() 

489 

490 try: 

491 self.renewal.clean() 

492 except ValidationError as e: 

493 self.assertCountEqual( 

494 e.error_dict, 

495 { 

496 "length": "Benefactors cannot have a membership " 

497 "that lasts their entire study duration.", 

498 }, 

499 ) 

500 

501 def test_has_active_membership(self): 

502 membership = self.member.current_membership 

503 membership.until = None 

504 membership.save() 

505 

506 with self.assertRaises(ValidationError): 

507 self.renewal.clean() 

508 

509 try: 

510 self.renewal.clean() 

511 except ValidationError as e: 

512 self.assertCountEqual( 

513 e.error_dict, 

514 { 

515 "length": "You currently have an active membership.", 

516 "membership_type": "You currently have an active membership.", 

517 }, 

518 ) 

519 

520 

521@override_settings(SUSPEND_SIGNALS=True) 

522class ReferenceTest(TestCase): 

523 fixtures = ["members.json"] 

524 

525 def test_str(self): 

526 member = Member.objects.filter(last_name="Wiggers").first() 

527 renewal = Renewal( 

528 member=member, 

529 length=Entry.MEMBERSHIP_YEAR, 

530 membership_type=Membership.MEMBER, 

531 ) 

532 

533 ref = Reference(member=member, entry=renewal) 

534 self.assertEqual( 

535 str(ref), "Reference from Thom Wiggers (thom) for Thom Wiggers ()" 

536 )