rapid-router 5.4.1__py2.py3-none-any.whl → 7.6.8__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.
- example_project/rapid_router_test_settings.py +164 -0
- example_project/settings.py +152 -0
- example_project/urls.py +15 -0
- example_project/{example_project/wsgi.py → wsgi.py} +2 -1
- game/__init__.py +1 -1
- game/admin.py +43 -4
- game/app_settings.py +3 -7
- game/character.py +26 -18
- game/decor.py +172 -97
- game/end_to_end_tests/base_game_test.py +44 -33
- game/end_to_end_tests/editor_page.py +17 -2
- game/end_to_end_tests/game_page.py +127 -45
- game/end_to_end_tests/selenium_test_case.py +1 -20
- game/end_to_end_tests/test_cow_crashes.py +3 -5
- game/end_to_end_tests/test_language_dropdown.py +14 -0
- game/end_to_end_tests/test_level_editor.py +290 -0
- game/end_to_end_tests/test_level_failures.py +1 -1
- game/end_to_end_tests/test_level_selection.py +79 -0
- game/end_to_end_tests/test_play_through.py +240 -102
- game/end_to_end_tests/test_python_levels.py +44 -13
- game/end_to_end_tests/test_saving_workspace.py +22 -0
- game/forms.py +9 -2
- game/level_management.py +38 -29
- game/messages.py +1218 -203
- game/migrations/0001_squashed_0025_levels_ordering_pt1.py +19 -1
- game/migrations/0026_levels_pt2.py +13 -2
- game/migrations/0032_cannot_turn_left_level.py +13 -2
- game/migrations/0033_recursion_level.py +13 -2
- game/migrations/0034_joes_level.py +13 -2
- game/migrations/0035_disable_route_score_level_70.py +0 -2
- game/migrations/0036_level_score_73.py +0 -2
- game/migrations/0037_level_score_79.py +0 -2
- game/migrations/0038_level_score_40.py +0 -1
- game/migrations/0042_level_score_73.py +0 -2
- game/migrations/0048_add_cow_field_and_blocks.py +0 -2
- game/migrations/0049_level_score_34.py +0 -2
- game/migrations/0050_level_score_40.py +0 -2
- game/migrations/0051_level_score_49.py +0 -1
- game/migrations/0076_level_locked_for_class.py +19 -0
- game/migrations/0077_alter_level_next_level.py +52 -0
- game/migrations/0078_add_block_types.py +23 -0
- game/migrations/0079_populate_block_type_add_cow_blocks.py +60 -0
- game/migrations/0080_level_disable_algorithm_score.py +18 -0
- game/migrations/0081_first_12_levels_no_algo_score.py +29 -0
- game/migrations/0082_level_43_solution.py +16 -0
- game/migrations/0083_add_cows_to_existing_levels.py +195 -0
- game/migrations/0084_alter_block_block_type.py +18 -0
- game/migrations/0085_add_new_blocks.py +53 -0
- game/migrations/0086_loop_levels.py +482 -0
- game/migrations/0087_workspace_python_view_enabled.py +18 -0
- game/migrations/0088_rename_episodes.py +35 -0
- game/migrations/0089_episodes_in_development.py +30 -0
- game/migrations/0090_add_missing_model_solutions.py +144 -0
- game/migrations/0091_disable_algo_score_if_no_model_solution.py +46 -0
- game/migrations/0092_disable_algo_score_in_custom_levels.py +28 -0
- game/migrations/0093_alter_level_character_name.py +18 -0
- game/migrations/0094_add_hint_lesson_subtitle_to_levels.py +28 -0
- game/migrations/0095_level_commands.py +18 -0
- game/migrations/0096_alter_level_commands.py +18 -0
- game/migrations/0097_add_python_den_levels.py +1515 -0
- game/migrations/0098_add_episode_link_fields.py +44 -0
- game/migrations/0099_python_episodes_links.py +103 -0
- game/migrations/0100_reorder_python_levels.py +179 -0
- game/migrations/0101_rename_episodes.py +45 -0
- game/migrations/0102_reoder_episodes_13_14.py +136 -0
- game/migrations/0103_level_1015_solution.py +26 -0
- game/migrations/0104_remove_level_direct_drive.py +17 -0
- game/migrations/0105_delete_invalid_attempts.py +18 -0
- game/migrations/0106_fields_to_snake_case.py +48 -0
- game/migrations/0107_rename_worksheet_link_episode_student_worksheet_link.py +18 -0
- game/migrations/0108_episode_indy_worksheet_link.py +18 -0
- game/migrations/0109_create_episodes_23_and_24.py +99 -0
- game/migrations/0110_remove_episode_indy_worksheet_link_and_more.py +100 -0
- game/migrations/0111_create_worksheets.py +149 -0
- game/migrations/0112_worksheet_locked_classes.py +21 -0
- game/migrations/0113_level_needs_approval.py +18 -0
- game/migrations/0114_default_and_non_student_levels_no_approval.py +31 -0
- game/migrations/0115_level_level__default_does_not_need_approval.py +22 -0
- game/migrations/0116_update_worksheet_video_links.py +68 -0
- game/migrations/0117_update_solutions_to_if_else.py +61 -0
- game/models.py +157 -16
- game/permissions.py +34 -19
- game/python_den_urls.py +26 -0
- game/random_road.py +43 -127
- game/serializers.py +12 -17
- game/static/django_reverse_js/js/reverse.js +171 -0
- game/static/game/css/LilitaOne-Regular.ttf +0 -0
- game/static/game/css/backgrounds.css +14 -10
- game/static/game/css/dataTables.custom.css +4 -2
- game/static/game/css/dataTables.jqueryui.css +561 -320
- game/static/game/css/editor.css +47 -0
- game/static/game/css/game.css +43 -49
- game/static/game/css/game_screen.css +116 -53
- game/static/game/css/jquery.dataTables.css +455 -251
- game/static/game/css/level_editor.css +10 -1
- game/static/game/css/level_selection.css +32 -3
- game/static/game/css/level_share.css +6 -5
- game/static/game/css/skulpt/codemirror.css +1 -0
- game/static/game/image/Python_Den_hero_student.png +0 -0
- game/static/game/image/Python_levels_page.svg +1954 -0
- game/static/game/image/characters/front_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/image/decor/city/solar_panel.svg +1200 -0
- game/static/game/image/decor/farm/solar_panel.svg +86 -0
- game/static/game/image/decor/grass/solar_panel.svg +86 -0
- game/static/game/image/decor/snow/barn.svg +1788 -0
- game/static/game/image/decor/snow/cfc.svg +1050 -147
- game/static/game/image/decor/snow/crops.svg +7370 -0
- game/static/game/image/decor/snow/hospital.svg +1220 -0
- game/static/game/image/decor/snow/house1.svg +971 -0
- game/static/game/image/decor/snow/house2.svg +1574 -0
- game/static/game/image/decor/snow/school.svg +1071 -0
- game/static/game/image/decor/snow/shop.svg +3211 -0
- game/static/game/image/decor/snow/solar_panel.svg +173 -0
- game/static/game/image/electric_van.svg +448 -0
- game/static/game/image/icons/add_house.svg +26 -0
- game/static/game/image/icons/delete_house.svg +26 -0
- game/static/game/image/icons/description.svg +1 -0
- game/static/game/image/icons/hint.svg +1 -0
- game/static/game/image/icons/if_else.svg +3 -0
- game/static/game/image/icons/python.svg +1 -1
- game/static/game/image/if_else_example.png +0 -0
- game/static/game/image/pigeon.svg +684 -0
- game/static/game/image/python_den_header.svg +19 -0
- game/static/game/js/animation.js +84 -28
- game/static/game/js/blockly/msg/js/bg.js +52 -1
- game/static/game/js/blockly/msg/js/ca.js +52 -1
- game/static/game/js/blockly/msg/js/en-gb.js +52 -1
- game/static/game/js/blockly/msg/js/en.js +52 -1
- game/static/game/js/blockly/msg/js/es.js +52 -1
- game/static/game/js/blockly/msg/js/fr.js +52 -1
- game/static/game/js/blockly/msg/js/hi.js +52 -1
- game/static/game/js/blockly/msg/js/it.js +52 -1
- game/static/game/js/blockly/msg/js/pl.js +52 -1
- game/static/game/js/blockly/msg/js/pt-br.js +52 -1
- game/static/game/js/blockly/msg/js/ru.js +52 -1
- game/static/game/js/blockly/msg/js/ur.js +52 -1
- game/static/game/js/blocklyCompiler.js +550 -392
- game/static/game/js/blocklyControl.js +335 -302
- game/static/game/js/blocklyCustomBlocks.js +691 -458
- game/static/game/js/blocklyCustomisations.js +3 -1
- game/static/game/js/button.js +12 -0
- game/static/game/js/cow.js +15 -130
- game/static/game/js/drawing.js +313 -201
- game/static/game/js/editor.js +23 -0
- game/static/game/js/game.js +148 -139
- game/static/game/js/jquery.dataTables.min.js +3 -159
- game/static/game/js/level_editor.js +823 -448
- game/static/game/js/level_moderation.js +33 -2
- game/static/game/js/level_selection.js +62 -25
- game/static/game/js/loadLanguages.js +21 -0
- game/static/game/js/map.js +106 -36
- game/static/game/js/model.js +55 -107
- game/static/game/js/pathFinder.js +73 -72
- game/static/game/js/program.js +184 -193
- game/static/game/js/pythonControl.js +14 -1
- game/static/game/js/scoreboard.js +0 -37
- game/static/game/js/scoreboardSharedLevels.js +48 -0
- game/static/game/js/sharing.js +22 -10
- game/static/game/js/skulpt/codemirror.js +5 -4
- game/static/game/js/skulpt/skulpt-stdlib.js +1 -1
- game/static/game/js/sound.js +52 -5
- game/static/game/js/van.js +0 -7
- game/static/game/raphael_image/characters/top_view/Electric_van.svg +448 -0
- game/static/game/raphael_image/characters/top_view/Sleigh.svg +436 -0
- game/static/game/raphael_image/decor/city/solar_panel.svg +1200 -0
- game/static/game/raphael_image/decor/farm/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/grass/solar_panel.svg +86 -0
- game/static/game/raphael_image/decor/snow/barn.svg +1788 -0
- game/static/game/raphael_image/decor/snow/cfc.svg +1050 -147
- game/static/game/raphael_image/decor/snow/crops.svg +7370 -0
- game/static/game/raphael_image/decor/snow/hospital.svg +1220 -0
- game/static/game/raphael_image/decor/snow/house1.svg +971 -0
- game/static/game/raphael_image/decor/snow/house2.svg +1574 -0
- game/static/game/raphael_image/decor/snow/school.svg +1071 -0
- game/static/game/raphael_image/decor/snow/shop.svg +3211 -0
- game/static/game/raphael_image/decor/snow/solar_panel.svg +173 -0
- game/static/game/raphael_image/pigeon.svg +685 -0
- game/static/game/raphael_image/sleigh_wreckage.svg +430 -0
- game/static/game/sass/game.scss +22 -6
- game/static/game/sound/clown_horn.mp3 +0 -0
- game/static/game/sound/clown_horn.ogg +0 -0
- game/static/game/sound/electric_van_starting.mp3 +0 -0
- game/static/game/sound/electric_van_starting.ogg +0 -0
- game/static/game/sound/pigeon.mp3 +0 -0
- game/static/game/sound/pigeon.ogg +0 -0
- game/static/game/sound/sleigh_bells.mp3 +0 -0
- game/static/game/sound/sleigh_bells.ogg +0 -0
- game/static/game/sound/sleigh_crash.mp3 +0 -0
- game/static/game/sound/sleigh_crash.ogg +0 -0
- game/templates/game/base.html +35 -15
- game/templates/game/basenonav.html +23 -17
- game/templates/game/game.html +236 -111
- game/templates/game/level_editor.html +353 -275
- game/templates/game/level_moderation.html +19 -6
- game/templates/game/level_selection.html +75 -62
- game/templates/game/python_den_level_selection.html +291 -0
- game/templates/game/python_den_worksheet.html +101 -0
- game/templates/game/scoreboard.html +88 -65
- game/tests/test_level_editor.py +210 -35
- game/tests/test_level_moderation.py +6 -20
- game/tests/test_level_selection.py +332 -11
- game/tests/test_python_den_worksheet.py +85 -0
- game/tests/test_scoreboard.py +258 -66
- game/tests/utils/level.py +43 -3
- game/tests/utils/teacher.py +2 -2
- game/theme.py +21 -21
- game/urls.py +125 -78
- game/views/language_code_conversions.py +90 -0
- game/views/level.py +201 -63
- game/views/level_editor.py +109 -48
- game/views/level_moderation.py +29 -6
- game/views/level_selection.py +179 -56
- game/views/level_solutions.py +600 -106
- game/views/scoreboard.py +181 -66
- game/views/worksheet.py +25 -0
- rapid_router-7.6.8.dist-info/METADATA +174 -0
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/RECORD +222 -242
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/WHEEL +1 -1
- rapid_router-7.6.8.dist-info/licenses/LICENSE.md +3 -0
- example_project/example_project/__init__.py +0 -1
- example_project/example_project/settings.py +0 -54
- example_project/example_project/urls.py +0 -16
- example_project/manage.py +0 -10
- game/autoconfig.py +0 -59
- game/csp_config.py +0 -23
- game/locale/ar_SA/LC_MESSAGES/django.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/django.po +0 -405
- game/locale/ar_SA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ar_SA/LC_MESSAGES/djangojs.po +0 -743
- game/locale/bg_BG/LC_MESSAGES/django.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/django.po +0 -405
- game/locale/bg_BG/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/bg_BG/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ca_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/django.po +0 -405
- game/locale/ca_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ca_ES/LC_MESSAGES/djangojs.po +0 -740
- game/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/django.po +0 -405
- game/locale/cs_CZ/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cs_CZ/LC_MESSAGES/djangojs.po +0 -741
- game/locale/cy_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/django.po +0 -405
- game/locale/cy_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/cy_GB/LC_MESSAGES/djangojs.po +0 -743
- game/locale/de_DE/LC_MESSAGES/django.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/django.po +0 -405
- game/locale/de_DE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/de_DE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/el_GR/LC_MESSAGES/django.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/django.po +0 -405
- game/locale/el_GR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/el_GR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/en_GB/LC_MESSAGES/django.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/django.po +0 -405
- game/locale/en_GB/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/en_GB/LC_MESSAGES/djangojs.po +0 -739
- game/locale/es_ES/LC_MESSAGES/django.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/django.po +0 -405
- game/locale/es_ES/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/es_ES/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fi_FI/LC_MESSAGES/django.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/django.po +0 -405
- game/locale/fi_FI/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fi_FI/LC_MESSAGES/djangojs.po +0 -739
- game/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/django.po +0 -405
- game/locale/fr_FR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/fr_FR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/gu_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/django.po +0 -405
- game/locale/gu_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/gu_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/hi_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/django.po +0 -405
- game/locale/hi_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/hi_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/id_ID/LC_MESSAGES/django.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/django.po +0 -405
- game/locale/id_ID/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/id_ID/LC_MESSAGES/djangojs.po +0 -738
- game/locale/it_IT/LC_MESSAGES/django.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/django.po +0 -405
- game/locale/it_IT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/it_IT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ja_JP/LC_MESSAGES/django.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/django.po +0 -405
- game/locale/ja_JP/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ja_JP/LC_MESSAGES/djangojs.po +0 -738
- game/locale/lol_US/LC_MESSAGES/django.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/django.po +0 -405
- game/locale/lol_US/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/lol_US/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nb_NO/LC_MESSAGES/django.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/django.po +0 -405
- game/locale/nb_NO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nb_NO/LC_MESSAGES/djangojs.po +0 -739
- game/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/django.po +0 -405
- game/locale/nl_NL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/nl_NL/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/django.po +0 -405
- game/locale/pl_PL/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pl_PL/LC_MESSAGES/djangojs.po +0 -741
- game/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/django.po +0 -405
- game/locale/pt_BR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_BR/LC_MESSAGES/djangojs.po +0 -739
- game/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/django.po +0 -405
- game/locale/pt_PT/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/pt_PT/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ro_RO/LC_MESSAGES/django.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/django.po +0 -405
- game/locale/ro_RO/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ro_RO/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ru_RU/LC_MESSAGES/django.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/django.po +0 -405
- game/locale/ru_RU/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ru_RU/LC_MESSAGES/djangojs.po +0 -741
- game/locale/sv_SE/LC_MESSAGES/django.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/django.po +0 -405
- game/locale/sv_SE/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/sv_SE/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tl_PH/LC_MESSAGES/django.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/django.po +0 -405
- game/locale/tl_PH/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tl_PH/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tlh_AA/LC_MESSAGES/django.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/django.po +0 -405
- game/locale/tlh_AA/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tlh_AA/LC_MESSAGES/djangojs.po +0 -739
- game/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/django.po +0 -405
- game/locale/tr_TR/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/tr_TR/LC_MESSAGES/djangojs.po +0 -740
- game/locale/ur_IN/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/django.po +0 -405
- game/locale/ur_IN/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_IN/LC_MESSAGES/djangojs.po +0 -739
- game/locale/ur_PK/LC_MESSAGES/django.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/django.po +0 -405
- game/locale/ur_PK/LC_MESSAGES/djangojs.mo +0 -0
- game/locale/ur_PK/LC_MESSAGES/djangojs.po +0 -739
- game/static/game/image/actions/go.svg +0 -18
- game/static/game/image/icons/destination.svg +0 -9
- game/static/game/js/pqselect.min.js +0 -9
- game/static/game/js/widget-scroller.js +0 -906
- rapid_router-5.4.1.dist-info/LICENSE.md +0 -577
- rapid_router-5.4.1.dist-info/METADATA +0 -24
- {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/top_level.txt +0 -0
game/tests/test_level_editor.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import json
|
|
2
|
+
from unittest.mock import patch
|
|
2
3
|
|
|
3
|
-
from common.models import Teacher
|
|
4
|
+
from common.models import Teacher, User
|
|
4
5
|
from common.tests.utils.classes import create_class_directly
|
|
5
6
|
from common.tests.utils.organisation import create_organisation_directly
|
|
6
7
|
from common.tests.utils.student import create_school_student_directly
|
|
@@ -10,22 +11,21 @@ from django.core import mail
|
|
|
10
11
|
from django.test.client import Client
|
|
11
12
|
from django.test.testcases import TestCase
|
|
12
13
|
from django.urls import reverse
|
|
13
|
-
from hamcrest import assert_that, equal_to
|
|
14
14
|
|
|
15
15
|
from game.models import Level
|
|
16
|
-
from game.tests.utils.level import create_save_level
|
|
16
|
+
from game.tests.utils.level import create_save_level, create_save_level_with_multiple_houses, multiple_house_data
|
|
17
17
|
from game.tests.utils.teacher import add_teacher_to_school, create_school
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
class LevelEditorTestCase(TestCase):
|
|
21
21
|
LEVEL_DATA1 = {
|
|
22
22
|
"origin": '{"coordinate":[3,5],"direction":"S"}',
|
|
23
|
-
"
|
|
23
|
+
"python_enabled": False,
|
|
24
24
|
"decor": [],
|
|
25
|
-
"
|
|
25
|
+
"blockly_enabled": True,
|
|
26
26
|
"blocks": [{"type": "move_forwards"}, {"type": "turn_left"}, {"type": "turn_right"}],
|
|
27
27
|
"max_fuel": "50",
|
|
28
|
-
"
|
|
28
|
+
"python_view_enabled": False,
|
|
29
29
|
"character": "3",
|
|
30
30
|
"name": "abc",
|
|
31
31
|
"theme": 1,
|
|
@@ -87,10 +87,21 @@ class LevelEditorTestCase(TestCase):
|
|
|
87
87
|
url = reverse("save_level_for_editor")
|
|
88
88
|
response = self.client.post(url, {"data": json.dumps(self.LEVEL_DATA1)})
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
assert response.status_code == 200
|
|
91
|
+
|
|
92
|
+
level = Level.objects.all().last()
|
|
93
|
+
teacher_user = User.objects.get(email=email)
|
|
94
|
+
|
|
95
|
+
assert level.needs_approval == True
|
|
96
|
+
assert level.shared_with.count() == 1
|
|
97
|
+
assert level.shared_with.filter(id=teacher_user.id).exists()
|
|
98
|
+
assert len(mail.outbox) == 1
|
|
99
|
+
|
|
100
|
+
level.needs_approval = False
|
|
101
|
+
level.save()
|
|
102
|
+
|
|
91
103
|
sharing_info1 = json.loads(self.get_sharing_information(json.loads(response.content)["id"]).getvalue())
|
|
92
|
-
|
|
93
|
-
assert_that(len(mail.outbox), equal_to(1))
|
|
104
|
+
assert sharing_info1["teacher"]["shared"]
|
|
94
105
|
|
|
95
106
|
def test_anonymous_level_saving_school_student(self):
|
|
96
107
|
email, password = signup_teacher_directly()
|
|
@@ -102,12 +113,12 @@ class LevelEditorTestCase(TestCase):
|
|
|
102
113
|
url = reverse("save_level_for_editor")
|
|
103
114
|
data1 = {
|
|
104
115
|
"origin": '{"coordinate":[3,5],"direction":"S"}',
|
|
105
|
-
"
|
|
116
|
+
"python_enabled": False,
|
|
106
117
|
"decor": [],
|
|
107
|
-
"
|
|
118
|
+
"blockly_enabled": True,
|
|
108
119
|
"blocks": [{"type": "move_forwards"}, {"type": "turn_left"}, {"type": "turn_right"}],
|
|
109
120
|
"max_fuel": "50",
|
|
110
|
-
"
|
|
121
|
+
"python_view_enabled": False,
|
|
111
122
|
"character": "3",
|
|
112
123
|
"name": "abc",
|
|
113
124
|
"theme": 1,
|
|
@@ -119,10 +130,14 @@ class LevelEditorTestCase(TestCase):
|
|
|
119
130
|
}
|
|
120
131
|
response = self.client.post(url, {"data": json.dumps(data1)})
|
|
121
132
|
|
|
122
|
-
|
|
133
|
+
level = Level.objects.all().last()
|
|
134
|
+
level.needs_approval = False
|
|
135
|
+
level.save()
|
|
136
|
+
|
|
137
|
+
assert response.status_code == 200
|
|
123
138
|
sharing_info1 = json.loads(self.get_sharing_information(json.loads(response.content)["id"]).getvalue())
|
|
124
|
-
|
|
125
|
-
|
|
139
|
+
assert sharing_info1["teacher"]["shared"]
|
|
140
|
+
assert len(mail.outbox) == 0
|
|
126
141
|
|
|
127
142
|
def test_level_sharing_with_no_school(self):
|
|
128
143
|
email1, password1 = signup_teacher_directly()
|
|
@@ -131,7 +146,7 @@ class LevelEditorTestCase(TestCase):
|
|
|
131
146
|
level = create_save_level(teacher1)
|
|
132
147
|
|
|
133
148
|
sharing_info1 = json.loads(self.get_sharing_information(level.id).getvalue())
|
|
134
|
-
|
|
149
|
+
assert len(sharing_info1["teachers"]) == 0
|
|
135
150
|
|
|
136
151
|
def test_level_sharing_with_school(self):
|
|
137
152
|
email1, password1 = signup_teacher_directly()
|
|
@@ -148,7 +163,7 @@ class LevelEditorTestCase(TestCase):
|
|
|
148
163
|
add_teacher_to_school(teacher2, school1)
|
|
149
164
|
|
|
150
165
|
sharing_info1 = json.loads(self.get_sharing_information(level.id).getvalue())
|
|
151
|
-
|
|
166
|
+
assert len(sharing_info1["teachers"]) == 1
|
|
152
167
|
|
|
153
168
|
def test_level_sharing_with_empty_school(self):
|
|
154
169
|
email1, password1 = signup_teacher_directly()
|
|
@@ -161,7 +176,7 @@ class LevelEditorTestCase(TestCase):
|
|
|
161
176
|
add_teacher_to_school(teacher1, school1)
|
|
162
177
|
|
|
163
178
|
sharing_info1 = json.loads(self.get_sharing_information(level.id).getvalue())
|
|
164
|
-
|
|
179
|
+
assert len(sharing_info1["teachers"]) == 0
|
|
165
180
|
|
|
166
181
|
def test_level_sharing_permissions(self):
|
|
167
182
|
email1, password1 = signup_teacher_directly()
|
|
@@ -175,18 +190,19 @@ class LevelEditorTestCase(TestCase):
|
|
|
175
190
|
share_url = reverse("share_level_for_editor", args=[level.id])
|
|
176
191
|
|
|
177
192
|
school1 = create_school()
|
|
178
|
-
add_teacher_to_school(teacher1, school1)
|
|
193
|
+
add_teacher_to_school(teacher1, school1, is_admin=True)
|
|
179
194
|
add_teacher_to_school(teacher2, school1)
|
|
180
195
|
|
|
181
|
-
# Create a class and
|
|
196
|
+
# Create a class and 2 students for the second teacher
|
|
182
197
|
_, class_name2, access_code2 = create_class_directly(email2)
|
|
198
|
+
student_name1, student_password1, student1 = create_school_student_directly(access_code2)
|
|
183
199
|
student_name2, student_password2, student2 = create_school_student_directly(access_code2)
|
|
184
200
|
|
|
185
201
|
self.logout()
|
|
186
202
|
self.login(email2, password2)
|
|
187
203
|
|
|
188
204
|
# Second teacher can't share the level as it's not been shared with them yet
|
|
189
|
-
response = self.client.post(share_url, {"recipientIDs[]": [
|
|
205
|
+
response = self.client.post(share_url, {"recipientIDs[]": [student1.new_user.id], "action": ["share"]})
|
|
190
206
|
assert response.status_code == 403
|
|
191
207
|
|
|
192
208
|
# Log in as the first teacher again
|
|
@@ -202,14 +218,34 @@ class LevelEditorTestCase(TestCase):
|
|
|
202
218
|
self.login(email2, password2)
|
|
203
219
|
|
|
204
220
|
# Now the second teacher should be able to share the level
|
|
205
|
-
response = self.client.post(share_url, {"recipientIDs[]": [
|
|
221
|
+
response = self.client.post(share_url, {"recipientIDs[]": [student1.new_user.id], "action": ["share"]})
|
|
206
222
|
assert response.status_code == 200
|
|
207
223
|
# and load it
|
|
208
224
|
load_level_url = reverse("load_level_for_editor", kwargs={"levelID": level.id})
|
|
209
225
|
response = self.client.get(load_level_url)
|
|
210
226
|
assert response.status_code == 200
|
|
211
227
|
|
|
212
|
-
#
|
|
228
|
+
# Log in as the first student
|
|
229
|
+
self.logout()
|
|
230
|
+
self.student_login(student_name1, access_code2, student_password1)
|
|
231
|
+
|
|
232
|
+
# Check that the student cannot share the level
|
|
233
|
+
sharing_info = json.loads(self.get_sharing_information(level.id).getvalue())
|
|
234
|
+
assert sharing_info["detail"] == "You do not have permission to perform this action."
|
|
235
|
+
|
|
236
|
+
# Check the student can view the level
|
|
237
|
+
response = self.client.get(reverse("play_custom_level", args=[level.id]))
|
|
238
|
+
assert response.status_code == 200
|
|
239
|
+
|
|
240
|
+
# Log in as first teacher again
|
|
241
|
+
self.logout()
|
|
242
|
+
self.login(email1, password1)
|
|
243
|
+
|
|
244
|
+
# Share the level with the second student of teacher 2
|
|
245
|
+
response = self.client.post(share_url, {"recipientIDs[]": [student2.new_user.id], "action": ["share"]})
|
|
246
|
+
assert response.status_code == 200
|
|
247
|
+
|
|
248
|
+
# Log in as the second student
|
|
213
249
|
self.logout()
|
|
214
250
|
self.student_login(student_name2, access_code2, student_password2)
|
|
215
251
|
|
|
@@ -221,6 +257,8 @@ class LevelEditorTestCase(TestCase):
|
|
|
221
257
|
response = self.client.get(reverse("play_custom_level", args=[level.id]))
|
|
222
258
|
assert response.status_code == 200
|
|
223
259
|
|
|
260
|
+
self.logout()
|
|
261
|
+
|
|
224
262
|
def test_level_can_only_be_edited_by_owner(self):
|
|
225
263
|
email, password = signup_teacher_directly()
|
|
226
264
|
create_organisation_directly(email)
|
|
@@ -233,14 +271,14 @@ class LevelEditorTestCase(TestCase):
|
|
|
233
271
|
self.student_login(hacker_name, access_code, hacker_password)
|
|
234
272
|
resp = self.client.get(reverse("level_editor_chosen_level", kwargs={"levelId": new_level.id}))
|
|
235
273
|
|
|
236
|
-
|
|
274
|
+
assert "level" not in resp.context
|
|
237
275
|
|
|
238
276
|
self.logout()
|
|
239
277
|
|
|
240
278
|
self.student_login(student_name, access_code, student_password)
|
|
241
279
|
resp = self.client.get(reverse("level_editor_chosen_level", kwargs={"levelId": new_level.id}))
|
|
242
280
|
|
|
243
|
-
|
|
281
|
+
assert "level" in resp.context
|
|
244
282
|
|
|
245
283
|
def test_no_character_set_defaults_to_van(self):
|
|
246
284
|
|
|
@@ -253,12 +291,12 @@ class LevelEditorTestCase(TestCase):
|
|
|
253
291
|
url = reverse("save_level_for_editor")
|
|
254
292
|
data_with_no_character = {
|
|
255
293
|
"origin": '{"coordinate":[3,5],"direction":"S"}',
|
|
256
|
-
"
|
|
294
|
+
"python_enabled": False,
|
|
257
295
|
"decor": [],
|
|
258
|
-
"
|
|
296
|
+
"blockly_enabled": True,
|
|
259
297
|
"blocks": [{"type": "move_forwards"}, {"type": "turn_left"}, {"type": "turn_right"}],
|
|
260
298
|
"max_fuel": "50",
|
|
261
|
-
"
|
|
299
|
+
"python_view_enabled": False,
|
|
262
300
|
"name": "abc",
|
|
263
301
|
"theme": 1,
|
|
264
302
|
"anonymous": True,
|
|
@@ -269,9 +307,48 @@ class LevelEditorTestCase(TestCase):
|
|
|
269
307
|
}
|
|
270
308
|
response = self.client.post(url, {"data": json.dumps(data_with_no_character)})
|
|
271
309
|
|
|
272
|
-
|
|
310
|
+
assert response.status_code == 200
|
|
273
311
|
new_level = Level.objects.get(name="abc")
|
|
274
|
-
|
|
312
|
+
assert new_level.character.name == "Van"
|
|
313
|
+
|
|
314
|
+
def test_language_set_appropriately(self):
|
|
315
|
+
|
|
316
|
+
email, password = signup_teacher_directly()
|
|
317
|
+
create_organisation_directly(email)
|
|
318
|
+
_, class_name, access_code = create_class_directly(email)
|
|
319
|
+
student_name, student_password, _ = create_school_student_directly(access_code)
|
|
320
|
+
|
|
321
|
+
self.student_login(student_name, access_code, student_password)
|
|
322
|
+
url = reverse("save_level_for_editor")
|
|
323
|
+
data_with_split_language = {
|
|
324
|
+
"origin": '{"coordinate":[3,5],"direction":"S"}',
|
|
325
|
+
"python_enabled": False,
|
|
326
|
+
"decor": [],
|
|
327
|
+
"blockly_enabled": True,
|
|
328
|
+
"blocks": [
|
|
329
|
+
{"type": "move_forwards"},
|
|
330
|
+
{"type": "turn_left"},
|
|
331
|
+
{"type": "turn_right"},
|
|
332
|
+
],
|
|
333
|
+
"max_fuel": "50",
|
|
334
|
+
"python_view_enabled": True,
|
|
335
|
+
"name": "abc",
|
|
336
|
+
"theme": 1,
|
|
337
|
+
"anonymous": True,
|
|
338
|
+
"cows": "[]",
|
|
339
|
+
"path": '[{"coordinate":[3,5],"connectedNodes":[1]},{"coordinate":[3,4],'
|
|
340
|
+
'"connectedNodes":[0]}]',
|
|
341
|
+
"traffic_lights": "[]",
|
|
342
|
+
"destinations": "[[3,4]]",
|
|
343
|
+
}
|
|
344
|
+
response = self.client.post(url, {"data": json.dumps(data_with_split_language)})
|
|
345
|
+
|
|
346
|
+
assert response.status_code == 200
|
|
347
|
+
new_level = Level.objects.get(name="abc")
|
|
348
|
+
|
|
349
|
+
assert new_level.python_view_enabled
|
|
350
|
+
assert not new_level.python_enabled
|
|
351
|
+
assert new_level.blockly_enabled
|
|
275
352
|
|
|
276
353
|
def test_level_loading(self):
|
|
277
354
|
email1, password1 = signup_teacher_directly()
|
|
@@ -283,7 +360,70 @@ class LevelEditorTestCase(TestCase):
|
|
|
283
360
|
url = reverse("load_level_for_editor", kwargs={"levelID": level.id})
|
|
284
361
|
response = self.client.get(url)
|
|
285
362
|
|
|
286
|
-
|
|
363
|
+
assert response.status_code == 200
|
|
364
|
+
|
|
365
|
+
def test_level_saving_with_multiple_houses(self):
|
|
366
|
+
email, password = signup_teacher_directly()
|
|
367
|
+
create_organisation_directly(email)
|
|
368
|
+
_, class_name, access_code = create_class_directly(email)
|
|
369
|
+
student_name, student_password, _ = create_school_student_directly(access_code)
|
|
370
|
+
|
|
371
|
+
self.student_login(student_name, access_code, student_password)
|
|
372
|
+
url = reverse("save_level_for_editor")
|
|
373
|
+
data_with_multiple_houses = {
|
|
374
|
+
"origin": '{"coordinate":[3,5],"direction":"S"}',
|
|
375
|
+
"python_enabled": False,
|
|
376
|
+
"decor": [],
|
|
377
|
+
"blockly_enabled": True,
|
|
378
|
+
"blocks": [{"type": "move_forwards"}, {"type": "turn_left"}, {"type": "turn_right"}],
|
|
379
|
+
"max_fuel": "50",
|
|
380
|
+
"python_view_enabled": False,
|
|
381
|
+
"name": "multiple_houses",
|
|
382
|
+
"theme": 1,
|
|
383
|
+
"anonymous": True,
|
|
384
|
+
"cows": "[]",
|
|
385
|
+
"path": '[{"coordinate":[3,5],"connectedNodes":[1]},{"coordinate":[3,4],"connectedNodes":[0,2]}, {"coordinate":[3,3],"connectedNodes":[1]}]',
|
|
386
|
+
"traffic_lights": "[]",
|
|
387
|
+
"destinations": "[[3,4],[3,3]]",
|
|
388
|
+
}
|
|
389
|
+
response = self.client.post(url, {"data": json.dumps(data_with_multiple_houses)})
|
|
390
|
+
|
|
391
|
+
assert response.status_code == 200
|
|
392
|
+
new_level = Level.objects.get(name="multiple_houses")
|
|
393
|
+
assert new_level.destinations == "[[3,4],[3,3]]"
|
|
394
|
+
|
|
395
|
+
def test_level_loading_with_multiple_houses(self):
|
|
396
|
+
|
|
397
|
+
email1, password1 = signup_teacher_directly()
|
|
398
|
+
|
|
399
|
+
teacher1 = Teacher.objects.get(new_user__email=email1)
|
|
400
|
+
|
|
401
|
+
self.login(email1, password1)
|
|
402
|
+
level = create_save_level_with_multiple_houses(teacher1)
|
|
403
|
+
url = reverse("load_level_for_editor", kwargs={"levelID": level.id})
|
|
404
|
+
response = self.client.get(url)
|
|
405
|
+
response_data = response.json()
|
|
406
|
+
|
|
407
|
+
assert response.status_code == 200
|
|
408
|
+
assert response_data["level"]["destinations"] == "[[3,4], [3,3]]"
|
|
409
|
+
|
|
410
|
+
@patch("game.level_management.save_level")
|
|
411
|
+
def test_custom_level_scoring(self, mock_save_level):
|
|
412
|
+
email1, password1 = signup_teacher_directly()
|
|
413
|
+
|
|
414
|
+
teacher1 = Teacher.objects.get(new_user__email=email1)
|
|
415
|
+
|
|
416
|
+
self.login(email1, password1)
|
|
417
|
+
|
|
418
|
+
level = create_save_level_with_multiple_houses(teacher1)
|
|
419
|
+
|
|
420
|
+
save_url = reverse("save_level_for_editor", kwargs={"levelId": level.id})
|
|
421
|
+
response = self.client.post(save_url, {"data": json.dumps(multiple_house_data)})
|
|
422
|
+
|
|
423
|
+
disable_algorithm_score = mock_save_level.call_args.args[1]["disable_algorithm_score"]
|
|
424
|
+
|
|
425
|
+
assert response.status_code == 200
|
|
426
|
+
assert disable_algorithm_score
|
|
287
427
|
|
|
288
428
|
def test_level_of_anonymised_teacher_is_hidden(self):
|
|
289
429
|
# Create 2 teacher accounts
|
|
@@ -309,7 +449,7 @@ class LevelEditorTestCase(TestCase):
|
|
|
309
449
|
# Check `teacher1` can see `teacher2`'s shared level
|
|
310
450
|
levels_url = reverse("levels")
|
|
311
451
|
response = self.client.get(levels_url)
|
|
312
|
-
assert len(response.context["
|
|
452
|
+
assert len(response.context["directly_shared_levels"]) == 1
|
|
313
453
|
|
|
314
454
|
# Make teacher2 inactive
|
|
315
455
|
teacher2.new_user.is_active = 0
|
|
@@ -317,7 +457,7 @@ class LevelEditorTestCase(TestCase):
|
|
|
317
457
|
|
|
318
458
|
# `teacher1` shouldn't see any shared levels now
|
|
319
459
|
response = self.client.get(levels_url)
|
|
320
|
-
assert len(response.context["
|
|
460
|
+
assert len(response.context["directly_shared_levels"]) == 0
|
|
321
461
|
|
|
322
462
|
def test_level_of_anonymised_student_is_hidden(self):
|
|
323
463
|
# Create a teacher and a student
|
|
@@ -339,7 +479,7 @@ class LevelEditorTestCase(TestCase):
|
|
|
339
479
|
# Check teacher can see student's shared level
|
|
340
480
|
levels_url = reverse("levels")
|
|
341
481
|
response = self.client.get(levels_url)
|
|
342
|
-
assert len(response.context["
|
|
482
|
+
assert len(response.context["directly_shared_levels"]) == 1
|
|
343
483
|
|
|
344
484
|
# Make student inactive
|
|
345
485
|
student.new_user.is_active = 0
|
|
@@ -347,4 +487,39 @@ class LevelEditorTestCase(TestCase):
|
|
|
347
487
|
|
|
348
488
|
# Teacher shouldn't see any shared levels now
|
|
349
489
|
response = self.client.get(levels_url)
|
|
350
|
-
assert len(response.context["
|
|
490
|
+
assert len(response.context["directly_shared_levels"]) == 0
|
|
491
|
+
|
|
492
|
+
def test_level_cannot_be_created_with_invalid_fields(self):
|
|
493
|
+
email, password = signup_teacher_directly()
|
|
494
|
+
create_organisation_directly(email)
|
|
495
|
+
_, _, access_code = create_class_directly(email)
|
|
496
|
+
create_school_student_directly(access_code)
|
|
497
|
+
|
|
498
|
+
level_data = self.LEVEL_DATA1
|
|
499
|
+
level_data["subtitle"] = "<a>invalid subtitle</a>"
|
|
500
|
+
|
|
501
|
+
self.login(email, password)
|
|
502
|
+
url = reverse("save_level_for_editor")
|
|
503
|
+
response = self.client.post(url, {"data": json.dumps(self.LEVEL_DATA1)})
|
|
504
|
+
|
|
505
|
+
assert response.status_code == 401
|
|
506
|
+
|
|
507
|
+
level_data["subtitle"] = "valid subtitle"
|
|
508
|
+
level_data["lesson"] = "<a>invalid lesson</a>"
|
|
509
|
+
|
|
510
|
+
response = self.client.post(url, {"data": json.dumps(self.LEVEL_DATA1)})
|
|
511
|
+
|
|
512
|
+
assert response.status_code == 401
|
|
513
|
+
|
|
514
|
+
level_data["lesson"] = "valid lesson"
|
|
515
|
+
level_data["hint"] = "<a>invalid hint</a>"
|
|
516
|
+
|
|
517
|
+
response = self.client.post(url, {"data": json.dumps(self.LEVEL_DATA1)})
|
|
518
|
+
|
|
519
|
+
assert response.status_code == 401
|
|
520
|
+
|
|
521
|
+
level_data["hint"] = "valid hint"
|
|
522
|
+
|
|
523
|
+
response = self.client.post(url, {"data": json.dumps(self.LEVEL_DATA1)})
|
|
524
|
+
|
|
525
|
+
assert response.status_code == 200
|
|
@@ -1,17 +1,11 @@
|
|
|
1
|
-
import json
|
|
2
|
-
|
|
3
1
|
from common.tests.utils.classes import create_class_directly
|
|
2
|
+
from common.tests.utils.organisation import create_organisation_directly, join_teacher_to_organisation
|
|
4
3
|
from common.tests.utils.student import create_school_student_directly
|
|
5
4
|
from common.tests.utils.teacher import signup_teacher_directly
|
|
6
|
-
from common.tests.utils.organisation import (
|
|
7
|
-
create_organisation_directly,
|
|
8
|
-
join_teacher_to_organisation,
|
|
9
|
-
)
|
|
10
5
|
from deploy import captcha
|
|
11
6
|
from django.test.client import Client
|
|
12
7
|
from django.test.testcases import TestCase
|
|
13
8
|
from django.urls import reverse
|
|
14
|
-
from hamcrest import *
|
|
15
9
|
|
|
16
10
|
from .utils.level import create_save_level
|
|
17
11
|
|
|
@@ -114,8 +108,8 @@ class LevelModerationTestCase(TestCase):
|
|
|
114
108
|
# Create 2 teachers in the same school, one admin, one standard
|
|
115
109
|
email1, password1 = signup_teacher_directly()
|
|
116
110
|
email2, password2 = signup_teacher_directly()
|
|
117
|
-
|
|
118
|
-
join_teacher_to_organisation(email2, name
|
|
111
|
+
school = create_organisation_directly(email1)
|
|
112
|
+
join_teacher_to_organisation(email2, school.name)
|
|
119
113
|
|
|
120
114
|
# Create one class and student for each teacher
|
|
121
115
|
_, class_name1, access_code1 = create_class_directly(email1)
|
|
@@ -137,9 +131,7 @@ class LevelModerationTestCase(TestCase):
|
|
|
137
131
|
assert student1.new_user.first_name not in response.content.decode()
|
|
138
132
|
assert student2.new_user.first_name in response.content.decode()
|
|
139
133
|
# Try to delete level1, it shouldn't work
|
|
140
|
-
delete_level1_url = reverse(
|
|
141
|
-
"delete_level_for_editor", kwargs={"levelId": level1.id}
|
|
142
|
-
)
|
|
134
|
+
delete_level1_url = reverse("delete_level_for_editor", kwargs={"levelId": level1.id})
|
|
143
135
|
response = self.client.get(delete_level1_url)
|
|
144
136
|
assert response.status_code == 401
|
|
145
137
|
# Check level2 is still there
|
|
@@ -157,9 +149,7 @@ class LevelModerationTestCase(TestCase):
|
|
|
157
149
|
assert student1.new_user.first_name in response.content.decode()
|
|
158
150
|
assert student2.new_user.first_name in response.content.decode()
|
|
159
151
|
# Delete level2
|
|
160
|
-
delete_level2_url = reverse(
|
|
161
|
-
"delete_level_for_editor", kwargs={"levelId": level2.id}
|
|
162
|
-
)
|
|
152
|
+
delete_level2_url = reverse("delete_level_for_editor", kwargs={"levelId": level2.id})
|
|
163
153
|
response = self.client.get(delete_level2_url)
|
|
164
154
|
assert response.status_code == 200
|
|
165
155
|
# Check level1 is still there and level2 is not there anymore
|
|
@@ -171,10 +161,6 @@ class LevelModerationTestCase(TestCase):
|
|
|
171
161
|
def teacher_login(self, email, password):
|
|
172
162
|
self.client.post(
|
|
173
163
|
reverse("teacher_login"),
|
|
174
|
-
{
|
|
175
|
-
"auth-username": email,
|
|
176
|
-
"auth-password": password,
|
|
177
|
-
"teacher_login_view-current_step": "auth",
|
|
178
|
-
},
|
|
164
|
+
{"auth-username": email, "auth-password": password, "teacher_login_view-current_step": "auth"},
|
|
179
165
|
follow=True,
|
|
180
166
|
)
|