From 10cabe75367a41f8c764ee3c29b6284b926e1638 Mon Sep 17 00:00:00 2001
From: Florian Aucomte <33633200+faucomte97@users.noreply.github.com>
Date: Thu, 16 Jun 2022 16:28:06 +0100
Subject: [PATCH] fix: Fix badges disappearing randomly (#1671)
* fix: Get badges after code updated
* Merge branch 'master' into badges_disappearing
* Merge branch 'master' into badges_disappearing
* Make initial code update not trigger badge check
* fix test
* Try index 0 in log list in test
* Filter badges in frontend
* Fix tests
* Run prettier
* Make sure gamestate is defined
* Update comment
* Simplify filtering
---
Pipfile.lock | 234 +++++++++---------
game_frontend/src/components/Badge/index.js | 18 +-
.../src/components/NavigationBar/index.js | 36 +--
game_frontend/src/pyodide/badges.test.ts | 68 ++---
game_frontend/src/pyodide/badges.ts | 36 +--
game_frontend/src/pyodide/pyodideRunner.ts | 9 +-
.../redux/features/AvatarWorker/actions.js | 6 -
.../src/redux/features/AvatarWorker/epics.js | 34 +--
.../redux/features/AvatarWorker/reducers.js | 4 +-
.../src/redux/features/AvatarWorker/types.js | 2 -
10 files changed, 183 insertions(+), 264 deletions(-)
diff --git a/Pipfile.lock b/Pipfile.lock
index 18236db92..6ce35c152 100644
--- a/Pipfile.lock
+++ b/Pipfile.lock
@@ -38,25 +38,26 @@
},
"cachetools": {
"hashes": [
- "sha256:4ebbd38701cdfd3603d1f751d851ed248ab4570929f2d8a7ce69e30c420b141c",
- "sha256:8b3b8fa53f564762e5b221e9896798951e7f915513abf2ba072ce0f07f3f5a98"
+ "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757",
+ "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db"
],
"markers": "python_version ~= '3.7'",
- "version": "==5.1.0"
+ "version": "==5.2.0"
},
"certifi": {
"hashes": [
- "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
- "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
+ "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7",
+ "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"
],
- "version": "==2021.10.8"
+ "markers": "python_version >= '3.6'",
+ "version": "==2022.5.18.1"
},
"cfl-common": {
"hashes": [
- "sha256:85684210372755fad77b01ed32c8f82509fc058a04e6c627f77d3622e35914bf",
- "sha256:d92d13412781756ea8a85d246e35bf8560779ff9d89c7947f4c9021aff8dcbba"
+ "sha256:358b78ac5e30c95917c69c8c65bfd174661d22d98f32b928dd66a5e9de849cfd",
+ "sha256:c0b6e182fd8fcb42b70a7243f890f7e43033432488693c605f5c5500fca73c2c"
],
- "version": "==6.7.0"
+ "version": "==6.8.4"
},
"chardet": {
"hashes": [
@@ -162,11 +163,11 @@
},
"google-auth": {
"hashes": [
- "sha256:1ba4938e032b73deb51e59c4656a00e0939cf0b1112575099f136babb4563312",
- "sha256:349ac49b18b01019453cc99c11c92ed772739778c92f184002b7ab3a5b7ac77d"
+ "sha256:8a954960f852d5f19e6af14dd8e75c20159609e85d8db37e4013cc8c3824a7e1",
+ "sha256:df549a1433108801b11bdcc0e312eaf0d5f0500db42f0523e4d65c78722e8475"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
- "version": "==2.6.6"
+ "version": "==2.7.0"
},
"greenlet": {
"hashes": [
@@ -301,7 +302,7 @@
"sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
"sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==2.8.2"
},
"pytz": {
@@ -352,9 +353,7 @@
},
"qrcode": {
"hashes": [
- "sha256:375a6ff240ca9bd41adc070428b5dfc1dcfbb0f2507f1ac848f6cded38956578",
- "sha256:3996ee560fc39532910603704c82980ff6d4d5d629f9c3f25f34174ce8606cf5",
- "sha256:505253854f607f2abf4d16092c61d4e9d511a3b4392e60bff957a68592b04369"
+ "sha256:375a6ff240ca9bd41adc070428b5dfc1dcfbb0f2507f1ac848f6cded38956578"
],
"markers": "python_version >= '3.6'",
"version": "==7.3.1"
@@ -385,18 +384,18 @@
},
"setuptools": {
"hashes": [
- "sha256:28c79c24d83c42a5e6d6cc711e5e9a6c1b89326229feaa5807fc277040658600",
- "sha256:588ffd1dc6e20e9f4f7057aa9873fcdc26e0270362602735d32476bad67d82c5"
+ "sha256:d1746e7fd520e83bbe210d02fff1aa1a425ad671c7a9da7d246ec2401a087198",
+ "sha256:e7d11f3db616cda0751372244c2ba798e8e56a28e096ec4529010b803485f3fe"
],
"markers": "python_version >= '3.7'",
- "version": "==62.3.1"
+ "version": "==62.3.3"
},
"six": {
"hashes": [
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==1.16.0"
},
"sortedcontainers": {
@@ -499,25 +498,26 @@
},
"cachetools": {
"hashes": [
- "sha256:4ebbd38701cdfd3603d1f751d851ed248ab4570929f2d8a7ce69e30c420b141c",
- "sha256:8b3b8fa53f564762e5b221e9896798951e7f915513abf2ba072ce0f07f3f5a98"
+ "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757",
+ "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db"
],
"markers": "python_version ~= '3.7'",
- "version": "==5.1.0"
+ "version": "==5.2.0"
},
"certifi": {
"hashes": [
- "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
- "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
+ "sha256:9c5705e395cd70084351dd8ad5c41e65655e08ce46f2ec9cf6c2c08390f71eb7",
+ "sha256:f1d53542ee8cbedbe2118b5686372fb33c297fcd6379b050cca0ef13a597382a"
],
- "version": "==2021.10.8"
+ "markers": "python_version >= '3.6'",
+ "version": "==2022.5.18.1"
},
"cfl-common": {
"hashes": [
- "sha256:85684210372755fad77b01ed32c8f82509fc058a04e6c627f77d3622e35914bf",
- "sha256:d92d13412781756ea8a85d246e35bf8560779ff9d89c7947f4c9021aff8dcbba"
+ "sha256:358b78ac5e30c95917c69c8c65bfd174661d22d98f32b928dd66a5e9de849cfd",
+ "sha256:c0b6e182fd8fcb42b70a7243f890f7e43033432488693c605f5c5500fca73c2c"
],
- "version": "==6.7.0"
+ "version": "==6.8.4"
},
"chardet": {
"hashes": [
@@ -536,61 +536,61 @@
},
"codeforlife-portal": {
"hashes": [
- "sha256:29a94cf281d76e99ca7f942ef79cf06b1ad44ca2c2a3f888341c58639d9868f0",
- "sha256:79adaa8746b89e1d78ad90ec6e31cbcbcfb340f84d7e164c88b88e471e7ed367"
+ "sha256:3c30220f5b070f040ad7e271ba6a5a72687e6951e7da3b23c7bd6cb791767e1d",
+ "sha256:d91d46f4f867cc621ab987ef93853100aded7837fcedf3cd09ea8b89969995b8"
],
"index": "pypi",
- "version": "==6.7.0"
+ "version": "==6.8.4"
},
"coverage": {
"extras": [
"toml"
],
"hashes": [
- "sha256:06f54765cdbce99901871d50fe9f41d58213f18e98b170a30ca34f47de7dd5e8",
- "sha256:114944e6061b68a801c5da5427b9173a0dd9d32cd5fcc18a13de90352843737d",
- "sha256:1414e8b124611bf4df8d77215bd32cba6e3425da8ce9c1f1046149615e3a9a31",
- "sha256:2781c43bffbbec2b8867376d4d61916f5e9c4cc168232528562a61d1b4b01879",
- "sha256:2ab88a01cd180b5640ccc9c47232e31924d5f9967ab7edd7e5c91c68eee47a69",
- "sha256:338c417613f15596af9eb7a39353b60abec9d8ce1080aedba5ecee6a5d85f8d3",
- "sha256:3401b0d2ed9f726fadbfa35102e00d1b3547b73772a1de5508ef3bdbcb36afe7",
- "sha256:462105283de203df8de58a68c1bb4ba2a8a164097c2379f664fa81d6baf94b81",
- "sha256:4cd696aa712e6cd16898d63cf66139dc70d998f8121ab558f0e1936396dbc579",
- "sha256:4d06380e777dd6b35ee936f333d55b53dc4a8271036ff884c909cf6e94be8b6c",
- "sha256:61f4fbf3633cb0713437291b8848634ea97f89c7e849c2be17a665611e433f53",
- "sha256:6d4a6f30f611e657495cc81a07ff7aa8cd949144e7667c5d3e680d73ba7a70e4",
- "sha256:6f5fee77ec3384b934797f1873758f796dfb4f167e1296dc00f8b2e023ce6ee9",
- "sha256:75b5dbffc334e0beb4f6c503fb95e6d422770fd2d1b40a64898ea26d6c02742d",
- "sha256:7835f76a081787f0ca62a53504361b3869840a1620049b56d803a8cb3a9eeea3",
- "sha256:79bf405432428e989cad7b8bc60581963238f7645ae8a404f5dce90236cc0293",
- "sha256:8329635c0781927a2c6ae068461e19674c564e05b86736ab8eb29c420ee7dc20",
- "sha256:8586b177b4407f988731eb7f41967415b2197f35e2a6ee1a9b9b561f6323c8e9",
- "sha256:892e7fe32191960da559a14536768a62e83e87bbb867e1b9c643e7e0fbce2579",
- "sha256:91502bf27cbd5c83c95cfea291ef387469f2387508645602e1ca0fd8a4ba7548",
- "sha256:93b16b08f94c92cab88073ffd185070cdcb29f1b98df8b28e6649145b7f2c90d",
- "sha256:9c9441d57b0963cf8340268ad62fc83de61f1613034b79c2b1053046af0c5284",
- "sha256:ad8f9068f5972a46d50fe5f32c09d6ee11da69c560fcb1b4c3baea246ca4109b",
- "sha256:afb03f981fadb5aed1ac6e3dd34f0488e1a0875623d557b6fad09b97a942b38a",
- "sha256:b5ba058610e8289a07db2a57bce45a1793ec0d3d11db28c047aae2aa1a832572",
- "sha256:baa8be8aba3dd1e976e68677be68a960a633a6d44c325757aefaa4d66175050f",
- "sha256:c06455121a089252b5943ea682187a4e0a5cf0a3fb980eb8e7ce394b144430a9",
- "sha256:c1a9942e282cc9d3ed522cd3e3cab081149b27ea3bda72d6f61f84eaf88c1a63",
- "sha256:c488db059848702aff30aa1d90ef87928d4e72e4f00717343800546fdbff0a94",
- "sha256:cb5311d6ccbd22578c80028c5e292a7ab9adb91bd62c1982087fad75abe2e63d",
- "sha256:cbe91bc84be4e5ef0b1480d15c7b18e29c73bdfa33e07d3725da7d18e1b0aff2",
- "sha256:cc692c9ee18f0dd3214843779ba6b275ee4bb9b9a5745ba64265bce911aefd1a",
- "sha256:cc972d829ad5ef4d4c5fcabd2bbe2add84ce8236f64ba1c0c72185da3a273130",
- "sha256:ceb6534fcdfb5c503affb6b1130db7b5bfc8a0f77fa34880146f7a5c117987d0",
- "sha256:d522f1dc49127eab0bfbba4e90fa068ecff0899bbf61bf4065c790ddd6c177fe",
- "sha256:db094a6a4ae6329ed322a8973f83630b12715654c197dd392410400a5bfa1a73",
- "sha256:df32ee0f4935a101e4b9a5f07b617d884a531ed5666671ff6ac66d2e8e8246d8",
- "sha256:e5af1feee71099ae2e3b086ec04f57f9950e1be9ecf6c420696fea7977b84738",
- "sha256:e814a4a5a1d95223b08cdb0f4f57029e8eab22ffdbae2f97107aeef28554517e",
- "sha256:f8cabc5fd0091976ab7b020f5708335033e422de25e20ddf9416bdce2b7e07d8",
- "sha256:fbc86ae8cc129c801e7baaafe3addf3c8d49c9c1597c44bdf2d78139707c3c62"
+ "sha256:01c5615d13f3dd3aa8543afc069e5319cfa0c7d712f6e04b920431e5c564a749",
+ "sha256:106c16dfe494de3193ec55cac9640dd039b66e196e4641fa8ac396181578b982",
+ "sha256:129cd05ba6f0d08a766d942a9ed4b29283aff7b2cccf5b7ce279d50796860bb3",
+ "sha256:145f296d00441ca703a659e8f3eb48ae39fb083baba2d7ce4482fb2723e050d9",
+ "sha256:1480ff858b4113db2718848d7b2d1b75bc79895a9c22e76a221b9d8d62496428",
+ "sha256:269eaa2c20a13a5bf17558d4dc91a8d078c4fa1872f25303dddcbba3a813085e",
+ "sha256:26dff09fb0d82693ba9e6231248641d60ba606150d02ed45110f9ec26404ed1c",
+ "sha256:2bd9a6fc18aab8d2e18f89b7ff91c0f34ff4d5e0ba0b33e989b3cd4194c81fd9",
+ "sha256:309ce4a522ed5fca432af4ebe0f32b21d6d7ccbb0f5fcc99290e71feba67c264",
+ "sha256:3384f2a3652cef289e38100f2d037956194a837221edd520a7ee5b42d00cc605",
+ "sha256:342d4aefd1c3e7f620a13f4fe563154d808b69cccef415415aece4c786665397",
+ "sha256:39ee53946bf009788108b4dd2894bf1349b4e0ca18c2016ffa7d26ce46b8f10d",
+ "sha256:4321f075095a096e70aff1d002030ee612b65a205a0a0f5b815280d5dc58100c",
+ "sha256:4803e7ccf93230accb928f3a68f00ffa80a88213af98ed338a57ad021ef06815",
+ "sha256:4ce1b258493cbf8aec43e9b50d89982346b98e9ffdfaae8ae5793bc112fb0068",
+ "sha256:664a47ce62fe4bef9e2d2c430306e1428ecea207ffd68649e3b942fa8ea83b0b",
+ "sha256:75ab269400706fab15981fd4bd5080c56bd5cc07c3bccb86aab5e1d5a88dc8f4",
+ "sha256:83c4e737f60c6936460c5be330d296dd5b48b3963f48634c53b3f7deb0f34ec4",
+ "sha256:84631e81dd053e8a0d4967cedab6db94345f1c36107c71698f746cb2636c63e3",
+ "sha256:84e65ef149028516c6d64461b95a8dbcfce95cfd5b9eb634320596173332ea84",
+ "sha256:865d69ae811a392f4d06bde506d531f6a28a00af36f5c8649684a9e5e4a85c83",
+ "sha256:87f4f3df85aa39da00fd3ec4b5abeb7407e82b68c7c5ad181308b0e2526da5d4",
+ "sha256:8c08da0bd238f2970230c2a0d28ff0e99961598cb2e810245d7fc5afcf1254e8",
+ "sha256:961e2fb0680b4f5ad63234e0bf55dfb90d302740ae9c7ed0120677a94a1590cb",
+ "sha256:9b3e07152b4563722be523e8cd0b209e0d1a373022cfbde395ebb6575bf6790d",
+ "sha256:a7f3049243783df2e6cc6deafc49ea123522b59f464831476d3d1448e30d72df",
+ "sha256:bf5601c33213d3cb19d17a796f8a14a9eaa5e87629a53979a5981e3e3ae166f6",
+ "sha256:cec3a0f75c8f1031825e19cd86ee787e87cf03e4fd2865c79c057092e69e3a3b",
+ "sha256:d42c549a8f41dc103a8004b9f0c433e2086add8a719da00e246e17cbe4056f72",
+ "sha256:d67d44996140af8b84284e5e7d398e589574b376fb4de8ccd28d82ad8e3bea13",
+ "sha256:d9c80df769f5ec05ad21ea34be7458d1dc51ff1fb4b2219e77fe24edf462d6df",
+ "sha256:e57816f8ffe46b1df8f12e1b348f06d164fd5219beba7d9433ba79608ef011cc",
+ "sha256:ee2ddcac99b2d2aec413e36d7a429ae9ebcadf912946b13ffa88e7d4c9b712d6",
+ "sha256:f02cbbf8119db68455b9d763f2f8737bb7db7e43720afa07d8eb1604e5c5ae28",
+ "sha256:f1d5aa2703e1dab4ae6cf416eb0095304f49d004c39e9db1d86f57924f43006b",
+ "sha256:f5b66caa62922531059bc5ac04f836860412f7f88d38a476eda0a6f11d4724f4",
+ "sha256:f69718750eaae75efe506406c490d6fc5a6161d047206cc63ce25527e8a3adad",
+ "sha256:fb73e0011b8793c053bfa85e53129ba5f0250fdc0392c1591fd35d915ec75c46",
+ "sha256:fd180ed867e289964404051a958f7cccabdeed423f91a899829264bb7974d3d3",
+ "sha256:fdb6f7bd51c2d1714cea40718f6149ad9be6a2ee7d93b19e9f00934c0f2a74d9",
+ "sha256:ffa9297c3a453fba4717d06df579af42ab9a28022444cae7fa605af4df612d54"
],
"markers": "python_version >= '3.7'",
- "version": "==6.3.3"
+ "version": "==6.4.1"
},
"django": {
"hashes": [
@@ -734,16 +734,16 @@
"hashes": [
"sha256:b1bead90b70cf6ec3f0710ae53a525360fa360d306a86583adc6bf83a4db537d"
],
- "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'",
"version": "==0.18.2"
},
"google-auth": {
"hashes": [
- "sha256:1ba4938e032b73deb51e59c4656a00e0939cf0b1112575099f136babb4563312",
- "sha256:349ac49b18b01019453cc99c11c92ed772739778c92f184002b7ab3a5b7ac77d"
+ "sha256:8a954960f852d5f19e6af14dd8e75c20159609e85d8db37e4013cc8c3824a7e1",
+ "sha256:df549a1433108801b11bdcc0e312eaf0d5f0500db42f0523e4d65c78722e8475"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'",
- "version": "==2.6.6"
+ "version": "==2.7.0"
},
"greenlet": {
"hashes": [
@@ -823,11 +823,11 @@
},
"importlib-metadata": {
"hashes": [
- "sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6",
- "sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539"
+ "sha256:5d26852efe48c0a32b0509ffbc583fda1a2266545a78d104a6f4aff3db17d700",
+ "sha256:c58c8eb8a762858f49e18436ff552e83914778e50e9d2f1660535ffb364552ec"
],
"markers": "python_version < '3.8'",
- "version": "==4.11.3"
+ "version": "==4.11.4"
},
"iniconfig": {
"hashes": [
@@ -1061,7 +1061,7 @@
"sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86",
"sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==2.8.2"
},
"pytz": {
@@ -1112,19 +1112,17 @@
},
"qrcode": {
"hashes": [
- "sha256:375a6ff240ca9bd41adc070428b5dfc1dcfbb0f2507f1ac848f6cded38956578",
- "sha256:3996ee560fc39532910603704c82980ff6d4d5d629f9c3f25f34174ce8606cf5",
- "sha256:505253854f607f2abf4d16092c61d4e9d511a3b4392e60bff957a68592b04369"
+ "sha256:375a6ff240ca9bd41adc070428b5dfc1dcfbb0f2507f1ac848f6cded38956578"
],
"markers": "python_version >= '3.6'",
"version": "==7.3.1"
},
"rapid-router": {
"hashes": [
- "sha256:20522ae77361b36e3adcdaa8bf1d869e1dca33a0453d8b2498a6073fbeb0af4e",
- "sha256:633033ee4503e9f484d486525d6fe55bd64903e3c0bc0737b23696ce8995d9a7"
+ "sha256:04233006c35c42140a2e956390da46def8149c3129c4533af1e93e6369cd3220",
+ "sha256:d9142f7c93b6b14928b9f19d59d5e281438d47482e0cb8efefd744fb08b5563b"
],
- "version": "==4.1.0"
+ "version": "==4.1.1"
},
"reportlab": {
"hashes": [
@@ -1181,18 +1179,18 @@
},
"setuptools": {
"hashes": [
- "sha256:28c79c24d83c42a5e6d6cc711e5e9a6c1b89326229feaa5807fc277040658600",
- "sha256:588ffd1dc6e20e9f4f7057aa9873fcdc26e0270362602735d32476bad67d82c5"
+ "sha256:d1746e7fd520e83bbe210d02fff1aa1a425ad671c7a9da7d246ec2401a087198",
+ "sha256:e7d11f3db616cda0751372244c2ba798e8e56a28e096ec4529010b803485f3fe"
],
"markers": "python_version >= '3.7'",
- "version": "==62.3.1"
+ "version": "==62.3.3"
},
"six": {
"hashes": [
"sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926",
"sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"
],
- "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'",
"version": "==1.16.0"
},
"sortedcontainers": {
@@ -1215,7 +1213,7 @@
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
"sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"
],
- "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
+ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'",
"version": "==0.10.2"
},
"tomli": {
@@ -1228,33 +1226,33 @@
},
"typed-ast": {
"hashes": [
- "sha256:20d5118e494478ef2d3a2702d964dae830aedd7b4d3b626d003eea526be18718",
- "sha256:27e46cdd01d6c3a0dd8f728b6a938a6751f7bd324817501c15fb056307f918c6",
- "sha256:27f25232e2dd0edfe1f019d6bfaaf11e86e657d9bdb7b0956db95f560cceb2b3",
- "sha256:3042bfc9ca118712c9809201f55355479cfcdc17449f9f8db5e744e9625c6805",
- "sha256:37e5349d1d5de2f4763d534ccb26809d1c24b180a477659a12c4bde9dd677d74",
- "sha256:4fff9fdcce59dc61ec1b317bdb319f8f4e6b69ebbe61193ae0a60c5f9333dc49",
- "sha256:542cd732351ba8235f20faa0fc7398946fe1a57f2cdb289e5497e1e7f48cfedb",
- "sha256:5dc2c11ae59003d4a26dda637222d9ae924387f96acae9492df663843aefad55",
- "sha256:8831479695eadc8b5ffed06fdfb3e424adc37962a75925668deeb503f446c0a3",
- "sha256:8cdf91b0c466a6c43f36c1964772918a2c04cfa83df8001ff32a89e357f8eb06",
- "sha256:8e0b8528838ffd426fea8d18bde4c73bcb4167218998cc8b9ee0a0f2bfe678a6",
- "sha256:8ef1d96ad05a291f5c36895d86d1375c0ee70595b90f6bb5f5fdbee749b146db",
- "sha256:9ad3b48cf2b487be140072fb86feff36801487d4abb7382bb1929aaac80638ea",
- "sha256:9cc9e1457e1feb06b075c8ef8aeb046a28ec351b1958b42c7c31c989c841403a",
- "sha256:9e237e74fd321a55c90eee9bc5d44be976979ad38a29bbd734148295c1ce7617",
- "sha256:c9f1a27592fac87daa4e3f16538713d705599b0a27dfe25518b80b6b017f0a6d",
- "sha256:d64dabc6336ddc10373922a146fa2256043b3b43e61f28961caec2a5207c56d5",
- "sha256:e20d196815eeffb3d76b75223e8ffed124e65ee62097e4e73afb5fec6b993e7a",
- "sha256:e34f9b9e61333ecb0f7d79c21c28aa5cd63bec15cb7e1310d7d3da6ce886bc9b",
- "sha256:ed44e81517364cb5ba367e4f68fca01fba42a7a4690d40c07886586ac267d9b9",
- "sha256:ee852185964744987609b40aee1d2eb81502ae63ee8eef614558f96a56c1902d",
- "sha256:f60d9de0d087454c91b3999a296d0c4558c1666771e3460621875021bf899af9",
- "sha256:f818c5b81966d4728fec14caa338e30a70dfc3da577984d38f97816c4b3071ec",
- "sha256:fd5df1313915dbd70eaaa88c19030b441742e8b05e6103c631c83b75e0435ccc"
+ "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2",
+ "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1",
+ "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6",
+ "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62",
+ "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac",
+ "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d",
+ "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc",
+ "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2",
+ "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97",
+ "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35",
+ "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6",
+ "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1",
+ "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4",
+ "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c",
+ "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e",
+ "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec",
+ "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f",
+ "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72",
+ "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47",
+ "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72",
+ "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe",
+ "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6",
+ "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3",
+ "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"
],
"markers": "python_version < '3.8' and implementation_name == 'cpython'",
- "version": "==1.5.3"
+ "version": "==1.5.4"
},
"typing-extensions": {
"hashes": [
diff --git a/game_frontend/src/components/Badge/index.js b/game_frontend/src/components/Badge/index.js
index f16c455ec..b8b3c5057 100644
--- a/game_frontend/src/components/Badge/index.js
+++ b/game_frontend/src/components/Badge/index.js
@@ -29,7 +29,7 @@ const BadgeModalImg = styled(Box)`
export default class BadgeModal extends Component {
static propTypes = {
modalOpen: PropTypes.bool,
- taskId: PropTypes.string,
+ badgeId: PropTypes.string,
}
render() {
@@ -37,8 +37,8 @@ export default class BadgeModal extends Component {
return null
}
- const taskId = this.props.taskId
- const info = badgeInfo[taskId]
+ const badgeId = this.props.badgeId
+ const info = badgeInfo[badgeId]
if (info === undefined) {
return null
}
@@ -62,15 +62,15 @@ export default class BadgeModal extends Component {
}
}
-export function getBadges(tasks) {
- return tasks.map((task) => (
+export function getBadges(badges) {
+ return badges.map((badge) => (
))
}
diff --git a/game_frontend/src/components/NavigationBar/index.js b/game_frontend/src/components/NavigationBar/index.js
index 247fdfa96..2ea6e8241 100644
--- a/game_frontend/src/components/NavigationBar/index.js
+++ b/game_frontend/src/components/NavigationBar/index.js
@@ -38,11 +38,12 @@ export class NavigationBar extends Component {
static propTypes = {
// the props received from redux state or reducers
modalOpen: PropTypes.bool,
- completedTasks: PropTypes.string,
+ completedBadges: PropTypes.string,
badgesInit: PropTypes.func,
+ gameState: PropTypes.any,
}
- state = { modalOpen: false, completedTasks: [], lastTask: '' }
+ state = { modalOpen: false, completedBadges: [], lastBadge: '' }
componentDidMount() {
this.props.badgesInit()
@@ -56,19 +57,25 @@ export class NavigationBar extends Component {
static getDerivedStateFromProps(props, state) {
// Any time completedTasks change, pass the new info as state
- if (props.completedTasks !== undefined) {
- // convert to string for comparison
- const stateTasksString = state.completedTasks.join() + ','
+ if (props.completedBadges !== undefined && props.gameState !== undefined) {
+ const worksheetID = props.gameState.worksheetID
+ let badges = props.completedBadges.split(',')
+ badges = badges.filter((s) => s) // remove empty element
+ // remove any badge that's not relevant to the current worksheet
+ badges = badges.filter((b) => {
+ return b.startsWith(worksheetID + ':')
+ })
- if (props.completedTasks !== stateTasksString) {
- let newTasks = props.completedTasks.split(',')
- newTasks = newTasks.filter((s) => s) // remove empty element
- const lastTask = newTasks[newTasks.length - 1] // assume the last element is the last task
+ // convert to string for comparison
+ const stateBadgesString = state.completedBadges.join() + ','
+ if (props.completedBadges !== stateBadgesString) {
+ const lastBadge = badges[badges.length - 1] // assume the last element is the last badge
+ // return badge info with popup if there is a new badge earned
return {
modalOpen: props.modalOpen,
- completedTasks: newTasks,
- lastTask: lastTask,
+ completedBadges: badges,
+ lastBadge: lastBadge,
}
}
}
@@ -76,7 +83,7 @@ export class NavigationBar extends Component {
}
renderLogoToolbar = () => {
- const badges = getBadges(this.state.completedTasks)
+ const badges = getBadges(this.state.completedBadges)
return (
@@ -109,15 +116,16 @@ export class NavigationBar extends Component {
{this.renderLogoToolbar()}
{this.renderButtonToolbar()}
-
+
)
}
}
const mapStateToProps = (state) => ({
- completedTasks: state.avatarWorker.completedTasks,
+ completedBadges: state.avatarWorker.completedBadges,
modalOpen: state.avatarWorker.modalOpen,
+ gameState: state.game.gameState,
})
const mapDispatchToProps = {
diff --git a/game_frontend/src/pyodide/badges.test.ts b/game_frontend/src/pyodide/badges.test.ts
index e2cf3cc62..c86df3628 100644
--- a/game_frontend/src/pyodide/badges.test.ts
+++ b/game_frontend/src/pyodide/badges.test.ts
@@ -1,5 +1,5 @@
/* eslint-env jest */
-import { checkIfBadgeEarned, filterByWorksheet } from './badges'
+import { checkIfBadgeEarned } from './badges'
jest.mock('threads/worker')
describe('Badges check', () => {
@@ -7,21 +7,21 @@ describe('Badges check', () => {
const badges = ''
const turnResult = {
action: {
- action_type: "move",
+ action_type: 'move',
options: {
- direction: {x: 0, y: -1}
- }
+ direction: { x: 0, y: -1 },
+ },
},
- log: "",
+ log: '',
turnCount: 1,
}
const userCode = ''
- const gameState = {worksheetID: 1}
+ const gameState = { worksheetID: 1 }
const playerAvatarId = 1
const result = checkIfBadgeEarned(badges, turnResult, userCode, gameState, playerAvatarId)
- const expected = "1:1,"
+ const expected = '1:1,'
expect(result).toBe(expected)
})
@@ -30,12 +30,12 @@ describe('Badges check', () => {
const badges = ''
const turnResult = {
action: {
- action_type: "move",
+ action_type: 'move',
options: {
- direction: {x: 0, y: -1}
- }
+ direction: { x: 0, y: -1 },
+ },
},
- log: "",
+ log: '',
turnCount: 1,
}
const userCode = `
@@ -56,12 +56,12 @@ def next_turn(world_state, avatar_state):
return action
`
- const gameState = {worksheetID: 1}
+ const gameState = { worksheetID: 1 }
const playerAvatarId = 1
const result = checkIfBadgeEarned(badges, turnResult, userCode, gameState, playerAvatarId)
- const expected = "1:1,1:2,"
+ const expected = '1:1,1:2,'
expect(result).toBe(expected)
})
@@ -70,12 +70,12 @@ def next_turn(world_state, avatar_state):
const badges = ''
const turnResult = {
action: {
- action_type: "move",
+ action_type: 'move',
options: {
- direction: {x: 0, y: -1}
- }
+ direction: { x: 0, y: -1 },
+ },
},
- log: "",
+ log: '',
turnCount: 1,
}
const userCode = `
@@ -108,8 +108,8 @@ def next_turn(world_state, avatar_state):
players: [
{
id: 1,
- location: {x: 10, y: 10}
- }
+ location: { x: 10, y: 10 },
+ },
],
obstacles: [],
}
@@ -117,35 +117,7 @@ def next_turn(world_state, avatar_state):
const result = checkIfBadgeEarned(badges, turnResult, userCode, gameState, playerAvatarId)
- const expected = "1:1,1:2,1:3,"
-
- expect(result).toBe(expected)
- })
-
- it('filters badges', () => {
- const badges = '1:1,1:2,1:3,2:1,2:2,3:1'
-
- let gameState = {worksheetID: 1}
-
- let result = filterByWorksheet(badges, gameState)
-
- let expected = "1:1,1:2,1:3"
-
- expect(result).toBe(expected)
-
- gameState = {worksheetID: 2}
-
- result = filterByWorksheet(badges, gameState)
-
- expected = "2:1,2:2"
-
- expect(result).toBe(expected)
-
- gameState = {worksheetID: 3}
-
- result = filterByWorksheet(badges, gameState)
-
- expected = "3:1"
+ const expected = '1:1,1:2,1:3,'
expect(result).toBe(expected)
})
diff --git a/game_frontend/src/pyodide/badges.ts b/game_frontend/src/pyodide/badges.ts
index 144e2da22..89e8039ea 100644
--- a/game_frontend/src/pyodide/badges.ts
+++ b/game_frontend/src/pyodide/badges.ts
@@ -1,25 +1,11 @@
/* eslint-env worker */
import ComputedTurnResult from './computedTurnResult'
-export function filterByWorksheet(badges: any, gameState: any): string {
- const worksheetID = gameState.worksheetID
- let badgesArr = badges.split(',')
-
- badgesArr = badgesArr.filter((s) => s) // remove empty element
- // remove any badge that's not relevant to the current worksheet
- badgesArr = badgesArr.filter((b) => {
- return b.startsWith(worksheetID + ':')
- })
-
- return badgesArr.join(',')
-}
-
export function checkIfBadgeEarned(
badges: string,
result: ComputedTurnResult,
userCode: string,
- gameState: any,
- playerAvatarId: number
+ gameState: any
): string {
const userPythonCode = userCode.replace(/\s*#.*/gm, '') // Remove all comment lines from the user's code
const badgesPerWorksheet = [
@@ -28,7 +14,7 @@ export function checkIfBadgeEarned(
{
id: 3,
worksheetID: 1,
- trigger: badge3Trigger(result, userPythonCode, gameState, playerAvatarId),
+ trigger: badge3Trigger(result, userPythonCode),
},
]
@@ -40,7 +26,7 @@ export function checkIfBadgeEarned(
badge.trigger
) {
// Here is when a new badge is earned
- // TODO on worksshet 2: This might have to order the badges, in case user does not do the worksheet in order
+ // TODO on worksheet 2: This might have to order the badges, in case user does not do the worksheet in order
badges += `${badgeWorksheetPair},`
}
}
@@ -71,21 +57,11 @@ function badge2Trigger(userPythonCode: string): boolean {
return substrings.every((substring) => userPythonCode.includes(substring))
}
-function badge3Trigger(
- result: any,
- userPythonCode: string,
- gameState: any,
- playerAvatarId: number
-): boolean {
+function badge3Trigger(result: any, userPythonCode: string): boolean {
// Check the code contains certain keywords about moving to a cell
const substrings = ['world_state.can_move_to(', 'print(', 'if ']
const codeContainsKeywords = substrings.every((substring) => userPythonCode.includes(substring))
- if (!codeContainsKeywords) return false
-
- // Check action is move action
- const isMoveAction = result.action.action_type === 'move'
- if (!isMoveAction) return false
-
- return true
+ // And check it returns a move action
+ return codeContainsKeywords && result.action.action_type === 'move'
}
diff --git a/game_frontend/src/pyodide/pyodideRunner.ts b/game_frontend/src/pyodide/pyodideRunner.ts
index 11548c113..8116c463f 100644
--- a/game_frontend/src/pyodide/pyodideRunner.ts
+++ b/game_frontend/src/pyodide/pyodideRunner.ts
@@ -16,18 +16,13 @@ async function initializePyodideWorker() {
await worker.initializePyodide()
}
-export async function filterByWorksheet(badges: string, gameState: any): Promise {
- return worker.filterByWorksheet(badges, gameState)
-}
-
export async function checkIfBadgeEarned(
badges: string,
result: ComputedTurnResult,
userCode: string,
- gameState: any,
- playerAvatarId: number
+ gameState: any
): Promise {
- return worker.checkIfBadgeEarned(badges, result, userCode, gameState, playerAvatarId)
+ return worker.checkIfBadgeEarned(badges, result, userCode, gameState)
}
export async function updateAvatarCode(
diff --git a/game_frontend/src/redux/features/AvatarWorker/actions.js b/game_frontend/src/redux/features/AvatarWorker/actions.js
index a29351fda..6f2f8753b 100644
--- a/game_frontend/src/redux/features/AvatarWorker/actions.js
+++ b/game_frontend/src/redux/features/AvatarWorker/actions.js
@@ -26,11 +26,6 @@ const getBadgesRequest = () => ({
type: types.GET_BADGES_REQUEST,
})
-const filterBadges = (badges) => ({
- type: types.FILTER_BADGES,
- payload: badges,
-})
-
const getBadgesReceived = (badges) => ({
type: types.GET_BADGES_SUCCESS,
payload: badges,
@@ -61,7 +56,6 @@ export default {
avatarCodeUpdated,
avatarsNextActionComputed,
badgesEarned,
- filterBadges,
getBadgesRequest,
getBadgesReceived,
checkBadgesReceived,
diff --git a/game_frontend/src/redux/features/AvatarWorker/epics.js b/game_frontend/src/redux/features/AvatarWorker/epics.js
index a2dd633c8..f49f7e8e3 100644
--- a/game_frontend/src/redux/features/AvatarWorker/epics.js
+++ b/game_frontend/src/redux/features/AvatarWorker/epics.js
@@ -95,7 +95,7 @@ const getBadgesEpic = (action$, state$, { api }) =>
ofType(types.PYODIDE_INITIALIZED),
mergeMap((action) =>
api.get(`badges/${state$.value.game.connectionParameters.game_id}/`).pipe(
- map((response) => actions.filterBadges(response.badges)),
+ map((response) => actions.getBadgesReceived(response.badges)),
catchError((error) =>
of({
type: types.GET_BADGES_FAILURE,
@@ -109,26 +109,6 @@ const getBadgesEpic = (action$, state$, { api }) =>
)
)
-/**
- * Filter the badges to return those that are from the game's worksheet.
- * @returns a redux action that contains a string storing the user's earned badges of that worksheet.
- */
-const filterBadgesEpic = (action$, state$, { pyodideRunner: { filterByWorksheet } }) =>
- action$.pipe(
- ofType(types.FILTER_BADGES),
- switchMap(({ payload: badges }) =>
- from(filterByWorksheet(badges, state$.value.game.gameState))
- ),
- map((badges) => actions.getBadgesReceived(badges)),
- catchError((error) =>
- of({
- type: types.BADGES_CHECKED_FAILURE,
- payload: error,
- error: true,
- })
- )
- )
-
/**
* Whenever the avatar's code is updated, get the user's badges information.
* @returns a redux action that contains a string storing the user's earned badges information.
@@ -157,18 +137,17 @@ const checkBadgesEpic = (action$, state$, { api }) =>
*/
const checkBadgesEarnedEpic = (action$, state$, { pyodideRunner: { checkIfBadgeEarned } }) =>
action$.pipe(
- ofType(types.BADGES_CHECKED_SUCCESS),
- switchMap(({ payload: badges }) =>
+ ofType(types.AVATAR_CODE_UPDATED),
+ switchMap(({ payload: computedTurnResult }) =>
action$.pipe(
- ofType(types.AVATAR_CODE_UPDATED),
- switchMap(({ payload: computedTurnResult }) =>
+ ofType(types.BADGES_CHECKED_SUCCESS),
+ switchMap(({ payload: badges }) =>
from(
checkIfBadgeEarned(
badges,
computedTurnResult,
state$.value.editor.code.codeOnServer,
- state$.value.game.gameState,
- state$.value.game.connectionParameters.currentAvatarID
+ state$.value.game.gameState
)
)
),
@@ -214,5 +193,4 @@ export default {
checkBadgesEpic,
postBadgesEpic,
checkBadgesEarnedEpic,
- filterBadgesEpic,
}
diff --git a/game_frontend/src/redux/features/AvatarWorker/reducers.js b/game_frontend/src/redux/features/AvatarWorker/reducers.js
index b3bd147f8..41605beb9 100644
--- a/game_frontend/src/redux/features/AvatarWorker/reducers.js
+++ b/game_frontend/src/redux/features/AvatarWorker/reducers.js
@@ -15,13 +15,13 @@ const actionReducer = (state = { initialized: false }, action) => {
case types.GET_BADGES_SUCCESS:
return {
...state,
- completedTasks: action.payload,
+ completedBadges: action.payload,
modalOpen: false,
}
case types.BADGES_EARNED:
return {
...state,
- completedTasks: action.payload,
+ completedBadges: action.payload,
modalOpen: true,
}
default:
diff --git a/game_frontend/src/redux/features/AvatarWorker/types.js b/game_frontend/src/redux/features/AvatarWorker/types.js
index d82dd9c00..cdd032c58 100644
--- a/game_frontend/src/redux/features/AvatarWorker/types.js
+++ b/game_frontend/src/redux/features/AvatarWorker/types.js
@@ -8,7 +8,6 @@ const AVATARS_NEXT_ACTION_COMPUTED = 'features/AvatarWorker/AVATARS_NEXT_ACTION_
const BADGES_EARNED = 'features/AvatarWorker/BADGES_EARNED'
const BADGES_CHECKED_FAILURE = 'features/AvatarWorker/BADGES_CHECKED_FAILURE'
const BADGES_CHECKED_SUCCESS = 'features/AvatarWorker/BADGES_CHECKED_SUCCESS'
-const FILTER_BADGES = 'features/AvatarWorker/FILTER_BADGES'
const GET_BADGES_REQUEST = 'features/AvatarWorker/GET_CODE_REQUEST'
const GET_BADGES_SUCCESS = 'features/AvatarWorker/GET_CODE_SUCCESS'
const GET_BADGES_FAILURE = 'features/AvatarWorker/GET_CODE_FAILURE'
@@ -24,7 +23,6 @@ export default {
BADGES_EARNED,
BADGES_CHECKED_FAILURE,
BADGES_CHECKED_SUCCESS,
- FILTER_BADGES,
GET_BADGES_REQUEST,
GET_BADGES_SUCCESS,
GET_BADGES_FAILURE,