codeforlife-portal 6.46.1__py2.py3-none-any.whl → 7.0.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.
- cfl_common/common/csp_config.py +0 -2
- 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/0054_delete_aimmo_models.py +20 -0
- cfl_common/common/models.py +0 -25
- {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/METADATA +3 -4
- {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/RECORD +42 -66
- example_project/portal_test_settings.py +0 -1
- example_project/settings.py +0 -1
- example_project/urls.py +0 -2
- portal/__init__.py +1 -1
- portal/static/portal/sass/partials/_banners.scss +0 -177
- portal/static/portal/sass/partials/_buttons.scss +0 -12
- portal/static/portal/sass/partials/_grids.scss +0 -53
- portal/static/portal/sass/partials/_text.scss +1 -10
- portal/static/portal/sass/styles.scss +0 -1
- portal/strings/play.py +1 -2
- portal/strings/teacher_resources.py +0 -10
- portal/templates/portal/about.html +91 -60
- portal/templates/portal/contribute.html +45 -49
- portal/templates/portal/partials/header.html +0 -12
- portal/templates/portal/play/independent_student_dashboard.html +12 -25
- portal/templates/portal/play/student_dashboard.html +16 -34
- portal/templates/portal/play.html +36 -49
- portal/templates/portal/register.html +1 -1
- portal/templates/portal/teach.html +37 -55
- portal/templates/portal/ten_year_map.html +9 -9
- portal/templatetags/app_tags.py +13 -28
- portal/tests/conftest.py +4 -16
- portal/tests/pageObjects/portal/base_page.py +20 -20
- portal/tests/snapshots/snap_test_partials.py +0 -452
- portal/tests/test_class.py +213 -45
- portal/tests/test_independent_student.py +0 -9
- portal/tests/test_partials.py +6 -56
- portal/tests/test_teacher.py +221 -285
- portal/tests/test_views.py +156 -73
- portal/urls.py +23 -20
- portal/views/student/play.py +36 -25
- portal/views/teacher/teach.py +0 -5
- cfl_common/common/tests/test_migration_aimmo_characters.py +0 -29
- portal/forms/add_game.py +0 -29
- portal/static/portal/img/kurono_hero.jpg +0 -0
- portal/static/portal/img/kurono_landing_hero.png +0 -0
- portal/static/portal/img/kurono_logo.svg +0 -1
- portal/static/portal/img/kurono_logo_grey_background.svg +0 -1
- portal/static/portal/img/kurono_logo_mark.svg +0 -1
- portal/static/portal/img/kurono_resources_hero.jpg +0 -0
- portal/static/portal/img/kurono_story.png +0 -0
- portal/static/portal/img/thumbnail_educate_kurono.png +0 -0
- portal/static/portal/img/thumbnail_kurono_resources.png +0 -0
- portal/static/portal/img/thumbnail_play_kurono.png +0 -0
- portal/static/portal/js/aimmoGame.js +0 -106
- portal/static/portal/sass/partials/_videos.scss +0 -10
- portal/static/portal/video/aimmo_play_now_background_video.mp4 +0 -0
- portal/strings/student_aimmo_dashboard.py +0 -6
- portal/templates/portal/partials/aimmo_games_table.html +0 -89
- portal/templates/portal/play/student_aimmo_dashboard.html +0 -46
- portal/templates/portal/teach/teacher_aimmo_dashboard.html +0 -95
- portal/templatetags/character_list_tags.py +0 -16
- portal/tests/pageObjects/portal/kurono_teacher_dashboard_page.py +0 -49
- portal/tests/test_aimmo_dashboards.py +0 -206
- portal/tests/utils/aimmo_games.py +0 -30
- portal/views/aimmo/__init__.py +0 -0
- portal/views/aimmo/dashboard.py +0 -105
- {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/LICENSE.md +0 -0
- {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/WHEEL +0 -0
- {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.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
|
|
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">
|
portal/templatetags/app_tags.py
CHANGED
|
@@ -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 (
|
|
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
|
|
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
|
-
(
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 =
|
|
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):
|