codeforlife-portal 7.3.2__py2.py3-none-any.whl → 7.3.4__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.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codeforlife-portal
3
- Version: 7.3.2
3
+ Version: 7.3.4
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.2
24
+ Requires-Dist: cfl-common==7.3.4
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
@@ -107,7 +107,7 @@ example_project/portal_test_settings.py,sha256=NfLY72mt1LR2c0_kxF-Yg5pCm2vQ52ece
107
107
  example_project/settings.py,sha256=Smpr5FHAaQQhXPgh6-Zsy-jnH5_ZV9htPTWJWlGqptI,5575
108
108
  example_project/urls.py,sha256=3SsP5jvPAXV5xmduka4zbSZB5PbXggjsalu1ojY5KIo,434
109
109
  example_project/wsgi.py,sha256=U1W6WzZxZaIdYZ5tks7w9fqp5WS5qvn2iThsVcskrWw,829
110
- portal/__init__.py,sha256=8Jco-UfTOBG0bR83qZyBQc0_drTG-H86kUcnKWGtY7o,22
110
+ portal/__init__.py,sha256=Pie6c5yU6jjDgfnsf1R_OJAfz9jFfPl8WlzAvB4l9_w,22
111
111
  portal/admin.py,sha256=on1-zNRnZvf2cwBN6GVRVYRhkaksrCgfzX8XPWtkvz8,6062
112
112
  portal/app_settings.py,sha256=DhWLQOwM0zVOXE3O5TNKbMM9K6agfLuCsHOdr1J7xEI,651
113
113
  portal/backends.py,sha256=2Dss6_WoQwPuDzJUF1yEaTQTNG4eUrD12ujJQ5cp5Tc,812
@@ -469,7 +469,7 @@ portal/templates/portal/partials/card_list.html,sha256=yHcp4oc0WRG9H6Ek871VCHbwY
469
469
  portal/templates/portal/partials/character_list.html,sha256=SnNFHzbIkOSaiRPIvSdplEf_B87UYgJ1pOvMltNDxLE,415
470
470
  portal/templates/portal/partials/delete_popup.html,sha256=nEhnwgnmKoFzb6LlCwdX973Em9bVOFh6MON36RPteYs,1275
471
471
  portal/templates/portal/partials/footer.html,sha256=V6xKYyhPoqSRUL0HQu7OB9vKVJWun8Q0PUGa5Dbdyl4,4922
472
- portal/templates/portal/partials/header.html,sha256=musjJqC4abBo63vF0Sgkyx1p6qJt-4lKD2WNq03k7KA,20052
472
+ portal/templates/portal/partials/header.html,sha256=HRrfwyUFhuuTKSp0bzFXsNwuQ_cBLyxnvw2bgV1jMbw,20142
473
473
  portal/templates/portal/partials/headline.html,sha256=xKb-WtkT0FyQqT0smyNSKkXFvU7KQ5Czad8ca6YKQg4,89
474
474
  portal/templates/portal/partials/hero_card.html,sha256=UN5hyxrw-McuXFsDzPBIECB9yGrv9VjsFf8SEBowwXc,786
475
475
  portal/templates/portal/partials/info_popup.html,sha256=gzffd5MBVb7p2hGQuZMNDudThrRgs847hCu9ziT9uLE,566
@@ -548,7 +548,7 @@ portal/tests/test_school_student.py,sha256=bFZwY4twaFHQLp0cltMq8cLNDZGgCHTZBCZHK
548
548
  portal/tests/test_security.py,sha256=FGrlRfnzi-Xx2_bn4fTZlYORKm7w_GhGkD3havvplwc,3239
549
549
  portal/tests/test_teacher.py,sha256=vjnJi_aj_x48OJOMMRIBr0JTCxy4tFxqrLfCgw0fRxQ,29315
550
550
  portal/tests/test_teacher_student.py,sha256=NWITbUw1kijqu3c8eRHLHJKaYQMOsOMvl7PAVx5QghI,21567
551
- portal/tests/test_views.py,sha256=uyvdt-nlp-sN9NKl_hKeUgu7d0Z0kK-0g_nimi2boyY,45679
551
+ portal/tests/test_views.py,sha256=krg_3ZPbpPti7WNFyQkP7Mg4yX4_1dErZAX2iRJ2hu0,46751
552
552
  portal/tests/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
553
553
  portal/tests/migrations/test_migration_make_portaladmin_teacher.py,sha256=ekMRb6cU97oT0k9gCKW7IUB7oPuGmv4uWJCqInQN7x8,2589
554
554
  portal/tests/migrations/test_migration_preview_user_remove.py,sha256=K6D-FZT9YFEA8oMxHz9VTglVV6MZOTRYVlvwWwXc2vU,555
@@ -616,7 +616,7 @@ portal/views/play_landing_page.py,sha256=FFmjUFub3ZdlbMqkB8yX3jAImCzqrUqgb8AZcpK
616
616
  portal/views/registration.py,sha256=L9AzIG2nOU946cSOXmUMQRtDo3uxApHX-0ceXopbOCw,10888
617
617
  portal/views/teach.py,sha256=nzlyTcgq9ImAjnqrF3esqi212qBLH5Ww1LKE2gSjoRY,210
618
618
  portal/views/cron/__init__.py,sha256=5rxXyhJmLOExRdrYZ1VJttTsyRIPRybzdftbUDwFByI,20
619
- portal/views/cron/user.py,sha256=IP4hngpHg1GrKqh6dyyW13dr3R6617MenAcObWH9zbY,10287
619
+ portal/views/cron/user.py,sha256=iKM_FOcSQvrXtRSZUtxSiMFD3M869JP5jvEfRWHLpvM,10731
620
620
  portal/views/login/__init__.py,sha256=xSCtyFPSI87BRUybBgqa86ekFEolX5gUDbBSfBUMTyI,399
621
621
  portal/views/login/independent_student.py,sha256=3dFULhwMAlX4VDrJl-Znril6a9M5xKBSHO1eWvujfS0,2662
622
622
  portal/views/login/student.py,sha256=dt6cMfWepBJsVCRcADltfYSHVpyeP1WGLKSogMJ22E0,5539
@@ -631,8 +631,8 @@ portal/views/two_factor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
631
631
  portal/views/two_factor/core.py,sha256=O_wcBeFqdPYSGNGv-pT_vbs5-Dj1Z-Jfkd6f9-E5yZI,760
632
632
  portal/views/two_factor/form.py,sha256=lnHNKI-BMlpncTuW3zUzjPaJJNuEra2I_nOam0eOKFY,257
633
633
  portal/views/two_factor/profile.py,sha256=tkl_ludo8arMtd5LKNmohM66vpC_YQiP-0nspTSJiJ4,383
634
- codeforlife_portal-7.3.2.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
635
- codeforlife_portal-7.3.2.dist-info/METADATA,sha256=eLaHacKxdRwzJSuRSbPPW0ZRStXgMc_YmRwVJLWqy7c,3317
636
- codeforlife_portal-7.3.2.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
637
- codeforlife_portal-7.3.2.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
638
- codeforlife_portal-7.3.2.dist-info/RECORD,,
634
+ codeforlife_portal-7.3.4.dist-info/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
635
+ codeforlife_portal-7.3.4.dist-info/METADATA,sha256=mEgZdg2M-pm6MMsnjzWnU_eKKNbQmgF2zRW5qzIqcQ0,3317
636
+ codeforlife_portal-7.3.4.dist-info/WHEEL,sha256=fS9sRbCBHs7VFcwJLnLXN1MZRR0_TVTxvXKzOnaSFs8,110
637
+ codeforlife_portal-7.3.4.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
638
+ codeforlife_portal-7.3.4.dist-info/RECORD,,
portal/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = "7.3.2"
1
+ __version__ = "7.3.4"
@@ -157,19 +157,19 @@
157
157
  <li class="dropdown-menu__option">
158
158
  <a id="teacher_login_button" class="button--regular" aria-labelledby="Teacher" href="{% url 'teacher_login' %}">
159
159
  <div class="dropdown-menu__option__text">Teacher</div>
160
- <span class="material-icons-outlined">chevron_right</span>
160
+ <span data-nosnippet class="material-icons-outlined">chevron_right</span>
161
161
  </a>
162
162
  </li>
163
163
  <li class="dropdown-menu__option">
164
164
  <a id="student_login_button" class="button--regular" aria-labelledby="Student" href="{% url 'student_login_access_code' %}">
165
165
  <div class="dropdown-menu__option__text">Student</div>
166
- <span class="material-icons-outlined">chevron_right</span>
166
+ <span data-nosnippet class="material-icons-outlined">chevron_right</span>
167
167
  </a>
168
168
  </li>
169
169
  <li class="dropdown-menu__option">
170
170
  <a id="independent_login_button" class="button--regular" aria-labelledby="Independent" href="{% url 'independent_student_login' %}">
171
171
  <div class="dropdown-menu__option__text">Independent</div>
172
- <span class="material-icons-outlined">chevron_right</span>
172
+ <span data-nosnippet class="material-icons-outlined">chevron_right</span>
173
173
  </a>
174
174
  </li>
175
175
  </ul>
@@ -243,11 +243,11 @@
243
243
  data-toggle="collapse" data-target="#login-tabs">Log in</button>
244
244
  <div id="login-tabs" class="collapse">
245
245
  <a class="button button--menu__item button--menu__item__sub"
246
- href="{% url 'teacher_login' %}">Teacher<span class="material-icons-outlined md-32">chevron_right</span></a>
246
+ href="{% url 'teacher_login' %}">Teacher<span data-nosnippet class="material-icons-outlined md-32">chevron_right</span></a>
247
247
  <a class="button button--menu__item button--menu__item__sub"
248
- href="{% url 'student_login_access_code' %}">Student<span class="material-icons-outlined md-32">chevron_right</span></a>
248
+ href="{% url 'student_login_access_code' %}">Student<span data-nosnippet class="material-icons-outlined md-32">chevron_right</span></a>
249
249
  <a class="button button--menu__item button--menu__item__sub"
250
- href="{% url 'independent_student_login' %}">Independent<span class="material-icons-outlined md-32">chevron_right</span></a>
250
+ href="{% url 'independent_student_login' %}">Independent<span data-nosnippet class="material-icons-outlined md-32">chevron_right</span></a>
251
251
  </div>
252
252
  <a class="button button--menu__item" href="{% url 'teach' %}">Teacher
253
253
  <span class="material-icons-outlined md-32">chevron_right</span></a>
@@ -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