<commit_before>import requests
import unittest
from queue import Queue
import requests_mock

from bears.general.InvalidLinkBear import InvalidLinkBear
from coalib.settings.Section import Section
from coalib.settings.Setting import Setting


def custom_matcher(request):
    """
    Mock the status codes for every request by taking the last three characters
    of the request URL.

    For connection checking url, it always passes 200 (prerequisite checking).

    For URLs with no status codes appended, a ``RequestException`` is raised.

    To test for URLs that redirect to URLs with a much larger length, the
    ``redirect_long_url`` is returned.

    :param request: The ``request`` that the mocker recieves.
    :return:        A mocked ``Response`` object.
    """
    redirect_long_url = ("https://confluence.atlassian.com/bitbucket"
                         "/use-the-bitbucket-cloud-rest-apis-222724129.html")
    redirect_urls = ("https://bitbucket.org/api/301",
                     "https://bitbucket.org/api/302")

    change_url = False
    # the connection check url needs to be explicitly
    # set to 200
    if request.url == InvalidLinkBear.check_connection_url:
        status_code = 200
    else:
        try:
            status_code = int(request.path_url[-3:])
        except ValueError:
            raise requests.exceptions.RequestException
    if status_code in range(300, 400):
        change_url = True
        url = (redirect_long_url if request.url in redirect_urls else
               "http://httpbin.org/get")
    resp = requests.Response()
    if change_url:
        resp.url = url
    resp.status_code = status_code
    return resp


class InvalidLinkBearTest(unittest.TestCase):

    """
    The tests are mocked (don't actually connect to internet) and
    return the int conversion of the last three chars of
    the URL as status code.

    Check ``custom matcher`` for more info on implementation.
    """

    def setUp(self):
        self.section = Section("")

    def assertResult(self, valid_file=None, invalid_file=None, settings={}):
        with requests_mock.Mocker() as m:
            InvalidLinkBear.check_prerequisites = lambda *args: True
            uut = InvalidLinkBear(self.section, Queue())
            for name, value in settings.items():
                self.section.append(Setting(name, value))
            m.add_matcher(custom_matcher)
            if valid_file:
                out = uut.execute("valid", valid_file)
                self.assertEqual(out, [])
            if invalid_file:
                out = uut.execute("invalid", invalid_file)
                self.assertNotEqual(out, [])
                self.assertNotEqual(out, None)

    def test_run(self):
        # Valid Links
        valid_file = """
        http://httpbin.org/status/200
        http://httpbin.org/status/201
        http://httpbin.org/status/401  # Unauthorized<commit_msg>InvalidLinkBearTests: Use run instead of execute<commit_after>import requests
import unittest
from queue import Queue
import requests_mock

from bears.general.InvalidLinkBear import InvalidLinkBear
from coalib.settings.Section import Section
from coalib.settings.Setting import Setting


def custom_matcher(request):
    """
    Mock the status codes for every request by taking the last three characters
    of the request URL.

    For connection checking url, it always passes 200 (prerequisite checking).

    For URLs with no status codes appended, a ``RequestException`` is raised.

    To test for URLs that redirect to URLs with a much larger length, the
    ``redirect_long_url`` is returned.

    :param request: The ``request`` that the mocker recieves.
    :return:        A mocked ``Response`` object.
    """
    redirect_long_url = ("https://confluence.atlassian.com/bitbucket"
                         "/use-the-bitbucket-cloud-rest-apis-222724129.html")
    redirect_urls = ("https://bitbucket.org/api/301",
                     "https://bitbucket.org/api/302")

    change_url = False
    # the connection check url needs to be explicitly
    # set to 200
    if request.url == InvalidLinkBear.check_connection_url:
        status_code = 200
    else:
        try:
            status_code = int(request.path_url[-3:])
        except ValueError:
            raise requests.exceptions.RequestException
    if status_code in range(300, 400):
        change_url = True
        url = (redirect_long_url if request.url in redirect_urls else
               "http://httpbin.org/get")
    resp = requests.Response()
    if change_url:
        resp.url = url
    resp.status_code = status_code
    return resp


class InvalidLinkBearTest(unittest.TestCase):

    """
    The tests are mocked (don't actually connect to internet) and
    return the int conversion of the last three chars of
    the URL as status code.

    Check ``custom matcher`` for more info on implementation.
    """

    def setUp(self):
        self.section = Section("")

    def assertResult(self, valid_file=None, invalid_file=None, settings={}):
        with requests_mock.Mocker() as m:
            InvalidLinkBear.check_prerequisites = lambda *args: True
            uut = InvalidLinkBear(self.section, Queue())
            m.add_matcher(custom_matcher)
            if valid_file:
                out = list(uut.run("valid", valid_file, **settings))
                self.assertEqual(out, [])
            if invalid_file:
                out = list(uut.run("invalid", invalid_file, **settings))
                self.assertNotEqual(out, [])
                self.assertNotEqual(out, None)

    def test_run(self):
        # Valid Links
        valid_file = """
        http://httpbin.org/status/200
        http://httpbin.org/status/201
        http://httpbin.org/status/401  # Unauthorized
{'fraction_non_alphanumeric': 0.09130134622022783, 'fraction_numerical': 0.013807386952019331, 'mean_word_length': 2.48676293622142, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5091538', 'n_tokens_mistral': 1687, 'n_tokens_neox': 1573, 'n_words': 469}