Repository: oppia/oppia

Issue:
Fix the "finished an exploration in a collection" experience.
To reproduce: Play https://www.oppia.org/explore/DIWZiVgs0km-?collection_id=4UgTQUc1tala to the end. After it's completed, instead of seeing just the next exploration in the collection, you'll see instead a bunch of randomly-recommended explorations. This is a pretty bad experience -- it means that students would need to go back to the library page, find the collection, click into it, remember and find the next exploration, and click into that to play it. This is likely to result in a significant dropoff rate in continuing the collection.

Instead, for explorations in a collection, there should be a clear link at the end that points to the next lesson in the collection. Based on wireframes from @amitdeutsch, the expected look-and-feel should be as follows (for explorations in a collection):

![next in collection](https://user-images.githubusercontent.com/10575562/32694344-5635b472-c6f2-11e7-96c7-13f4145f6209.png)

In addition, the experience for explorations outside a collection should be as follows:

![next exploration 1](https://user-images.githubusercontent.com/10575562/32694353-75392f7a-c6f2-11e7-9d11-a83ddfe0d36b.png)

Note that whether an exploration is being played in the context of a collection or not can be determined from the existence of the "collection_id" parameter in the URL bar.


Discussion:
So when investigating this issue, both @seanlip and I were unable to repro the underlying issue of not seeing the correct 'next exploration in the collection' for the logged out case. We need more information on why this was hit before, as it may have been a regression that's since been fixed. The original code to support proper guest continuation in collections was introduced over a year ago.

Given #3708 was submitted a while back, is there any additional work needed here?
#3708 was never submitted, so that work is still needed. The current experience in develop does not match the one described above.
Ah I missed that. Okay, thanks

Resolving patch:
diff --git a/feconf.py b/feconf.py
--- a/feconf.py
+++ b/feconf.py
@@ -495,6 +495,9 @@ def get_empty_ratings():
     u'16': 'all_interactions',
     u'17': 'audio_test',
     u'18': 'code_classifier_test.yaml',
+    u'19': 'example_exploration_in_collection1.yaml',
+    u'20': 'example_exploration_in_collection2.yaml',
+    u'21': 'example_exploration_in_collection3.yaml',
 }
 
 DEMO_COLLECTIONS = {


Test patch:
diff --git a/core/controllers/collection_viewer_test.py b/core/controllers/collection_viewer_test.py
--- a/core/controllers/collection_viewer_test.py
+++ b/core/controllers/collection_viewer_test.py
@@ -129,60 +129,58 @@ def test_welcome_collection(self):
         self.assertEqual(
             collection_dict['title'], 'Introduction to Collections in Oppia')
 
-        # Verify there are 5 explorations in this collection, the initial
+        # Verify there are 4 explorations in this collection, the initial
         # explorations to be completed, and that there are no explorations
         # currently completed within the context of this collection.
-        self.assertEqual(len(collection_dict['nodes']), 5)
+        self.assertEqual(len(collection_dict['nodes']), 4)
 
         playthrough_dict = collection_dict['playthrough_dict']
-        self.assertEqual(playthrough_dict['next_exploration_ids'], ['0'])
+        self.assertEqual(playthrough_dict['next_exploration_ids'], ['19'])
         self.assertEqual(playthrough_dict['completed_exploration_ids'], [])
 
-        # 'Complete' the first exploration. This should lead to 3 more being
+        # 'Complete' the first exploration. This should lead to 1 new one being
         # suggested to the learner.
         collection_services.record_played_exploration_in_collection_context(
-            self.viewer_id, '0', '0')
+            self.viewer_id, '0', '19')
         response_dict = self.get_json(
             '%s/0' % feconf.COLLECTION_DATA_URL_PREFIX)
         collection_dict = response_dict['collection']
 
         playthrough_dict = collection_dict['playthrough_dict']
         self.assertEqual(
-            playthrough_dict['next_exploration_ids'], ['13'])
-        self.assertEqual(playthrough_dict['completed_exploration_ids'], ['0'])
+            playthrough_dict['next_exploration_ids'], ['20'])
+        self.assertEqual(playthrough_dict['completed_exploration_ids'], ['19'])
 
-        # Completing the 'Solar System' exploration results in no branching.
+        # Completing the next exploration results in a third suggested exp.
         collection_services.record_played_exploration_in_collection_context(
-            self.viewer_id, '0', '13')
+            self.viewer_id, '0', '20')
         response_dict = self.get_json(
             '%s/0' % feconf.COLLECTION_DATA_URL_PREFIX)
         collection_dict = response_dict['collection']
 
         playthrough_dict = collection_dict['playthrough_dict']
         self.assertEqual(
-            playthrough_dict['next_exploration_ids'], ['4'])
+            playthrough_dict['next_exploration_ids'], ['21'])
         self.assertEqual(
-            playthrough_dict['completed_exploration_ids'], ['0', '13'])
+            playthrough_dict['completed_exploration_ids'], ['19', '20'])
 
-        # Completing the 'About Oppia' exploration results in another
-        # exploration being suggested.
+        # Completing the next exploration results in a fourth and final
+        # suggested exp.
         collection_services.record_played_exploration_in_collection_context(
-            self.viewer_id, '0', '14')
+            self.viewer_id, '0', '21')
         response_dict = self.get_json(
             '%s/0' % feconf.COLLECTION_DATA_URL_PREFIX)
         collection_dict = response_dict['collection']
 
         playthrough_dict = collection_dict['playthrough_dict']
         self.assertEqual(
-            playthrough_dict['next_exploration_ids'], ['4'])
+            playthrough_dict['next_exploration_ids'], ['0'])
         self.assertEqual(
-            playthrough_dict['completed_exploration_ids'], ['0', '13', '14'])
+            playthrough_dict['completed_exploration_ids'], ['19', '20', '21'])
 
-        # Completing all explorations should lead to no other suggestions.
-        collection_services.record_played_exploration_in_collection_context(
-            self.viewer_id, '0', '15')
+        # Completing the final exploration should result in no new suggestions.
         collection_services.record_played_exploration_in_collection_context(
-            self.viewer_id, '0', '4')
+            self.viewer_id, '0', '0')
         response_dict = self.get_json(
             '%s/0' % feconf.COLLECTION_DATA_URL_PREFIX)
         collection_dict = response_dict['collection']
@@ -191,4 +189,4 @@ def test_welcome_collection(self):
         self.assertEqual(playthrough_dict['next_exploration_ids'], [])
         self.assertEqual(
             playthrough_dict['completed_exploration_ids'],
-            ['0', '13', '14', '15', '4'])
+            ['19', '20', '21', '0'])