Repository: oppia/oppia

Issue:
Redirect signed-in learners to the library page when they visit root
As a learner, being redirected to the Creator Dashboard when visiting root (e.g. by clicking the logo in the navbar) is unexpected. I would like to be sent to the library or another page relevant to me as a learner.

The best way I can think of determining whether a logged-in user is a creator or a learner is whether or not the user has an exploration associated with their account from playing around with the exploration creator (though perhaps there is a better way of determining this).

If a logged-in user does not have an exploration associated with their account, redirect them to the library page instead of the creator dashboard when they visit root.
Redirect signed-in learners to the library page when they visit root
As a learner, being redirected to the Creator Dashboard when visiting root (e.g. by clicking the logo in the navbar) is unexpected. I would like to be sent to the library or another page relevant to me as a learner.

The best way I can think of determining whether a logged-in user is a creator or a learner is whether or not the user has an exploration associated with their account from playing around with the exploration creator (though perhaps there is a better way of determining this).

If a logged-in user does not have an exploration associated with their account, redirect them to the library page instead of the creator dashboard when they visit root.
Redirect signed-in learners to the library page when they visit root
As a learner, being redirected to the Creator Dashboard when visiting root (e.g. by clicking the logo in the navbar) is unexpected. I would like to be sent to the library or another page relevant to me as a learner.

The best way I can think of determining whether a logged-in user is a creator or a learner is whether or not the user has an exploration associated with their account from playing around with the exploration creator (though perhaps there is a better way of determining this).

If a logged-in user does not have an exploration associated with their account, redirect them to the library page instead of the creator dashboard when they visit root.


Discussion:
Im working on this issue.
Hello @jaredsilver , I have implemented this feature as suggested by you. I modified HomePageRedirectHandler get() method. I retrieved the user contributions using user_services.get_user_contributions() function and checked the length of the list of contribution ids. if the length is more than 0 then user has explorations associated so my code redirect them to dashboard else redirect them to library page. I have Tested it locally, it's working as intended. Now can I send a pull request ? This is my first pull request please advise. 
Thanks
Im working on this issue.
Hello @jaredsilver , I have implemented this feature as suggested by you. I modified HomePageRedirectHandler get() method. I retrieved the user contributions using user_services.get_user_contributions() function and checked the length of the list of contribution ids. if the length is more than 0 then user has explorations associated so my code redirect them to dashboard else redirect them to library page. I have Tested it locally, it's working as intended. Now can I send a pull request ? This is my first pull request please advise. 
Thanks
Im working on this issue.
Hello @jaredsilver , I have implemented this feature as suggested by you. I modified HomePageRedirectHandler get() method. I retrieved the user contributions using user_services.get_user_contributions() function and checked the length of the list of contribution ids. if the length is more than 0 then user has explorations associated so my code redirect them to dashboard else redirect them to library page. I have Tested it locally, it's working as intended. Now can I send a pull request ? This is my first pull request please advise. 
Thanks

Resolving patch:
diff --git a/main.py b/main.py
--- a/main.py
+++ b/main.py
@@ -71,7 +71,17 @@ class HomePageRedirectHandler(base.BaseHandler):
     """
     def get(self):
         if self.user_id and user_services.has_fully_registered(self.user_id):
-            self.redirect(feconf.DASHBOARD_URL)
+            user_contributions = user_services.get_user_contributions(
+                self.user_id)
+
+            # 'Creator' is a user who has created or edited an exploration.
+            user_is_creator = (
+                len(user_contributions.created_exploration_ids) > 0 or
+                len(user_contributions.edited_exploration_ids) > 0)
+            if user_is_creator:
+                self.redirect(feconf.DASHBOARD_URL)
+            else:
+                self.redirect(feconf.LIBRARY_INDEX_URL)
         else:
             self.redirect(feconf.SPLASH_URL)
 


Test patch:
diff --git a/core/controllers/base_test.py b/core/controllers/base_test.py
--- a/core/controllers/base_test.py
+++ b/core/controllers/base_test.py
@@ -24,6 +24,7 @@
 
 from core.controllers import base
 from core.domain import exp_services
+from core.domain import rights_manager
 from core.platform import models
 from core.tests import test_utils
 import feconf
@@ -42,10 +43,28 @@
 
 class BaseHandlerTest(test_utils.GenericTestBase):
 
+    TEST_LEARNER_EMAIL = "test.learner@example.com"
+    TEST_LEARNER_USERNAME = "testlearneruser"
+    TEST_CREATOR_EMAIL = "test.creator@example.com"
+    TEST_CREATOR_USERNAME = "testcreatoruser"
+    TEST_EDITOR_EMAIL = "test.editor@example.com"
+    TEST_EDITOR_USERNAME = "testeditoruser"
+
     def setUp(self):
         super(BaseHandlerTest, self).setUp()
         self.signup('user@example.com', 'user')
 
+        # Create a user to test redirect behavior for the learner.
+        # A "learner" is defined as a user who has not created or contributed
+        # to any exploration ever.
+        self.signup(self.TEST_LEARNER_EMAIL, self.TEST_LEARNER_USERNAME)
+
+        # Create two users to test redirect behavior for the creators.
+        # A "creator" is defined as a user who has created, edited or
+        # contributed to any exploration at present or in past.
+        self.signup(self.TEST_CREATOR_EMAIL, self.TEST_CREATOR_USERNAME)
+        self.signup(self.TEST_EDITOR_EMAIL, self.TEST_EDITOR_USERNAME)
+
     def test_dev_indicator_appears_in_dev_and_not_in_production(self):
         """Test dev indicator appears in dev and not in production."""
 
@@ -95,16 +114,72 @@ def test_requests_for_invalid_paths(self):
         response = self.testapp.put('/library/extra', {}, expect_errors=True)
         self.assertEqual(response.status_int, 404)
 
-    def test_redirect_in_both_logged_in_and_logged_out_states(self):
-        "Test for a redirect in both logged in and logged out states on '/'."
+    def test_redirect_in_logged_out_states(self):
+        """Test for a redirect in logged out state on '/'."""
 
-        # Logged out state
         response = self.testapp.get('/')
         self.assertEqual(response.status_int, 302)
         self.assertIn('splash', response.headers['location'])
 
-        # Login and assert that there is a redirect
-        self.login('user@example.com')
+    def test_root_redirect_rules_for_logged_in_learners(self):
+        self.login(self.TEST_LEARNER_EMAIL)
+
+        # Since no exploration has been created, going to '/' should redirect
+        # to the library page.
+        response = self.testapp.get('/')
+        self.assertEqual(response.status_int, 302)
+        self.assertIn('library', response.headers['location'])
+        self.logout()
+
+    def test_root_redirect_rules_for_logged_in_creators(self):
+        self.login(self.TEST_CREATOR_EMAIL)
+        creator_user_id = self.get_user_id_from_email(self.TEST_CREATOR_EMAIL)
+        exploration_id = '0_en_test_exploration'
+        self.save_new_valid_exploration(
+            exploration_id, creator_user_id, title='Test',
+            category='Test', language_code='en')
+
+        # Since at least one exploration has been created, going to '/' should
+        # redirect to the dashboard page.
+        response = self.testapp.get('/')
+        self.assertIn('dashboard', response.headers['location'])
+        exp_services.delete_exploration(creator_user_id, exploration_id)
+        self.logout()
+        self.login(self.TEST_CREATOR_EMAIL)
+        response = self.testapp.get('/')
+
+        # Even though the exploration is deleted, the user is still redirected
+        # to the dashboard. This is because deleted explorations are still
+        # associated with their creators.
+        self.assertEqual(response.status_int, 302)
+        self.assertIn('dashboard', response.headers['location'])
+
+    def test_root_redirect_rules_for_logged_in_editors(self):
+        self.login(self.TEST_CREATOR_EMAIL)
+        creator_user_id = self.get_user_id_from_email(self.TEST_CREATOR_EMAIL)
+        editor_user_id = self.get_user_id_from_email(self.TEST_EDITOR_EMAIL)
+        exploration_id = '1_en_test_exploration'
+        self.save_new_valid_exploration(
+            exploration_id, creator_user_id, title='Test',
+            category='Test', language_code='en')
+        rights_manager.assign_role_for_exploration(
+            creator_user_id, exploration_id, editor_user_id,
+            rights_manager.ROLE_EDITOR)
+        self.logout()
+        self.login(self.TEST_EDITOR_EMAIL)
+        exp_services.update_exploration(
+            editor_user_id, exploration_id, [{
+                'cmd': 'edit_exploration_property',
+                'property_name': 'title',
+                'new_value': 'edited title'
+            }, {
+                'cmd': 'edit_exploration_property',
+                'property_name': 'category',
+                'new_value': 'edited category'
+            }], 'Change title and category')
+
+        # Since user has edited one exploration created by another user,
+        # going to '/' should redirect to the dashboard page.
         response = self.testapp.get('/')
         self.assertEqual(response.status_int, 302)
         self.assertIn('dashboard', response.headers['location'])
diff --git a/core/tests/protractor/privileges.js b/core/tests/protractor/privileges.js
--- a/core/tests/protractor/privileges.js
+++ b/core/tests/protractor/privileges.js
@@ -48,7 +48,7 @@ describe('Permissions for private explorations', function() {
       general.openEditor(explorationId);
       // Eve is redirected to the homepage.
       expect(browser.getCurrentUrl()).toEqual(
-        general.SERVER_URL_PREFIX + '/dashboard');
+        general.SERVER_URL_PREFIX + '/library');
       users.logout();
     });
   });