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

Files changed (69) hide show
  1. cfl_common/common/csp_config.py +0 -2
  2. cfl_common/common/mail.py +31 -6
  3. cfl_common/common/migrations/0005_add_worksheets.py +1 -5
  4. cfl_common/common/migrations/0007_add_pdf_names_to_first_two_worksheets.py +1 -5
  5. cfl_common/common/migrations/0054_delete_aimmo_models.py +20 -0
  6. cfl_common/common/models.py +0 -25
  7. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.1.0.dist-info}/METADATA +3 -4
  8. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.1.0.dist-info}/RECORD +44 -68
  9. example_project/portal_test_settings.py +0 -1
  10. example_project/settings.py +0 -1
  11. example_project/urls.py +0 -2
  12. portal/__init__.py +1 -1
  13. portal/static/portal/sass/partials/_banners.scss +0 -177
  14. portal/static/portal/sass/partials/_buttons.scss +0 -12
  15. portal/static/portal/sass/partials/_grids.scss +0 -53
  16. portal/static/portal/sass/partials/_text.scss +1 -10
  17. portal/static/portal/sass/styles.scss +0 -1
  18. portal/strings/play.py +1 -2
  19. portal/strings/teacher_resources.py +0 -10
  20. portal/templates/portal/about.html +91 -60
  21. portal/templates/portal/contribute.html +45 -49
  22. portal/templates/portal/partials/header.html +0 -12
  23. portal/templates/portal/play/independent_student_dashboard.html +12 -25
  24. portal/templates/portal/play/student_dashboard.html +16 -34
  25. portal/templates/portal/play.html +36 -49
  26. portal/templates/portal/register.html +1 -1
  27. portal/templates/portal/teach.html +37 -55
  28. portal/templates/portal/ten_year_map.html +9 -9
  29. portal/templatetags/app_tags.py +13 -28
  30. portal/tests/conftest.py +4 -16
  31. portal/tests/pageObjects/portal/base_page.py +20 -20
  32. portal/tests/snapshots/snap_test_partials.py +0 -452
  33. portal/tests/test_class.py +213 -45
  34. portal/tests/test_independent_student.py +0 -9
  35. portal/tests/test_partials.py +6 -56
  36. portal/tests/test_teacher.py +221 -285
  37. portal/tests/test_views.py +257 -73
  38. portal/urls.py +38 -20
  39. portal/views/cron/user.py +158 -15
  40. portal/views/student/play.py +36 -25
  41. portal/views/teacher/teach.py +0 -5
  42. cfl_common/common/tests/test_migration_aimmo_characters.py +0 -29
  43. portal/forms/add_game.py +0 -29
  44. portal/static/portal/img/kurono_hero.jpg +0 -0
  45. portal/static/portal/img/kurono_landing_hero.png +0 -0
  46. portal/static/portal/img/kurono_logo.svg +0 -1
  47. portal/static/portal/img/kurono_logo_grey_background.svg +0 -1
  48. portal/static/portal/img/kurono_logo_mark.svg +0 -1
  49. portal/static/portal/img/kurono_resources_hero.jpg +0 -0
  50. portal/static/portal/img/kurono_story.png +0 -0
  51. portal/static/portal/img/thumbnail_educate_kurono.png +0 -0
  52. portal/static/portal/img/thumbnail_kurono_resources.png +0 -0
  53. portal/static/portal/img/thumbnail_play_kurono.png +0 -0
  54. portal/static/portal/js/aimmoGame.js +0 -106
  55. portal/static/portal/sass/partials/_videos.scss +0 -10
  56. portal/static/portal/video/aimmo_play_now_background_video.mp4 +0 -0
  57. portal/strings/student_aimmo_dashboard.py +0 -6
  58. portal/templates/portal/partials/aimmo_games_table.html +0 -89
  59. portal/templates/portal/play/student_aimmo_dashboard.html +0 -46
  60. portal/templates/portal/teach/teacher_aimmo_dashboard.html +0 -95
  61. portal/templatetags/character_list_tags.py +0 -16
  62. portal/tests/pageObjects/portal/kurono_teacher_dashboard_page.py +0 -49
  63. portal/tests/test_aimmo_dashboards.py +0 -206
  64. portal/tests/utils/aimmo_games.py +0 -30
  65. portal/views/aimmo/__init__.py +0 -0
  66. portal/views/aimmo/dashboard.py +0 -105
  67. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.1.0.dist-info}/LICENSE.md +0 -0
  68. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.1.0.dist-info}/WHEEL +0 -0
  69. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.1.0.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  {% extends 'portal/base.html' %}
2
2
  {% load static %}
3
- {% load app_tags banner_tags headline_tags character_list_tags %}
3
+ {% load app_tags banner_tags headline_tags %}
4
4
 
5
5
  {% block subNav %}
6
6
  {% banner banner_name="BANNER" %}
@@ -66,14 +66,14 @@
66
66
  July 2024
67
67
  </h5>
68
68
  <p>
69
- We completed the UK leg of our world tour with an enthusiastic reception from Year 4 students at Howe Dell Primary School
70
- in Hatfield. The pupils were captivated by our presentation on different types of robots and Ocado Group's automation
71
- technology used in sorting and packing deliveries. They were then tasked with designing robots to solve problems, producing
72
- creative concepts like robot childminders and homework helpers. Midway through, we introduced them to coding with Rapid Router,
73
- explaining algorithms and letting them experiment with the levels. The students were thrilled about the competition for the
74
- best robot design, which included a prize of a golden 3D printed medal. Teachers praised the engaging and educational workshop,
75
- while Ocado volunteers found the experience rewarding and beneficial for developing their communication and teaching skills.
76
- The children's designs were exceptional, making the judging process challenging, but ultimately a few standout innovations were
69
+ We completed the UK leg of our world tour with an enthusiastic reception from Year 4 students at Howe Dell Primary School
70
+ in Hatfield. The pupils were captivated by our presentation on different types of robots and Ocado Group's automation
71
+ technology used in sorting and packing deliveries. They were then tasked with designing robots to solve problems, producing
72
+ creative concepts like robot childminders and homework helpers. Midway through, we introduced them to coding with Rapid Router,
73
+ explaining algorithms and letting them experiment with the levels. The students were thrilled about the competition for the
74
+ best robot design, which included a prize of a golden 3D printed medal. Teachers praised the engaging and educational workshop,
75
+ while Ocado volunteers found the experience rewarding and beneficial for developing their communication and teaching skills.
76
+ The children's designs were exceptional, making the judging process challenging, but ultimately a few standout innovations were
77
77
  selected.
78
78
  </p>
79
79
  <div class="carousel-button">
@@ -1,14 +1,7 @@
1
- from aimmo.templatetags.players_utils import get_user_playable_games
2
- from aimmo.worksheets import get_complete_worksheets, get_incomplete_worksheets
3
1
  from common import app_settings as common_app_settings
4
- from common.permissions import logged_in_as_teacher
5
2
  from common.utils import using_two_factor
6
3
  from django import template
7
4
  from django.conf import settings
8
- from django.contrib.auth.models import User
9
- from django.core.exceptions import ObjectDoesNotExist
10
- from django.shortcuts import reverse
11
- from django.template.context import RequestContext
12
5
  from django.template.defaultfilters import stringfilter
13
6
 
14
7
  from portal import __version__, beta
@@ -32,7 +25,10 @@ def is_logged_in(user):
32
25
  return (
33
26
  user
34
27
  and user.is_authenticated
35
- and (not using_two_factor(user) or (hasattr(user, "is_verified") and user.userprofile.is_verified))
28
+ and (
29
+ not using_two_factor(user)
30
+ or (hasattr(user, "is_verified") and user.userprofile.is_verified)
31
+ )
36
32
  )
37
33
 
38
34
 
@@ -52,16 +48,6 @@ def has_beta_access(request):
52
48
  return beta.has_beta_access(request)
53
49
 
54
50
 
55
- @register.inclusion_tag("portal/partials/aimmo_games_table.html", takes_context=True)
56
- def games_table(context, base_url):
57
- playable_games = get_user_playable_games(context, base_url)
58
-
59
- playable_games["complete_worksheets"] = get_complete_worksheets()
60
- playable_games["incomplete_worksheets"] = get_incomplete_worksheets()
61
-
62
- return playable_games
63
-
64
-
65
51
  @register.filter(name="make_into_username")
66
52
  def make_into_username(user):
67
53
  username = ""
@@ -76,7 +62,11 @@ def make_into_username(user):
76
62
 
77
63
  @register.filter(name="is_logged_in_as_teacher")
78
64
  def is_logged_in_as_teacher(user):
79
- return is_logged_in(user) and user.userprofile and hasattr(user.userprofile, "teacher")
65
+ return (
66
+ is_logged_in(user)
67
+ and user.userprofile
68
+ and hasattr(user.userprofile, "teacher")
69
+ )
80
70
 
81
71
 
82
72
  @register.filter(name="is_logged_in_as_admin_teacher")
@@ -116,7 +106,10 @@ def is_logged_in_as_school_user(user):
116
106
  is_logged_in(user)
117
107
  and user.userprofile
118
108
  and (
119
- (hasattr(user.userprofile, "student") and user.userprofile.student.class_field is not None)
109
+ (
110
+ hasattr(user.userprofile, "student")
111
+ and user.userprofile.student.class_field is not None
112
+ )
120
113
  or hasattr(user.userprofile, "teacher")
121
114
  )
122
115
  )
@@ -153,14 +146,6 @@ def get_project_version():
153
146
  return __version__
154
147
 
155
148
 
156
- @register.simple_tag(takes_context=True)
157
- def url_for_aimmo_dashboard(context: RequestContext):
158
- if logged_in_as_teacher(context.request.user):
159
- return reverse("teacher_aimmo_dashboard")
160
- else:
161
- return reverse("student_aimmo_dashboard")
162
-
163
-
164
149
  @register.filter
165
150
  def get_dict_item(dictionary, key):
166
151
  return dictionary[key]
portal/tests/conftest.py CHANGED
@@ -1,16 +1,15 @@
1
1
  from collections import namedtuple
2
- from unittest.mock import MagicMock
3
2
 
4
3
  import pytest
5
- from aimmo.models import Game
6
4
  from common.models import Class
7
5
  from common.tests.utils.classes import create_class_directly
8
6
  from common.tests.utils.organisation import create_organisation_directly
9
- from common.tests.utils.student import create_independent_student_directly, create_school_student_directly
7
+ from common.tests.utils.student import (
8
+ create_independent_student_directly,
9
+ create_school_student_directly,
10
+ )
10
11
  from common.tests.utils.teacher import signup_teacher_directly
11
12
 
12
- from .utils.aimmo_games import create_aimmo_game_directly
13
-
14
13
  SchoolStudent = namedtuple("student", ["username", "password"])
15
14
  IndependentStudent = namedtuple("independent_student", ["username", "password"])
16
15
  TeacherLoginDetails = namedtuple("teacher", ["email", "password"])
@@ -38,14 +37,3 @@ def student1(db, class1) -> SchoolStudent:
38
37
  def independent_student1(db) -> IndependentStudent:
39
38
  username, password, _ = create_independent_student_directly()
40
39
  return IndependentStudent(username, password)
41
-
42
-
43
- @pytest.fixture
44
- def aimmo_game1(db, class1) -> Game:
45
- return create_aimmo_game_directly(klass=class1, worksheet_id=1)
46
-
47
-
48
- @pytest.fixture(autouse=True)
49
- def mock_game_manager(monkeypatch):
50
- """Mock GameManager for all tests."""
51
- monkeypatch.setattr("aimmo.models.GameManager", MagicMock())
@@ -26,17 +26,23 @@ class BasePage(object):
26
26
  def wait_for_element_by_css(self, css, wait_seconds=DEFAULT_WAIT_SECONDS):
27
27
  self.wait_for_presence((By.CSS_SELECTOR, css), wait_seconds)
28
28
 
29
- def wait_for_element_to_be_clickable(self, locator, wait_seconds=DEFAULT_WAIT_SECONDS):
29
+ def wait_for_element_to_be_clickable(
30
+ self, locator, wait_seconds=DEFAULT_WAIT_SECONDS
31
+ ):
30
32
  self.wait(EC.element_to_be_clickable(locator), wait_seconds)
31
33
 
32
- def wait_for_element_to_be_invisible(self, locator, wait_seconds=DEFAULT_WAIT_SECONDS):
34
+ def wait_for_element_to_be_invisible(
35
+ self, locator, wait_seconds=DEFAULT_WAIT_SECONDS
36
+ ):
33
37
  self.wait(EC.invisibility_of_element_located(locator), wait_seconds)
34
38
 
35
39
  def wait_for_presence(self, locator, wait_seconds=DEFAULT_WAIT_SECONDS):
36
40
  self.wait(EC.presence_of_element_located(locator), wait_seconds)
37
41
 
38
42
  def wait_for_absence(self, locator, wait_seconds=DEFAULT_WAIT_SECONDS):
39
- self.wait_until_not(EC.presence_of_element_located(locator), wait_seconds)
43
+ self.wait_until_not(
44
+ EC.presence_of_element_located(locator), wait_seconds
45
+ )
40
46
 
41
47
  def wait(self, method, wait_seconds=DEFAULT_WAIT_SECONDS):
42
48
  WebDriverWait(self.browser, wait_seconds).until(method)
@@ -74,31 +80,21 @@ class BasePage(object):
74
80
  return self.element_exists_by_id(pageName)
75
81
 
76
82
  def hover_over_resources_dropdown(self):
77
- resources_dropdown = self.browser.find_element(By.ID, "teaching_resources_button")
83
+ resources_dropdown = self.browser.find_element(
84
+ By.ID, "teaching_resources_button"
85
+ )
78
86
  hover = ActionChains(self.browser).move_to_element(resources_dropdown)
79
87
  hover.perform()
80
88
 
81
89
  def go_to_rapid_router_resources_page(self):
82
90
  self.hover_over_resources_dropdown()
83
- self.browser.find_element(By.ID, "rapid_router_resources_button").click()
91
+ self.browser.find_element(
92
+ By.ID, "rapid_router_resources_button"
93
+ ).click()
84
94
  from .resources_page import ResourcesPage
85
95
 
86
96
  return ResourcesPage(self.browser)
87
97
 
88
- def go_to_kurono_resources_page(self):
89
- self.hover_over_resources_dropdown()
90
- self.browser.find_element(By.ID, "kurono_resources_button").click()
91
- from .resources_page import ResourcesPage
92
-
93
- return ResourcesPage(self.browser)
94
-
95
- def go_to_kurono_teacher_dashboard_page(self):
96
- self.browser.find_element(By.ID, "games_button").click()
97
- self.browser.find_element(By.ID, "teacher_kurono_dashboard_button").click()
98
- from .kurono_teacher_dashboard_page import KuronoTeacherDashboardPage
99
-
100
- return KuronoTeacherDashboardPage(self.browser)
101
-
102
98
  def is_on_admin_login_page(self):
103
99
  return self.on_correct_page("administration_login")
104
100
 
@@ -112,7 +108,11 @@ class BasePage(object):
112
108
  return self.on_correct_page("403_forbidden")
113
109
 
114
110
  def was_form_invalid(self, formID, error):
115
- errors = self.browser.find_element(By.ID, formID).find_element(By.CLASS_NAME, "errorlist").text
111
+ errors = (
112
+ self.browser.find_element(By.ID, formID)
113
+ .find_element(By.CLASS_NAME, "errorlist")
114
+ .text
115
+ )
116
116
  return error in errors
117
117
 
118
118
  def is_dialog_showing(self):