import mock
import os
import pandas as pd
import pytest
from flexmock import flexmock
from sportsreference import utils
from sportsreference.nfl.roster import Player, Roster
from sportsreference.nfl.teams import Team


def read_file(filename):
    filepath = os.path.join(os.path.dirname(__file__), 'nfl', filename)
    return open('%s.htm' % filepath, 'r').read()


def mock_pyquery(url):
    class MockPQ:
        def __init__(self, html_contents, status=200):
            self.url = url
            self.reason = 'Bad URL'  # Used when throwing HTTPErrors
            self.headers = {}  # Used when throwing HTTPErrors
            self.status_code = status
            self.html_contents = html_contents
            self.text = html_contents

    if 'BAD' in url or 'bad' in url:
        return MockPQ(None, 404)
    if '404' in url:
        return MockPQ('Page Not Found (404 error)')
    if 'Davi' in url:
        return MockPQ(read_file('DaviDe00'))
    if 'Lewi' in url:
        return MockPQ(read_file('LewiTo00'))
    if 'Lutz' in url:
        return MockPQ(read_file('LutzWi00'))
    if 'Mors' in url:
        return MockPQ(read_file('MorsTh00'))
    if 'Hatf' in url:
        return MockPQ(read_file('HatfDo00'))
    if '2018_roster' in url:
        return MockPQ(read_file('2018_roster'))
    return MockPQ(read_file('BreeDr00'))


class TestNFLPlayer:
    def setup_method(self):
        self.qb_results_career = {
            'adjusted_net_yards_per_attempt_index': 113,
            'adjusted_net_yards_per_pass_attempt': 6.98,
            'adjusted_yards_per_attempt': 7.6,
            'adjusted_yards_per_attempt_index': 111,
            'all_purpose_yards': None,
            'approximate_value': 239,
            'assists_on_tackles': 0,
            'attempted_passes': 9423,
            'birth_date': '1979-01-15',
            'blocked_punts': None,
            'catch_percentage': None,
            'completed_passes': 6326,
            'completion_percentage_index': 119,
            'espn_qbr': None,
            'extra_point_percentage': None,
            'extra_points_attempted': None,
            'extra_points_made': None,
            'field_goal_percentage': None,
            'field_goals_attempted': None,
            'field_goals_made': None,
            'fifty_plus_yard_field_goal_attempts': None,
            'fifty_plus_yard_field_goals_made': None,
            'fourth_quarter_comebacks': 30,
            'fourty_to_fourty_nine_yard_field_goal_attempts': None,
            'fourty_to_fourty_nine_yard_field_goals_made': None,
            'fumbles': 102,
            'fumbles_forced': 0,
            'fumbles_recovered': 29,
            'fumbles_recovered_for_touchdown': -111,
            'game_winning_drives': 43,
            'games': 252,
            'games_started': 251,
            'height': '6-0',
            'interception_percentage': 2.4,
            'interception_percentage_index': 105,
            'interceptions': None,
            'interceptions_returned_for_touchdown': None,
            'interceptions_thrown': 228,
            'kickoff_return_touchdown': None,
            'kickoff_return_yards': None,
            'kickoff_returns': None,
            'less_than_nineteen_yards_field_goal_attempts': None,
            'less_than_nineteen_yards_field_goals_made': None,
            'longest_field_goal_made': None,
            'longest_interception_return': None,
            'longest_kickoff_return': None,
            'longest_pass': 98,
            'longest_punt': None,
            'longest_punt_return': None,
            'longest_reception': 38,
            'longest_rush': 22,
            'name': 'Drew Brees',
            'net_yards_per_attempt_index': 114,
            'net_yards_per_pass_attempt': 7.01,
            'passer_rating_index': 114,
            'passes_defended': None,
            'passing_completion': 67.1,
            'passing_touchdown_percentage': 5.3,
            'passing_touchdowns': 496,
            'passing_yards': 71523,
            'passing_yards_per_attempt': 7.6,
            'player_id': 'BreeDr00',
            'position': '',
            'punt_return_touchdown': None,
            'punt_return_yards': None,
            'punt_returns': None,
            'punts': None,
            'qb_record': '144-107-0',
            'quarterback_rating': 97.1,
            'receiving_touchdowns': 1,
            'receiving_yards': 73,
            'receiving_yards_per_game': 0.3,
            'receiving_yards_per_reception': 10.4,
            'receptions': 7,
            'receptions_per_game': 0.0,
            'rush_attempts': 444,
            'rush_attempts_per_game': 1.8,
            'rush_touchdowns': 20,
            'rush_yards': 742,
            'rush_yards_per_attempt': 1.7,
            'rush_yards_per_game': 2.9,
            'rushing_and_receiving_touchdowns': 21,
            'sack_percentage': None,
            'sack_percentage_index': 116,
            'sacks': None,
            'safeties': None,
            'season': 'Career',
            'tackles': 13,
            'team_abbreviation': '',
            'thirty_to_thirty_nine_yard_field_goal_attempts': None,
            'thirty_to_thirty_nine_yard_field_goals_made': None,
            'times_pass_target': 8,
            'times_sacked': 383,
            'total_punt_yards': None,
            'touchdown_percentage_index': 110,
            'touches': 451,
            'twenty_to_twenty_nine_yard_field_goal_attempts': None,
            'twenty_to_twenty_nine_yard_field_goals_made': None,
            'weight': 209,
            'yards_from_scrimmage': 815,
            'yards_lost_to_sacks': 2734,
            'yards_per_attempt_index': 110,
            'yards_per_completed_pass': 11.3,
            'yards_per_game_played': 283.8,
            'yards_per_kickoff_return': None,
            'yards_per_punt': None,
            'yards_per_punt_return': None,
            'yards_per_touch': 1.8,
            'yards_recovered_from_fumble': -111,
            'yards_returned_from_interception': None
        }

        self.qb_results_2017 = {
            'adjusted_net_yards_per_attempt_index': 116,
            'adjusted_net_yards_per_pass_attempt': 7.71,
            'adjusted_yards_per_attempt': 8.3,
            'adjusted_yards_per_attempt_index': 114,
            'all_purpose_yards': None,
            'approximate_value': 16,
            'assists_on_tackles': None,
            'attempted_passes': 536,
            'birth_date': '1979-01-15',
            'blocked_punts': None,
            'catch_percentage': None,
            'completed_passes': 386,
            'completion_percentage_index': 128,
            'espn_qbr': 64.6,
            'extra_point_percentage': None,
            'extra_points_attempted': None,
            'extra_points_made': None,
            'field_goal_percentage': None,
            'field_goals_attempted': None,
            'field_goals_made': None,
            'fifty_plus_yard_field_goal_attempts': None,
            'fifty_plus_yard_field_goals_made': None,
            'fourth_quarter_comebacks': 2,
            'fourty_to_fourty_nine_yard_field_goal_attempts': None,
            'fourty_to_fourty_nine_yard_field_goals_made': None,
            'fumbles': 5,
            'fumbles_forced': 0,
            'fumbles_recovered': 3,
            'fumbles_recovered_for_touchdown': -12,
            'game_winning_drives': 2,
            'games': 16,
            'games_started': 16,
            'height': '6-0',
            'interception_percentage': 1.5,
            'interception_percentage_index': 112,
            'interceptions': None,
            'interceptions_returned_for_touchdown': None,
            'interceptions_thrown': 8,
            'kickoff_return_touchdown': None,
            'kickoff_return_yards': None,
            'kickoff_returns': None,
            'less_than_nineteen_yards_field_goal_attempts': None,
            'less_than_nineteen_yards_field_goals_made': None,
            'longest_field_goal_made': None,
            'longest_interception_return': None,
            'longest_kickoff_return': None,
            'longest_pass': 54,
            'longest_punt': None,
            'longest_punt_return': None,
            'longest_reception': None,
            'longest_rush': 7,
            'name': 'Drew Brees',
            'net_yards_per_attempt_index': 118,
            'net_yards_per_pass_attempt': 7.53,
            'passer_rating_index': 116,
            'passes_defended': None,
            'passing_completion': 72.0,
            'passing_touchdown_percentage': 4.3,
            'passing_touchdowns': 23,
            'passing_yards': 4334,
            'passing_yards_per_attempt': 8.1,
            'player_id': 'BreeDr00',
            'position': 'QB',
            'punt_return_touchdown': None,
            'punt_return_yards': None,
            'punt_returns': None,
            'punts': None,
            'qb_record': '11-5-0',
            'quarterback_rating': 103.9,
            'receiving_touchdowns': None,
            'receiving_yards': None,
            'receiving_yards_per_game': None,
            'receiving_yards_per_reception': None,
            'receptions': None,
            'receptions_per_game': None,
            'rush_attempts': 33,
            'rush_attempts_per_game': 2.1,
            'rush_touchdowns': 2,
            'rush_yards': 12,
            'rush_yards_per_attempt': 0.4,
            'rush_yards_per_game': 0.8,
            'rushing_and_receiving_touchdowns': 2,
            'sack_percentage': None,
            'sack_percentage_index': 116,
            'sacks': None,
            'safeties': None,
            'season': '2017',
            'tackles': None,
            'team_abbreviation': 'NOR',
            'thirty_to_thirty_nine_yard_field_goal_attempts': None,
            'thirty_to_thirty_nine_yard_field_goals_made': None,
            'times_pass_target': None,
            'times_sacked': 20,
            'total_punt_yards': None,
            'touchdown_percentage_index': 100,
            'touches': 33,
            'twenty_to_twenty_nine_yard_field_goal_attempts': None,
            'twenty_to_twenty_nine_yard_field_goals_made': None,
            'weight': 209,
            'yards_from_scrimmage': 12,
            'yards_lost_to_sacks': 145,
            'yards_per_attempt_index': 115,
            'yards_per_completed_pass': 11.2,
            'yards_per_game_played': 270.9,
            'yards_per_kickoff_return': None,
            'yards_per_punt': None,
            'yards_per_punt_return': None,
            'yards_per_touch': 0.4,
            'yards_recovered_from_fumble': -12,
            'yards_returned_from_interception': None
        }

        self.olb_results_career = {
            'adjusted_net_yards_per_attempt_index': None,
            'adjusted_net_yards_per_pass_attempt': None,
            'adjusted_yards_per_attempt': None,
            'adjusted_yards_per_attempt_index': None,
            'all_purpose_yards': None,
            'approximate_value': 44,
            'assists_on_tackles': 208,
            'attempted_passes': None,
            'birth_date': '1989-01-11',
            'blocked_punts': None,
            'catch_percentage': None,
            'completed_passes': None,
            'completion_percentage_index': None,
            'espn_qbr': None,
            'extra_point_percentage': None,
            'extra_points_attempted': None,
            'extra_points_made': None,
            'field_goal_percentage': None,
            'field_goals_attempted': None,
            'field_goals_made': None,
            'fifty_plus_yard_field_goal_attempts': None,
            'fifty_plus_yard_field_goals_made': None,
            'fourth_quarter_comebacks': None,
            'fourty_to_fourty_nine_yard_field_goal_attempts': None,
            'fourty_to_fourty_nine_yard_field_goals_made': None,
            'fumbles': 0,
            'fumbles_forced': 2,
            'fumbles_recovered': 5,
            'fumbles_recovered_for_touchdown': 8,
            'game_winning_drives': None,
            'games': 99,
            'games_started': 85,
            'height': '6-2',
            'interception_percentage': None,
            'interception_percentage_index': None,
            'interceptions': 1,
            'interceptions_returned_for_touchdown': 0,
            'interceptions_thrown': None,
            'kickoff_return_touchdown': None,
            'kickoff_return_yards': None,
            'kickoff_returns': None,
            'less_than_nineteen_yards_field_goal_attempts': None,
            'less_than_nineteen_yards_field_goals_made': None,
            'longest_field_goal_made': None,
            'longest_interception_return': 0,
            'longest_kickoff_return': None,
            'longest_pass': None,
            'longest_punt': None,
            'longest_punt_return': None,
            'longest_reception': None,
            'longest_rush': None,
            'name': 'Demario Davis',
            'net_yards_per_attempt_index': None,
            'net_yards_per_pass_attempt': None,
            'passer_rating_index': None,
            'passes_defended': 13,
            'passing_completion': None,
            'passing_touchdown_percentage': None,
            'passing_touchdowns': None,
            'passing_yards': None,
            'passing_yards_per_attempt': None,
            'player_id': 'DaviDe00',
            'position': '',
            'punt_return_touchdown': None,
            'punt_return_yards': None,
            'punt_returns': None,
            'punts': None,
            'qb_record': None,
            'quarterback_rating': None,
            'receiving_touchdowns': None,
            'receiving_yards': None,
            'receiving_yards_per_game': None,
            'receiving_yards_per_reception': None,
            'receptions': None,
            'receptions_per_game': None,
            'rush_attempts': None,
            'rush_attempts_per_game': None,
            'rush_touchdowns': None,
            'rush_yards': None,
            'rush_yards_per_attempt': None,
            'rush_yards_per_game': None,
            'rushing_and_receiving_touchdowns': None,
            'sack_percentage': None,
            'sack_percentage_index': None,
            'sacks': 13.5,
            'safeties': None,
            'season': 'Career',
            'tackles': 389,
            'team_abbreviation': '',
            'thirty_to_thirty_nine_yard_field_goal_attempts': None,
            'thirty_to_thirty_nine_yard_field_goals_made': None,
            'times_pass_target': None,
            'times_sacked': None,
            'total_punt_yards': None,
            'touchdown_percentage_index': None,
            'touches': None,
            'twenty_to_twenty_nine_yard_field_goal_attempts': None,
            'twenty_to_twenty_nine_yard_field_goals_made': None,
            'weight': 248,
            'yards_from_scrimmage': None,
            'yards_lost_to_sacks': None,
            'yards_per_attempt_index': None,
            'yards_per_completed_pass': None,
            'yards_per_game_played': None,
            'yards_per_kickoff_return': None,
            'yards_per_punt': None,
            'yards_per_punt_return': None,
            'yards_per_touch': None,
            'yards_recovered_from_fumble': 8,
            'yards_returned_from_interception': 0
        }

        self.kicker_results_career = {
            'adjusted_net_yards_per_attempt_index': None,
            'adjusted_net_yards_per_pass_attempt': None,
            'adjusted_yards_per_attempt': None,
            'adjusted_yards_per_attempt_index': None,
            'all_purpose_yards': None,
            'approximate_value': 7,
            'assists_on_tackles': None,
            'attempted_passes': None,
            'birth_date': '1994-07-07',
            'blocked_punts': None,
            'catch_percentage': None,
            'completed_passes': None,
            'completion_percentage_index': None,
            'espn_qbr': None,
            'extra_point_percentage': 96.3,
            'extra_points_attempted': 108,
            'extra_points_made': 104,
            'field_goal_percentage': 84.4,
            'field_goals_attempted': 77,
            'field_goals_made': 65,
            'fifty_plus_yard_field_goal_attempts': 12,
            'fifty_plus_yard_field_goals_made': 7,
            'fourth_quarter_comebacks': None,
            'fourty_to_fourty_nine_yard_field_goal_attempts': 28,
            'fourty_to_fourty_nine_yard_field_goals_made': 24,
            'fumbles': 0,
            'fumbles_forced': None,
            'fumbles_recovered': None,
            'fumbles_recovered_for_touchdown': None,
            'game_winning_drives': None,
            'games': 35,
            'games_started': None,
            'height': '5-11',
            'interception_percentage': None,
            'interception_percentage_index': None,
            'interceptions': None,
            'interceptions_returned_for_touchdown': None,
            'interceptions_thrown': None,
            'kickoff_return_touchdown': None,
            'kickoff_return_yards': None,
            'kickoff_returns': None,
            'less_than_nineteen_yards_field_goal_attempts': 1,
            'less_than_nineteen_yards_field_goals_made': 1,
            'longest_field_goal_made': 57,
            'longest_interception_return': None,
            'longest_kickoff_return': None,
            'longest_pass': None,
            'longest_punt': None,
            'longest_punt_return': None,
            'longest_reception': None,
            'longest_rush': 4,
            'name': 'Wil Lutz',
            'net_yards_per_attempt_index': None,
            'net_yards_per_pass_attempt': None,
            'passer_rating_index': None,
            'passes_defended': None,
            'passing_completion': None,
            'passing_touchdown_percentage': None,
            'passing_touchdowns': None,
            'passing_yards': None,
            'passing_yards_per_attempt': None,
            'player_id': 'LutzWi00',
            'position': '',
            'punt_return_touchdown': None,
            'punt_return_yards': None,
            'punt_returns': None,
            'punts': None,
            'qb_record': None,
            'quarterback_rating': None,
            'receiving_touchdowns': None,
            'receiving_yards': None,
            'receiving_yards_per_game': None,
            'receiving_yards_per_reception': None,
            'receptions': None,
            'receptions_per_game': None,
            'rush_attempts': 1,
            'rush_attempts_per_game': 0.0,
            'rush_touchdowns': 0,
            'rush_yards': 4,
            'rush_yards_per_attempt': 4.0,
            'rush_yards_per_game': 0.1,
            'rushing_and_receiving_touchdowns': 0,
            'sack_percentage': None,
            'sack_percentage_index': None,
            'sacks': None,
            'safeties': None,
            'season': 'Career',
            'tackles': None,
            'team_abbreviation': '',
            'thirty_to_thirty_nine_yard_field_goal_attempts': 18,
            'thirty_to_thirty_nine_yard_field_goals_made': 15,
            'times_pass_target': None,
            'times_sacked': None,
            'total_punt_yards': None,
            'touchdown_percentage_index': None,
            'touches': 1,
            'twenty_to_twenty_nine_yard_field_goal_attempts': 18,
            'twenty_to_twenty_nine_yard_field_goals_made': 18,
            'weight': 184,
            'yards_from_scrimmage': 4,
            'yards_lost_to_sacks': None,
            'yards_per_attempt_index': None,
            'yards_per_completed_pass': None,
            'yards_per_game_played': None,
            'yards_per_kickoff_return': None,
            'yards_per_punt': None,
            'yards_per_punt_return': None,
            'yards_per_touch': 4.0,
            'yards_recovered_from_fumble': None,
            'yards_returned_from_interception': None
        }

        self.punter_results_career = {
            'adjusted_net_yards_per_attempt_index': None,
            'adjusted_net_yards_per_pass_attempt': None,
            'adjusted_yards_per_attempt': None,
            'adjusted_yards_per_attempt_index': None,
            'all_purpose_yards': None,
            'approximate_value': 26,
            'assists_on_tackles': None,
            'attempted_passes': None,
            'birth_date': '1986-03-08',
            'blocked_punts': 1,
            'catch_percentage': None,
            'completed_passes': None,
            'completion_percentage_index': None,
            'espn_qbr': None,
            'extra_point_percentage': None,
            'extra_points_attempted': None,
            'extra_points_made': None,
            'field_goal_percentage': None,
            'field_goals_attempted': None,
            'field_goals_made': None,
            'fifty_plus_yard_field_goal_attempts': None,
            'fifty_plus_yard_field_goals_made': None,
            'fourth_quarter_comebacks': None,
            'fourty_to_fourty_nine_yard_field_goal_attempts': None,
            'fourty_to_fourty_nine_yard_field_goals_made': None,
            'fumbles': None,
            'fumbles_forced': None,
            'fumbles_recovered': None,
            'fumbles_recovered_for_touchdown': None,
            'game_winning_drives': None,
            'games': 145,
            'games_started': None,
            'height': '6-4',
            'interception_percentage': None,
            'interception_percentage_index': None,
            'interceptions': None,
            'interceptions_returned_for_touchdown': None,
            'interceptions_thrown': None,
            'kickoff_return_touchdown': None,
            'kickoff_return_yards': None,
            'kickoff_returns': None,
            'less_than_nineteen_yards_field_goal_attempts': None,
            'less_than_nineteen_yards_field_goals_made': None,
            'longest_field_goal_made': None,
            'longest_interception_return': None,
            'longest_kickoff_return': None,
            'longest_pass': None,
            'longest_punt': 70,
            'longest_punt_return': None,
            'longest_reception': None,
            'longest_rush': None,
            'name': 'Thomas Morstead',
            'net_yards_per_attempt_index': None,
            'net_yards_per_pass_attempt': None,
            'passer_rating_index': None,
            'passes_defended': None,
            'passing_completion': None,
            'passing_touchdown_percentage': None,
            'passing_touchdowns': None,
            'passing_yards': None,
            'passing_yards_per_attempt': None,
            'player_id': 'MorsTh00',
            'position': '',
            'punt_return_touchdown': None,
            'punt_return_yards': None,
            'punt_returns': None,
            'punts': 538,
            'qb_record': None,
            'quarterback_rating': None,
            'receiving_touchdowns': None,
            'receiving_yards': None,
            'receiving_yards_per_game': None,
            'receiving_yards_per_reception': None,
            'receptions': None,
            'receptions_per_game': None,
            'rush_attempts': None,
            'rush_attempts_per_game': None,
            'rush_touchdowns': None,
            'rush_yards': None,
            'rush_yards_per_attempt': None,
            'rush_yards_per_game': None,
            'rushing_and_receiving_touchdowns': None,
            'sack_percentage': None,
            'sack_percentage_index': None,
            'sacks': None,
            'safeties': None,
            'season': 'Career',
            'tackles': None,
            'team_abbreviation': '',
            'thirty_to_thirty_nine_yard_field_goal_attempts': None,
            'thirty_to_thirty_nine_yard_field_goals_made': None,
            'times_pass_target': None,
            'times_sacked': None,
            'total_punt_yards': 25287,
            'touchdown_percentage_index': None,
            'touches': None,
            'twenty_to_twenty_nine_yard_field_goal_attempts': None,
            'twenty_to_twenty_nine_yard_field_goals_made': None,
            'weight': 235,
            'yards_from_scrimmage': None,
            'yards_lost_to_sacks': None,
            'yards_per_attempt_index': None,
            'yards_per_completed_pass': None,
            'yards_per_game_played': None,
            'yards_per_kickoff_return': None,
            'yards_per_punt': 47.0,
            'yards_per_punt_return': None,
            'yards_per_touch': None,
            'yards_recovered_from_fumble': None,
            'yards_returned_from_interception': None
        }

        self.receiver_results_career = {
            'adjusted_net_yards_per_attempt_index': None,
            'adjusted_net_yards_per_pass_attempt': None,
            'adjusted_yards_per_attempt': None,
            'adjusted_yards_per_attempt_index': None,
            'all_purpose_yards': 1020,
            'approximate_value': 2,
            'assists_on_tackles': None,
            'attempted_passes': None,
            'birth_date': '1992-10-24',
            'blocked_punts': None,
            'catch_percentage': None,
            'completed_passes': None,
            'completion_percentage_index': None,
            'espn_qbr': None,
            'extra_point_percentage': None,
            'extra_points_attempted': None,
            'extra_points_made': None,
            'field_goal_percentage': None,
            'field_goals_attempted': None,
            'field_goals_made': None,
            'fifty_plus_yard_field_goal_attempts': None,
            'fifty_plus_yard_field_goals_made': None,
            'fourth_quarter_comebacks': None,
            'fourty_to_fourty_nine_yard_field_goal_attempts': None,
            'fourty_to_fourty_nine_yard_field_goals_made': None,
            'fumbles': 3,
            'fumbles_forced': 0,
            'fumbles_recovered': 1,
            'fumbles_recovered_for_touchdown': 0,
            'game_winning_drives': None,
            'games': 29,
            'games_started': 1,
            'height': '5-7',
            'interception_percentage': None,
            'interception_percentage_index': None,
            'interceptions': None,
            'interceptions_returned_for_touchdown': None,
            'interceptions_thrown': None,
            'kickoff_return_touchdown': 0,
            'kickoff_return_yards': 528,
            'kickoff_returns': 24,
            'less_than_nineteen_yards_field_goal_attempts': None,
            'less_than_nineteen_yards_field_goals_made': None,
            'longest_field_goal_made': None,
            'longest_interception_return': None,
            'longest_kickoff_return': 39,
            'longest_pass': None,
            'longest_punt': None,
            'longest_punt_return': 59,
            'longest_reception': None,
            'longest_rush': None,
            'name': 'Tommylee Lewis',
            'net_yards_per_attempt_index': None,
            'net_yards_per_pass_attempt': None,
            'passer_rating_index': None,
            'passes_defended': None,
            'passing_completion': None,
            'passing_touchdown_percentage': None,
            'passing_touchdowns': None,
            'passing_yards': None,
            'passing_yards_per_attempt': None,
            'player_id': 'LewiTo00',
            'position': '',
            'punt_return_touchdown': 0,
            'punt_return_yards': 275,
            'punt_returns': 30,
            'punts': None,
            'qb_record': None,
            'quarterback_rating': None,
            'receiving_touchdowns': None,
            'receiving_yards': None,
            'receiving_yards_per_game': None,
            'receiving_yards_per_reception': None,
            'receptions': None,
            'receptions_per_game': None,
            'rush_attempts': None,
            'rush_attempts_per_game': None,
            'rush_touchdowns': None,
            'rush_yards': None,
            'rush_yards_per_attempt': None,
            'rush_yards_per_game': None,
            'rushing_and_receiving_touchdowns': None,
            'sack_percentage': None,
            'sack_percentage_index': None,
            'sacks': None,
            'safeties': None,
            'season': 'Career',
            'tackles': None,
            'team_abbreviation': '',
            'thirty_to_thirty_nine_yard_field_goal_attempts': None,
            'thirty_to_thirty_nine_yard_field_goals_made': None,
            'times_pass_target': None,
            'times_sacked': None,
            'total_punt_yards': None,
            'touchdown_percentage_index': None,
            'touches': None,
            'twenty_to_twenty_nine_yard_field_goal_attempts': None,
            'twenty_to_twenty_nine_yard_field_goals_made': None,
            'weight': 168,
            'yards_from_scrimmage': None,
            'yards_lost_to_sacks': None,
            'yards_per_attempt_index': None,
            'yards_per_completed_pass': None,
            'yards_per_game_played': None,
            'yards_per_kickoff_return': 22.0,
            'yards_per_punt': None,
            'yards_per_punt_return': 9.2,
            'yards_per_touch': None,
            'yards_recovered_from_fumble': 0,
            'yards_returned_from_interception': None
        }

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_qb_returns_requested_career_stats(self, *args, **kwargs):
        # Request the career stats
        player = Player('BreeDr00')
        player = player('')

        for attribute, value in self.qb_results_career.items():
            assert getattr(player, attribute) == value

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_qb_returns_requested_player_season_stats(self,
                                                          *args,
                                                          **kwargs):
        # Request the 2017 stats
        player = Player('BreeDr00')
        player = player('2017')

        for attribute, value in self.qb_results_2017.items():
            assert getattr(player, attribute) == value

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_olb_returns_requested_career_stats(self, *args, **kwargs):
        # Request the career stats
        player = Player('DaviDe00')
        player = player('')

        for attribute, value in self.olb_results_career.items():
            assert getattr(player, attribute) == value

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_kicker_returns_requested_career_stats(self, *args, **kwargs):
        # Request the career stats
        player = Player('LutzWi00')
        player = player('')

        for attribute, value in self.kicker_results_career.items():
            assert getattr(player, attribute) == value

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_punter_returns_requested_career_stats(self, *args, **kwargs):
        # Request the career stats
        player = Player('MorsTh00')
        player = player('')

        for attribute, value in self.punter_results_career.items():
            assert getattr(player, attribute) == value

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_olb_receiver_requested_career_stats(self, *args, **kwargs):
        # Request the career stats
        player = Player('LewiTo00')
        player = player('')

        for attribute, value in self.receiver_results_career.items():
            assert getattr(player, attribute) == value

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_dataframe_returns_dataframe(self, *args, **kwargs):
        dataframe = [
            {'adjusted_net_yards_per_attempt_index': 116,
             'adjusted_net_yards_per_pass_attempt': 7.71,
             'adjusted_yards_per_attempt': 8.3,
             'adjusted_yards_per_attempt_index': 114,
             'all_purpose_yards': None,
             'approximate_value': 16,
             'assists_on_tackles': None,
             'attempted_passes': 536,
             'birth_date': '1979-01-15',
             'blocked_punts': None,
             'catch_percentage': None,
             'completed_passes': 386,
             'completion_percentage_index': 128,
             'espn_qbr': 64.6,
             'extra_point_percentage': None,
             'extra_points_attempted': None,
             'extra_points_made': None,
             'field_goal_percentage': None,
             'field_goals_attempted': None,
             'field_goals_made': None,
             'fifty_plus_yard_field_goal_attempts': None,
             'fifty_plus_yard_field_goals_made': None,
             'fourth_quarter_comebacks': 2,
             'fourty_to_fourty_nine_yard_field_goal_attempts': None,
             'fourty_to_fourty_nine_yard_field_goals_made': None,
             'fumbles': 5,
             'fumbles_forced': 0,
             'fumbles_recovered': 5,
             'fumbles_recovered_for_touchdown': -12,
             'game_winning_drives': 2,
             'games': 16,
             'games_started': 16,
             'height': '6-0',
             'interception_percentage': 1.5,
             'interception_percentage_index': 112,
             'interceptions': None,
             'interceptions_returned_for_touchdown': None,
             'interceptions_thrown': 8,
             'kickoff_return_touchdown': None,
             'kickoff_return_yards': None,
             'kickoff_returns': None,
             'less_than_nineteen_yards_field_goal_attempts': None,
             'less_than_nineteen_yards_field_goals_made': None,
             'longest_field_goal_made': None,
             'longest_interception_return': None,
             'longest_kickoff_return': None,
             'longest_pass': 54,
             'longest_punt': None,
             'longest_punt_return': None,
             'longest_reception': None,
             'longest_rush': 7,
             'name': 'Drew Brees',
             'net_yards_per_attempt_index': 118,
             'net_yards_per_pass_attempt': 7.53,
             'passer_rating_index': 116,
             'passes_defended': None,
             'passing_completion': 72.0,
             'passing_touchdown_percentage': 4.3,
             'passing_touchdowns': 23,
             'passing_yards': 4334,
             'passing_yards_per_attempt': 8.1,
             'player_id': 'BreeDr00',
             'position': 'QB',
             'punt_return_touchdown': None,
             'punt_return_yards': None,
             'punt_returns': None,
             'punts': None,
             'qb_record': '11-5-0',
             'quarterback_rating': 103.9,
             'receiving_touchdowns': None,
             'receiving_yards': None,
             'receiving_yards_per_game': None,
             'receiving_yards_per_reception': None,
             'receptions': None,
             'receptions_per_game': None,
             'rush_attempts': 33,
             'rush_attempts_per_game': 2.1,
             'rush_touchdowns': 2,
             'rush_yards': 12,
             'rush_yards_per_attempt': 0.4,
             'rush_yards_per_game': 0.8,
             'rushing_and_receiving_touchdowns': 2,
             'sack_percentage': None,
             'sack_percentage_index': 116,
             'sacks': None,
             'safeties': None,
             'season': '2017',
             'tackles': None,
             'team_abbreviation': 'NOR',
             'thirty_to_thirty_nine_yard_field_goal_attempts': None,
             'thirty_to_thirty_nine_yard_field_goals_made': None,
             'times_pass_target': None,
             'times_sacked': 20,
             'total_punt_yards': None,
             'touchdown_percentage_index': 100,
             'touches': 33,
             'twenty_to_twenty_nine_yard_field_goal_attempts': None,
             'twenty_to_twenty_nine_yard_field_goals_made': None,
             'weight': 209,
             'yards_from_scrimmage': 12,
             'yards_lost_to_sacks': 145,
             'yards_per_attempt_index': 115,
             'yards_per_completed_pass': 11.2,
             'yards_per_game_played': 270.9,
             'yards_per_kickoff_return': None,
             'yards_per_punt': None,
             'yards_per_punt_return': None,
             'yards_per_touch': 0.4,
             'yards_recovered_from_fumble': 3,
             'yards_returned_from_interception': None},
            {'adjusted_net_yards_per_attempt_index': 126,
             'adjusted_net_yards_per_pass_attempt': 8.93,
             'adjusted_yards_per_attempt': 9.6,
             'adjusted_yards_per_attempt_index': 125,
             'all_purpose_yards': None,
             'approximate_value': None,
             'assists_on_tackles': None,
             'attempted_passes': 129,
             'birth_date': '1979-01-15',
             'blocked_punts': None,
             'catch_percentage': None,
             'completed_passes': 104,
             'completion_percentage_index': 151,
             'espn_qbr': None,
             'extra_point_percentage': None,
             'extra_points_attempted': None,
             'extra_points_made': None,
             'field_goal_percentage': None,
             'field_goals_attempted': None,
             'field_goals_made': None,
             'fifty_plus_yard_field_goal_attempts': None,
             'fifty_plus_yard_field_goals_made': None,
             'fourth_quarter_comebacks': 2,
             'fourty_to_fourty_nine_yard_field_goal_attempts': None,
             'fourty_to_fourty_nine_yard_field_goals_made': None,
             'fumbles': 1,
             'fumbles_forced': 0,
             'fumbles_recovered': 1,
             'fumbles_recovered_for_touchdown': 0,
             'game_winning_drives': 2,
             'games': 3,
             'games_started': 3,
             'height': '6-0',
             'interception_percentage': 0.0,
             'interception_percentage_index': 131,
             'interceptions': None,
             'interceptions_returned_for_touchdown': None,
             'interceptions_thrown': 0,
             'kickoff_return_touchdown': None,
             'kickoff_return_yards': None,
             'kickoff_returns': None,
             'less_than_nineteen_yards_field_goal_attempts': None,
             'less_than_nineteen_yards_field_goals_made': None,
             'longest_field_goal_made': None,
             'longest_interception_return': None,
             'longest_kickoff_return': None,
             'longest_pass': 42,
             'longest_punt': None,
             'longest_punt_return': None,
             'longest_reception': None,
             'longest_rush': 7,
             'name': 'Drew Brees',
             'net_yards_per_attempt_index': 120,
             'net_yards_per_pass_attempt': 7.73,
             'passer_rating_index': 133,
             'passes_defended': None,
             'passing_completion': 80.6,
             'passing_touchdown_percentage': 6.2,
             'passing_touchdowns': 8,
             'passing_yards': 1078,
             'passing_yards_per_attempt': 8.4,
             'player_id': 'BreeDr00',
             'position': 'QB',
             'punt_return_touchdown': None,
             'punt_return_yards': None,
             'punt_returns': None,
             'punts': None,
             'qb_record': '2-1-0',
             'quarterback_rating': 122.2,
             'receiving_touchdowns': None,
             'receiving_yards': None,
             'receiving_yards_per_game': None,
             'receiving_yards_per_reception': None,
             'receptions': None,
             'receptions_per_game': None,
             'rush_attempts': 4,
             'rush_attempts_per_game': 1.3,
             'rush_touchdowns': 2,
             'rush_yards': 6,
             'rush_yards_per_attempt': 1.5,
             'rush_yards_per_game': 2.0,
             'rushing_and_receiving_touchdowns': 2,
             'sack_percentage': None,
             'sack_percentage_index': 116,
             'sacks': None,
             'safeties': None,
             'season': '2018',
             'tackles': None,
             'team_abbreviation': 'NOR',
             'thirty_to_thirty_nine_yard_field_goal_attempts': None,
             'thirty_to_thirty_nine_yard_field_goals_made': None,
             'times_pass_target': None,
             'times_sacked': 5,
             'total_punt_yards': None,
             'touchdown_percentage_index': 113,
             'touches': 4,
             'twenty_to_twenty_nine_yard_field_goal_attempts': None,
             'twenty_to_twenty_nine_yard_field_goals_made': None,
             'weight': 209,
             'yards_from_scrimmage': 6,
             'yards_lost_to_sacks': 42,
             'yards_per_attempt_index': 117,
             'yards_per_completed_pass': 10.4,
             'yards_per_game_played': 359.3,
             'yards_per_kickoff_return': None,
             'yards_per_punt': None,
             'yards_per_punt_return': None,
             'yards_per_touch': 1.5,
             'yards_recovered_from_fumble': 1,
             'yards_returned_from_interception': None},
            {'adjusted_net_yards_per_attempt_index': 113,
             'adjusted_net_yards_per_pass_attempt': 6.98,
             'adjusted_yards_per_attempt': 7.6,
             'adjusted_yards_per_attempt_index': 111,
             'all_purpose_yards': None,
             'approximate_value': 239,
             'assists_on_tackles': 0,
             'attempted_passes': 9423,
             'birth_date': '1979-01-15',
             'blocked_punts': None,
             'catch_percentage': None,
             'completed_passes': 6326,
             'completion_percentage_index': 119,
             'espn_qbr': None,
             'extra_point_percentage': None,
             'extra_points_attempted': None,
             'extra_points_made': None,
             'field_goal_percentage': None,
             'field_goals_attempted': None,
             'field_goals_made': None,
             'fifty_plus_yard_field_goal_attempts': None,
             'fifty_plus_yard_field_goals_made': None,
             'fourth_quarter_comebacks': 30,
             'fourty_to_fourty_nine_yard_field_goal_attempts': None,
             'fourty_to_fourty_nine_yard_field_goals_made': None,
             'fumbles': 102,
             'fumbles_forced': 0,
             'fumbles_recovered': 102,
             'fumbles_recovered_for_touchdown': -111,
             'game_winning_drives': 43,
             'games': 252,
             'games_started': 251,
             'height': '6-0',
             'interception_percentage': 2.4,
             'interception_percentage_index': 105,
             'interceptions': None,
             'interceptions_returned_for_touchdown': None,
             'interceptions_thrown': 228,
             'kickoff_return_touchdown': None,
             'kickoff_return_yards': None,
             'kickoff_returns': None,
             'less_than_nineteen_yards_field_goal_attempts': None,
             'less_than_nineteen_yards_field_goals_made': None,
             'longest_field_goal_made': None,
             'longest_interception_return': None,
             'longest_kickoff_return': None,
             'longest_pass': 98,
             'longest_punt': None,
             'longest_punt_return': None,
             'longest_reception': 38,
             'longest_rush': 22,
             'name': 'Drew Brees',
             'net_yards_per_attempt_index': 114,
             'net_yards_per_pass_attempt': 7.01,
             'passer_rating_index': 114,
             'passes_defended': None,
             'passing_completion': 67.1,
             'passing_touchdown_percentage': 5.3,
             'passing_touchdowns': 496,
             'passing_yards': 71523,
             'passing_yards_per_attempt': 7.6,
             'player_id': 'BreeDr00',
             'position': '',
             'punt_return_touchdown': None,
             'punt_return_yards': None,
             'punt_returns': None,
             'punts': None,
             'qb_record': '144-107-0',
             'quarterback_rating': 97.1,
             'receiving_touchdowns': 1,
             'receiving_yards': 73,
             'receiving_yards_per_game': 0.3,
             'receiving_yards_per_reception': 10.4,
             'receptions': 7,
             'receptions_per_game': 0.0,
             'rush_attempts': 444,
             'rush_attempts_per_game': 1.8,
             'rush_touchdowns': 20,
             'rush_yards': 742,
             'rush_yards_per_attempt': 1.7,
             'rush_yards_per_game': 2.9,
             'rushing_and_receiving_touchdowns': 21,
             'sack_percentage': None,
             'sack_percentage_index': 116,
             'sacks': None,
             'safeties': None,
             'season': 'Career',
             'tackles': 13,
             'team_abbreviation': '',
             'thirty_to_thirty_nine_yard_field_goal_attempts': None,
             'thirty_to_thirty_nine_yard_field_goals_made': None,
             'times_pass_target': 8,
             'times_sacked': 383,
             'total_punt_yards': None,
             'touchdown_percentage_index': 110,
             'touches': 451,
             'twenty_to_twenty_nine_yard_field_goal_attempts': None,
             'twenty_to_twenty_nine_yard_field_goals_made': None,
             'weight': 209,
             'yards_from_scrimmage': 815,
             'yards_lost_to_sacks': 2734,
             'yards_per_attempt_index': 110,
             'yards_per_completed_pass': 11.3,
             'yards_per_game_played': 283.8,
             'yards_per_kickoff_return': None,
             'yards_per_punt': None,
             'yards_per_punt_return': None,
             'yards_per_touch': 1.8,
             'yards_recovered_from_fumble': 29,
             'yards_returned_from_interception': None}
        ]
        indices = ['2017', '2018', 'Career']

        df = pd.DataFrame(dataframe, index=indices)
        player = Player('BreeDr00')
        player = player('')

        # Pandas doesn't natively allow comparisons of DataFrames.
        # Concatenating the two DataFrames (the one generated during the test
        # and the expected one above) and dropping duplicate rows leaves only
        # the rows that are unique between the two frames. This allows a quick
        # check of the DataFrame to see if it is empty - if so, all rows are
        # duplicates, and they are equal.
        frames = [df, player.dataframe]
        df1 = pd.concat(frames).drop_duplicates(keep=False)

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_fake_404_page_returns_none_with_no_errors(self,
                                                           *args,
                                                           **kwargs):
        player = Player('404')

        assert player.name is None
        assert player.dataframe is None

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_fake_404_page_returns_none_for_different_season(self,
                                                                 *args,
                                                                 **kwargs):
        player = Player('404')
        player = player('2017')

        assert player.name is None
        assert player.dataframe is None

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_nfl_player_with_no_career_stats_handled_properly(self,
                                                              *args,
                                                              **kwargs):
        player = Player('HatfDo00')

        assert player.name == 'Dominique Hatfield'


class TestNFLRoster:
    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_roster_class_pulls_all_player_stats(self, *args, **kwargs):
        flexmock(utils) \
            .should_receive('_find_year_for_season') \
            .and_return('2018')
        roster = Roster('NOR')

        assert len(roster.players) == 5

        for player in roster.players:
            assert player.name in ['Drew Brees', 'Demario Davis',
                                   'Tommylee Lewis', 'Wil Lutz',
                                   'Thomas Morstead']

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_bad_url_raises_value_error(self, *args, **kwargs):
        with pytest.raises(ValueError):
            roster = Roster('BAD')

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_roster_from_team_class(self, *args, **kwargs):
        flexmock(Team) \
            .should_receive('_parse_team_data') \
            .and_return(None)
        team = Team(None, 1, '2018')
        mock_abbreviation = mock.PropertyMock(return_value='NOR')
        type(team)._abbreviation = mock_abbreviation

        assert len(team.roster.players) == 5

        for player in team.roster.players:
            assert player.name in ['Drew Brees', 'Demario Davis',
                                   'Tommylee Lewis', 'Wil Lutz',
                                   'Thomas Morstead']
        type(team)._abbreviation = None

    @mock.patch('requests.get', side_effect=mock_pyquery)
    def test_roster_class_with_slim_parameter(self, *args, **kwargs):
        flexmock(utils) \
            .should_receive('_find_year_for_season') \
            .and_return('2018')
        roster = Roster('NOR', slim=True)

        assert len(roster.players) == 5
        assert roster.players == {
            'BreeDr00': 'Drew Brees',
            'DaviDe00': 'Demario Davis',
            'LewiTo00': 'Tommylee Lewis',
            'LutzWi00': 'Wil Lutz',
            'MorsTh00': 'Thomas Morstead'
        }
