codeforlife-portal 8.7.3__py2.py3-none-any.whl → 8.7.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.
- {codeforlife_portal-8.7.3.dist-info → codeforlife_portal-8.7.4.dist-info}/METADATA +3 -3
- {codeforlife_portal-8.7.3.dist-info → codeforlife_portal-8.7.4.dist-info}/RECORD +11 -11
- portal/__init__.py +1 -1
- portal/forms/organisation.py +5 -11
- portal/tests/pageObjects/portal/teach/dashboard_page.py +0 -6
- portal/tests/pageObjects/portal/teach/onboarding_organisation_page.py +5 -12
- portal/tests/test_organisation.py +37 -5
- portal/tests/test_teacher.py +1 -1
- {codeforlife_portal-8.7.3.dist-info → codeforlife_portal-8.7.4.dist-info}/WHEEL +0 -0
- {codeforlife_portal-8.7.3.dist-info → codeforlife_portal-8.7.4.dist-info}/licenses/LICENSE.md +0 -0
- {codeforlife_portal-8.7.3.dist-info → codeforlife_portal-8.7.4.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeforlife-portal
|
|
3
|
-
Version: 8.7.
|
|
3
|
+
Version: 8.7.4
|
|
4
4
|
Classifier: Programming Language :: Python
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.12
|
|
6
6
|
Classifier: Framework :: Django
|
|
@@ -8,7 +8,7 @@ Description-Content-Type: text/markdown
|
|
|
8
8
|
License-File: LICENSE.md
|
|
9
9
|
Requires-Dist: asgiref==3.8.1; python_version >= "3.8"
|
|
10
10
|
Requires-Dist: certifi==2025.4.26; python_version >= "3.6"
|
|
11
|
-
Requires-Dist: cfl-common==8.7.
|
|
11
|
+
Requires-Dist: cfl-common==8.7.4
|
|
12
12
|
Requires-Dist: chardet==5.2.0; python_version >= "3.7"
|
|
13
13
|
Requires-Dist: charset-normalizer==3.4.2; python_version >= "3.7"
|
|
14
14
|
Requires-Dist: diff-match-patch==20241021; python_version >= "3.7"
|
|
@@ -60,7 +60,7 @@ Requires-Dist: asttokens==3.0.0; python_version >= "3.8" and extra == "dev"
|
|
|
60
60
|
Requires-Dist: attrs==25.3.0; python_version >= "3.8" and extra == "dev"
|
|
61
61
|
Requires-Dist: black==25.1.0; python_version >= "3.9" and extra == "dev"
|
|
62
62
|
Requires-Dist: certifi==2025.4.26; python_version >= "3.6" and extra == "dev"
|
|
63
|
-
Requires-Dist: cfl-common==8.7.
|
|
63
|
+
Requires-Dist: cfl-common==8.7.4; extra == "dev"
|
|
64
64
|
Requires-Dist: charset-normalizer==3.4.2; python_version >= "3.7" and extra == "dev"
|
|
65
65
|
Requires-Dist: click==8.2.1; python_version >= "3.10" and extra == "dev"
|
|
66
66
|
Requires-Dist: coverage[toml]==7.8.2; python_version >= "3.9" and extra == "dev"
|
|
@@ -87,7 +87,7 @@ cfl_common/common/tests/utils/organisation.py,sha256=vNgKFtU3VPcWRnZfh82yCS90PLA
|
|
|
87
87
|
cfl_common/common/tests/utils/student.py,sha256=PLd980iSlxmMoB8J3C2pVjNC5xHdVxfAkJXzhv_dRhg,3814
|
|
88
88
|
cfl_common/common/tests/utils/teacher.py,sha256=KQ_NAl4yQqiX_zwcULQjkovc29JPhnkLR5Nk3Ljzbpg,2661
|
|
89
89
|
cfl_common/common/tests/utils/user.py,sha256=NvLzZLVP4jy5Hn1iztOYF_BTQ9WsbSmuWMEzGzhAsRU,919
|
|
90
|
-
codeforlife_portal-8.7.
|
|
90
|
+
codeforlife_portal-8.7.4.dist-info/licenses/LICENSE.md,sha256=9AbRlCDqD2D1tPibimysFv3zg3AIc49-eyv9aEsyq9w,115
|
|
91
91
|
deploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
92
92
|
deploy/captcha.py,sha256=MbOBuGnbT_SOIltSjP1XMOLrfo1DldCilaVAEim0vM4,23
|
|
93
93
|
deploy/views.py,sha256=7mY2zNPkaBFrlWGByJHp2zFqHIHSMc0YArjE_sFWMMU,131
|
|
@@ -111,7 +111,7 @@ example_project/portal_test_settings.py,sha256=AaXwSSB2A6qu6My_7cBciQa_jONy084uq
|
|
|
111
111
|
example_project/settings.py,sha256=RRSHhAgJVDn4uNZG395V6_Td7jwsSaBGNwQBZ_KJm0Y,5973
|
|
112
112
|
example_project/urls.py,sha256=FUTzHPlUS1O5kqMHjL5V4L552N2ln7uTDXcw9wjKUto,422
|
|
113
113
|
example_project/wsgi.py,sha256=U1W6WzZxZaIdYZ5tks7w9fqp5WS5qvn2iThsVcskrWw,829
|
|
114
|
-
portal/__init__.py,sha256=
|
|
114
|
+
portal/__init__.py,sha256=wHEOdRusBiLao3c9nqf81YK6XRQABxAMpJ9HVGTQfWg,22
|
|
115
115
|
portal/admin.py,sha256=RKJizTF6dPJKmGPZw7nZUM0X8jkiTjgyKhLQxtvHJ0I,6148
|
|
116
116
|
portal/app_settings.py,sha256=DhWLQOwM0zVOXE3O5TNKbMM9K6agfLuCsHOdr1J7xEI,651
|
|
117
117
|
portal/backends.py,sha256=2Dss6_WoQwPuDzJUF1yEaTQTNG4eUrD12ujJQ5cp5Tc,812
|
|
@@ -126,7 +126,7 @@ portal/forms/admin.py,sha256=Cdl8-wvasAzvMfgUlFYzQjYeuyC7gIsSiy8V_-jMp7w,2080
|
|
|
126
126
|
portal/forms/dotmailer.py,sha256=AiHoN8ZRl3A69FYSldkjlhICGx_l4BujP5HjYdSRCok,897
|
|
127
127
|
portal/forms/error_messages.py,sha256=8d3z_3e2L-5zwj5hFhnUByC5k2CEpIVVuJg2nYkCUQ8,148
|
|
128
128
|
portal/forms/invite_teacher.py,sha256=jkDNcCfkts4_lXRzhcI3xBam21Zn2yX9wMpMVhDtW1w,880
|
|
129
|
-
portal/forms/organisation.py,sha256
|
|
129
|
+
portal/forms/organisation.py,sha256=-h4Lpl4WisqNGgohlsmqh_ABA0aLfeXtUxAR1sUdi0I,7278
|
|
130
130
|
portal/forms/play.py,sha256=j_QYAKb4qyW0uy0VUUG49dmzDLINc3jR6ddK-djrbc4,11523
|
|
131
131
|
portal/forms/registration.py,sha256=a-TuzikRc0Q-BAYs3rJ3Sz1wmQ1o_rTEtZmWdF7-xss,6008
|
|
132
132
|
portal/forms/teach.py,sha256=lQivQ4pXnvJw8nJMSbqtg-Il5RYkw54ZxE5rJuNlFn0,22391
|
|
@@ -543,12 +543,12 @@ portal/tests/test_helper_methods.py,sha256=-SQCDZm2XUtyXGEp0CHIb_SSC9CPD-XOSnpnY
|
|
|
543
543
|
portal/tests/test_independent_student.py,sha256=NrRjTEr6V4WXpCE74N8LYNVocvLSvddkjuo3dYpfAZc,27245
|
|
544
544
|
portal/tests/test_invite_teacher.py,sha256=hynk2p63URQocCS8N6-IQnQWkdzggQ-1jGDuWcRSY_Y,14902
|
|
545
545
|
portal/tests/test_middleware.py,sha256=HV7AdgWyvgrtPyDMw3np5YDbUstFpKif7Qqw-e8gs5s,8258
|
|
546
|
-
portal/tests/test_organisation.py,sha256=
|
|
546
|
+
portal/tests/test_organisation.py,sha256=1rTHTUhdDHMG1Xf4FXMvwOAuXWzFWTVUnryJyW9zOgs,8949
|
|
547
547
|
portal/tests/test_partials.py,sha256=cSLNLjdsriROjPxkZlM3HKD3CSKDuKgpaDIdL3fPyBs,1794
|
|
548
548
|
portal/tests/test_ratelimit.py,sha256=XWq1A9XgRrlcMHibGoJ0kc4gLc5U_u5UhKHjthxCfYA,19376
|
|
549
549
|
portal/tests/test_school_student.py,sha256=bFZwY4twaFHQLp0cltMq8cLNDZGgCHTZBCZHK0JcV8s,8604
|
|
550
550
|
portal/tests/test_security.py,sha256=FGrlRfnzi-Xx2_bn4fTZlYORKm7w_GhGkD3havvplwc,3239
|
|
551
|
-
portal/tests/test_teacher.py,sha256=
|
|
551
|
+
portal/tests/test_teacher.py,sha256=fYdqWYVT-EcWUzQBNZ5qOORO7UC_S14NtACx64Rsrbg,29159
|
|
552
552
|
portal/tests/test_teacher_student.py,sha256=4Di29Lsymbmh6WxZ0FYpqZ4fMN8NqNMTXXOsii1dfW4,21624
|
|
553
553
|
portal/tests/test_views.py,sha256=Hv0rVOLmYivMqzJK1AQeRJ85YHTCRrlr12hcf1B83Bk,47566
|
|
554
554
|
portal/tests/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -588,7 +588,7 @@ portal/tests/pageObjects/portal/teach/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCe
|
|
|
588
588
|
portal/tests/pageObjects/portal/teach/add_independent_student_to_class_page.py,sha256=P2iW94L7tiLfPz789GcQMyEvGf0QW5i4FUQ_EyVCQyY,931
|
|
589
589
|
portal/tests/pageObjects/portal/teach/added_independent_student_to_class_page.py,sha256=FnFfIref2Izu6Gquql_D5rvQ32_khulGM1LHnU0cHv8,585
|
|
590
590
|
portal/tests/pageObjects/portal/teach/class_page.py,sha256=4UuKJxEglZcprR5redmoeVuO3wf0tuwsn-glucS8hKc,3932
|
|
591
|
-
portal/tests/pageObjects/portal/teach/dashboard_page.py,sha256=
|
|
591
|
+
portal/tests/pageObjects/portal/teach/dashboard_page.py,sha256=rWtKgw6urggoIgKj10fj5IAh_X_C9MVPeLD7CWnTo1Y,6404
|
|
592
592
|
portal/tests/pageObjects/portal/teach/dismiss_students_page.py,sha256=qU3D3og4sxIbn4RAKYTaQNQxF0OKodbYzH5XA2detnE,882
|
|
593
593
|
portal/tests/pageObjects/portal/teach/edit_student_page.py,sha256=qv0B9tc2w1nmW21zu2ObhIhBYOAvF-HswqNZe39jkts,1399
|
|
594
594
|
portal/tests/pageObjects/portal/teach/move_class_page.py,sha256=GbhCrSfUSIm_NWmqgw4qQPH8tgNiTn6HNSmOyTQ_CJU,1032
|
|
@@ -596,7 +596,7 @@ portal/tests/pageObjects/portal/teach/move_classes_page.py,sha256=FsXJV8s9hvI5lf
|
|
|
596
596
|
portal/tests/pageObjects/portal/teach/move_students_disambiguate_page.py,sha256=-seb1yylbDzGMLeUrlu2-SlTqTBU-Awa_kPV_EXpfpM,673
|
|
597
597
|
portal/tests/pageObjects/portal/teach/move_students_page.py,sha256=j_nt8e908Deq-d51tL88KHJfcRQkEJH2eQm6Hvz9Vfs,1078
|
|
598
598
|
portal/tests/pageObjects/portal/teach/onboarding_classes_page.py,sha256=rVKaJyDeRpSYkG86KB3QWQfgsxuL4Gftj-z19KYOmNM,1046
|
|
599
|
-
portal/tests/pageObjects/portal/teach/onboarding_organisation_page.py,sha256=
|
|
599
|
+
portal/tests/pageObjects/portal/teach/onboarding_organisation_page.py,sha256=Rm_zxQYn2STpgLPUyASnjG8Mdf5TvXeTIz8k5ve6-NM,1679
|
|
600
600
|
portal/tests/pageObjects/portal/teach/onboarding_student_list_page.py,sha256=28Vz8-IrKf0VoFE_KisAApkunfEE7lX1yj0-nxvKsDw,1147
|
|
601
601
|
portal/tests/pageObjects/portal/teach/onboarding_students_page.py,sha256=522Y79PfNV1PcR-Clf19KnNe2r3xf4sPPAUnroIzk80,971
|
|
602
602
|
portal/tests/pageObjects/portal/teach/teach_base_page.py,sha256=vnd5YO15baBgCkqyBkXGZpdjZRMRpeeN69dH-fG383A,1229
|
|
@@ -634,7 +634,7 @@ portal/views/two_factor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
|
634
634
|
portal/views/two_factor/core.py,sha256=Lk32z2SN2Pg0rRkK-N-LXMvXC1kKKsH3l692kiSDQ4E,964
|
|
635
635
|
portal/views/two_factor/form.py,sha256=lnHNKI-BMlpncTuW3zUzjPaJJNuEra2I_nOam0eOKFY,257
|
|
636
636
|
portal/views/two_factor/profile.py,sha256=SHSg_xHccE5PtD-OfuOkYhREYz_er4bj5ro1RjJ88Yw,393
|
|
637
|
-
codeforlife_portal-8.7.
|
|
638
|
-
codeforlife_portal-8.7.
|
|
639
|
-
codeforlife_portal-8.7.
|
|
640
|
-
codeforlife_portal-8.7.
|
|
637
|
+
codeforlife_portal-8.7.4.dist-info/METADATA,sha256=GjLnfnrWW_nLiHkpJOUYaC-HqcOKkLqJ4F6FOkY-4i4,12342
|
|
638
|
+
codeforlife_portal-8.7.4.dist-info/WHEEL,sha256=JNWh1Fm1UdwIQV075glCn4MVuCRs0sotJIq-J6rbxCU,109
|
|
639
|
+
codeforlife_portal-8.7.4.dist-info/top_level.txt,sha256=8e5pdsuIoTqEAMqpelHBjGjLbffcBtgOoggmd2q7nMw,41
|
|
640
|
+
codeforlife_portal-8.7.4.dist-info/RECORD,,
|
portal/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "8.7.
|
|
1
|
+
__version__ = "8.7.4"
|
portal/forms/organisation.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
import re
|
|
1
2
|
from builtins import object
|
|
2
3
|
|
|
3
4
|
from common.models import School
|
|
4
5
|
from django import forms
|
|
5
6
|
from django.core.exceptions import ObjectDoesNotExist
|
|
6
|
-
from django.core.validators import EmailValidator
|
|
7
7
|
from django_countries.widgets import CountrySelectWidget
|
|
8
8
|
|
|
9
9
|
|
|
@@ -167,16 +167,10 @@ class OrganisationForm(forms.ModelForm):
|
|
|
167
167
|
|
|
168
168
|
def clean_name(self):
|
|
169
169
|
name = self.cleaned_data.get("name", None)
|
|
170
|
-
validator = EmailValidator()
|
|
171
170
|
|
|
172
|
-
if name:
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
except forms.ValidationError:
|
|
177
|
-
is_email = False
|
|
178
|
-
|
|
179
|
-
if is_email:
|
|
180
|
-
raise forms.ValidationError("Please make sure your organisation name is valid")
|
|
171
|
+
if re.match(re.compile("^[\w\.' ]+$"), name) is None:
|
|
172
|
+
raise forms.ValidationError(
|
|
173
|
+
"School names cannot contain special characters except full stops and apostrophes."
|
|
174
|
+
)
|
|
181
175
|
|
|
182
176
|
return name
|
|
@@ -52,12 +52,6 @@ class TeachDashboardPage(TeachBasePage):
|
|
|
52
52
|
self.browser.find_element(By.ID, "update_details_button").click()
|
|
53
53
|
return self
|
|
54
54
|
|
|
55
|
-
def has_edit_failed(self):
|
|
56
|
-
self.wait_for_element_by_id("edit_form")
|
|
57
|
-
errorlist = self.browser.find_element(By.ID, "edit_form").find_element(By.CLASS_NAME, "errorlist").text
|
|
58
|
-
error = "There is already a school or club registered with that name"
|
|
59
|
-
return error in errorlist
|
|
60
|
-
|
|
61
55
|
def create_class(self, name, classmate_progress, teacher_id=None):
|
|
62
56
|
self.browser.find_element(By.ID, "id_class_name").send_keys(name)
|
|
63
57
|
if classmate_progress:
|
|
@@ -13,13 +13,13 @@ class OnboardingOrganisationPage(TeachBasePage):
|
|
|
13
13
|
|
|
14
14
|
assert self.on_correct_page("onboarding_organisation_page")
|
|
15
15
|
|
|
16
|
-
def create_organisation(self, name,
|
|
17
|
-
self._create_organisation(name,
|
|
16
|
+
def create_organisation(self, name, country="GB"):
|
|
17
|
+
self._create_organisation(name, country)
|
|
18
18
|
|
|
19
19
|
return onboarding_classes_page.OnboardingClassesPage(self.browser)
|
|
20
20
|
|
|
21
|
-
def create_organisation_failure(self, name,
|
|
22
|
-
self._create_organisation(name,
|
|
21
|
+
def create_organisation_failure(self, name, country="GB"):
|
|
22
|
+
self._create_organisation(name, country)
|
|
23
23
|
|
|
24
24
|
return self
|
|
25
25
|
|
|
@@ -28,7 +28,7 @@ class OnboardingOrganisationPage(TeachBasePage):
|
|
|
28
28
|
|
|
29
29
|
return self
|
|
30
30
|
|
|
31
|
-
def _create_organisation(self, name,
|
|
31
|
+
def _create_organisation(self, name, country):
|
|
32
32
|
self.browser.find_element(By.ID, "id_name").send_keys(name)
|
|
33
33
|
country_element = self.browser.find_element(By.ID, "id_country")
|
|
34
34
|
select = Select(country_element)
|
|
@@ -47,10 +47,3 @@ class OnboardingOrganisationPage(TeachBasePage):
|
|
|
47
47
|
)
|
|
48
48
|
error = "There is already a school or club registered with that name and postcode"
|
|
49
49
|
return error in errors
|
|
50
|
-
|
|
51
|
-
def was_postcode_invalid(self):
|
|
52
|
-
errors = (
|
|
53
|
-
self.browser.find_element(By.ID, "form-create-organisation").find_element(By.CLASS_NAME, "errorlist").text
|
|
54
|
-
)
|
|
55
|
-
error = "Please enter a valid postcode or ZIP code"
|
|
56
|
-
return error in errors
|
|
@@ -16,7 +16,6 @@ from selenium.webdriver.common.by import By
|
|
|
16
16
|
from portal.tests.pageObjects.portal.base_page import BasePage
|
|
17
17
|
from portal.tests.pageObjects.portal.home_page import HomePage
|
|
18
18
|
from portal.tests.test_invite_teacher import FADE_TIME
|
|
19
|
-
|
|
20
19
|
from .base_test import BaseTest
|
|
21
20
|
from .utils.messages import is_organisation_created_message_showing
|
|
22
21
|
|
|
@@ -28,8 +27,22 @@ class TestOrganisation(BaseTest, BasePage):
|
|
|
28
27
|
self.selenium.get(self.live_server_url)
|
|
29
28
|
page = HomePage(self.selenium).go_to_teacher_login_page().login_no_school(email, password)
|
|
30
29
|
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
school_name = "My School"
|
|
31
|
+
page.create_organisation(school_name)
|
|
32
|
+
assert is_organisation_created_message_showing(self.selenium, school_name)
|
|
33
|
+
|
|
34
|
+
def test_create_invalid_name(self):
|
|
35
|
+
email, password = signup_teacher_directly()
|
|
36
|
+
|
|
37
|
+
self.selenium.get(self.live_server_url)
|
|
38
|
+
page = HomePage(self.selenium).go_to_teacher_login_page().login_no_school(email, password)
|
|
39
|
+
|
|
40
|
+
invalid_school_name = "<a>My School</a"
|
|
41
|
+
page.create_organisation_failure(invalid_school_name)
|
|
42
|
+
assert page.was_form_invalid(
|
|
43
|
+
"form-create-organisation",
|
|
44
|
+
"School names cannot contain special characters except full stops and apostrophes.",
|
|
45
|
+
)
|
|
33
46
|
|
|
34
47
|
def test_kick(self):
|
|
35
48
|
email_1, password_1 = signup_teacher_directly()
|
|
@@ -171,11 +184,30 @@ class TestOrganisation(BaseTest, BasePage):
|
|
|
171
184
|
|
|
172
185
|
assert page.check_organisation_details({"name": school.name})
|
|
173
186
|
|
|
174
|
-
new_name = "new
|
|
187
|
+
new_name = f"new {school.name}"
|
|
175
188
|
|
|
176
189
|
page.change_organisation_details({"name": new_name})
|
|
177
190
|
assert page.check_organisation_details({"name": new_name})
|
|
178
191
|
|
|
192
|
+
def test_edit_details_invalid_name(self):
|
|
193
|
+
email, password = signup_teacher_directly()
|
|
194
|
+
school = create_organisation_directly(email)
|
|
195
|
+
_, _, access_code = create_class_directly(email)
|
|
196
|
+
create_school_student_directly(access_code)
|
|
197
|
+
|
|
198
|
+
self.selenium.get(self.live_server_url)
|
|
199
|
+
page = HomePage(self.selenium).go_to_teacher_login_page().login(email, password)
|
|
200
|
+
|
|
201
|
+
assert page.check_organisation_details({"name": school.name})
|
|
202
|
+
|
|
203
|
+
new_name = f"<a>{school.name}</a>"
|
|
204
|
+
|
|
205
|
+
page.change_organisation_details({"name": new_name})
|
|
206
|
+
|
|
207
|
+
assert page.was_form_invalid(
|
|
208
|
+
"edit_form", "School names cannot contain special characters except full stops and apostrophes."
|
|
209
|
+
)
|
|
210
|
+
|
|
179
211
|
def test_edit_clash(self):
|
|
180
212
|
email_1, _ = signup_teacher_directly()
|
|
181
213
|
email_2, password_2 = signup_teacher_directly()
|
|
@@ -193,4 +225,4 @@ class TestOrganisation(BaseTest, BasePage):
|
|
|
193
225
|
|
|
194
226
|
page = page.change_organisation_details({"name": school1.name})
|
|
195
227
|
|
|
196
|
-
assert page.
|
|
228
|
+
assert page.was_form_invalid("edit_form", "There is already a school or club registered with that name")
|
portal/tests/test_teacher.py
CHANGED
|
@@ -772,7 +772,7 @@ class TestTeacherFrontend(BaseTest):
|
|
|
772
772
|
.login_no_school(email, password)
|
|
773
773
|
)
|
|
774
774
|
|
|
775
|
-
page = page.create_organisation("Test school"
|
|
775
|
+
page = page.create_organisation("Test school")
|
|
776
776
|
page = page.create_class("Test class", True)
|
|
777
777
|
page = (
|
|
778
778
|
page.type_student_name("Test Student")
|
|
File without changes
|
{codeforlife_portal-8.7.3.dist-info → codeforlife_portal-8.7.4.dist-info}/licenses/LICENSE.md
RENAMED
|
File without changes
|
|
File without changes
|