Repository: uccser/cs-unplugged

Issue:
Workaround Crowdin bug where integer yaml keys are not preserved
When downloading in-context localisation files, integer keys in YAML files are not preserved. This is only an issue in the file `topics/content/en/programming-challenges-structure-difficulties.yaml`, which uses the difficulty number as the key.

As a work around, we can use the string value of the integer as the key, i.e. `"0"` instead of `0`
Workaround Crowdin bug where integer yaml keys are not preserved
When downloading in-context localisation files, integer keys in YAML files are not preserved. This is only an issue in the file `topics/content/en/programming-challenges-structure-difficulties.yaml`, which uses the difficulty number as the key.

As a work around, we can use the string value of the integer as the key, i.e. `"0"` instead of `0`


Discussion:
Turns out it still fails even with forced string keys, if they are integers. Instead, we will need to modify the keys to [a-zA-Z] identifiers
Turns out it still fails even with forced string keys, if they are integers. Instead, we will need to modify the keys to [a-zA-Z] identifiers

Resolving patch:
diff --git a/csunplugged/topics/management/commands/_ProgrammingChallengesStructureLoader.py b/csunplugged/topics/management/commands/_ProgrammingChallengesStructureLoader.py
--- a/csunplugged/topics/management/commands/_ProgrammingChallengesStructureLoader.py
+++ b/csunplugged/topics/management/commands/_ProgrammingChallengesStructureLoader.py
@@ -86,13 +86,13 @@ def load(self):
             required_fields=["name"],
         )
 
-        for difficulty in difficulty_levels:
+        for level, difficulty_slug in enumerate(difficulty_levels):
 
             new_difficulty = ProgrammingChallengeDifficulty(
-                level=int(difficulty),
+                level=level,
             )
 
-            translations = difficulties_translations.get(difficulty, dict())
+            translations = difficulties_translations.get(difficulty_slug, dict())
             self.populate_translations(new_difficulty, translations)
             self.mark_translation_availability(new_difficulty, required_fields=["name"])
             new_difficulty.save()


Test patch:
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/de/translation-difficulties.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/de/translation-difficulties.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/de/translation-difficulties.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/de/translation-difficulties.yaml
@@ -1,2 +1,2 @@
-1:
+difficulty-1:
   name: German difficulty 1
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/basic-config-difficulties.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/basic-config-difficulties.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/basic-config-difficulties.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/basic-config-difficulties.yaml
@@ -1,2 +1,2 @@
-1:
+difficulty-1:
   name: Level 1
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/empty-difficulties-name-difficulties.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/empty-difficulties-name-difficulties.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/empty-difficulties-name-difficulties.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/empty-difficulties-name-difficulties.yaml
@@ -1,2 +1,2 @@
-1:
+difficulty-1:
   name:
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/translation-difficulties.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/translation-difficulties.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/translation-difficulties.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/en/translation-difficulties.yaml
@@ -1,4 +1,4 @@
-1:
+difficulty-1:
   name: English difficulty 1
-2:
+difficulty-2:
   name: English difficulty 2
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/basic-config.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/basic-config.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/basic-config.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/basic-config.yaml
@@ -3,4 +3,4 @@ languages:
     number: 1
 
 difficulties:
-  - 1
+  - difficulty-1
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-difficulties-name.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-difficulties-name.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-difficulties-name.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-difficulties-name.yaml
@@ -3,4 +3,4 @@ languages:
     number: 1
 
 difficulties:
-  - 1
+  - difficulty-1
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-data.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-data.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-data.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-data.yaml
@@ -2,4 +2,4 @@ languages:
   language-1:
 
 difficulties:
-  - 1
+  - difficulty-1
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-number.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-number.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-number.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/empty-languages-number.yaml
@@ -3,4 +3,4 @@ languages:
     number:
 
 difficulties:
-  - 1
+  - difficulty-1
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/missing-languages.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/missing-languages.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/missing-languages.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/missing-languages.yaml
@@ -1,2 +1,2 @@
 difficulties:
-  1:
+  - difficulty-1
diff --git a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/translation.yaml b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/translation.yaml
--- a/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/translation.yaml
+++ b/csunplugged/tests/topics/loaders/assets/programming_challenges_structure/structure/translation.yaml
@@ -5,5 +5,5 @@ languages:
     number: 2
 
 difficulties:
-  - 1
-  - 2
+  - difficulty-1
+  - difficulty-2
diff --git a/csunplugged/tests/topics/loaders/test_programming_challenges_structure_loader.py b/csunplugged/tests/topics/loaders/test_programming_challenges_structure_loader.py
--- a/csunplugged/tests/topics/loaders/test_programming_challenges_structure_loader.py
+++ b/csunplugged/tests/topics/loaders/test_programming_challenges_structure_loader.py
@@ -108,7 +108,7 @@ def test_translation(self):
         with translation.override("de"):
             self.assertEqual("German language 1", translated_lang.name)
 
-        translated_difficulty = ProgrammingChallengeDifficulty.objects.get(level=1)
+        translated_difficulty = ProgrammingChallengeDifficulty.objects.get(level=0)
         self.assertSetEqual(set(["en", "de"]), set(translated_difficulty.languages))
         self.assertEqual("English difficulty 1", translated_difficulty.name)
         with translation.override("de"):
@@ -127,7 +127,7 @@ def test_translation_missing(self):
         with translation.override("de"):
             self.assertEqual("English language 2", untranslated_lang.name)
 
-        untranslated_difficulty = ProgrammingChallengeDifficulty.objects.get(level=2)
+        untranslated_difficulty = ProgrammingChallengeDifficulty.objects.get(level=1)
         self.assertSetEqual(set(["en"]), set(untranslated_difficulty.languages))
         self.assertEqual("English difficulty 2", untranslated_difficulty.name)
         # Check name does not fall back to english for missing translation