# coding: utf-8
"""test_find_fork."""
# pylint: disable=no-self-use
from __future__ import absolute_import, division, print_function, unicode_literals

from os import path
import unittest

from six import PY3

from find_forks.__init__ import CONFIG
from find_forks.find_forks import add_forks, determine_names, find_forks, main

from .__init__ import BASEPATH

if PY3:
    from unittest.mock import patch, MagicMock, Mock  # pylint: disable=no-name-in-module
else:
    from mock import patch, MagicMock, Mock


class FindForksCommon(unittest.TestCase):
    @staticmethod
    def make_mock(json_response):
        """Used in test_interesting.py."""
        response_mock = MagicMock()
        response_mock.read = Mock(return_value=json_response)
        if PY3:
            response_mock.status = 200
            response_mock.getheader = Mock(return_value='<https://api.github.com/repos/frost-nzcr4/find_forks/forks?page=2>; rel="next", '
                                           '<https://api.github.com/repos/frost-nzcr4/find_forks/forks?page=3>; rel="last"')
        else:
            response_mock.code = 200
            response_mock.info = Mock(return_value=(('link', '<https://api.github.com/repos/frost-nzcr4/find_forks/forks?page=2>; rel="next", '
                                                             '<https://api.github.com/repos/frost-nzcr4/find_forks/forks?page=3>; rel="last"'), ))

        return response_mock

    def make_test(self, response_mock):
        """Used in test_interesting.py."""
        url = 'https://github.com/frost-nzcr4/find_forks'
        with patch('find_forks.find_forks.urllib.request.urlopen', return_value=response_mock) as urlopen_mock:
            with patch('find_forks.git_wrapper.subprocess.call', return_value=None):
                self.assertEqual(add_forks(url), 'https://api.github.com/repos/frost-nzcr4/find_forks/forks?page=2')
                urlopen_mock.assert_called_once_with(url, timeout=6)
                if PY3:
                    response_mock.status = 404
                else:
                    response_mock.code = 404
                self.assertIsNone(add_forks(url))


class FindForksTest(FindForksCommon):
    def test_add_forks(self):
        self.assertIsNone(add_forks('httttps://unavailable!url'))

        with open(path.join(BASEPATH, 'fixture/response.json'), 'rb') as fixture:
            json_response = fixture.read()
        response_mock = self.make_mock(json_response)
        self.make_test(response_mock)

    def test_determine_names(self):
        """To run this test you'll need to prepare git first, run:

        git remote add test-origin-1 https://github.com/frost-nzcr4/find_forks.git
        git remote add test-origin-2 https://github.com/yagmort/symfony1.git
        git remote add test-origin-3 git@github.com:tjerkw/Android-SlideExpandableListView.git
        """
        user, repo = determine_names()
        self.assertEqual(user, 'frost-nzcr4')
        self.assertEqual(repo, 'find_forks')

        user, repo = determine_names('test-origin-1')
        self.assertEqual(user, 'frost-nzcr4')
        self.assertEqual(repo, 'webmoney')

        user, repo = determine_names('test-origin-2')
        self.assertEqual(user, 'yagmort')
        self.assertEqual(repo, 'symfony1')

        user, repo = determine_names('test-origin-3')
        self.assertEqual(user, 'tjerkw')
        self.assertEqual(repo, 'Android-SlideExpandableListView')

        with self.assertRaises(RuntimeError):
            user, repo = determine_names('name-with-an-error')

    def test_find_forks(self):
        sent_args = {
            'per_page': 99,
            'start_page': 3
        }
        url = 'https://api.github.com/repos/frost-nzcr4/find_forks/forks?per_page=%s&page=%s' % (sent_args['per_page'], sent_args['start_page'])

        with patch('find_forks.git_wrapper.subprocess.call', return_value=None) as call_mock:
            with patch('find_forks.find_forks.add_forks', return_value=None) as add_forks_mock:
                find_forks(**sent_args)
        add_forks_mock.assert_called_once_with(url)
        call_mock.assert_called_once()

    def test_main(self):
        with patch('find_forks.find_forks.find_forks', return_value=None) as find_forks_mock:
            main()
            sent_args = CONFIG.copy()
            sent_args.update({'user': None, 'repo': None, 'no_fetch': False})
            find_forks_mock.assert_called_once_with(**sent_args)

            # Test __version__ exceptions.
            find_forks_mock = MagicMock(side_effect=SystemError())
            del find_forks_mock.__version__
            modules = {
                'find_forks.__init__': find_forks_mock
            }
            with patch.dict('sys.modules', modules):
                self.assertRaises(ImportError, main)

[((26, 24, 26, 35), 'mock.MagicMock', 'MagicMock', ({}, {}), '()', False, 'from mock import patch, MagicMock, Mock\n'), ((27, 29, 27, 61), 'mock.Mock', 'Mock', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((69, 21, 69, 38), 'find_forks.find_forks.determine_names', 'determine_names', ({}, {}), '()', False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((73, 21, 73, 53), 'find_forks.find_forks.determine_names', 'determine_names', ({(73, 37, 73, 52): '"""test-origin-1"""'}, {}), "('test-origin-1')", False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((77, 21, 77, 53), 'find_forks.find_forks.determine_names', 'determine_names', ({(77, 37, 77, 52): '"""test-origin-2"""'}, {}), "('test-origin-2')", False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((81, 21, 81, 53), 'find_forks.find_forks.determine_names', 'determine_names', ({(81, 37, 81, 52): '"""test-origin-3"""'}, {}), "('test-origin-3')", False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((30, 38, 31, 124), 'mock.Mock', 'Mock', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((34, 33, 35, 146), 'mock.Mock', 'Mock', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((42, 13, 42, 94), 'mock.patch', 'patch', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((55, 26, 55, 64), 'find_forks.find_forks.add_forks', 'add_forks', ({(55, 36, 55, 63): '"""httttps://unavailable!url"""'}, {}), "('httttps://unavailable!url')", False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((86, 25, 86, 62), 'find_forks.find_forks.determine_names', 'determine_names', ({(86, 41, 86, 61): '"""name-with-an-error"""'}, {}), "('name-with-an-error')", False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((95, 13, 95, 79), 'mock.patch', 'patch', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((102, 13, 102, 73), 'mock.patch', 'patch', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((103, 12, 103, 18), 'find_forks.find_forks.main', 'main', ({}, {}), '()', False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((104, 24, 104, 37), 'find_forks.__init__.CONFIG.copy', 'CONFIG.copy', ({}, {}), '()', False, 'from find_forks.__init__ import CONFIG\n'), ((43, 17, 43, 83), 'mock.patch', 'patch', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((57, 18, 57, 62), 'os.path.join', 'path.join', ({(57, 28, 57, 36): 'BASEPATH', (57, 38, 57, 61): '"""fixture/response.json"""'}, {}), "(BASEPATH, 'fixture/response.json')", False, 'from os import path\n'), ((96, 17, 96, 76), 'mock.patch', 'patch', (), '', False, 'from mock import patch, MagicMock, Mock\n'), ((97, 16, 97, 39), 'find_forks.find_forks.find_forks', 'find_forks', ({}, {}), '(**sent_args)', False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((114, 17, 114, 51), 'mock.patch.dict', 'patch.dict', ({(114, 28, 114, 41): '"""sys.modules"""', (114, 43, 114, 50): 'modules'}, {}), "('sys.modules', modules)", False, 'from mock import patch, MagicMock, Mock\n'), ((44, 33, 44, 47), 'find_forks.find_forks.add_forks', 'add_forks', ({(44, 43, 44, 46): 'url'}, {}), '(url)', False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n'), ((50, 34, 50, 48), 'find_forks.find_forks.add_forks', 'add_forks', ({(50, 44, 50, 47): 'url'}, {}), '(url)', False, 'from find_forks.find_forks import add_forks, determine_names, find_forks, main\n')]