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,