codeforlife-portal 7.3.3__py2.py3-none-any.whl → 7.3.5__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of codeforlife-portal might be problematic. Click here for more details.

@@ -0,0 +1,18 @@
1
+ # Generated by Django 3.2.25 on 2024-09-27 16:04
2
+
3
+ from django.db import migrations, models
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('common', '0054_delete_aimmo_models'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterField(
14
+ model_name='schoolteacherinvitation',
15
+ name='token',
16
+ field=models.CharField(max_length=88),
17
+ ),
18
+ ]
@@ -152,7 +152,7 @@ class SchoolTeacherInvitationModelManager(models.Manager):
152
152
 
153
153
 
154
154
  class SchoolTeacherInvitation(models.Model):
155
- token = models.CharField(max_length=32)
155
+ token = models.CharField(max_length=88)
156
156
  school = models.ForeignKey(
157
157
  School,
158
158
  related_name="teacher_invitations",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codeforlife-portal
3
- Version: 7.3.3
3
+ Version: 7.3.5
4
4
  Classifier: Programming Language :: Python
5
5
  Classifier: Programming Language :: Python :: 3.12
6
6
  Classifier: Framework :: Django
@@ -21,7 +21,7 @@ Requires-Dist: django-classy-tags==2.0.0
21
21
  Requires-Dist: libsass==0.23.0
22
22
  Requires-Dist: phonenumbers==8.12.12
23
23
  Requires-Dist: more-itertools==8.7.0
24
- Requires-Dist: cfl-common==7.3.3
24
+ Requires-Dist: cfl-common==7.3.5
25
25
  Requires-Dist: django-ratelimit==3.0.1
26
26
  Requires-Dist: django-preventconcurrentlogins==0.8.2
27
27
  Requires-Dist: django-csp==3.7
@@ -6,7 +6,7 @@ cfl_common/common/apps.py,sha256=49UXZ3bSkFKvIEOL4zM7y1sAhccQJyRtsoOg5XVd_8Y,129
6
6
  cfl_common/common/context_processors.py,sha256=X0iuX5qu9kMWa7q8osE9CJ2LgM7pPOYQFGdjm8X3rk0,236
7
7
  cfl_common/common/csp_config.py,sha256=9ECOLnp60ENRFAYEEIoYOMhqQzLgfKA-wkWxeUBwDrQ,2824
8
8
  cfl_common/common/mail.py,sha256=nCY5aRiyiBCudonewpHOQ3GnXhQu4HLJRaqx1vOYhfI,6799
9
- cfl_common/common/models.py,sha256=FB34xkpmTpYkvypgrDHv3QSRWnds69JnjHFw0X0fjrI,15989
9
+ cfl_common/common/models.py,sha256=yAULJtzuF4loEt6mPrgZjwHGiQH6Hqm82etE7Sofvys,15989
10
10
  cfl_common/common/permissions.py,sha256=gC6RQGZI2QDBbglx-xr_V4Hl2C2nf1V2_uPmEuoEcJo,2416
11
11
  cfl_common/common/utils.py,sha256=Nn2Npao9Uqad5Js_IdHwF-ow6wrPNpBLW4AO1LxoEBc,1727
12
12
  cfl_common/common/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -68,6 +68,7 @@ cfl_common/common/migrations/0051_verify_returning_users.py,sha256=WMpoTA24WgimL
68
68
  cfl_common/common/migrations/0052_add_cse_fields.py,sha256=NhUkkcu2EBzJFhewCTccQ63AoANkGq1CXbFWIGJG9jk,2232
69
69
  cfl_common/common/migrations/0053_clean_class_data.py,sha256=lBKlDa49YwT660o-Ot6IYe4I1KfervTn4uAijda0nyw,584
70
70
  cfl_common/common/migrations/0054_delete_aimmo_models.py,sha256=fmn4mDdlHr5DhPbIl_ygvGwWVFD8TZHAgQ6VUQQgCx8,415
71
+ cfl_common/common/migrations/0055_alter_schoolteacherinvitation_token.py,sha256=lzPAMaI3zU_q25RuIos_LV97NXOa3MIn_eWaEL71Y4I,403
71
72
  cfl_common/common/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
73
  cfl_common/common/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
74
  cfl_common/common/tests/test_migration_anonymise_orphan_schools.py,sha256=wJRyPgRvBsXLSCFdbBi2GXjgSgDbKUTRiM31CXIvpqs,1194
@@ -107,7 +108,7 @@ example_project/portal_test_settings.py,sha256=NfLY72mt1LR2c0_kxF-Yg5pCm2vQ52ece
107
108
  example_project/settings.py,sha256=Smpr5FHAaQQhXPgh6-Zsy-jnH5_ZV9htPTWJWlGqptI,5575
108
109
  example_project/urls.py,sha256=3SsP5jvPAXV5xmduka4zbSZB5PbXggjsalu1ojY5KIo,434
109
110
  example_project/wsgi.py,sha256=U1W6WzZxZaIdYZ5tks7w9fqp5WS5qvn2iThsVcskrWw,829
110
- portal/__init__.py,sha256=0toPzfNzgKGz4jRa-Ox6B7nbLNoBzmpwgBujvzkybx0,22
111
+ portal/__init__.py,sha256=M1Lk7wtZo07-pOYT24InoD_8ELHmXmGPngYBeKjWKiQ,22
111
112
  portal/admin.py,sha256=on1-zNRnZvf2cwBN6GVRVYRhkaksrCgfzX8XPWtkvz8,6062
112
113
  portal/app_settings.py,sha256=DhWLQOwM0zVOXE3O5TNKbMM9K6agfLuCsHOdr1J7xEI,651
113
114
  portal/backends.py,sha256=2Dss6_WoQwPuDzJUF1yEaTQTNG4eUrD12ujJQ5cp5Tc,812
@@ -548,7 +549,7 @@ portal/tests/test_school_student.py,sha256=bFZwY4twaFHQLp0cltMq8cLNDZGgCHTZBCZHK
548
549
  portal/tests/test_security.py,sha256=FGrlRfnzi-Xx2_bn4fTZlYORKm7w_GhGkD3havvplwc,3239
549
550
  portal/tests/test_teacher.py,sha256=vjnJi_aj_x48OJOMMRIBr0JTCxy4tFxqrLfCgw0fRxQ,29315
550
551
  portal/tests/test_teacher_student.py,sha256=NWITbUw1kijqu3c8eRHLHJKaYQMOsOMvl7PAVx5QghI,21567
551
- portal/tests/test_views.py,sha256=uyvdt-nlp-sN9NKl_hKeUgu7d0Z0kK-0g_nimi2boyY,45679
552
+ portal/tests/test_views.py,sha256=krg_3ZPbpPti7WNFyQkP7Mg4yX4_1dErZAX2iRJ2hu0,46751
552
553
  portal/tests/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
553
554
  portal/tests/migrations/test_migration_make_portaladmin_teacher.py,sha256=ekMRb6cU97oT0k9gCKW7IUB7oPuGmv4uWJCqInQN7x8,2589
554
555
  portal/tests/migrations/test_migration_preview_user_remove.py,sha256=K6D-FZT9YFEA8oMxHz9VTglVV6MZOTRYVlvwWwXc2vU,555
@@ -616,7 +617,7 @@ portal/views/play_landing_page.py,sha256=FFmjUFub3ZdlbMqkB8yX3jAImCzqrUqgb8AZcpK
616
617
  portal/views/registration.py,sha256=L9AzIG2nOU946cSOXmUMQRtDo3uxApHX-0ceXopbOCw,10888
617
618
  portal/views/teach.py,sha256=nzlyTcgq9ImAjnqrF3esqi212qBLH5Ww1LKE2gSjoRY,210
618
619
  portal/views/cron/__init__.py,sha256=5rxXyhJmLOExRdrYZ1VJttTsyRIPRybzdftbUDwFByI,20
619
- portal/views/cron/user.py,sha256=IP4hngpHg1GrKqh6dyyW13dr3R6617MenAcObWH9zbY,10287
620
+ portal/views/cron/user.py,sha256=iKM_FOcSQvrXtRSZUtxSiMFD3M869JP5jvEfRWHLpvM,10731
620
621
  portal/views/login/__init__.py,sha256=xSCtyFPSI87BRUybBgqa86ekFEolX5gUDbBSfBUMTyI,399
621
622
  portal/views/login/independent_student.py,sha256=3dFULhwMAlX4VDrJl-Znril6a9M5xKBSHO1eWvujfS0,2662
622
623
  portal/views/login/student.py,sha256=dt6cMfWepBJsVCRcADltfYSHVpyeP1WGLKSogMJ22E0,5539
@@ -631,8 +632,8 @@ portal/views/two_factor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
631
632
  portal/views/two_factor/core.py,sha256=O_wcBeFqdPYSGNGv-pT_vbs5-Dj1Z-Jfkd6f9-E5yZI,760
632
633
  portal/views/two_factor/form.py,sha256=lnHNKI-BMlpncTuW3zUzjPaJJNuEra2I_nOam0eOKFY,257
633
634
  portal/views/two_factor/profile.py,sha256=tkl_ludo8arMtd5LKNmohM66vpC_YQiP-0nspTSJiJ4,383
634
- codeforlife_portal-7.3.3.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
635
- codeforlife_portal-7.3.3.dist-info/METADATA,sha256=ZnS_f1ciHft66Np8pW27jVf4WWyxwYGSYZyTNI8sMHo,3317
636
- codeforlife_portal-7.3.3.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
637
- codeforlife_portal-7.3.3.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
638
- codeforlife_portal-7.3.3.dist-info/RECORD,,
635
+ codeforlife_portal-7.3.5.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
636
+ codeforlife_portal-7.3.5.dist-info/METADATA,sha256=ArUl7ZGlxBmaD6OMUM7u7gMy4dRFzc18BUxtE-sCNek,3317
637
+ codeforlife_portal-7.3.5.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
638
+ codeforlife_portal-7.3.5.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
639
+ codeforlife_portal-7.3.5.dist-info/RECORD,,
portal/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "7.3.3"
1
+ __version__ = "7.3.5"
@@ -40,7 +40,12 @@ from rest_framework.test import APIClient, APITestCase
40
40
  from deploy import captcha
41
41
  from portal.templatetags.app_tags import is_logged_in_as_admin_teacher
42
42
  from portal.views.api import anonymise
43
- from portal.views.cron.user import USER_DELETE_UNVERIFIED_ACCOUNT_DAYS
43
+ from portal.views.cron.user import (
44
+ USER_DELETE_UNVERIFIED_ACCOUNT_DAYS,
45
+ USER_2ND_INACTIVE_REMINDER_DAYS,
46
+ USER_FINAL_INACTIVE_REMINDER_DAYS,
47
+ USER_RETENTION_PERIOD,
48
+ )
44
49
  from portal.views.teacher.teach import (
45
50
  REMINDER_CARDS_PDF_COLUMNS,
46
51
  REMINDER_CARDS_PDF_ROWS,
@@ -1238,6 +1243,7 @@ class TestUser(CronTestCase):
1238
1243
  assert_called: bool,
1239
1244
  campaign_name: str,
1240
1245
  mock_send_dotdigital_email: Mock,
1246
+ personalization_values=None,
1241
1247
  ):
1242
1248
  self.teacher_user.date_joined = timezone.now() - timedelta(
1243
1249
  days=days, hours=12
@@ -1255,13 +1261,28 @@ class TestUser(CronTestCase):
1255
1261
  self.client.get(reverse(view_name))
1256
1262
 
1257
1263
  if assert_called:
1258
- mock_send_dotdigital_email.assert_any_call(
1259
- campaign_ids[campaign_name], [self.teacher_user.email]
1260
- )
1264
+ if personalization_values is not None:
1265
+ mock_send_dotdigital_email.assert_any_call(
1266
+ campaign_ids[campaign_name],
1267
+ [self.teacher_user.email],
1268
+ personalization_values=personalization_values,
1269
+ )
1261
1270
 
1262
- mock_send_dotdigital_email.assert_any_call(
1263
- campaign_ids[campaign_name], [self.indy_user.email]
1264
- )
1271
+ mock_send_dotdigital_email.assert_any_call(
1272
+ campaign_ids[campaign_name],
1273
+ [self.indy_user.email],
1274
+ personalization_values=personalization_values,
1275
+ )
1276
+ else:
1277
+ mock_send_dotdigital_email.assert_any_call(
1278
+ campaign_ids[campaign_name],
1279
+ [self.teacher_user.email],
1280
+ )
1281
+
1282
+ mock_send_dotdigital_email.assert_any_call(
1283
+ campaign_ids[campaign_name],
1284
+ [self.indy_user.email],
1285
+ )
1265
1286
 
1266
1287
  # Check only two emails are sent - the student should never be included.
1267
1288
  assert mock_send_dotdigital_email.call_count == 2
@@ -1302,6 +1323,10 @@ class TestUser(CronTestCase):
1302
1323
  "second-inactivity-reminder",
1303
1324
  True,
1304
1325
  "inactive_users_on_website_second_reminder",
1326
+ personalization_values={
1327
+ "DAYS_LEFT": USER_RETENTION_PERIOD
1328
+ - USER_2ND_INACTIVE_REMINDER_DAYS
1329
+ },
1305
1330
  )
1306
1331
  self.send_inactivity_reminder(
1307
1332
  974,
@@ -1322,6 +1347,10 @@ class TestUser(CronTestCase):
1322
1347
  "final-inactivity-reminder",
1323
1348
  True,
1324
1349
  "inactive_users_on_website_final_reminder",
1350
+ personalization_values={
1351
+ "DAYS_LEFT": USER_RETENTION_PERIOD
1352
+ - USER_FINAL_INACTIVE_REMINDER_DAYS
1353
+ },
1325
1354
  )
1326
1355
  self.send_inactivity_reminder(
1327
1356
  1066,
portal/views/cron/user.py CHANGED
@@ -22,6 +22,7 @@ USER_DELETE_UNVERIFIED_ACCOUNT_DAYS = 19
22
22
  USER_1ST_INACTIVE_REMINDER_DAYS = 730 # 2 years
23
23
  USER_2ND_INACTIVE_REMINDER_DAYS = 973 # roughly 2 years and 8 months
24
24
  USER_FINAL_INACTIVE_REMINDER_DAYS = 1065 # 2 years and 11 months
25
+ USER_RETENTION_PERIOD = 1096 # 3 years
25
26
 
26
27
 
27
28
  def get_unverified_users(
@@ -266,6 +267,10 @@ class SecondInactivityReminderView(CronMixin, APIView):
266
267
  "inactive_users_on_website_second_reminder"
267
268
  ],
268
269
  [email],
270
+ personalization_values={
271
+ "DAYS_LEFT": USER_RETENTION_PERIOD
272
+ - USER_2ND_INACTIVE_REMINDER_DAYS
273
+ },
269
274
  )
270
275
 
271
276
  sent_email_count += 1
@@ -300,6 +305,10 @@ class FinalInactivityReminderView(CronMixin, APIView):
300
305
  "inactive_users_on_website_final_reminder"
301
306
  ],
302
307
  [email],
308
+ personalization_values={
309
+ "DAYS_LEFT": USER_RETENTION_PERIOD
310
+ - USER_FINAL_INACTIVE_REMINDER_DAYS
311
+ },
303
312
  )
304
313
 
305
314
  sent_email_count += 1