codeforlife-portal 6.41.5__py2.py3-none-any.whl → 6.41.6__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.
- cfl_common/common/app_settings.py +3 -0
- cfl_common/common/email_messages.py +0 -58
- cfl_common/common/helpers/data_migration_loader.py +3 -4
- cfl_common/common/helpers/emails.py +27 -45
- cfl_common/common/helpers/generators.py +1 -1
- cfl_common/common/mail.py +116 -0
- cfl_common/common/migrations/0002_emailverification.py +1 -3
- cfl_common/common/migrations/0005_add_worksheets.py +1 -5
- cfl_common/common/migrations/0007_add_pdf_names_to_first_two_worksheets.py +1 -5
- cfl_common/common/migrations/0008_unlock_worksheet_3.py +1 -5
- cfl_common/common/migrations/0017_copy_email_to_username.py +2 -8
- cfl_common/common/migrations/0021_school_is_active.py +7 -7
- cfl_common/common/migrations/0022_school_cleanup.py +9 -9
- cfl_common/common/migrations/0023_userprofile_aimmo_badges.py +4 -4
- cfl_common/common/migrations/0025_schoolteacherinvitation.py +29 -13
- cfl_common/common/migrations/0026_teacher_remove_join_request.py +5 -5
- cfl_common/common/migrations/0027_class_created_by.py +10 -4
- cfl_common/common/migrations/0028_coding_club_downloads.py +5 -5
- cfl_common/common/migrations/0029_dynamicelement.py +6 -6
- cfl_common/common/migrations/0030_add_maintenance_banner.py +1 -3
- cfl_common/common/migrations/0031_improve_admin_panel.py +32 -14
- cfl_common/common/migrations/0032_dailyactivity_level_control_submits.py +3 -3
- cfl_common/common/migrations/0033_password_reset_tracking_fields.py +5 -5
- cfl_common/common/migrations/0034_dailyactivity_daily_school_student_lockout_reset.py +3 -3
- cfl_common/common/migrations/0035_rename_lockout_fields.py +10 -10
- cfl_common/common/migrations/0037_migrate_email_verification.py +2 -2
- cfl_common/common/migrations/0038_delete_emailverification.py +2 -2
- cfl_common/common/migrations/0039_copy_email_to_username.py +1 -6
- cfl_common/common/migrations/0040_school_county.py +3 -3
- cfl_common/common/migrations/0042_totalactivity.py +7 -7
- cfl_common/common/migrations/0044_update_activity_models.py +9 -9
- cfl_common/common/migrations/0045_otp.py +5 -5
- cfl_common/common/migrations/0046_alter_school_country.py +3 -3
- cfl_common/common/tests/utils/email.py +14 -34
- cfl_common/common/tests/utils/student.py +8 -8
- cfl_common/common/tests/utils/teacher.py +8 -8
- {codeforlife_portal-6.41.5.dist-info → codeforlife_portal-6.41.6.dist-info}/METADATA +2 -2
- {codeforlife_portal-6.41.5.dist-info → codeforlife_portal-6.41.6.dist-info}/RECORD +49 -48
- example_project/portal_test_settings.py +5 -1
- portal/__init__.py +1 -1
- portal/tests/test_independent_student.py +30 -17
- portal/tests/test_ratelimit.py +15 -12
- portal/tests/test_teacher.py +35 -21
- portal/tests/test_teacher_student.py +13 -3
- portal/tests/test_views.py +55 -194
- portal/views/cron/user.py +12 -49
- {codeforlife_portal-6.41.5.dist-info → codeforlife_portal-6.41.6.dist-info}/LICENSE.md +0 -0
- {codeforlife_portal-6.41.5.dist-info → codeforlife_portal-6.41.6.dist-info}/WHEEL +0 -0
- {codeforlife_portal-6.41.5.dist-info → codeforlife_portal-6.41.6.dist-info}/top_level.txt +0 -0
|
@@ -22,6 +22,4 @@ class Migration(migrations.Migration):
|
|
|
22
22
|
|
|
23
23
|
dependencies = [("common", "0029_dynamicelement")]
|
|
24
24
|
|
|
25
|
-
operations = [
|
|
26
|
-
migrations.RunPython(add_maintenance_banner, remove_maintenance_banner)
|
|
27
|
-
]
|
|
25
|
+
operations = [migrations.RunPython(add_maintenance_banner, remove_maintenance_banner)]
|
|
@@ -7,32 +7,50 @@ import django.db.models.deletion
|
|
|
7
7
|
class Migration(migrations.Migration):
|
|
8
8
|
|
|
9
9
|
dependencies = [
|
|
10
|
-
(
|
|
10
|
+
("common", "0030_add_maintenance_banner"),
|
|
11
11
|
]
|
|
12
12
|
|
|
13
13
|
operations = [
|
|
14
14
|
migrations.AlterModelOptions(
|
|
15
|
-
name=
|
|
16
|
-
options={
|
|
15
|
+
name="dailyactivity",
|
|
16
|
+
options={"verbose_name_plural": "Daily activities"},
|
|
17
17
|
),
|
|
18
18
|
migrations.AlterField(
|
|
19
|
-
model_name=
|
|
20
|
-
name=
|
|
19
|
+
model_name="student",
|
|
20
|
+
name="blocked_time",
|
|
21
21
|
field=models.DateTimeField(blank=True, null=True),
|
|
22
22
|
),
|
|
23
23
|
migrations.AlterField(
|
|
24
|
-
model_name=
|
|
25
|
-
name=
|
|
26
|
-
field=models.ForeignKey(
|
|
24
|
+
model_name="student",
|
|
25
|
+
name="class_field",
|
|
26
|
+
field=models.ForeignKey(
|
|
27
|
+
blank=True,
|
|
28
|
+
null=True,
|
|
29
|
+
on_delete=django.db.models.deletion.CASCADE,
|
|
30
|
+
related_name="students",
|
|
31
|
+
to="common.class",
|
|
32
|
+
),
|
|
27
33
|
),
|
|
28
34
|
migrations.AlterField(
|
|
29
|
-
model_name=
|
|
30
|
-
name=
|
|
31
|
-
field=models.ForeignKey(
|
|
35
|
+
model_name="student",
|
|
36
|
+
name="pending_class_request",
|
|
37
|
+
field=models.ForeignKey(
|
|
38
|
+
blank=True,
|
|
39
|
+
null=True,
|
|
40
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
41
|
+
related_name="class_request",
|
|
42
|
+
to="common.class",
|
|
43
|
+
),
|
|
32
44
|
),
|
|
33
45
|
migrations.AlterField(
|
|
34
|
-
model_name=
|
|
35
|
-
name=
|
|
36
|
-
field=models.ForeignKey(
|
|
46
|
+
model_name="teacher",
|
|
47
|
+
name="school",
|
|
48
|
+
field=models.ForeignKey(
|
|
49
|
+
blank=True,
|
|
50
|
+
null=True,
|
|
51
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
52
|
+
related_name="teacher_school",
|
|
53
|
+
to="common.school",
|
|
54
|
+
),
|
|
37
55
|
),
|
|
38
56
|
]
|
|
@@ -6,13 +6,13 @@ from django.db import migrations, models
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0031_improve_admin_panel"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.AddField(
|
|
14
|
-
model_name=
|
|
15
|
-
name=
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="level_control_submits",
|
|
16
16
|
field=models.PositiveBigIntegerField(default=0),
|
|
17
17
|
),
|
|
18
18
|
]
|
|
@@ -6,18 +6,18 @@ from django.db import migrations, models
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0032_dailyactivity_level_control_submits"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.AddField(
|
|
14
|
-
model_name=
|
|
15
|
-
name=
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="daily_indy_lockout_reset",
|
|
16
16
|
field=models.PositiveIntegerField(default=0),
|
|
17
17
|
),
|
|
18
18
|
migrations.AddField(
|
|
19
|
-
model_name=
|
|
20
|
-
name=
|
|
19
|
+
model_name="dailyactivity",
|
|
20
|
+
name="daily_teacher_lockout_reset",
|
|
21
21
|
field=models.PositiveIntegerField(default=0),
|
|
22
22
|
),
|
|
23
23
|
]
|
|
@@ -6,13 +6,13 @@ from django.db import migrations, models
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0033_password_reset_tracking_fields"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.AddField(
|
|
14
|
-
model_name=
|
|
15
|
-
name=
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="daily_school_student_lockout_reset",
|
|
16
16
|
field=models.PositiveIntegerField(default=0),
|
|
17
17
|
),
|
|
18
18
|
]
|
|
@@ -5,23 +5,23 @@ from django.db import migrations
|
|
|
5
5
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
dependencies = [
|
|
8
|
-
(
|
|
8
|
+
("common", "0034_dailyactivity_daily_school_student_lockout_reset"),
|
|
9
9
|
]
|
|
10
10
|
|
|
11
11
|
operations = [
|
|
12
12
|
migrations.RenameField(
|
|
13
|
-
model_name=
|
|
14
|
-
old_name=
|
|
15
|
-
new_name=
|
|
13
|
+
model_name="dailyactivity",
|
|
14
|
+
old_name="daily_indy_lockout_reset",
|
|
15
|
+
new_name="indy_lockout_resets",
|
|
16
16
|
),
|
|
17
17
|
migrations.RenameField(
|
|
18
|
-
model_name=
|
|
19
|
-
old_name=
|
|
20
|
-
new_name=
|
|
18
|
+
model_name="dailyactivity",
|
|
19
|
+
old_name="daily_school_student_lockout_reset",
|
|
20
|
+
new_name="school_student_lockout_resets",
|
|
21
21
|
),
|
|
22
22
|
migrations.RenameField(
|
|
23
|
-
model_name=
|
|
24
|
-
old_name=
|
|
25
|
-
new_name=
|
|
23
|
+
model_name="dailyactivity",
|
|
24
|
+
old_name="daily_teacher_lockout_reset",
|
|
25
|
+
new_name="teacher_lockout_resets",
|
|
26
26
|
),
|
|
27
27
|
]
|
|
@@ -7,13 +7,13 @@ class Migration(migrations.Migration):
|
|
|
7
7
|
]
|
|
8
8
|
|
|
9
9
|
def forwards(apps, schema_editor):
|
|
10
|
-
"""
|
|
10
|
+
"""Finds the users of verified Email Verification objects and sets their `is_verified` to True"""
|
|
11
11
|
UserProfile = apps.get_model("common", "UserProfile")
|
|
12
12
|
db_alias = schema_editor.connection.alias
|
|
13
13
|
UserProfile.objects.using(db_alias).filter(user__email_verifications__verified=True).update(is_verified=True)
|
|
14
14
|
|
|
15
15
|
def backwards(apps, schema_editor):
|
|
16
|
-
"""
|
|
16
|
+
"""Finds the users of verified Email Verification objects and sets their `is_verified` to False"""
|
|
17
17
|
UserProfile = apps.get_model("common", "UserProfile")
|
|
18
18
|
db_alias = schema_editor.connection.alias
|
|
19
19
|
UserProfile.objects.using(db_alias).filter(user__email_verifications__verified=True).update(is_verified=False)
|
|
@@ -6,11 +6,11 @@ from django.db import migrations
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0037_migrate_email_verification"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.DeleteModel(
|
|
14
|
-
name=
|
|
14
|
+
name="EmailVerification",
|
|
15
15
|
),
|
|
16
16
|
]
|
|
@@ -15,9 +15,4 @@ class Migration(migrations.Migration):
|
|
|
15
15
|
("common", "0038_delete_emailverification"),
|
|
16
16
|
]
|
|
17
17
|
|
|
18
|
-
operations = [
|
|
19
|
-
migrations.RunPython(
|
|
20
|
-
code=copy_email_to_username, reverse_code=migrations.RunPython.noop
|
|
21
|
-
)
|
|
22
|
-
]
|
|
23
|
-
|
|
18
|
+
operations = [migrations.RunPython(code=copy_email_to_username, reverse_code=migrations.RunPython.noop)]
|
|
@@ -6,13 +6,13 @@ from django.db import migrations, models
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0039_copy_email_to_username"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.AddField(
|
|
14
|
-
model_name=
|
|
15
|
-
name=
|
|
14
|
+
model_name="school",
|
|
15
|
+
name="county",
|
|
16
16
|
field=models.CharField(blank=True, max_length=50, null=True),
|
|
17
17
|
),
|
|
18
18
|
]
|
|
@@ -6,20 +6,20 @@ from django.db import migrations, models
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0041_populate_gb_counties"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.CreateModel(
|
|
14
|
-
name=
|
|
14
|
+
name="TotalActivity",
|
|
15
15
|
fields=[
|
|
16
|
-
(
|
|
17
|
-
(
|
|
18
|
-
(
|
|
19
|
-
(
|
|
16
|
+
("id", models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
17
|
+
("teacher_registrations", models.PositiveIntegerField(default=0)),
|
|
18
|
+
("student_registrations", models.PositiveIntegerField(default=0)),
|
|
19
|
+
("independent_registrations", models.PositiveIntegerField(default=0)),
|
|
20
20
|
],
|
|
21
21
|
options={
|
|
22
|
-
|
|
22
|
+
"verbose_name_plural": "Total activity",
|
|
23
23
|
},
|
|
24
24
|
),
|
|
25
25
|
]
|
|
@@ -6,28 +6,28 @@ from django.db import migrations, models
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0043_add_total_activity"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.AddField(
|
|
14
|
-
model_name=
|
|
15
|
-
name=
|
|
14
|
+
model_name="dailyactivity",
|
|
15
|
+
name="anonymised_unverified_independents",
|
|
16
16
|
field=models.PositiveIntegerField(default=0),
|
|
17
17
|
),
|
|
18
18
|
migrations.AddField(
|
|
19
|
-
model_name=
|
|
20
|
-
name=
|
|
19
|
+
model_name="dailyactivity",
|
|
20
|
+
name="anonymised_unverified_teachers",
|
|
21
21
|
field=models.PositiveIntegerField(default=0),
|
|
22
22
|
),
|
|
23
23
|
migrations.AddField(
|
|
24
|
-
model_name=
|
|
25
|
-
name=
|
|
24
|
+
model_name="totalactivity",
|
|
25
|
+
name="anonymised_unverified_independents",
|
|
26
26
|
field=models.PositiveIntegerField(default=0),
|
|
27
27
|
),
|
|
28
28
|
migrations.AddField(
|
|
29
|
-
model_name=
|
|
30
|
-
name=
|
|
29
|
+
model_name="totalactivity",
|
|
30
|
+
name="anonymised_unverified_teachers",
|
|
31
31
|
field=models.PositiveIntegerField(default=0),
|
|
32
32
|
),
|
|
33
33
|
]
|
|
@@ -6,18 +6,18 @@ from django.db import migrations, models
|
|
|
6
6
|
class Migration(migrations.Migration):
|
|
7
7
|
|
|
8
8
|
dependencies = [
|
|
9
|
-
(
|
|
9
|
+
("common", "0044_update_activity_models"),
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
operations = [
|
|
13
13
|
migrations.AddField(
|
|
14
|
-
model_name=
|
|
15
|
-
name=
|
|
14
|
+
model_name="userprofile",
|
|
15
|
+
name="last_otp_for_time",
|
|
16
16
|
field=models.DateTimeField(blank=True, null=True),
|
|
17
17
|
),
|
|
18
18
|
migrations.AddField(
|
|
19
|
-
model_name=
|
|
20
|
-
name=
|
|
19
|
+
model_name="userprofile",
|
|
20
|
+
name="otp_secret",
|
|
21
21
|
field=models.CharField(blank=True, max_length=40, null=True),
|
|
22
22
|
),
|
|
23
23
|
]
|
|
@@ -7,13 +7,13 @@ import django_countries.fields
|
|
|
7
7
|
class Migration(migrations.Migration):
|
|
8
8
|
|
|
9
9
|
dependencies = [
|
|
10
|
-
(
|
|
10
|
+
("common", "0045_otp"),
|
|
11
11
|
]
|
|
12
12
|
|
|
13
13
|
operations = [
|
|
14
14
|
migrations.AlterField(
|
|
15
|
-
model_name=
|
|
16
|
-
name=
|
|
15
|
+
model_name="school",
|
|
16
|
+
name="country",
|
|
17
17
|
field=django_countries.fields.CountryField(blank=True, max_length=2, null=True),
|
|
18
18
|
),
|
|
19
19
|
]
|
|
@@ -2,20 +2,14 @@ import re
|
|
|
2
2
|
from builtins import str
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
def follow_verify_email_link_to_onboarding(page,
|
|
6
|
-
|
|
5
|
+
def follow_verify_email_link_to_onboarding(page, url):
|
|
6
|
+
page.browser.get(url)
|
|
7
7
|
|
|
8
8
|
return go_to_teacher_login_page(page.browser)
|
|
9
9
|
|
|
10
10
|
|
|
11
|
-
def
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return go_to_teacher_dashboard_page(page.browser)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def follow_verify_email_link_to_login(page, email, user_type):
|
|
18
|
-
_follow_verify_email_link(page, email)
|
|
11
|
+
def follow_verify_email_link_to_login(page, url, user_type):
|
|
12
|
+
page.browser.get(url)
|
|
19
13
|
|
|
20
14
|
if user_type == "teacher":
|
|
21
15
|
return go_to_teacher_login_page(page.browser)
|
|
@@ -32,15 +26,6 @@ def follow_duplicate_account_link_to_login(page, email, user_type):
|
|
|
32
26
|
return go_to_independent_student_login_page(page.browser)
|
|
33
27
|
|
|
34
28
|
|
|
35
|
-
def _follow_verify_email_link(page, email):
|
|
36
|
-
message = str(email.message())
|
|
37
|
-
prefix = '<p>Please go to <a href="'
|
|
38
|
-
i = str.find(message, prefix) + len(prefix)
|
|
39
|
-
suffix = '" rel="nofollow">'
|
|
40
|
-
j = str.find(message, suffix, i)
|
|
41
|
-
page.browser.get(message[i:j])
|
|
42
|
-
|
|
43
|
-
|
|
44
29
|
def _follow_duplicate_account_email_link(page, email):
|
|
45
30
|
message = str(email.message())
|
|
46
31
|
prefix = 'please login: <a href="'
|
|
@@ -55,32 +40,25 @@ def follow_reset_email_link(browser, email):
|
|
|
55
40
|
link = re.search("http.+/", message).group(0)[:-1]
|
|
56
41
|
browser.get(link)
|
|
57
42
|
|
|
58
|
-
from portal.tests.pageObjects.portal.password_reset_form_page import
|
|
43
|
+
from portal.tests.pageObjects.portal.password_reset_form_page import (
|
|
44
|
+
PasswordResetPage,
|
|
45
|
+
)
|
|
59
46
|
|
|
60
47
|
return PasswordResetPage(browser)
|
|
61
48
|
|
|
62
49
|
|
|
63
|
-
def follow_change_email_link_to_dashboard(page,
|
|
64
|
-
|
|
50
|
+
def follow_change_email_link_to_dashboard(page, url):
|
|
51
|
+
page.browser.get(url)
|
|
65
52
|
|
|
66
53
|
return go_to_teacher_login_page(page.browser)
|
|
67
54
|
|
|
68
55
|
|
|
69
|
-
def follow_change_email_link_to_independent_dashboard(page,
|
|
70
|
-
|
|
56
|
+
def follow_change_email_link_to_independent_dashboard(page, url):
|
|
57
|
+
page.browser.get(url)
|
|
71
58
|
|
|
72
59
|
return go_to_independent_student_login_page(page.browser)
|
|
73
60
|
|
|
74
61
|
|
|
75
|
-
def _follow_change_email_link(page, email):
|
|
76
|
-
message = str(email.message())
|
|
77
|
-
prefix = "please go to "
|
|
78
|
-
i = str.find(message, prefix) + len(prefix)
|
|
79
|
-
suffix = " to verify"
|
|
80
|
-
j = str.find(message, suffix, i)
|
|
81
|
-
page.browser.get(message[i:j])
|
|
82
|
-
|
|
83
|
-
|
|
84
62
|
def go_to_teacher_login_page(browser):
|
|
85
63
|
from portal.tests.pageObjects.portal.teacher_login_page import TeacherLoginPage
|
|
86
64
|
|
|
@@ -94,6 +72,8 @@ def go_to_teacher_dashboard_page(browser):
|
|
|
94
72
|
|
|
95
73
|
|
|
96
74
|
def go_to_independent_student_login_page(browser):
|
|
97
|
-
from portal.tests.pageObjects.portal.independent_login_page import
|
|
75
|
+
from portal.tests.pageObjects.portal.independent_login_page import (
|
|
76
|
+
IndependentStudentLoginPage,
|
|
77
|
+
)
|
|
98
78
|
|
|
99
79
|
return IndependentStudentLoginPage(browser)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from builtins import range
|
|
2
2
|
from typing import Tuple
|
|
3
|
+
from unittest.mock import patch
|
|
3
4
|
|
|
4
5
|
from common.helpers.emails import generate_token
|
|
5
6
|
from common.helpers.generators import generate_login_id
|
|
@@ -118,7 +119,8 @@ def signup_duplicate_independent_student_fail(page, duplicate_email=None):
|
|
|
118
119
|
return page, name, username, email_address, password
|
|
119
120
|
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
@patch("common.helpers.emails.send_dotdigital_email")
|
|
123
|
+
def create_independent_student(page, mock_send_dotdigital_email):
|
|
122
124
|
page = page.go_to_signup_page()
|
|
123
125
|
|
|
124
126
|
name, username, email_address, password = generate_independent_student_details()
|
|
@@ -126,16 +128,14 @@ def create_independent_student(page):
|
|
|
126
128
|
|
|
127
129
|
page = page.return_to_home_page()
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
mail.outbox = []
|
|
131
|
+
verification_url = mock_send_dotdigital_email.call_args.kwargs["personalization_values"]["VERIFICATION_LINK"]
|
|
131
132
|
|
|
132
|
-
|
|
133
|
+
page = email.follow_verify_email_link_to_login(page, verification_url, "independent")
|
|
133
134
|
|
|
135
|
+
return page, name, username, email_address, password
|
|
134
136
|
|
|
135
|
-
def verify_email(page):
|
|
136
|
-
assert len(mail.outbox) > 0
|
|
137
137
|
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
def verify_email(page, verification_url):
|
|
139
|
+
page = email.follow_verify_email_link_to_login(page, verification_url, "independent")
|
|
140
140
|
|
|
141
141
|
return page
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import random
|
|
2
2
|
import sys
|
|
3
|
+
from unittest.mock import patch
|
|
3
4
|
|
|
4
5
|
from common.helpers.emails import generate_token
|
|
5
6
|
from common.models import Teacher
|
|
@@ -47,7 +48,8 @@ def signup_duplicate_teacher_fail(page, duplicate_email):
|
|
|
47
48
|
return page, email_address, password
|
|
48
49
|
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
@patch("common.helpers.emails.send_dotdigital_email")
|
|
52
|
+
def signup_teacher(page, mock_send_dotdigital_email, newsletter=False):
|
|
51
53
|
page = page.go_to_signup_page()
|
|
52
54
|
|
|
53
55
|
first_name, last_name, email_address, password = generate_details()
|
|
@@ -57,16 +59,14 @@ def signup_teacher(page, newsletter=False):
|
|
|
57
59
|
|
|
58
60
|
page = page.return_to_home_page()
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
mail.outbox = []
|
|
62
|
+
verification_url = mock_send_dotdigital_email.call_args.kwargs["personalization_values"]["VERIFICATION_LINK"]
|
|
62
63
|
|
|
63
|
-
|
|
64
|
+
page = email.follow_verify_email_link_to_onboarding(page, verification_url)
|
|
64
65
|
|
|
66
|
+
return page, email_address, password
|
|
65
67
|
|
|
66
|
-
def verify_email(page):
|
|
67
|
-
assert len(mail.outbox) > 0
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
def verify_email(page, verification_url):
|
|
70
|
+
page = email.follow_verify_email_link_to_login(page, verification_url, "teacher")
|
|
71
71
|
|
|
72
72
|
return page
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: codeforlife-portal
|
|
3
|
-
Version: 6.41.
|
|
3
|
+
Version: 6.41.6
|
|
4
4
|
Classifier: Programming Language :: Python
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.8
|
|
6
6
|
Classifier: Framework :: Django
|
|
@@ -25,7 +25,7 @@ Requires-Dist: sqlparse ==0.4.4
|
|
|
25
25
|
Requires-Dist: libsass ==0.22.0
|
|
26
26
|
Requires-Dist: phonenumbers ==8.12.12
|
|
27
27
|
Requires-Dist: more-itertools ==8.7.0
|
|
28
|
-
Requires-Dist: cfl-common ==6.41.
|
|
28
|
+
Requires-Dist: cfl-common ==6.41.6
|
|
29
29
|
Requires-Dist: django-ratelimit ==3.0.1
|
|
30
30
|
Requires-Dist: django-preventconcurrentlogins ==0.8.2
|
|
31
31
|
Requires-Dist: django-csp ==3.7
|