Repository: InstaPy/InstaPy

Issue:
get_given_user_followers return error
I am getting this error when trying this specific user "Bxxar_xxxcial".
```
Traceback (most recent call last):
  File ".../scheduleInstaPy.py", line 71, in job
    amountUserFollowers=5, randomize=True)
  File "...xxx\instapy\instapy.py", line 1798, in iblabla
    self.logger)
  File "...xxx\instapy\unfollow_util.py", line 739, in get_given_user_followers
    click_element(browser, following_link[0]) # following_link.send_keys("\n")
IndexError: list index out of range
```

Will investigate!
SCK


Discussion:
Hi the issue is since the name is not lower case.
Should we catch this or cast to lower ?

Resolving patch:
diff --git a/instapy/unfollow_util.py b/instapy/unfollow_util.py
--- a/instapy/unfollow_util.py
+++ b/instapy/unfollow_util.py
@@ -620,13 +620,21 @@ def follow_through_dialog(browser,
     return person_followed
 
 
-def get_given_user_followers(browser,
-                             user_name,
-                             amount,
-                             dont_include,
-                             login,
-                             randomize,
-                             logger):
+def get_given_user_followers(browser, user_name, amount, dont_include, login, randomize, logger):
+    """
+    Get the followers of the user
+
+    :param browser: webdriver instance
+    :param user_name: the user who's followers to retrieve
+    :param amount: limit the number of users to this
+    :param dont_include: not used
+    :param login: not used
+    :param randomize: randomize the list of users
+    :param logger: logger instance
+    :return:
+        list of followers links
+        None on error
+    """
 
     browser.get('https://www.instagram.com/' + user_name)
     # update server calls
@@ -642,9 +650,13 @@ def get_given_user_followers(browser,
         logger.warning('Can\'t interact with private account')
         return
 
-    following_link = browser.find_elements_by_xpath(
-        '//a[@href="/' + user_name + '/followers/"]')
-    click_element(browser, following_link[0]) # following_link.send_keys("\n")
+    try:
+        following_link = browser.find_element_by_xpath(
+            '//a[@href="/' + user_name.lower() + '/followers/"]')
+    except NoSuchElementException:
+        logger.error('Could not find followers link for {}'.format(user_name))
+        return
+    click_element(browser, following_link)
     # update server calls
     update_activity()
 


Test patch:
diff --git a/tests/test_unfollow_util.py b/tests/test_unfollow_util.py
--- a/tests/test_unfollow_util.py
+++ b/tests/test_unfollow_util.py
@@ -1,33 +1,55 @@
-from unittest.mock import MagicMock, Mock
+from unittest.mock import MagicMock, Mock, patch
 
 from selenium.common.exceptions import NoSuchElementException
 
-from instapy.unfollow_util import follow_given_user_followers
-
-
-def test_follow_given_user_followers_with_missing_count():
-    """ensure follower count error returns empty"""
-    webdriver = MagicMock()
-    webdriver.find_element_by_xpath.side_effect = NoSuchElementException
-    params = [MagicMock()] * 11
-    res = follow_given_user_followers(webdriver, *params)
-    assert len(res) == 0
-
-
-def test_follow_given_user_followers_with_no_followers():
-    """ensure follower count is not zero"""
-    webdriver = MagicMock()
-    webdriver.find_element_by_xpath.return_value = Mock(text='0')
-    params = [MagicMock()] * 11
-    res = follow_given_user_followers(webdriver, *params)
-    assert len(res) == 0
-
-
-def test_follow_given_user_followers_with_missing_link():
-    """ensure follower link error returns empty"""
-    webdriver = MagicMock()
-    webdriver.find_element_by_xpath.return_value = Mock(text='123')
-    webdriver.find_elements_by_xpath.side_effect = BaseException
-    params = [MagicMock()] * 9
-    res = follow_given_user_followers(webdriver, 'foo', 10, *params)
-    assert len(res) == 0
+from instapy.unfollow_util import follow_given_user_followers, get_given_user_followers
+
+
+class TestFollowGivenUserFollowers:
+
+    def test_with_missing_count():
+        """ensure follower count error returns empty"""
+        webdriver = MagicMock()
+        webdriver.find_element_by_xpath.side_effect = NoSuchElementException
+        params = [MagicMock()] * 11
+        res = follow_given_user_followers(webdriver, *params)
+        assert len(res) == 0
+
+    def test_with_no_followers():
+        """ensure follower count is not zero"""
+        webdriver = MagicMock()
+        webdriver.find_element_by_xpath.return_value = Mock(text='0')
+        params = [MagicMock()] * 11
+        res = follow_given_user_followers(webdriver, *params)
+        assert len(res) == 0
+
+    def test_with_missing_link():
+        """ensure follower link error returns empty"""
+        webdriver = MagicMock()
+        webdriver.find_element_by_xpath.return_value = Mock(text='123')
+        webdriver.find_elements_by_xpath.side_effect = BaseException
+        params = [MagicMock()] * 11
+        res = follow_given_user_followers(webdriver, *params)
+        assert len(res) == 0
+
+
+class TestGetGivenUserFollowers:
+
+    @patch('instapy.unfollow_util.scroll_bottom')
+    @patch('instapy.unfollow_util.sleep')
+    def test_following_link_is_lowercase(self, sleep, scroll_bottom):
+        browser = MagicMock()
+        browser.find_element_by_xpath.side_effect = [Mock(text='123'), MagicMock(), MagicMock()]
+        res = get_given_user_followers(browser, 'FoOb2r', 10, [], MagicMock(), False, MagicMock())
+        assert not res
+        assert 'foob2r' in browser.find_element_by_xpath.call_args_list[1][0][0]
+
+    @patch('instapy.unfollow_util.scroll_bottom')
+    @patch('instapy.unfollow_util.sleep')
+    def test_following_link_returns_on_fail(self, sleep, scroll_bottom):
+        browser = MagicMock()
+        browser.find_element_by_xpath.side_effect = [Mock(text='123'), NoSuchElementException()]
+        logger = MagicMock()
+        res = get_given_user_followers(browser, 'FoOb2r', 10, [], MagicMock(), False, logger)
+        assert not res
+        assert logger.error.call_count == 1