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.
Files changed (354) hide show
  1. example_project/rapid_router_test_settings.py +164 -0
  2. example_project/settings.py +152 -0
  3. example_project/urls.py +15 -0
  4. example_project/{example_project/wsgi.py → wsgi.py} +2 -1
  5. game/__init__.py +1 -1
  6. game/admin.py +43 -4
  7. game/app_settings.py +3 -7
  8. game/character.py +26 -18
  9. game/decor.py +172 -97
  10. game/end_to_end_tests/base_game_test.py +44 -33
  11. game/end_to_end_tests/editor_page.py +17 -2
  12. game/end_to_end_tests/game_page.py +127 -45
  13. game/end_to_end_tests/selenium_test_case.py +1 -20
  14. game/end_to_end_tests/test_cow_crashes.py +3 -5
  15. game/end_to_end_tests/test_language_dropdown.py +14 -0
  16. game/end_to_end_tests/test_level_editor.py +290 -0
  17. game/end_to_end_tests/test_level_failures.py +1 -1
  18. game/end_to_end_tests/test_level_selection.py +79 -0
  19. game/end_to_end_tests/test_play_through.py +240 -102
  20. game/end_to_end_tests/test_python_levels.py +44 -13
  21. game/end_to_end_tests/test_saving_workspace.py +22 -0
  22. game/forms.py +9 -2
  23. game/level_management.py +38 -29
  24. game/messages.py +1218 -203
  25. game/migrations/0001_squashed_0025_levels_ordering_pt1.py +19 -1
  26. game/migrations/0026_levels_pt2.py +13 -2
  27. game/migrations/0032_cannot_turn_left_level.py +13 -2
  28. game/migrations/0033_recursion_level.py +13 -2
  29. game/migrations/0034_joes_level.py +13 -2
  30. game/migrations/0035_disable_route_score_level_70.py +0 -2
  31. game/migrations/0036_level_score_73.py +0 -2
  32. game/migrations/0037_level_score_79.py +0 -2
  33. game/migrations/0038_level_score_40.py +0 -1
  34. game/migrations/0042_level_score_73.py +0 -2
  35. game/migrations/0048_add_cow_field_and_blocks.py +0 -2
  36. game/migrations/0049_level_score_34.py +0 -2
  37. game/migrations/0050_level_score_40.py +0 -2
  38. game/migrations/0051_level_score_49.py +0 -1
  39. game/migrations/0076_level_locked_for_class.py +19 -0
  40. game/migrations/0077_alter_level_next_level.py +52 -0
  41. game/migrations/0078_add_block_types.py +23 -0
  42. game/migrations/0079_populate_block_type_add_cow_blocks.py +60 -0
  43. game/migrations/0080_level_disable_algorithm_score.py +18 -0
  44. game/migrations/0081_first_12_levels_no_algo_score.py +29 -0
  45. game/migrations/0082_level_43_solution.py +16 -0
  46. game/migrations/0083_add_cows_to_existing_levels.py +195 -0
  47. game/migrations/0084_alter_block_block_type.py +18 -0
  48. game/migrations/0085_add_new_blocks.py +53 -0
  49. game/migrations/0086_loop_levels.py +482 -0
  50. game/migrations/0087_workspace_python_view_enabled.py +18 -0
  51. game/migrations/0088_rename_episodes.py +35 -0
  52. game/migrations/0089_episodes_in_development.py +30 -0
  53. game/migrations/0090_add_missing_model_solutions.py +144 -0
  54. game/migrations/0091_disable_algo_score_if_no_model_solution.py +46 -0
  55. game/migrations/0092_disable_algo_score_in_custom_levels.py +28 -0
  56. game/migrations/0093_alter_level_character_name.py +18 -0
  57. game/migrations/0094_add_hint_lesson_subtitle_to_levels.py +28 -0
  58. game/migrations/0095_level_commands.py +18 -0
  59. game/migrations/0096_alter_level_commands.py +18 -0
  60. game/migrations/0097_add_python_den_levels.py +1515 -0
  61. game/migrations/0098_add_episode_link_fields.py +44 -0
  62. game/migrations/0099_python_episodes_links.py +103 -0
  63. game/migrations/0100_reorder_python_levels.py +179 -0
  64. game/migrations/0101_rename_episodes.py +45 -0
  65. game/migrations/0102_reoder_episodes_13_14.py +136 -0
  66. game/migrations/0103_level_1015_solution.py +26 -0
  67. game/migrations/0104_remove_level_direct_drive.py +17 -0
  68. game/migrations/0105_delete_invalid_attempts.py +18 -0
  69. game/migrations/0106_fields_to_snake_case.py +48 -0
  70. game/migrations/0107_rename_worksheet_link_episode_student_worksheet_link.py +18 -0
  71. game/migrations/0108_episode_indy_worksheet_link.py +18 -0
  72. game/migrations/0109_create_episodes_23_and_24.py +99 -0
  73. game/migrations/0110_remove_episode_indy_worksheet_link_and_more.py +100 -0
  74. game/migrations/0111_create_worksheets.py +149 -0
  75. game/migrations/0112_worksheet_locked_classes.py +21 -0
  76. game/migrations/0113_level_needs_approval.py +18 -0
  77. game/migrations/0114_default_and_non_student_levels_no_approval.py +31 -0
  78. game/migrations/0115_level_level__default_does_not_need_approval.py +22 -0
  79. game/migrations/0116_update_worksheet_video_links.py +68 -0
  80. game/migrations/0117_update_solutions_to_if_else.py +61 -0
  81. game/models.py +157 -16
  82. game/permissions.py +34 -19
  83. game/python_den_urls.py +26 -0
  84. game/random_road.py +43 -127
  85. game/serializers.py +12 -17
  86. game/static/django_reverse_js/js/reverse.js +171 -0
  87. game/static/game/css/LilitaOne-Regular.ttf +0 -0
  88. game/static/game/css/backgrounds.css +14 -10
  89. game/static/game/css/dataTables.custom.css +4 -2
  90. game/static/game/css/dataTables.jqueryui.css +561 -320
  91. game/static/game/css/editor.css +47 -0
  92. game/static/game/css/game.css +43 -49
  93. game/static/game/css/game_screen.css +116 -53
  94. game/static/game/css/jquery.dataTables.css +455 -251
  95. game/static/game/css/level_editor.css +10 -1
  96. game/static/game/css/level_selection.css +32 -3
  97. game/static/game/css/level_share.css +6 -5
  98. game/static/game/css/skulpt/codemirror.css +1 -0
  99. game/static/game/image/Python_Den_hero_student.png +0 -0
  100. game/static/game/image/Python_levels_page.svg +1954 -0
  101. game/static/game/image/characters/front_view/Electric_van.svg +448 -0
  102. game/static/game/image/characters/top_view/Electric_van.svg +448 -0
  103. game/static/game/image/characters/top_view/Sleigh.svg +436 -0
  104. game/static/game/image/decor/city/solar_panel.svg +1200 -0
  105. game/static/game/image/decor/farm/solar_panel.svg +86 -0
  106. game/static/game/image/decor/grass/solar_panel.svg +86 -0
  107. game/static/game/image/decor/snow/barn.svg +1788 -0
  108. game/static/game/image/decor/snow/cfc.svg +1050 -147
  109. game/static/game/image/decor/snow/crops.svg +7370 -0
  110. game/static/game/image/decor/snow/hospital.svg +1220 -0
  111. game/static/game/image/decor/snow/house1.svg +971 -0
  112. game/static/game/image/decor/snow/house2.svg +1574 -0
  113. game/static/game/image/decor/snow/school.svg +1071 -0
  114. game/static/game/image/decor/snow/shop.svg +3211 -0
  115. game/static/game/image/decor/snow/solar_panel.svg +173 -0
  116. game/static/game/image/electric_van.svg +448 -0
  117. game/static/game/image/icons/add_house.svg +26 -0
  118. game/static/game/image/icons/delete_house.svg +26 -0
  119. game/static/game/image/icons/description.svg +1 -0
  120. game/static/game/image/icons/hint.svg +1 -0
  121. game/static/game/image/icons/if_else.svg +3 -0
  122. game/static/game/image/icons/python.svg +1 -1
  123. game/static/game/image/if_else_example.png +0 -0
  124. game/static/game/image/pigeon.svg +684 -0
  125. game/static/game/image/python_den_header.svg +19 -0
  126. game/static/game/js/animation.js +84 -28
  127. game/static/game/js/blockly/msg/js/bg.js +52 -1
  128. game/static/game/js/blockly/msg/js/ca.js +52 -1
  129. game/static/game/js/blockly/msg/js/en-gb.js +52 -1
  130. game/static/game/js/blockly/msg/js/en.js +52 -1
  131. game/static/game/js/blockly/msg/js/es.js +52 -1
  132. game/static/game/js/blockly/msg/js/fr.js +52 -1
  133. game/static/game/js/blockly/msg/js/hi.js +52 -1
  134. game/static/game/js/blockly/msg/js/it.js +52 -1
  135. game/static/game/js/blockly/msg/js/pl.js +52 -1
  136. game/static/game/js/blockly/msg/js/pt-br.js +52 -1
  137. game/static/game/js/blockly/msg/js/ru.js +52 -1
  138. game/static/game/js/blockly/msg/js/ur.js +52 -1
  139. game/static/game/js/blocklyCompiler.js +550 -392
  140. game/static/game/js/blocklyControl.js +335 -302
  141. game/static/game/js/blocklyCustomBlocks.js +691 -458
  142. game/static/game/js/blocklyCustomisations.js +3 -1
  143. game/static/game/js/button.js +12 -0
  144. game/static/game/js/cow.js +15 -130
  145. game/static/game/js/drawing.js +313 -201
  146. game/static/game/js/editor.js +23 -0
  147. game/static/game/js/game.js +148 -139
  148. game/static/game/js/jquery.dataTables.min.js +3 -159
  149. game/static/game/js/level_editor.js +823 -448
  150. game/static/game/js/level_moderation.js +33 -2
  151. game/static/game/js/level_selection.js +62 -25
  152. game/static/game/js/loadLanguages.js +21 -0
  153. game/static/game/js/map.js +106 -36
  154. game/static/game/js/model.js +55 -107
  155. game/static/game/js/pathFinder.js +73 -72
  156. game/static/game/js/program.js +184 -193
  157. game/static/game/js/pythonControl.js +14 -1
  158. game/static/game/js/scoreboard.js +0 -37
  159. game/static/game/js/scoreboardSharedLevels.js +48 -0
  160. game/static/game/js/sharing.js +22 -10
  161. game/static/game/js/skulpt/codemirror.js +5 -4
  162. game/static/game/js/skulpt/skulpt-stdlib.js +1 -1
  163. game/static/game/js/sound.js +52 -5
  164. game/static/game/js/van.js +0 -7
  165. game/static/game/raphael_image/characters/top_view/Electric_van.svg +448 -0
  166. game/static/game/raphael_image/characters/top_view/Sleigh.svg +436 -0
  167. game/static/game/raphael_image/decor/city/solar_panel.svg +1200 -0
  168. game/static/game/raphael_image/decor/farm/solar_panel.svg +86 -0
  169. game/static/game/raphael_image/decor/grass/solar_panel.svg +86 -0
  170. game/static/game/raphael_image/decor/snow/barn.svg +1788 -0
  171. game/static/game/raphael_image/decor/snow/cfc.svg +1050 -147
  172. game/static/game/raphael_image/decor/snow/crops.svg +7370 -0
  173. game/static/game/raphael_image/decor/snow/hospital.svg +1220 -0
  174. game/static/game/raphael_image/decor/snow/house1.svg +971 -0
  175. game/static/game/raphael_image/decor/snow/house2.svg +1574 -0
  176. game/static/game/raphael_image/decor/snow/school.svg +1071 -0
  177. game/static/game/raphael_image/decor/snow/shop.svg +3211 -0
  178. game/static/game/raphael_image/decor/snow/solar_panel.svg +173 -0
  179. game/static/game/raphael_image/pigeon.svg +685 -0
  180. game/static/game/raphael_image/sleigh_wreckage.svg +430 -0
  181. game/static/game/sass/game.scss +22 -6
  182. game/static/game/sound/clown_horn.mp3 +0 -0
  183. game/static/game/sound/clown_horn.ogg +0 -0
  184. game/static/game/sound/electric_van_starting.mp3 +0 -0
  185. game/static/game/sound/electric_van_starting.ogg +0 -0
  186. game/static/game/sound/pigeon.mp3 +0 -0
  187. game/static/game/sound/pigeon.ogg +0 -0
  188. game/static/game/sound/sleigh_bells.mp3 +0 -0
  189. game/static/game/sound/sleigh_bells.ogg +0 -0
  190. game/static/game/sound/sleigh_crash.mp3 +0 -0
  191. game/static/game/sound/sleigh_crash.ogg +0 -0
  192. game/templates/game/base.html +35 -15
  193. game/templates/game/basenonav.html +23 -17
  194. game/templates/game/game.html +236 -111
  195. game/templates/game/level_editor.html +353 -275
  196. game/templates/game/level_moderation.html +19 -6
  197. game/templates/game/level_selection.html +75 -62
  198. game/templates/game/python_den_level_selection.html +291 -0
  199. game/templates/game/python_den_worksheet.html +101 -0
  200. game/templates/game/scoreboard.html +88 -65
  201. game/tests/test_level_editor.py +210 -35
  202. game/tests/test_level_moderation.py +6 -20
  203. game/tests/test_level_selection.py +332 -11
  204. game/tests/test_python_den_worksheet.py +85 -0
  205. game/tests/test_scoreboard.py +258 -66
  206. game/tests/utils/level.py +43 -3
  207. game/tests/utils/teacher.py +2 -2
  208. game/theme.py +21 -21
  209. game/urls.py +125 -78
  210. game/views/language_code_conversions.py +90 -0
  211. game/views/level.py +201 -63
  212. game/views/level_editor.py +109 -48
  213. game/views/level_moderation.py +29 -6
  214. game/views/level_selection.py +179 -56
  215. game/views/level_solutions.py +600 -106
  216. game/views/scoreboard.py +181 -66
  217. game/views/worksheet.py +25 -0
  218. rapid_router-7.6.8.dist-info/METADATA +174 -0
  219. {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/RECORD +222 -242
  220. {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/WHEEL +1 -1
  221. rapid_router-7.6.8.dist-info/licenses/LICENSE.md +3 -0
  222. example_project/example_project/__init__.py +0 -1
  223. example_project/example_project/settings.py +0 -54
  224. example_project/example_project/urls.py +0 -16
  225. example_project/manage.py +0 -10
  226. game/autoconfig.py +0 -59
  227. game/csp_config.py +0 -23
  228. game/locale/ar_SA/LC_MESSAGES/django.mo +0 -0
  229. game/locale/ar_SA/LC_MESSAGES/django.po +0 -405
  230. game/locale/ar_SA/LC_MESSAGES/djangojs.mo +0 -0
  231. game/locale/ar_SA/LC_MESSAGES/djangojs.po +0 -743
  232. game/locale/bg_BG/LC_MESSAGES/django.mo +0 -0
  233. game/locale/bg_BG/LC_MESSAGES/django.po +0 -405
  234. game/locale/bg_BG/LC_MESSAGES/djangojs.mo +0 -0
  235. game/locale/bg_BG/LC_MESSAGES/djangojs.po +0 -739
  236. game/locale/ca_ES/LC_MESSAGES/django.mo +0 -0
  237. game/locale/ca_ES/LC_MESSAGES/django.po +0 -405
  238. game/locale/ca_ES/LC_MESSAGES/djangojs.mo +0 -0
  239. game/locale/ca_ES/LC_MESSAGES/djangojs.po +0 -740
  240. game/locale/cs_CZ/LC_MESSAGES/django.mo +0 -0
  241. game/locale/cs_CZ/LC_MESSAGES/django.po +0 -405
  242. game/locale/cs_CZ/LC_MESSAGES/djangojs.mo +0 -0
  243. game/locale/cs_CZ/LC_MESSAGES/djangojs.po +0 -741
  244. game/locale/cy_GB/LC_MESSAGES/django.mo +0 -0
  245. game/locale/cy_GB/LC_MESSAGES/django.po +0 -405
  246. game/locale/cy_GB/LC_MESSAGES/djangojs.mo +0 -0
  247. game/locale/cy_GB/LC_MESSAGES/djangojs.po +0 -743
  248. game/locale/de_DE/LC_MESSAGES/django.mo +0 -0
  249. game/locale/de_DE/LC_MESSAGES/django.po +0 -405
  250. game/locale/de_DE/LC_MESSAGES/djangojs.mo +0 -0
  251. game/locale/de_DE/LC_MESSAGES/djangojs.po +0 -739
  252. game/locale/el_GR/LC_MESSAGES/django.mo +0 -0
  253. game/locale/el_GR/LC_MESSAGES/django.po +0 -405
  254. game/locale/el_GR/LC_MESSAGES/djangojs.mo +0 -0
  255. game/locale/el_GR/LC_MESSAGES/djangojs.po +0 -739
  256. game/locale/en_GB/LC_MESSAGES/django.mo +0 -0
  257. game/locale/en_GB/LC_MESSAGES/django.po +0 -405
  258. game/locale/en_GB/LC_MESSAGES/djangojs.mo +0 -0
  259. game/locale/en_GB/LC_MESSAGES/djangojs.po +0 -739
  260. game/locale/es_ES/LC_MESSAGES/django.mo +0 -0
  261. game/locale/es_ES/LC_MESSAGES/django.po +0 -405
  262. game/locale/es_ES/LC_MESSAGES/djangojs.mo +0 -0
  263. game/locale/es_ES/LC_MESSAGES/djangojs.po +0 -739
  264. game/locale/fi_FI/LC_MESSAGES/django.mo +0 -0
  265. game/locale/fi_FI/LC_MESSAGES/django.po +0 -405
  266. game/locale/fi_FI/LC_MESSAGES/djangojs.mo +0 -0
  267. game/locale/fi_FI/LC_MESSAGES/djangojs.po +0 -739
  268. game/locale/fr_FR/LC_MESSAGES/django.mo +0 -0
  269. game/locale/fr_FR/LC_MESSAGES/django.po +0 -405
  270. game/locale/fr_FR/LC_MESSAGES/djangojs.mo +0 -0
  271. game/locale/fr_FR/LC_MESSAGES/djangojs.po +0 -739
  272. game/locale/gu_IN/LC_MESSAGES/django.mo +0 -0
  273. game/locale/gu_IN/LC_MESSAGES/django.po +0 -405
  274. game/locale/gu_IN/LC_MESSAGES/djangojs.mo +0 -0
  275. game/locale/gu_IN/LC_MESSAGES/djangojs.po +0 -739
  276. game/locale/hi_IN/LC_MESSAGES/django.mo +0 -0
  277. game/locale/hi_IN/LC_MESSAGES/django.po +0 -405
  278. game/locale/hi_IN/LC_MESSAGES/djangojs.mo +0 -0
  279. game/locale/hi_IN/LC_MESSAGES/djangojs.po +0 -739
  280. game/locale/id_ID/LC_MESSAGES/django.mo +0 -0
  281. game/locale/id_ID/LC_MESSAGES/django.po +0 -405
  282. game/locale/id_ID/LC_MESSAGES/djangojs.mo +0 -0
  283. game/locale/id_ID/LC_MESSAGES/djangojs.po +0 -738
  284. game/locale/it_IT/LC_MESSAGES/django.mo +0 -0
  285. game/locale/it_IT/LC_MESSAGES/django.po +0 -405
  286. game/locale/it_IT/LC_MESSAGES/djangojs.mo +0 -0
  287. game/locale/it_IT/LC_MESSAGES/djangojs.po +0 -739
  288. game/locale/ja_JP/LC_MESSAGES/django.mo +0 -0
  289. game/locale/ja_JP/LC_MESSAGES/django.po +0 -405
  290. game/locale/ja_JP/LC_MESSAGES/djangojs.mo +0 -0
  291. game/locale/ja_JP/LC_MESSAGES/djangojs.po +0 -738
  292. game/locale/lol_US/LC_MESSAGES/django.mo +0 -0
  293. game/locale/lol_US/LC_MESSAGES/django.po +0 -405
  294. game/locale/lol_US/LC_MESSAGES/djangojs.mo +0 -0
  295. game/locale/lol_US/LC_MESSAGES/djangojs.po +0 -739
  296. game/locale/nb_NO/LC_MESSAGES/django.mo +0 -0
  297. game/locale/nb_NO/LC_MESSAGES/django.po +0 -405
  298. game/locale/nb_NO/LC_MESSAGES/djangojs.mo +0 -0
  299. game/locale/nb_NO/LC_MESSAGES/djangojs.po +0 -739
  300. game/locale/nl_NL/LC_MESSAGES/django.mo +0 -0
  301. game/locale/nl_NL/LC_MESSAGES/django.po +0 -405
  302. game/locale/nl_NL/LC_MESSAGES/djangojs.mo +0 -0
  303. game/locale/nl_NL/LC_MESSAGES/djangojs.po +0 -739
  304. game/locale/pl_PL/LC_MESSAGES/django.mo +0 -0
  305. game/locale/pl_PL/LC_MESSAGES/django.po +0 -405
  306. game/locale/pl_PL/LC_MESSAGES/djangojs.mo +0 -0
  307. game/locale/pl_PL/LC_MESSAGES/djangojs.po +0 -741
  308. game/locale/pt_BR/LC_MESSAGES/django.mo +0 -0
  309. game/locale/pt_BR/LC_MESSAGES/django.po +0 -405
  310. game/locale/pt_BR/LC_MESSAGES/djangojs.mo +0 -0
  311. game/locale/pt_BR/LC_MESSAGES/djangojs.po +0 -739
  312. game/locale/pt_PT/LC_MESSAGES/django.mo +0 -0
  313. game/locale/pt_PT/LC_MESSAGES/django.po +0 -405
  314. game/locale/pt_PT/LC_MESSAGES/djangojs.mo +0 -0
  315. game/locale/pt_PT/LC_MESSAGES/djangojs.po +0 -739
  316. game/locale/ro_RO/LC_MESSAGES/django.mo +0 -0
  317. game/locale/ro_RO/LC_MESSAGES/django.po +0 -405
  318. game/locale/ro_RO/LC_MESSAGES/djangojs.mo +0 -0
  319. game/locale/ro_RO/LC_MESSAGES/djangojs.po +0 -740
  320. game/locale/ru_RU/LC_MESSAGES/django.mo +0 -0
  321. game/locale/ru_RU/LC_MESSAGES/django.po +0 -405
  322. game/locale/ru_RU/LC_MESSAGES/djangojs.mo +0 -0
  323. game/locale/ru_RU/LC_MESSAGES/djangojs.po +0 -741
  324. game/locale/sv_SE/LC_MESSAGES/django.mo +0 -0
  325. game/locale/sv_SE/LC_MESSAGES/django.po +0 -405
  326. game/locale/sv_SE/LC_MESSAGES/djangojs.mo +0 -0
  327. game/locale/sv_SE/LC_MESSAGES/djangojs.po +0 -739
  328. game/locale/tl_PH/LC_MESSAGES/django.mo +0 -0
  329. game/locale/tl_PH/LC_MESSAGES/django.po +0 -405
  330. game/locale/tl_PH/LC_MESSAGES/djangojs.mo +0 -0
  331. game/locale/tl_PH/LC_MESSAGES/djangojs.po +0 -739
  332. game/locale/tlh_AA/LC_MESSAGES/django.mo +0 -0
  333. game/locale/tlh_AA/LC_MESSAGES/django.po +0 -405
  334. game/locale/tlh_AA/LC_MESSAGES/djangojs.mo +0 -0
  335. game/locale/tlh_AA/LC_MESSAGES/djangojs.po +0 -739
  336. game/locale/tr_TR/LC_MESSAGES/django.mo +0 -0
  337. game/locale/tr_TR/LC_MESSAGES/django.po +0 -405
  338. game/locale/tr_TR/LC_MESSAGES/djangojs.mo +0 -0
  339. game/locale/tr_TR/LC_MESSAGES/djangojs.po +0 -740
  340. game/locale/ur_IN/LC_MESSAGES/django.mo +0 -0
  341. game/locale/ur_IN/LC_MESSAGES/django.po +0 -405
  342. game/locale/ur_IN/LC_MESSAGES/djangojs.mo +0 -0
  343. game/locale/ur_IN/LC_MESSAGES/djangojs.po +0 -739
  344. game/locale/ur_PK/LC_MESSAGES/django.mo +0 -0
  345. game/locale/ur_PK/LC_MESSAGES/django.po +0 -405
  346. game/locale/ur_PK/LC_MESSAGES/djangojs.mo +0 -0
  347. game/locale/ur_PK/LC_MESSAGES/djangojs.po +0 -739
  348. game/static/game/image/actions/go.svg +0 -18
  349. game/static/game/image/icons/destination.svg +0 -9
  350. game/static/game/js/pqselect.min.js +0 -9
  351. game/static/game/js/widget-scroller.js +0 -906
  352. rapid_router-5.4.1.dist-info/LICENSE.md +0 -577
  353. rapid_router-5.4.1.dist-info/METADATA +0 -24
  354. {rapid_router-5.4.1.dist-info → rapid_router-7.6.8.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,8 @@
1
1
  from __future__ import print_function
2
- from builtins import str
2
+
3
3
  import os
4
4
  import time
5
+ from builtins import str
5
6
 
6
7
  from django.urls import reverse
7
8
  from hamcrest import assert_that, equal_to, contains_string, ends_with
@@ -18,6 +19,10 @@ class GamePage(BasePage):
18
19
  def __init__(self, browser):
19
20
  super(GamePage, self).__init__(browser)
20
21
 
22
+ self.browser.execute_script(
23
+ "ocargo.animation.FAST_ANIMATION_DURATION = 1;"
24
+ )
25
+
21
26
  assert self.on_correct_page("game_page")
22
27
 
23
28
  self._dismiss_initial_dialog()
@@ -27,21 +32,41 @@ class GamePage(BasePage):
27
32
  return self
28
33
 
29
34
  def dismiss_dialog(self, button_id):
30
- self.wait_for_element_to_be_clickable((By.ID, button_id), wait_seconds=15)
31
- self.browser.find_element_by_id(button_id).click()
32
- self.wait_for_element_to_be_invisible((By.ID, button_id), wait_seconds=15)
35
+ self.wait_for_element_to_be_clickable(
36
+ (By.ID, button_id), wait_seconds=15
37
+ )
38
+ self.browser.find_element(By.ID, button_id).click()
39
+ self.wait_for_element_to_be_invisible(
40
+ (By.ID, button_id), wait_seconds=15
41
+ )
42
+
43
+ def save_solution(self, workspace_name):
44
+ self.browser.find_element(By.ID, "save_tab").click()
45
+ self.browser.find_element(By.ID, "workspaceNameInput").send_keys(
46
+ workspace_name
47
+ )
48
+ self.browser.find_element(By.ID, "saveWorkspace").click()
49
+ return self
50
+
51
+ def load_solution_by_name(self, solution_name):
52
+ self.browser.find_element(By.ID, "load_tab").click()
53
+ time.sleep(1)
54
+ self.browser.find_element(By.ID, solution_name).click()
55
+ self.browser.find_element(By.ID, "loadWorkspace").click()
56
+ time.sleep(1)
57
+ return self
33
58
 
34
59
  def load_solution(self, workspace_id):
35
- self.browser.find_element_by_id("load_tab").click()
60
+ self.browser.find_element(By.ID, "load_tab").click()
36
61
  selector = "#loadWorkspaceTable tr[value='" + str(workspace_id) + "']"
37
62
  self.wait_for_element_to_be_clickable((By.CSS_SELECTOR, selector))
38
- self.browser.find_element_by_css_selector(selector).click()
39
- self.browser.find_element_by_id("loadWorkspace").click()
63
+ self.browser.find_element(By.CSS_SELECTOR, selector).click()
64
+ self.browser.find_element(By.ID, "loadWorkspace").click()
40
65
  time.sleep(1)
41
66
  return self
42
67
 
43
68
  def clear(self):
44
- self.browser.find_element_by_id("clear_tab").click()
69
+ self.browser.find_element(By.ID, "clear_tab").click()
45
70
  return self
46
71
 
47
72
  def try_again(self):
@@ -49,12 +74,14 @@ class GamePage(BasePage):
49
74
  return self
50
75
 
51
76
  def step(self):
52
- self.browser.find_element_by_id("step_tab").click()
77
+ self.browser.find_element(By.ID, "step_tab").click()
53
78
  return self
54
79
 
55
80
  def solution_button(self):
56
- self.browser.find_element_by_id("solution_tab").click()
57
- solution_loaded = self.browser.execute_script("return ocargo.solutionLoaded;")
81
+ self.browser.find_element(By.ID, "solution_tab").click()
82
+ solution_loaded = self.browser.execute_script(
83
+ "return ocargo.solutionLoaded;"
84
+ )
58
85
  timeout = time.time() + 30
59
86
 
60
87
  while not solution_loaded:
@@ -66,20 +93,34 @@ class GamePage(BasePage):
66
93
  return self
67
94
 
68
95
  def python_commands_button(self):
69
- self.browser.find_element_by_id("van_commands_help").click()
96
+ self.browser.find_element(By.ID, "van_commands_help").click()
70
97
  return self
71
98
 
72
99
  def clear_console_button(self):
73
- self.browser.find_element_by_id("clear_console").click()
100
+ self.browser.find_element(By.ID, "clear_console").click()
74
101
  return self
75
102
 
76
- def assert_level_number(self, level_number):
77
- path = reverse("play_default_level", kwargs={"levelName": str(level_number)})
78
- assert_that(self.browser.current_url.replace("#myModal", ""), ends_with(path))
103
+ def assert_level_number(self, level_number, from_python_den):
104
+ viewname = (
105
+ "play_python_default_level"
106
+ if from_python_den
107
+ else "play_default_level"
108
+ )
79
109
 
80
- def assert_episode_number(self, episode_number):
81
- path = reverse("start_episode", kwargs={"episodeId": str(episode_number)})
82
- assert_that(self.browser.current_url.replace("#myModal", ""), ends_with(path))
110
+ path = reverse(viewname, kwargs={"level_name": str(level_number)})
111
+ assert_that(
112
+ self.browser.current_url.replace("#myModal", ""), ends_with(path)
113
+ )
114
+
115
+ def assert_episode_number(self, episode_number, from_python_den):
116
+ viewname = (
117
+ "start_python_episode" if from_python_den else "start_episode"
118
+ )
119
+
120
+ path = reverse(viewname, kwargs={"episodeId": str(episode_number)})
121
+ assert_that(
122
+ self.browser.current_url.replace("#myModal", ""), ends_with(path)
123
+ )
83
124
 
84
125
  def assert_is_green_light(self, traffic_light_index):
85
126
  self._assert_light_is_on(traffic_light_index, "green")
@@ -88,20 +129,20 @@ class GamePage(BasePage):
88
129
  self._assert_light_is_on(traffic_light_index, "red")
89
130
 
90
131
  def _assert_light_is_on(self, traffic_light_index, colour):
91
- image = self.browser.find_element_by_id(
92
- "trafficLight_%s_%s" % (traffic_light_index, colour)
132
+ image = self.browser.find_element(
133
+ By.ID, "trafficLight_%s_%s" % (traffic_light_index, colour)
93
134
  )
94
135
 
95
136
  assert_that(image.get_attribute("opacity"), equal_to("1"))
96
137
 
97
138
  def run_program(self, wait_for_element_id="modal-content"):
98
- self.browser.find_element_by_id("fast_tab").click()
139
+ self.browser.find_element(By.ID, "fast_tab").click()
99
140
 
100
141
  try:
101
- self.wait_for_element_to_be_clickable((By.ID, wait_for_element_id), 45)
142
+ self.wait_for_element_to_be_clickable(
143
+ (By.ID, wait_for_element_id), 45
144
+ )
102
145
  except TimeoutException as e:
103
- import time
104
-
105
146
  millis = int(round(time.time() * 1000))
106
147
  screenshot_filename = "/tmp/game_tests_%s-%s.png" % (
107
148
  os.getenv("BUILD_NUMBER", "nonumber"),
@@ -115,9 +156,11 @@ class GamePage(BasePage):
115
156
 
116
157
  def run_retry_program(self):
117
158
  self.run_program("try_again_button")
118
- modal_content = self.browser.find_element_by_id("modal-content").text
119
- assert_that(modal_content, contains_string("Try creating a simpler program."))
120
- self.browser.find_element_by_id("try_again_button").click()
159
+ modal_content = self.browser.find_element(By.ID, "modal-content").text
160
+ assert_that(
161
+ modal_content, contains_string("Try creating a simpler program.")
162
+ )
163
+ self.browser.find_element(By.ID, "try_again_button").click()
121
164
  time.sleep(1)
122
165
  return self
123
166
 
@@ -170,10 +213,24 @@ class GamePage(BasePage):
170
213
  "from van import Va", "You can only import 'Van' from 'van'"
171
214
  )
172
215
 
216
+ def run_animal_sound_horn_program(self):
217
+ return self._run_working_program(
218
+ """
219
+ while not my_van.at_destination():
220
+ if my_van.is_animal_crossing():
221
+ my_van.sound_horn()
222
+ if my_van.is_road_forward():
223
+ my_van.move_forwards()
224
+ elif my_van.is_road_left():
225
+ my_van.turn_left()
226
+ else:
227
+ my_van.turn_right()""",
228
+ )
229
+
173
230
  def check_python_commands(self):
174
231
  self.python_commands_button()
175
232
  time.sleep(1)
176
- python_commands = self.browser.find_element_by_id("myModal-lead").text
233
+ python_commands = self.browser.find_element(By.ID, "myModal-lead").text
177
234
  assert_that(
178
235
  python_commands,
179
236
  contains_string("Run the following commands on the van object v"),
@@ -182,51 +239,74 @@ class GamePage(BasePage):
182
239
 
183
240
  def write_to_then_clear_console(self):
184
241
  self._write_code("my_van.")
185
- self.browser.find_element_by_id("fast_tab").click()
242
+ self.browser.find_element(By.ID, "fast_tab").click()
186
243
  time.sleep(1)
187
- console = self.browser.find_element_by_id("consoleOutput")
244
+ console = self.browser.find_element(By.ID, "consoleOutput")
188
245
  self.clear_console_button()
189
246
  assert_that(console.text == "")
190
247
  return self
191
248
 
192
- def next_episode(self):
249
+ def next_episode(self, from_python_den=False):
250
+ self.assert_success()
251
+ self.browser.find_element(By.ID, "next_episode_button").click()
252
+
253
+ tabId = "python_tab" if from_python_den else "blockly_tab"
254
+
255
+ WebDriverWait(self.browser, 10).until(
256
+ presence_of_all_elements_located((By.ID, tabId))
257
+ )
258
+ return self
259
+
260
+ def next_level(self, from_python_den=False):
193
261
  self.assert_success()
194
- self.browser.find_element_by_id("next_episode_button").click()
262
+ self.browser.find_element(By.ID, "next_level_button").click()
263
+
264
+ tabId = "python_tab" if from_python_den else "blockly_tab"
265
+
195
266
  WebDriverWait(self.browser, 10).until(
196
- presence_of_all_elements_located((By.ID, "blockly_tab"))
267
+ presence_of_all_elements_located((By.ID, tabId))
197
268
  )
198
269
  return self
199
270
 
200
- def next_level(self):
271
+ def next_level_redirected(self, from_python_den=False):
201
272
  self.assert_success()
202
- self.browser.find_element_by_id("next_level_button").click()
273
+ self.browser.find_element(By.ID, "next_level_button").click()
274
+
275
+ episodeId = "episode-16" if from_python_den else "episode-1"
276
+
203
277
  WebDriverWait(self.browser, 10).until(
204
- presence_of_all_elements_located((By.ID, "blockly_tab"))
278
+ presence_of_all_elements_located((By.ID, episodeId))
205
279
  )
206
280
  return self
207
281
 
208
282
  def _run_failing_program(self, text):
209
283
  self.run_program("try_again_button")
210
- error_message = self.browser.find_element_by_id("myModal-lead").text
284
+ error_message = self.browser.find_element(By.ID, "myModal-lead").text
211
285
  assert_that(error_message, contains_string(text))
212
286
  return self
213
287
 
214
288
  def _run_failing_python_program_console(self, code, console_message):
215
289
  self._write_code(code)
216
- self.browser.find_element_by_id("fast_tab").click()
290
+ self.browser.find_element(By.ID, "fast_tab").click()
217
291
  time.sleep(1)
218
- console = self.browser.find_element_by_id("consoleOutput")
292
+ console = self.browser.find_element(By.ID, "consoleOutput")
219
293
  assert_that(console.text, contains_string(console_message))
220
294
  return self
221
295
 
222
296
  def _run_failing_python_program_popup(self, code, text):
223
297
  self._write_code(code)
224
- self.browser.find_element_by_id("fast_tab").click()
298
+ self.browser.find_element(By.ID, "fast_tab").click()
225
299
  time.sleep(1)
226
- error_message = self.browser.find_element_by_id("myModal-lead").text
300
+ error_message = self.browser.find_element(By.ID, "myModal-lead").text
227
301
  assert_that(error_message, contains_string(text))
228
302
  return self
229
303
 
304
+ def _run_working_program(self, code):
305
+ self._write_code(code)
306
+ self.browser.find_element(By.ID, "fast_tab").click()
307
+ time.sleep(1)
308
+ return self
309
+
230
310
  def _write_code(self, code):
231
311
  self.browser.execute_script(
232
312
  "ocargo.pythonControl.appendCode(arguments[0])", code
@@ -235,17 +315,19 @@ class GamePage(BasePage):
235
315
 
236
316
  def _run_procedure_error_program(self, text):
237
317
  self.run_program("close_button")
238
- error_message = self.browser.find_element_by_id("myModal-mainText").text
318
+ error_message = self.browser.find_element(
319
+ By.ID, "myModal-mainText"
320
+ ).text
239
321
  assert_that(error_message, contains_string(text))
240
322
 
241
323
  def _assert_score(self, element_id, score):
242
- score_text = self.browser.find_element_by_id(element_id).text
324
+ score_text = self.browser.find_element(By.ID, element_id).text
243
325
  score_number = score_text.split("/")[0]
244
326
  assert_that(score_number, equal_to(str(score)))
245
327
  return self
246
328
 
247
329
  def assert_success(self):
248
- modal_content = self.browser.find_element_by_id("modal-content").text
330
+ modal_content = self.browser.find_element(By.ID, "modal-content").text
249
331
  assert_that(modal_content, contains_string("Congratulations"))
250
332
  return self
251
333
 
@@ -6,26 +6,7 @@ This solves a bug introduced when upgrading to Django 1.11,
6
6
  see more information here: https://github.com/jazzband/django-pipeline/issues/593
7
7
  """
8
8
 
9
- from django.core.servers.basehttp import WSGIServer
10
- from django.test.testcases import (
11
- LiveServerTestCase,
12
- LiveServerThread,
13
- QuietWSGIRequestHandler,
14
- )
9
+ from django.contrib.staticfiles.testing import LiveServerTestCase
15
10
  from django_selenium_clean import SeleniumTestCase
16
11
 
17
-
18
- class NonThreadedLiveServerThread(LiveServerThread):
19
- """
20
- Replaces ThreadedWSGIServer with WSGIServer as the threaded one doesn't close the DB connections properly, thus
21
- triggering random "DB table locked" errors.
22
- """
23
-
24
- def _create_server(self):
25
- return WSGIServer(
26
- (self.host, self.port), QuietWSGIRequestHandler, allow_reuse_address=False
27
- )
28
-
29
-
30
12
  SeleniumTestCase.__bases__ = (LiveServerTestCase,)
31
- SeleniumTestCase.server_thread_class = NonThreadedLiveServerThread
@@ -1,8 +1,7 @@
1
+ from game.character import get_character
1
2
  from game.end_to_end_tests.base_game_test import BaseGameTest
2
3
  from game.models import Level, Block, LevelBlock
3
-
4
4
  from game.theme import get_theme
5
- from game.character import get_character
6
5
 
7
6
 
8
7
  class TestCowCrashes(BaseGameTest):
@@ -48,18 +47,17 @@ class TestCowCrashes(BaseGameTest):
48
47
  TestCowCrashes.cow_level = Level(
49
48
  name="Cow crashing",
50
49
  anonymous=False,
51
- blocklyEnabled=True,
50
+ blockly_enabled=True,
52
51
  character=van,
53
52
  cows='[{"minCows":"7","maxCows":"7","potentialCoordinates":[{"x":4,"y":4},{"x":2,"y":4},{"x":3,"y":7},{"x":4,"y":6},{"x":2,"y":6},{"x":3,"y":1},{"x":4,"y":2}],"type":"WHITE"}]',
54
53
  default=False,
55
54
  destinations="[[4,5]]",
56
- direct_drive=True,
57
55
  fuel_gauge=False,
58
56
  max_fuel=50,
59
57
  model_solution="[1]",
60
58
  origin='{"coordinate":[2,5],"direction":"E"}',
61
59
  path='[{"coordinate":[2,5],"connectedNodes":[1]},{"coordinate":[3,5],"connectedNodes":[0,4,2,5]},{"coordinate":[4,5],"connectedNodes":[1]},{"coordinate":[3,7],"connectedNodes":[4]},{"coordinate":[3,6],"connectedNodes":[8,3,6,1]},{"coordinate":[3,4],"connectedNodes":[10,1,11,16]},{"coordinate":[4,6],"connectedNodes":[4,7]},{"coordinate":[4,7],"connectedNodes":[6]},{"coordinate":[2,6],"connectedNodes":[9,4]},{"coordinate":[2,7],"connectedNodes":[8]},{"coordinate":[2,4],"connectedNodes":[13,5,12]},{"coordinate":[4,4],"connectedNodes":[5,14,15]},{"coordinate":[2,3],"connectedNodes":[10]},{"coordinate":[1,4],"connectedNodes":[10]},{"coordinate":[5,4],"connectedNodes":[11]},{"coordinate":[4,3],"connectedNodes":[11,19]},{"coordinate":[3,3],"connectedNodes":[5,17]},{"coordinate":[3,2],"connectedNodes":[18,16,19,20]},{"coordinate":[2,2],"connectedNodes":[17]},{"coordinate":[4,2],"connectedNodes":[17,15,23,22]},{"coordinate":[3,1],"connectedNodes":[21,17,22]},{"coordinate":[2,1],"connectedNodes":[20]},{"coordinate":[4,1],"connectedNodes":[20,19]},{"coordinate":[5,2],"connectedNodes":[19]}]',
62
- pythonEnabled=False,
60
+ python_enabled=False,
63
61
  theme=grass,
64
62
  threads=1,
65
63
  traffic_lights="[]",
@@ -0,0 +1,14 @@
1
+ from game.end_to_end_tests.base_game_test import BaseGameTest
2
+
3
+ from selenium.webdriver.common.by import By
4
+
5
+ class TestLanguageDropdown(BaseGameTest):
6
+ def test_level_language_dropdown(self):
7
+ page = self.go_to_level(1)
8
+ assert page.element_exists_by_id("language_dropdown")
9
+
10
+ self.selenium.find_element(By.ID, "language_dropdown").click()
11
+ self.selenium.find_element(By.ID, "language_dropdown_fr").click()
12
+
13
+ text_count = len(self.selenium.find_elements(By.XPATH, ("//*[contains(text(),'Move forwards')]")))
14
+ assert text_count == 0