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.

Files changed (67) hide show
  1. cfl_common/common/csp_config.py +0 -2
  2. cfl_common/common/migrations/0005_add_worksheets.py +1 -5
  3. cfl_common/common/migrations/0007_add_pdf_names_to_first_two_worksheets.py +1 -5
  4. cfl_common/common/migrations/0054_delete_aimmo_models.py +20 -0
  5. cfl_common/common/models.py +0 -25
  6. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/METADATA +3 -4
  7. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/RECORD +42 -66
  8. example_project/portal_test_settings.py +0 -1
  9. example_project/settings.py +0 -1
  10. example_project/urls.py +0 -2
  11. portal/__init__.py +1 -1
  12. portal/static/portal/sass/partials/_banners.scss +0 -177
  13. portal/static/portal/sass/partials/_buttons.scss +0 -12
  14. portal/static/portal/sass/partials/_grids.scss +0 -53
  15. portal/static/portal/sass/partials/_text.scss +1 -10
  16. portal/static/portal/sass/styles.scss +0 -1
  17. portal/strings/play.py +1 -2
  18. portal/strings/teacher_resources.py +0 -10
  19. portal/templates/portal/about.html +91 -60
  20. portal/templates/portal/contribute.html +45 -49
  21. portal/templates/portal/partials/header.html +0 -12
  22. portal/templates/portal/play/independent_student_dashboard.html +12 -25
  23. portal/templates/portal/play/student_dashboard.html +16 -34
  24. portal/templates/portal/play.html +36 -49
  25. portal/templates/portal/register.html +1 -1
  26. portal/templates/portal/teach.html +37 -55
  27. portal/templates/portal/ten_year_map.html +9 -9
  28. portal/templatetags/app_tags.py +13 -28
  29. portal/tests/conftest.py +4 -16
  30. portal/tests/pageObjects/portal/base_page.py +20 -20
  31. portal/tests/snapshots/snap_test_partials.py +0 -452
  32. portal/tests/test_class.py +213 -45
  33. portal/tests/test_independent_student.py +0 -9
  34. portal/tests/test_partials.py +6 -56
  35. portal/tests/test_teacher.py +221 -285
  36. portal/tests/test_views.py +156 -73
  37. portal/urls.py +23 -20
  38. portal/views/student/play.py +36 -25
  39. portal/views/teacher/teach.py +0 -5
  40. cfl_common/common/tests/test_migration_aimmo_characters.py +0 -29
  41. portal/forms/add_game.py +0 -29
  42. portal/static/portal/img/kurono_hero.jpg +0 -0
  43. portal/static/portal/img/kurono_landing_hero.png +0 -0
  44. portal/static/portal/img/kurono_logo.svg +0 -1
  45. portal/static/portal/img/kurono_logo_grey_background.svg +0 -1
  46. portal/static/portal/img/kurono_logo_mark.svg +0 -1
  47. portal/static/portal/img/kurono_resources_hero.jpg +0 -0
  48. portal/static/portal/img/kurono_story.png +0 -0
  49. portal/static/portal/img/thumbnail_educate_kurono.png +0 -0
  50. portal/static/portal/img/thumbnail_kurono_resources.png +0 -0
  51. portal/static/portal/img/thumbnail_play_kurono.png +0 -0
  52. portal/static/portal/js/aimmoGame.js +0 -106
  53. portal/static/portal/sass/partials/_videos.scss +0 -10
  54. portal/static/portal/video/aimmo_play_now_background_video.mp4 +0 -0
  55. portal/strings/student_aimmo_dashboard.py +0 -6
  56. portal/templates/portal/partials/aimmo_games_table.html +0 -89
  57. portal/templates/portal/play/student_aimmo_dashboard.html +0 -46
  58. portal/templates/portal/teach/teacher_aimmo_dashboard.html +0 -95
  59. portal/templatetags/character_list_tags.py +0 -16
  60. portal/tests/pageObjects/portal/kurono_teacher_dashboard_page.py +0 -49
  61. portal/tests/test_aimmo_dashboards.py +0 -206
  62. portal/tests/utils/aimmo_games.py +0 -30
  63. portal/views/aimmo/__init__.py +0 -0
  64. portal/views/aimmo/dashboard.py +0 -105
  65. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/LICENSE.md +0 -0
  66. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/WHEEL +0 -0
  67. {codeforlife_portal-6.46.1.dist-info → codeforlife_portal-7.0.0.dist-info}/top_level.txt +0 -0
@@ -2,10 +2,12 @@ from __future__ import absolute_import
2
2
 
3
3
  from datetime import datetime, timedelta
4
4
 
5
- from aimmo.models import Game
6
5
  from common.models import Class, DailyActivity, Teacher
7
6
  from common.tests.utils.classes import create_class_directly
8
- from common.tests.utils.organisation import create_organisation_directly, join_teacher_to_organisation
7
+ from common.tests.utils.organisation import (
8
+ create_organisation_directly,
9
+ join_teacher_to_organisation,
10
+ )
9
11
  from common.tests.utils.student import create_school_student_directly
10
12
  from common.tests.utils.teacher import signup_teacher_directly
11
13
  from django.test import Client, TestCase
@@ -19,26 +21,6 @@ from .utils.messages import is_class_created_message_showing
19
21
 
20
22
 
21
23
  class TestClass(TestCase):
22
- def test_class_deletion_deletes_game(self):
23
- email, password = signup_teacher_directly()
24
- create_organisation_directly(email)
25
- klass, _, access_code = create_class_directly(email, "class 1")
26
- teacher: Teacher = Teacher.objects.get(new_user__email=email)
27
- c = Client()
28
- c.login(username=email, password=password)
29
- assert Class.objects.filter(teacher=teacher).count() == 1
30
-
31
- # create a game
32
- response = c.post(reverse("teacher_aimmo_dashboard"), {"game_class": klass.pk})
33
- assert response.status_code == 302
34
- assert Game.objects.filter(game_class__teacher=teacher, is_archived=False).count() == 1
35
-
36
- # try do delete class and see if game is also gone
37
- delete_url = reverse("teacher_delete_class", kwargs={"access_code": access_code})
38
- c.post(delete_url)
39
- assert Class.objects.filter(teacher=teacher).count() == 0
40
- assert Game.objects.filter(game_class__teacher=teacher, is_archived=True).count() == 1
41
-
42
24
  def test_delete_class(self):
43
25
  email1, password1 = signup_teacher_directly()
44
26
  email2, password2 = signup_teacher_directly()
@@ -48,7 +30,9 @@ class TestClass(TestCase):
48
30
 
49
31
  c = Client()
50
32
 
51
- url = reverse("teacher_delete_class", kwargs={"access_code": access_code})
33
+ url = reverse(
34
+ "teacher_delete_class", kwargs={"access_code": access_code}
35
+ )
52
36
 
53
37
  # Login as another teacher, try to delete the class and check for 404
54
38
  c.login(username=email2, password=password2)
@@ -152,19 +136,93 @@ class TestClass(TestCase):
152
136
  old_daily_activity = DailyActivity(date=old_date)
153
137
  old_daily_activity.save()
154
138
 
155
- url = reverse("teacher_edit_class", kwargs={"access_code": access_code1})
139
+ url = reverse(
140
+ "teacher_edit_class", kwargs={"access_code": access_code1}
141
+ )
156
142
  # POST request data for locking only the first level
157
143
  data = {
158
- "Getting Started": ["2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
144
+ "Getting Started": [
145
+ "2",
146
+ "3",
147
+ "4",
148
+ "5",
149
+ "6",
150
+ "7",
151
+ "8",
152
+ "9",
153
+ "10",
154
+ "11",
155
+ "12",
156
+ ],
159
157
  "Shortest Route": ["13", "14", "15", "16", "17", "18"],
160
- "Loops and Repetitions": ["19", "20", "21", "22", "23", "24", "25", "26", "27", "28"],
158
+ "Loops and Repetitions": [
159
+ "19",
160
+ "20",
161
+ "21",
162
+ "22",
163
+ "23",
164
+ "24",
165
+ "25",
166
+ "26",
167
+ "27",
168
+ "28",
169
+ ],
161
170
  "Loops with Conditions": ["29", "30", "31", "32"],
162
- "If... Only": ["33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43"],
171
+ "If... Only": [
172
+ "33",
173
+ "34",
174
+ "35",
175
+ "36",
176
+ "37",
177
+ "38",
178
+ "39",
179
+ "40",
180
+ "41",
181
+ "42",
182
+ "43",
183
+ ],
163
184
  "Traffic Lights": ["44", "45", "46", "47", "48", "49", "50"],
164
- "Limited Blocks": ["53", "78", "79", "80", "81", "82", "83", "84", "54", "55"],
185
+ "Limited Blocks": [
186
+ "53",
187
+ "78",
188
+ "79",
189
+ "80",
190
+ "81",
191
+ "82",
192
+ "83",
193
+ "84",
194
+ "54",
195
+ "55",
196
+ ],
165
197
  "Procedures": ["85", "52", "60", "86", "62", "87", "61"],
166
- "Blockly Brain Teasers": ["56", "57", "58", "59", "88", "91", "90", "89", "110", "111", "112", "92"],
167
- "Introduction to Python": ["93", "63", "64", "65", "94", "66", "67", "68", "95", "69", "96", "97"],
198
+ "Blockly Brain Teasers": [
199
+ "56",
200
+ "57",
201
+ "58",
202
+ "59",
203
+ "88",
204
+ "91",
205
+ "90",
206
+ "89",
207
+ "110",
208
+ "111",
209
+ "112",
210
+ "92",
211
+ ],
212
+ "Introduction to Python": [
213
+ "93",
214
+ "63",
215
+ "64",
216
+ "65",
217
+ "94",
218
+ "66",
219
+ "67",
220
+ "68",
221
+ "95",
222
+ "69",
223
+ "96",
224
+ "97",
225
+ ],
168
226
  "Python": [
169
227
  "98",
170
228
  "70",
@@ -203,21 +261,99 @@ class TestClass(TestCase):
203
261
  assert str(messages[0]) == "Your level preferences have been saved."
204
262
 
205
263
  # test the old analytic stays the same and the new one is incremented
206
- assert DailyActivity.objects.get(date=old_date).level_control_submits == 0
207
- assert DailyActivity.objects.get(date=datetime.now()).level_control_submits == 1
264
+ assert (
265
+ DailyActivity.objects.get(date=old_date).level_control_submits == 0
266
+ )
267
+ assert (
268
+ DailyActivity.objects.get(date=datetime.now()).level_control_submits
269
+ == 1
270
+ )
208
271
 
209
272
  # Resubmitting to unlock level 1
210
273
  data = {
211
- "Getting Started": ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
274
+ "Getting Started": [
275
+ "1",
276
+ "2",
277
+ "3",
278
+ "4",
279
+ "5",
280
+ "6",
281
+ "7",
282
+ "8",
283
+ "9",
284
+ "10",
285
+ "11",
286
+ "12",
287
+ ],
212
288
  "Shortest Route": ["13", "14", "15", "16", "17", "18"],
213
- "Loops and Repetitions": ["19", "20", "21", "22", "23", "24", "25", "26", "27", "28"],
289
+ "Loops and Repetitions": [
290
+ "19",
291
+ "20",
292
+ "21",
293
+ "22",
294
+ "23",
295
+ "24",
296
+ "25",
297
+ "26",
298
+ "27",
299
+ "28",
300
+ ],
214
301
  "Loops with Conditions": ["29", "30", "31", "32"],
215
- "If... Only": ["33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43"],
302
+ "If... Only": [
303
+ "33",
304
+ "34",
305
+ "35",
306
+ "36",
307
+ "37",
308
+ "38",
309
+ "39",
310
+ "40",
311
+ "41",
312
+ "42",
313
+ "43",
314
+ ],
216
315
  "Traffic Lights": ["44", "45", "46", "47", "48", "49", "50"],
217
- "Limited Blocks": ["53", "78", "79", "80", "81", "82", "83", "84", "54", "55"],
316
+ "Limited Blocks": [
317
+ "53",
318
+ "78",
319
+ "79",
320
+ "80",
321
+ "81",
322
+ "82",
323
+ "83",
324
+ "84",
325
+ "54",
326
+ "55",
327
+ ],
218
328
  "Procedures": ["85", "52", "60", "86", "62", "87", "61"],
219
- "Blockly Brain Teasers": ["56", "57", "58", "59", "88", "91", "90", "89", "110", "111", "112", "92"],
220
- "Introduction to Python": ["93", "63", "64", "65", "94", "66", "67", "68", "95", "69", "96", "97"],
329
+ "Blockly Brain Teasers": [
330
+ "56",
331
+ "57",
332
+ "58",
333
+ "59",
334
+ "88",
335
+ "91",
336
+ "90",
337
+ "89",
338
+ "110",
339
+ "111",
340
+ "112",
341
+ "92",
342
+ ],
343
+ "Introduction to Python": [
344
+ "93",
345
+ "63",
346
+ "64",
347
+ "65",
348
+ "94",
349
+ "66",
350
+ "67",
351
+ "68",
352
+ "95",
353
+ "69",
354
+ "96",
355
+ "97",
356
+ ],
221
357
  "Python": [
222
358
  "98",
223
359
  "70",
@@ -270,7 +406,9 @@ class TestClass(TestCase):
270
406
 
271
407
  c = Client()
272
408
 
273
- url = reverse("teacher_edit_class", kwargs={"access_code": access_code1})
409
+ url = reverse(
410
+ "teacher_edit_class", kwargs={"access_code": access_code1}
411
+ )
274
412
  data = {"new_teacher": teacher2.id, "class_move_submit": ""}
275
413
 
276
414
  # Login as first teacher and transfer class to the second teacher
@@ -297,7 +435,12 @@ class TestClassFrontend(BaseTest):
297
435
  def test_create(self):
298
436
  email, password = signup_teacher_directly()
299
437
  create_organisation_directly(email)
300
- page = self.go_to_homepage().go_to_teacher_login_page().login_no_class(email, password).open_classes_tab()
438
+ page = (
439
+ self.go_to_homepage()
440
+ .go_to_teacher_login_page()
441
+ .login_no_class(email, password)
442
+ .open_classes_tab()
443
+ )
301
444
 
302
445
  assert page.does_not_have_classes()
303
446
 
@@ -312,19 +455,34 @@ class TestClassFrontend(BaseTest):
312
455
  join_teacher_to_organisation(email2, school.name)
313
456
 
314
457
  # Check teacher 2 doesn't have any classes
315
- page = self.go_to_homepage().go_to_teacher_login_page().login(email2, password2).open_classes_tab()
458
+ page = (
459
+ self.go_to_homepage()
460
+ .go_to_teacher_login_page()
461
+ .login(email2, password2)
462
+ .open_classes_tab()
463
+ )
316
464
  assert page.does_not_have_classes()
317
465
  page.logout()
318
466
 
319
467
  # Log in as the first teacher and create a class for the second one
320
- page = self.go_to_homepage().go_to_teacher_login_page().login(email1, password1).open_classes_tab()
468
+ page = (
469
+ self.go_to_homepage()
470
+ .go_to_teacher_login_page()
471
+ .login(email1, password1)
472
+ .open_classes_tab()
473
+ )
321
474
  page, class_name = create_class(page, teacher_id=teacher2.id)
322
475
  page = TeachClassPage(page.browser)
323
476
  assert is_class_created_message_showing(self.selenium, class_name)
324
477
  page.logout()
325
478
 
326
479
  # Check teacher 2 now has the class
327
- page = self.go_to_homepage().go_to_teacher_login_page().login(email2, password2).open_classes_tab()
480
+ page = (
481
+ self.go_to_homepage()
482
+ .go_to_teacher_login_page()
483
+ .login(email2, password2)
484
+ .open_classes_tab()
485
+ )
328
486
  assert page.has_classes()
329
487
 
330
488
  def test_create_dashboard(self):
@@ -333,7 +491,12 @@ class TestClassFrontend(BaseTest):
333
491
  klass, name, access_code = create_class_directly(email)
334
492
  create_school_student_directly(access_code)
335
493
 
336
- page = self.go_to_homepage().go_to_teacher_login_page().login(email, password).open_classes_tab()
494
+ page = (
495
+ self.go_to_homepage()
496
+ .go_to_teacher_login_page()
497
+ .login(email, password)
498
+ .open_classes_tab()
499
+ )
337
500
 
338
501
  page, class_name = create_class(page)
339
502
 
@@ -349,7 +512,12 @@ class TestClassFrontend(BaseTest):
349
512
  klass_2, class_name_2, access_code_2 = create_class_directly(email_2)
350
513
  create_school_student_directly(access_code_2)
351
514
 
352
- page = self.go_to_homepage().go_to_teacher_login_page().login(email_2, password_2).open_classes_tab()
515
+ page = (
516
+ self.go_to_homepage()
517
+ .go_to_teacher_login_page()
518
+ .login(email_2, password_2)
519
+ .open_classes_tab()
520
+ )
353
521
 
354
522
  page, class_name_3 = create_class(page)
355
523
 
@@ -1,7 +1,6 @@
1
1
  from __future__ import absolute_import
2
2
 
3
3
  import datetime
4
- import time
5
4
  from unittest.mock import ANY, Mock, patch
6
5
 
7
6
  from common.mail import campaign_ids
@@ -28,7 +27,6 @@ from selenium.webdriver.common.by import By
28
27
  from selenium.webdriver.support.wait import WebDriverWait
29
28
 
30
29
  from portal.forms.error_messages import INVALID_LOGIN_MESSAGE
31
-
32
30
  from .base_test import BaseTest
33
31
  from .pageObjects.portal.home_page import HomePage
34
32
  from .utils.messages import (
@@ -658,13 +656,6 @@ class TestIndependentStudentFrontend(BaseTest):
658
656
  assert student2.pending_class_request is None
659
657
  assert student2.is_independent()
660
658
 
661
- def test_cannot_see_aimmo(self):
662
- page = self.go_to_homepage()
663
- page, _, username, _, password = create_independent_student(page)
664
- page = page.independent_student_login(username, password)
665
-
666
- assert page.element_does_not_exist_by_link_text("Kurono")
667
-
668
659
  def get_to_forgotten_password_page(self):
669
660
  self.selenium.get(self.live_server_url)
670
661
  page = HomePage(self.selenium).go_to_independent_student_login_page().go_to_indep_forgotten_password_page()
@@ -1,4 +1,3 @@
1
- import pytest
2
1
  from django.template import Context, Template
3
2
 
4
3
 
@@ -12,7 +11,9 @@ def test_banner(snapshot):
12
11
  }
13
12
 
14
13
  context = Context({"BANNER": test_banner})
15
- template_to_render = Template("{% load banner_tags %}" '{% banner banner_name="BANNER" %}')
14
+ template_to_render = Template(
15
+ "{% load banner_tags %}" '{% banner banner_name="BANNER" %}'
16
+ )
16
17
  rendered_template = template_to_render.render(context)
17
18
 
18
19
  snapshot.assert_match(rendered_template)
@@ -22,7 +23,9 @@ def test_headline(snapshot):
22
23
  test_headline = {"title": "Test title", "description": "Test description"}
23
24
 
24
25
  context = Context({"HEADLINE": test_headline})
25
- template_to_render = Template("{% load headline_tags %}" '{% headline headline_name="HEADLINE" %}')
26
+ template_to_render = Template(
27
+ "{% load headline_tags %}" '{% headline headline_name="HEADLINE" %}'
28
+ )
26
29
  rendered_template = template_to_render.render(context)
27
30
 
28
31
  snapshot.assert_match(rendered_template)
@@ -57,56 +60,3 @@ def test_benefits(snapshot):
57
60
  rendered_template = template_to_render.render(context)
58
61
 
59
62
  snapshot.assert_match(rendered_template)
60
-
61
-
62
- def test_hero_card(snapshot):
63
- test_hero_card = {
64
- "image": "images/worksheets/future_active.png",
65
- "title": "Test title",
66
- "description": "Test description",
67
- "button1": {"text": "Test button 1", "url": "https://www.codeforlife.education"},
68
- "button2": {"text": "Test button 2", "url": "kurono/play", "url_args": 1},
69
- }
70
-
71
- context = Context({"HERO_CARD": test_hero_card})
72
-
73
- template_to_render = Template("{% load hero_card_tags %}" "{% hero_card hero_card_name='HERO_CARD' %}")
74
-
75
- rendered_template = template_to_render.render(context)
76
-
77
- snapshot.assert_match(rendered_template)
78
-
79
-
80
- def test_card_list(snapshot):
81
- test_card_list = {
82
- "cards": [
83
- {"image": "images/worksheets/future2.jpg", "title": "Test card 1", "description": "Test description 1"},
84
- {"image": "images/worksheets/ancient.jpg", "title": "Test card 2", "description": "Test description 2"},
85
- {"image": "images/worksheets/modern_day.jpg", "title": "Test card 3", "description": "Test description 3"},
86
- {"image": "images/worksheets/prehistory.jpg", "title": "Test card 4", "description": "Test description 4"},
87
- {
88
- "image": "images/worksheets/broken_future.jpg",
89
- "title": "Test card 5",
90
- "description": "Test description 5",
91
- },
92
- ]
93
- }
94
-
95
- context = Context({"CARD_LIST": test_card_list})
96
-
97
- template_to_render = Template("{% load card_list_tags %}" "{% card_list %}")
98
-
99
- rendered_template = template_to_render.render(context)
100
-
101
- snapshot.assert_match(rendered_template)
102
-
103
-
104
- @pytest.mark.django_db
105
- def test_character_list(snapshot):
106
- context = Context()
107
-
108
- template_to_render = Template("{% load character_list_tags %}" "{% character_list %}")
109
-
110
- rendered_template = template_to_render.render(context)
111
-
112
- snapshot.assert_match(rendered_template)