Repository: oppia/oppia

Issue:
Correctness banner is slightly offset to the right in the question player
**Describe the bug**
In the question player, when an answer is correct a banner shows up that says 'Correct!' but is slightly offset to the right. We would like to keep it central to the screen.

**To Reproduce**
Steps to reproduce the behavior:
 1. Create a topic and question
 2. Go to practice_session/<TopicName>
 3. Answer the question correctly

**Observed behavior**
The 'Correct' banner comes slightly to the right
<img width="1426" alt="Screen Shot 2019-05-22 at 12 26 57 PM" src="https://user-images.githubusercontent.com/11780495/58202632-e9b91f80-7c8c-11e9-9643-3b68dd702021.png">

**Expected behavior**
The 'Correct' banner should be central to the screen 
Correctness banner is slightly offset to the right in the question player
**Describe the bug**
In the question player, when an answer is correct a banner shows up that says 'Correct!' but is slightly offset to the right. We would like to keep it central to the screen.

**To Reproduce**
Steps to reproduce the behavior:
 1. Create a topic and question
 2. Go to practice_session/<TopicName>
 3. Answer the question correctly

**Observed behavior**
The 'Correct' banner comes slightly to the right
<img width="1426" alt="Screen Shot 2019-05-22 at 12 26 57 PM" src="https://user-images.githubusercontent.com/11780495/58202632-e9b91f80-7c8c-11e9-9643-3b68dd702021.png">

**Expected behavior**
The 'Correct' banner should be central to the screen 


Discussion:

Resolving patch:
diff --git a/core/controllers/practice_sessions.py b/core/controllers/practice_sessions.py
--- a/core/controllers/practice_sessions.py
+++ b/core/controllers/practice_sessions.py
@@ -83,14 +83,14 @@ def get(self, topic_name):
             skills = skill_services.get_multi_skills(topic.get_all_skill_ids())
         except Exception, e:
             raise self.PageNotFoundException(e)
-        skills_with_description = {}
+        skill_descriptions = {}
         for skill in skills:
-            skills_with_description[skill.id] = skill.description
+            skill_descriptions[skill.id] = skill.description
 
         topic_name = topic.name
 
         self.values.update({
             'topic_name': topic.name,
-            'skills_with_description': skills_with_description
+            'skill_descriptions': skill_descriptions
         })
         self.render_json(self.values)


Test patch:
diff --git a/core/controllers/practice_sessions_test.py b/core/controllers/practice_sessions_test.py
--- a/core/controllers/practice_sessions_test.py
+++ b/core/controllers/practice_sessions_test.py
@@ -121,12 +121,12 @@ def test_any_user_can_access_practice_sessions_data(self):
                     feconf.PRACTICE_SESSION_DATA_URL_PREFIX,
                     'public_topic_name'))
             self.assertEqual(json_response['topic_name'], 'public_topic_name')
-            self.assertEqual(len(json_response['skills_with_description']), 2)
+            self.assertEqual(len(json_response['skill_descriptions']), 2)
             self.assertEqual(
-                json_response['skills_with_description']['skill_id_1'],
+                json_response['skill_descriptions']['skill_id_1'],
                 'Skill 1')
             self.assertEqual(
-                json_response['skills_with_description']['skill_id_2'],
+                json_response['skill_descriptions']['skill_id_2'],
                 'Skill 2')
 
     def test_no_user_can_access_unpublished_topic_practice_session_data(self):
diff --git a/core/controllers/review_tests.py b/core/controllers/review_tests.py
--- a/core/controllers/review_tests.py
+++ b/core/controllers/review_tests.py
@@ -20,6 +20,7 @@
 from core.domain import dependency_registry
 from core.domain import interaction_registry
 from core.domain import obj_services
+from core.domain import skill_services
 from core.domain import story_services
 import feconf
 import jinja2
@@ -83,11 +84,19 @@ def get(self, story_id):
         if len(latest_completed_node_ids) == 0:
             raise self.PageNotFoundException
 
-        acquired_skill_ids = story.get_acquired_skill_ids_for_node_ids(
-            latest_completed_node_ids
-        )
+        try:
+            skills = skill_services.get_multi_skills(
+                story.get_acquired_skill_ids_for_node_ids(
+                    latest_completed_node_ids
+                ))
+        except Exception, e:
+            raise self.PageNotFoundException(e)
+        skill_descriptions = {}
+        for skill in skills:
+            skill_descriptions[skill.id] = skill.description
+
 
         self.values.update({
-            'skill_ids': acquired_skill_ids
+            'skill_descriptions': skill_descriptions
         })
         self.render_json(self.values)
diff --git a/core/controllers/review_tests_test.py b/core/controllers/review_tests_test.py
--- a/core/controllers/review_tests_test.py
+++ b/core/controllers/review_tests_test.py
@@ -63,6 +63,9 @@ def setUp(self):
             'exploration_id': self.exp_id
         }
 
+        self.save_new_skill('skill_id_1', self.admin_id, 'Skill 1')
+        self.save_new_skill('skill_id_2', self.admin_id, 'Skill 2')
+
         self.story = story_domain.Story.create_default_story(
             self.story_id_1, 'Public Story Title', self.topic_id)
         self.story.story_contents.nodes = [
@@ -132,9 +135,13 @@ def test_any_user_can_access_review_tests_data(self):
                 '%s/%s' % (
                     feconf.REVIEW_TEST_DATA_URL_PREFIX,
                     self.story_id_1))
-            self.assertEqual(len(json_response['skill_ids']), 2)
-            self.assertEqual(json_response['skill_ids'][0], 'skill_id_1')
-            self.assertEqual(json_response['skill_ids'][1], 'skill_id_2')
+            self.assertEqual(len(json_response['skill_descriptions']), 2)
+            self.assertEqual(
+                json_response['skill_descriptions']['skill_id_1'],
+                'Skill 1')
+            self.assertEqual(
+                json_response['skill_descriptions']['skill_id_2'],
+                'Skill 2')
 
     def test_no_user_can_access_unpublished_story_review_sessions_data(self):
         with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
@@ -143,6 +150,38 @@ def test_no_user_can_access_unpublished_story_review_sessions_data(self):
                     feconf.REVIEW_TEST_DATA_URL_PREFIX, self.story_id_2),
                 expected_status_int=404)
 
+    def test_get_fails_when_acquired_skills_dont_exist(self):
+        story_id = 'story_id_3'
+        node_id = 'node_1'
+        node = {
+            'id': node_id,
+            'title': 'Title 1',
+            'destination_node_ids': [],
+            'acquired_skill_ids': ['skill_id_3'],
+            'prerequisite_skill_ids': [],
+            'outline': '',
+            'outline_is_finalized': False,
+            'exploration_id': self.exp_id
+        }
+        story = story_domain.Story.create_default_story(
+            story_id, 'Public Story Title', self.topic_id)
+        story.story_contents.nodes = [
+            story_domain.StoryNode.from_dict(node)
+        ]
+        story.story_contents.initial_node_id = node_id
+        story.story_contents.next_node_id = self.node_id_2
+        story_services.save_new_story(self.admin_id, story)
+
+        story_services.publish_story(story_id, self.admin_id)
+
+        with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
+            story_services.record_completed_node_in_story_context(
+                self.viewer_id, story_id, node_id)
+            self.get_json(
+                '%s/%s' % (
+                    feconf.REVIEW_TEST_DATA_URL_PREFIX, story_id),
+                expected_status_int=404)
+
     def test_get_fails_when_story_doesnt_exist(self):
         with self.swap(constants, 'ENABLE_NEW_STRUCTURE_PLAYERS', True):
             self.get_json(