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


def read_file(filename):
    filepath = os.path.join(os.path.dirname(__file__), 'nba', filename)
    return open('%s.html' % 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 'HOU' in url:
        return MockPQ(read_file('2018'))
    if 'anderry01' in url:
        return MockPQ(read_file('anderry01'))
    if 'arizatr01' in url:
        return MockPQ(read_file('arizatr01'))
    if 'blackta01' in url:
        return MockPQ(read_file('blackta01'))
    if 'youngtr01' in url:
        return MockPQ(read_file('youngtr01'))
    if 'BAD' in url:
        return MockPQ(None, 404)
    return MockPQ(read_file('hardeja01'))


class TestNBAPlayer:
    @mock.patch('requests.get', side_effect=mock_pyquery)
    def setup_method(self, *args, **kwargs):
        self.results_career = {
            'player_id': 'hardeja01',
            'season': 'Career',
            'name': 'James Harden',
            'team_abbreviation': '',
            'position': 'SG',
            'height': '6-5',
            'weight': 220,
            'birth_date': datetime(1989, 8, 26),
            'nationality': 'United States of America',
            'games_played': 687,
            'games_started': 474,
            'minutes_played': 23239,
            'field_goals': 4656,
            'field_goal_attempts': 10502,
            'field_goal_percentage': .443,
            'three_pointers': 1647,
            'three_point_attempts': 4523,
            'three_point_percentage': .364,
            'two_pointers': 3009,
            'two_point_attempts': 5979,
            'two_point_percentage': .503,
            'effective_field_goal_percentage': .522,
            'free_throws': 4850,
            'free_throw_attempts': 5678,
            'free_throw_percentage': .854,
            'offensive_rebounds': 516,
            'defensive_rebounds': 2966,
            'total_rebounds': 3482,
            'assists': 4157,
            'steals': 1031,
            'blocks': 325,
            'turnovers': 2383,
            'personal_fouls': 1733,
            'points': 15809,
            'player_efficiency_rating': 23.7,
            'true_shooting_percentage': .608,
            'three_point_attempt_rate': .431,
            'free_throw_attempt_rate': .541,
            'offensive_rebound_percentage': 2.5,
            'defensive_rebound_percentage': 14.1,
            'total_rebound_percentage': 8.4,
            'assist_percentage': 30.9,
            'steal_percentage': 2.2,
            'block_percentage': 1.1,
            'turnover_percentage': 15.5,
            'usage_percentage': 28.9,
            'offensive_win_shares': 80.5,
            'defensive_win_shares': 26.2,
            'win_shares': 106.7,
            'win_shares_per_48_minutes': .220,
            'offensive_box_plus_minus': 6.3,
            'defensive_box_plus_minus': 0.2,
            'box_plus_minus': 6.5,
            'value_over_replacement_player': 50.0,
            'shooting_distance': 14.7,
            'percentage_shots_two_pointers': .569,
            'percentage_zero_to_three_footers': .282,
            'percentage_three_to_ten_footers': .117,
            'percentage_ten_to_sixteen_footers': .068,
            'percentage_sixteen_foot_plus_two_pointers': .103,
            'percentage_shots_three_pointers': .431,
            'field_goal_perc_zero_to_three_feet': .640,
            'field_goal_perc_three_to_ten_feet': .331,
            'field_goal_perc_ten_to_sixteen_feet': .421,
            'field_goal_perc_sixteen_foot_plus_two_pointers': .379,
            'two_pointers_assisted_percentage': .199,
            'percentage_field_goals_as_dunks': .029,
            'dunks': 290,
            'three_pointers_assisted_percentage': .514,
            'percentage_of_three_pointers_from_corner': .089,
            'three_point_shot_percentage_from_corner': .375,
            'half_court_heaves': 14,
            'half_court_heaves_made': 1,
            'point_guard_percentage': 15,
            'shooting_guard_percentage': 72,
            'small_forward_percentage': 13,
            'power_forward_percentage': 0,
            'center_percentage': 0,
            'on_court_plus_minus': 6.0,
            'net_plus_minus': 4.8,
            'passing_turnovers': 1236,
            'lost_ball_turnovers': 740,
            'other_turnovers': 406,
            'shooting_fouls': 668,
            'blocking_fouls': 25,
            'offensive_fouls': 275,
            'take_fouls': 27,
            'points_generated_by_assists': 9910,
            'shooting_fouls_drawn': 2223,
            'and_ones': 366,
            'shots_blocked': 693,
            'salary': 117809888,
            'contract': {
                '2018-19': '$30,431,854',
                '2019-20': '$37,800,000',
                '2020-21': '$40,824,000',
                '2021-22': '$43,848,000',
                '2022-23': '$46,872,000'
            }
        }

        self.results_2018 = {
            'player_id': 'hardeja01',
            'season': '2017-18',
            'name': 'James Harden',
            'team_abbreviation': 'HOU',
            'position': 'SG',
            'height': '6-5',
            'weight': 220,
            'birth_date': datetime(1989, 8, 26),
            'nationality': 'United States of America',
            'games_played': 72,
            'games_started': 72,
            'minutes_played': 2551,
            'field_goals': 651,
            'field_goal_attempts': 1449,
            'field_goal_percentage': .449,
            'three_pointers': 265,
            'three_point_attempts': 722,
            'three_point_percentage': .367,
            'two_pointers': 386,
            'two_point_attempts': 727,
            'two_point_percentage': .531,
            'effective_field_goal_percentage': .541,
            'free_throws': 624,
            'free_throw_attempts': 727,
            'free_throw_percentage': .858,
            'offensive_rebounds': 41,
            'defensive_rebounds': 348,
            'total_rebounds': 389,
            'assists': 630,
            'steals': 126,
            'blocks': 50,
            'turnovers': 315,
            'personal_fouls': 169,
            'points': 2191,
            'player_efficiency_rating': 29.8,
            'true_shooting_percentage': .619,
            'three_point_attempt_rate': .498,
            'free_throw_attempt_rate': .502,
            'offensive_rebound_percentage': 1.8,
            'defensive_rebound_percentage': 15.2,
            'total_rebound_percentage': 8.6,
            'assist_percentage': 45.1,
            'steal_percentage': 2.4,
            'block_percentage': 1.7,
            'turnover_percentage': 15.1,
            'usage_percentage': 36.1,
            'offensive_win_shares': 11.6,
            'defensive_win_shares': 3.8,
            'win_shares': 15.4,
            'win_shares_per_48_minutes': .289,
            'offensive_box_plus_minus': 9.6,
            'defensive_box_plus_minus': 1.3,
            'box_plus_minus': 10.9,
            'value_over_replacement_player': 8.3,
            'shooting_distance': 15.3,
            'percentage_shots_two_pointers': .502,
            'percentage_zero_to_three_footers': .273,
            'percentage_three_to_ten_footers': .118,
            'percentage_ten_to_sixteen_footers': .071,
            'percentage_sixteen_foot_plus_two_pointers': .039,
            'percentage_shots_three_pointers': .498,
            'field_goal_perc_zero_to_three_feet': .658,
            'field_goal_perc_three_to_ten_feet': .351,
            'field_goal_perc_ten_to_sixteen_feet': .437,
            'field_goal_perc_sixteen_foot_plus_two_pointers': .368,
            'two_pointers_assisted_percentage': .088,
            'percentage_field_goals_as_dunks': .013,
            'dunks': 19,
            'three_pointers_assisted_percentage': .260,
            'percentage_of_three_pointers_from_corner': .072,
            'three_point_shot_percentage_from_corner': .327,
            'half_court_heaves': 2,
            'half_court_heaves_made': 0,
            'point_guard_percentage': 19,
            'shooting_guard_percentage': 75,
            'small_forward_percentage': 6,
            'power_forward_percentage': 0,
            'center_percentage': 0,
            'on_court_plus_minus': 10.5,
            'net_plus_minus': 5.3,
            'passing_turnovers': 188,
            'lost_ball_turnovers': 87,
            'other_turnovers': 40,
            'shooting_fouls': 65,
            'blocking_fouls': 2,
            'offensive_fouls': 29,
            'take_fouls': 5,
            'points_generated_by_assists': 1499,
            'shooting_fouls_drawn': 273,
            'and_ones': 55,
            'shots_blocked': 98,
            'salary': 28299399,
            'contract': {
                '2018-19': '$30,431,854',
                '2019-20': '$37,800,000',
                '2020-21': '$40,824,000',
                '2021-22': '$43,848,000',
                '2022-23': '$46,872,000'
            }
        }

        self.player = Player('hardeja01')

    def test_nba_player_returns_requested_player_career_stats(self):
        # Request the career stats
        player = self.player('')

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

    def test_nba_player_returns_requested_player_season_stats(self):
        # Request the 2017-18 stats
        player = self.player('2017-18')

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

    def test_dataframe_returns_dataframe(self):
        dataframe = [
            {'field_goal_perc_ten_to_sixteen_feet': 0.463,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.411,
             'box_plus_minus': 5.7,
             'two_point_percentage': 0.515,
             'two_pointers': 372,
             'net_plus_minus': 7.6,
             'personal_fouls': 177,
             'three_point_percentage': 0.366,
             'player_efficiency_rating': 23.5,
             'offensive_rebound_percentage': 2.6,
             'percentage_sixteen_foot_plus_two_pointers': 0.125,
             'three_point_attempt_rate': 0.401,
             'field_goals': 549,
             'free_throw_attempts': 665,
             'shooting_fouls_drawn': 261,
             'defensive_rebound_percentage': 10.7,
             'steal_percentage': 2.1,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.395,
             'percentage_ten_to_sixteen_footers': 0.079,
             'turnover_percentage': 15.0,
             'points_generated_by_assists': 1040,
             'block_percentage': 0.8,
             'field_goal_percentage': 0.456,
             'percentage_of_three_pointers_from_corner': 0.066,
             'free_throw_percentage': 0.866,
             'offensive_fouls': 32,
             'half_court_heaves': 1,
             'percentage_three_to_ten_footers': 0.122,
             'passing_turnovers': 135,
             'value_over_replacement_player': 5.4,
             'blocking_fouls': 9,
             'field_goal_attempts': 1205,
             'free_throw_attempt_rate': 0.552,
             'effective_field_goal_percentage': 0.529,
             'total_rebounds': 344,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 10.1,
             'defensive_rebounds': 283,
             'total_rebound_percentage': 6.9,
             'assists': 446,
             'defensive_box_plus_minus': -0.5,
             'shooting_distance': 14.8,
             'height': '6-5',
             'true_shooting_percentage': 0.618,
             'small_forward_percentage': 7,
             'minutes_played': 2777,
             'on_court_plus_minus': 7.1,
             'games_started': 73,
             'win_shares_per_48_minutes': 0.221,
             'dunks': 45,
             'three_pointers_assisted_percentage': 0.588,
             'two_point_attempts': 722,
             'salary': 13701250,
             'offensive_box_plus_minus': 6.2,
             'lost_ball_turnovers': 79,
             'percentage_shots_two_pointers': 0.599,
             'shooting_guard_percentage': 92,
             'shots_blocked': 61,
             'and_ones': 42,
             'three_pointers': 177,
             'take_fouls': 1,
             'free_throws': 576,
             'usage_percentage': 27.8,
             'assist_percentage': 27.3,
             'three_point_attempts': 483,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.401,
             'percentage_field_goals_as_dunks': 0.039,
             'offensive_rebounds': 61,
             'other_turnovers': 51,
             'point_guard_percentage': 1,
             'half_court_heaves_made': 0,
             'blocks': 29,
             'two_pointers_assisted_percentage': 0.223,
             'win_shares': 12.8,
             'defensive_win_shares': 2.7,
             'games_played': 73,
             'percentage_zero_to_three_footers': 0.273,
             'steals': 115,
             'turnovers': 265,
             'field_goal_perc_zero_to_three_feet': 0.632,
             'shooting_fouls': 51,
             'team_abbreviation': 'HOU',
             'points': 1851,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.375},
            {'field_goal_perc_ten_to_sixteen_feet': 0.421,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.379,
             'box_plus_minus': 6.5,
             'two_point_percentage': 0.503,
             'two_pointers': 3009,
             'net_plus_minus': 4.8,
             'personal_fouls': 1733,
             'three_point_percentage': 0.364,
             'player_efficiency_rating': 23.7,
             'offensive_rebound_percentage': 2.5,
             'percentage_sixteen_foot_plus_two_pointers': 0.103,
             'three_point_attempt_rate': 0.431,
             'field_goals': 4656,
             'free_throw_attempts': 5678,
             'shooting_fouls_drawn': 2223,
             'defensive_rebound_percentage': 14.1,
             'steal_percentage': 2.2,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.331,
             'percentage_ten_to_sixteen_footers': 0.068,
             'turnover_percentage': 15.5,
             'points_generated_by_assists': 9910,
             'block_percentage': 1.1,
             'field_goal_percentage': 0.443,
             'percentage_of_three_pointers_from_corner': 0.089,
             'free_throw_percentage': 0.854,
             'offensive_fouls': 275,
             'half_court_heaves': 14,
             'percentage_three_to_ten_footers': 0.117,
             'passing_turnovers': 1236,
             'value_over_replacement_player': 50.0,
             'blocking_fouls': 25,
             'field_goal_attempts': 10502,
             'free_throw_attempt_rate': 0.541,
             'effective_field_goal_percentage': 0.522,
             'total_rebounds': 3482,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 80.5,
             'defensive_rebounds': 2966,
             'total_rebound_percentage': 8.4,
             'assists': 4157,
             'defensive_box_plus_minus': 0.2,
             'shooting_distance': 14.7,
             'height': '6-5',
             'true_shooting_percentage': 0.608,
             'small_forward_percentage': 13,
             'minutes_played': 23239,
             'on_court_plus_minus': 6.0,
             'games_started': 474,
             'win_shares_per_48_minutes': 0.22,
             'dunks': 290,
             'three_pointers_assisted_percentage': 0.514,
             'two_point_attempts': 5979,
             'salary': 117809888,
             'offensive_box_plus_minus': 6.3,
             'lost_ball_turnovers': 740,
             'percentage_shots_two_pointers': 0.569,
             'shooting_guard_percentage': 72,
             'shots_blocked': 693,
             'and_ones': 366,
             'three_pointers': 1647,
             'take_fouls': 27,
             'free_throws': 4850,
             'usage_percentage': 28.9,
             'assist_percentage': 30.9,
             'three_point_attempts': 4523,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.431,
             'percentage_field_goals_as_dunks': 0.029,
             'offensive_rebounds': 516,
             'other_turnovers': 406,
             'point_guard_percentage': 15,
             'half_court_heaves_made': 1,
             'blocks': 325,
             'two_pointers_assisted_percentage': 0.199,
             'win_shares': 106.7,
             'defensive_win_shares': 26.2,
             'games_played': 687,
             'percentage_zero_to_three_footers': 0.282,
             'steals': 1031,
             'turnovers': 2383,
             'field_goal_perc_zero_to_three_feet': 0.64,
             'shooting_fouls': 668,
             'team_abbreviation': 'HOU',
             'points': 15809,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.375},
            {'field_goal_perc_ten_to_sixteen_feet': 0.431,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.337,
             'box_plus_minus': 8.4,
             'two_point_percentage': 0.48,
             'two_pointers': 439,
             'net_plus_minus': 8.8,
             'personal_fouls': 208,
             'three_point_percentage': 0.375,
             'player_efficiency_rating': 26.7,
             'offensive_rebound_percentage': 2.8,
             'percentage_sixteen_foot_plus_two_pointers': 0.131,
             'three_point_attempt_rate': 0.378,
             'field_goals': 647,
             'free_throw_attempts': 824,
             'shooting_fouls_drawn': 318,
             'defensive_rebound_percentage': 14.2,
             'steal_percentage': 2.6,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.291,
             'percentage_ten_to_sixteen_footers': 0.074,
             'turnover_percentage': 14.9,
             'points_generated_by_assists': 1382,
             'block_percentage': 1.6,
             'field_goal_percentage': 0.44,
             'percentage_of_three_pointers_from_corner': 0.108,
             'free_throw_percentage': 0.868,
             'offensive_fouls': 36,
             'half_court_heaves': 1,
             'percentage_three_to_ten_footers': 0.107,
             'passing_turnovers': 176,
             'value_over_replacement_player': 7.8,
             'blocking_fouls': 4,
             'field_goal_attempts': 1470,
             'free_throw_attempt_rate': 0.561,
             'effective_field_goal_percentage': 0.511,
             'total_rebounds': 459,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 12.2,
             'defensive_rebounds': 384,
             'total_rebound_percentage': 8.5,
             'assists': 565,
             'defensive_box_plus_minus': 1.0,
             'shooting_distance': 14.0,
             'height': '6-5',
             'true_shooting_percentage': 0.605,
             'small_forward_percentage': 7,
             'minutes_played': 2981,
             'on_court_plus_minus': 5.8,
             'games_started': 81,
             'win_shares_per_48_minutes': 0.265,
             'dunks': 33,
             'three_pointers_assisted_percentage': 0.51,
             'two_point_attempts': 915,
             'salary': 14728844,
             'offensive_box_plus_minus': 7.4,
             'lost_ball_turnovers': 97,
             'percentage_shots_two_pointers': 0.622,
             'shooting_guard_percentage': 92,
             'shots_blocked': 107,
             'and_ones': 50,
             'three_pointers': 208,
             'take_fouls': 3,
             'free_throws': 715,
             'usage_percentage': 31.3,
             'assist_percentage': 34.6,
             'three_point_attempts': 555,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.378,
             'percentage_field_goals_as_dunks': 0.023,
             'offensive_rebounds': 75,
             'other_turnovers': 48,
             'point_guard_percentage': 1,
             'half_court_heaves_made': 0,
             'blocks': 60,
             'two_pointers_assisted_percentage': 0.166,
             'win_shares': 16.4,
             'defensive_win_shares': 4.2,
             'games_played': 81,
             'percentage_zero_to_three_footers': 0.31,
             'steals': 154,
             'turnovers': 321,
             'field_goal_perc_zero_to_three_feet': 0.618,
             'shooting_fouls': 84,
             'team_abbreviation': 'HOU',
             'points': 2217,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.467},
            {'field_goal_perc_ten_to_sixteen_feet': 0.419,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.427,
             'box_plus_minus': 10.1,
             'two_point_percentage': 0.53,
             'two_pointers': 412,
             'net_plus_minus': 3.0,
             'personal_fouls': 215,
             'three_point_percentage': 0.347,
             'player_efficiency_rating': 27.4,
             'offensive_rebound_percentage': 3.5,
             'percentage_sixteen_foot_plus_two_pointers': 0.053,
             'three_point_attempt_rate': 0.493,
             'field_goals': 674,
             'free_throw_attempts': 881,
             'shooting_fouls_drawn': 305,
             'defensive_rebound_percentage': 20.9,
             'steal_percentage': 2.0,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.364,
             'percentage_ten_to_sixteen_footers': 0.076,
             'turnover_percentage': 19.5,
             'points_generated_by_assists': 2179,
             'block_percentage': 1.0,
             'field_goal_percentage': 0.44,
             'percentage_of_three_pointers_from_corner': 0.056,
             'free_throw_percentage': 0.847,
             'offensive_fouls': 34,
             'half_court_heaves': 3,
             'percentage_three_to_ten_footers': 0.134,
             'passing_turnovers': 294,
             'value_over_replacement_player': 9.0,
             'blocking_fouls': 6,
             'field_goal_attempts': 1533,
             'free_throw_attempt_rate': 0.575,
             'effective_field_goal_percentage': 0.525,
             'total_rebounds': 659,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 11.5,
             'defensive_rebounds': 564,
             'total_rebound_percentage': 12.2,
             'assists': 907,
             'defensive_box_plus_minus': 1.5,
             'shooting_distance': 15.9,
             'height': '6-5',
             'true_shooting_percentage': 0.613,
             'small_forward_percentage': 0,
             'minutes_played': 2947,
             'on_court_plus_minus': 6.9,
             'games_started': 81,
             'win_shares_per_48_minutes': 0.245,
             'dunks': 21,
             'three_pointers_assisted_percentage': 0.317,
             'two_point_attempts': 777,
             'salary': 26540100,
             'offensive_box_plus_minus': 8.7,
             'lost_ball_turnovers': 114,
             'percentage_shots_two_pointers': 0.507,
             'shooting_guard_percentage': 1,
             'shots_blocked': 85,
             'and_ones': 29,
             'three_pointers': 262,
             'take_fouls': 2,
             'free_throws': 746,
             'usage_percentage': 34.2,
             'assist_percentage': 50.7,
             'three_point_attempts': 756,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.493,
             'percentage_field_goals_as_dunks': 0.014,
             'offensive_rebounds': 95,
             'other_turnovers': 55,
             'point_guard_percentage': 98,
             'half_court_heaves_made': 0,
             'blocks': 38,
             'two_pointers_assisted_percentage': 0.095,
             'win_shares': 15.0,
             'defensive_win_shares': 3.6,
             'games_played': 81,
             'percentage_zero_to_three_footers': 0.242,
             'steals': 121,
             'turnovers': 464,
             'field_goal_perc_zero_to_three_feet': 0.682,
             'shooting_fouls': 80,
             'team_abbreviation': 'HOU',
             'points': 2356,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.357},
            {'field_goal_perc_ten_to_sixteen_feet': 0.368,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.381,
             'box_plus_minus': 1.0,
             'two_point_percentage': 0.424,
             'two_pointers': 140,
             'net_plus_minus': 3.8,
             'personal_fouls': 200,
             'three_point_percentage': 0.375,
             'player_efficiency_rating': 14.0,
             'offensive_rebound_percentage': 3.2,
             'percentage_sixteen_foot_plus_two_pointers': 0.168,
             'three_point_attempt_rate': 0.429,
             'field_goals': 233,
             'free_throw_attempts': 240,
             'shooting_fouls_drawn': 113,
             'defensive_rebound_percentage': 12.7,
             'steal_percentage': 2.4,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.308,
             'percentage_ten_to_sixteen_footers': 0.033,
             'turnover_percentage': 13.4,
             'points_generated_by_assists': 299,
             'block_percentage': 0.9,
             'field_goal_percentage': 0.403,
             'percentage_of_three_pointers_from_corner': 0.19,
             'free_throw_percentage': 0.808,
             'offensive_fouls': 12,
             'half_court_heaves': 2,
             'percentage_three_to_ten_footers': 0.045,
             'passing_turnovers': 40,
             'value_over_replacement_player': 1.3,
             'blocking_fouls': 0,
             'field_goal_attempts': 578,
             'free_throw_attempt_rate': 0.415,
             'effective_field_goal_percentage': 0.484,
             'total_rebounds': 244,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 2.0,
             'defensive_rebounds': 197,
             'total_rebound_percentage': 8.1,
             'assists': 137,
             'defensive_box_plus_minus': 0.3,
             'shooting_distance': 14.7,
             'height': '6-5',
             'true_shooting_percentage': 0.551,
             'small_forward_percentage': 9,
             'minutes_played': 1738,
             'on_court_plus_minus': 6.4,
             'games_started': 0,
             'win_shares_per_48_minutes': 0.124,
             'dunks': 25,
             'three_pointers_assisted_percentage': 0.925,
             'two_point_attempts': 330,
             'salary': 4054160,
             'offensive_box_plus_minus': 0.7,
             'lost_ball_turnovers': 36,
             'percentage_shots_two_pointers': 0.571,
             'shooting_guard_percentage': 90,
             'shots_blocked': 45,
             'and_ones': 14,
             'three_pointers': 93,
             'take_fouls': 0,
             'free_throws': 194,
             'usage_percentage': 20.4,
             'assist_percentage': 12.3,
             'three_point_attempts': 248,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.429,
             'percentage_field_goals_as_dunks': 0.048,
             'offensive_rebounds': 47,
             'other_turnovers': 30,
             'point_guard_percentage': 1,
             'half_court_heaves_made': 0,
             'blocks': 20,
             'two_pointers_assisted_percentage': 0.379,
             'win_shares': 4.5,
             'defensive_win_shares': 2.5,
             'games_played': 76,
             'percentage_zero_to_three_footers': 0.325,
             'steals': 80,
             'turnovers': 106,
             'field_goal_perc_zero_to_three_feet': 0.468,
             'shooting_fouls': 98,
             'team_abbreviation': 'HOU',
             'points': 753,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.468},
            {'field_goal_perc_ten_to_sixteen_feet': 0.426,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.402,
             'box_plus_minus': 6.7,
             'two_point_percentage': 0.494,
             'two_pointers': 474,
             'net_plus_minus': 7.6,
             'personal_fouls': 229,
             'three_point_percentage': 0.359,
             'player_efficiency_rating': 25.3,
             'offensive_rebound_percentage': 2.2,
             'percentage_sixteen_foot_plus_two_pointers': 0.12,
             'three_point_attempt_rate': 0.406,
             'field_goals': 710,
             'free_throw_attempts': 837,
             'shooting_fouls_drawn': 311,
             'defensive_rebound_percentage': 15.6,
             'steal_percentage': 2.2,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.328,
             'percentage_ten_to_sixteen_footers': 0.105,
             'turnover_percentage': 15.9,
             'points_generated_by_assists': 1458,
             'block_percentage': 1.4,
             'field_goal_percentage': 0.439,
             'percentage_of_three_pointers_from_corner': 0.094,
             'free_throw_percentage': 0.86,
             'offensive_fouls': 42,
             'half_court_heaves': 0,
             'percentage_three_to_ten_footers': 0.124,
             'passing_turnovers': 169,
             'value_over_replacement_player': 6.9,
             'blocking_fouls': 4,
             'field_goal_attempts': 1617,
             'free_throw_attempt_rate': 0.518,
             'effective_field_goal_percentage': 0.512,
             'total_rebounds': 501,
             'center_percentage': 0,
             'power_forward_percentage': 1,
             'nationality': 'United States of America',
             'offensive_win_shares': 10.7,
             'defensive_rebounds': 438,
             'total_rebound_percentage': 8.8,
             'assists': 612,
             'defensive_box_plus_minus': -0.4,
             'shooting_distance': 14.4,
             'height': '6-5',
             'true_shooting_percentage': 0.598,
             'small_forward_percentage': 21,
             'minutes_played': 3125,
             'on_court_plus_minus': 1.7,
             'games_started': 82,
             'win_shares_per_48_minutes': 0.204,
             'dunks': 16,
             'three_pointers_assisted_percentage': 0.521,
             'two_point_attempts': 960,
             'salary': 15756438,
             'offensive_box_plus_minus': 7.1,
             'lost_ball_turnovers': 149,
             'percentage_shots_two_pointers': 0.594,
             'shooting_guard_percentage': 77,
             'shots_blocked': 95,
             'and_ones': 56,
             'three_pointers': 236,
             'take_fouls': 11,
             'free_throws': 720,
             'usage_percentage': 32.5,
             'assist_percentage': 35.4,
             'three_point_attempts': 657,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.406,
             'percentage_field_goals_as_dunks': 0.011,
             'offensive_rebounds': 63,
             'other_turnovers': 56,
             'point_guard_percentage': 2,
             'half_court_heaves_made': 0,
             'blocks': 51,
             'two_pointers_assisted_percentage': 0.181,
             'win_shares': 13.3,
             'defensive_win_shares': 2.6,
             'games_played': 82,
             'percentage_zero_to_three_footers': 0.246,
             'steals': 139,
             'turnovers': 374,
             'field_goal_perc_zero_to_three_feet': 0.65,
             'shooting_fouls': 93,
             'team_abbreviation': 'HOU',
             'points': 2376,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.274},
            {'field_goal_perc_ten_to_sixteen_feet': 0.4,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.413,
             'box_plus_minus': 4.5,
             'two_point_percentage': 0.579,
             'two_pointers': 195,
             'net_plus_minus': 8.0,
             'personal_fouls': 150,
             'three_point_percentage': 0.39,
             'player_efficiency_rating': 21.1,
             'offensive_rebound_percentage': 1.9,
             'percentage_sixteen_foot_plus_two_pointers': 0.073,
             'three_point_attempt_rate': 0.464,
             'field_goals': 309,
             'free_throw_attempts': 369,
             'shooting_fouls_drawn': 161,
             'defensive_rebound_percentage': 12.2,
             'steal_percentage': 1.6,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.3,
             'percentage_ten_to_sixteen_footers': 0.024,
             'turnover_percentage': 14.8,
             'points_generated_by_assists': 536,
             'block_percentage': 0.6,
             'field_goal_percentage': 0.491,
             'percentage_of_three_pointers_from_corner': 0.113,
             'free_throw_percentage': 0.846,
             'offensive_fouls': 24,
             'half_court_heaves': 1,
             'percentage_three_to_ten_footers': 0.111,
             'passing_turnovers': 62,
             'value_over_replacement_player': 3.2,
             'blocking_fouls': 0,
             'field_goal_attempts': 629,
             'free_throw_attempt_rate': 0.587,
             'effective_field_goal_percentage': 0.582,
             'total_rebounds': 252,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 7.5,
             'defensive_rebounds': 222,
             'total_rebound_percentage': 7.4,
             'assists': 229,
             'defensive_box_plus_minus': -1.1,
             'shooting_distance': 14.3,
             'height': '6-5',
             'true_shooting_percentage': 0.66,
             'small_forward_percentage': 44,
             'minutes_played': 1946,
             'on_court_plus_minus': 9.9,
             'games_started': 2,
             'win_shares_per_48_minutes': 0.23,
             'dunks': 39,
             'three_pointers_assisted_percentage': 0.86,
             'two_point_attempts': 337,
             'salary': 4604760,
             'offensive_box_plus_minus': 5.6,
             'lost_ball_turnovers': 39,
             'percentage_shots_two_pointers': 0.536,
             'shooting_guard_percentage': 55,
             'shots_blocked': 50,
             'and_ones': 28,
             'three_pointers': 114,
             'take_fouls': 0,
             'free_throws': 312,
             'usage_percentage': 21.6,
             'assist_percentage': 19.3,
             'three_point_attempts': 292,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.464,
             'percentage_field_goals_as_dunks': 0.062,
             'offensive_rebounds': 30,
             'other_turnovers': 36,
             'point_guard_percentage': 0,
             'half_court_heaves_made': 0,
             'blocks': 15,
             'two_pointers_assisted_percentage': 0.282,
             'win_shares': 9.3,
             'defensive_win_shares': 1.8,
             'games_played': 62,
             'percentage_zero_to_three_footers': 0.328,
             'steals': 62,
             'turnovers': 137,
             'field_goal_perc_zero_to_three_feet': 0.723,
             'shooting_fouls': 49,
             'team_abbreviation': 'HOU',
             'points': 1044,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.455},
            {'field_goal_perc_ten_to_sixteen_feet': 0.318,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.333,
             'box_plus_minus': 5.5,
             'two_point_percentage': 0.477,
             'two_pointers': 406,
             'net_plus_minus': -3.6,
             'personal_fouls': 178,
             'three_point_percentage': 0.368,
             'player_efficiency_rating': 23.0,
             'offensive_rebound_percentage': 2.4,
             'percentage_sixteen_foot_plus_two_pointers': 0.13,
             'three_point_attempt_rate': 0.364,
             'field_goals': 585,
             'free_throw_attempts': 792,
             'shooting_fouls_drawn': 329,
             'defensive_rebound_percentage': 11.9,
             'steal_percentage': 2.4,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.296,
             'percentage_ten_to_sixteen_footers': 0.049,
             'turnover_percentage': 14.9,
             'points_generated_by_assists': 1098,
             'block_percentage': 1.0,
             'field_goal_percentage': 0.438,
             'percentage_of_three_pointers_from_corner': 0.033,
             'free_throw_percentage': 0.851,
             'offensive_fouls': 37,
             'half_court_heaves': 3,
             'percentage_three_to_ten_footers': 0.149,
             'passing_turnovers': 143,
             'value_over_replacement_player': 5.7,
             'blocking_fouls': 0,
             'field_goal_attempts': 1337,
             'free_throw_attempt_rate': 0.592,
             'effective_field_goal_percentage': 0.504,
             'total_rebounds': 379,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 9.8,
             'defensive_rebounds': 317,
             'total_rebound_percentage': 7.2,
             'assists': 455,
             'defensive_box_plus_minus': 0.1,
             'shooting_distance': 13.7,
             'height': '6-5',
             'true_shooting_percentage': 0.6,
             'small_forward_percentage': 5,
             'minutes_played': 2985,
             'on_court_plus_minus': 2.8,
             'games_started': 78,
             'win_shares_per_48_minutes': 0.206,
             'dunks': 46,
             'three_pointers_assisted_percentage': 0.475,
             'two_point_attempts': 851,
             'salary': 5820417,
             'offensive_box_plus_minus': 5.4,
             'lost_ball_turnovers': 102,
             'percentage_shots_two_pointers': 0.636,
             'shooting_guard_percentage': 94,
             'shots_blocked': 106,
             'and_ones': 65,
             'three_pointers': 179,
             'take_fouls': 5,
             'free_throws': 674,
             'usage_percentage': 29.0,
             'assist_percentage': 25.7,
             'three_point_attempts': 486,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.364,
             'percentage_field_goals_as_dunks': 0.035,
             'offensive_rebounds': 62,
             'other_turnovers': 50,
             'point_guard_percentage': 0,
             'half_court_heaves_made': 1,
             'blocks': 38,
             'two_pointers_assisted_percentage': 0.241,
             'win_shares': 12.8,
             'defensive_win_shares': 3.0,
             'games_played': 78,
             'percentage_zero_to_three_footers': 0.308,
             'steals': 142,
             'turnovers': 295,
             'field_goal_perc_zero_to_three_feet': 0.65,
             'shooting_fouls': 67,
             'team_abbreviation': 'HOU',
             'points': 2023,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.25},
            {'field_goal_perc_ten_to_sixteen_feet': 0.437,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.368,
             'box_plus_minus': 10.9,
             'two_point_percentage': 0.531,
             'two_pointers': 386,
             'net_plus_minus': 5.3,
             'personal_fouls': 169,
             'three_point_percentage': 0.367,
             'player_efficiency_rating': 29.8,
             'offensive_rebound_percentage': 1.8,
             'percentage_sixteen_foot_plus_two_pointers': 0.039,
             'three_point_attempt_rate': 0.498,
             'field_goals': 651,
             'free_throw_attempts': 727,
             'shooting_fouls_drawn': 273,
             'defensive_rebound_percentage': 15.2,
             'steal_percentage': 2.4,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.351,
             'percentage_ten_to_sixteen_footers': 0.071,
             'turnover_percentage': 15.1,
             'points_generated_by_assists': 1499,
             'block_percentage': 1.7,
             'field_goal_percentage': 0.449,
             'percentage_of_three_pointers_from_corner': 0.072,
             'free_throw_percentage': 0.858,
             'offensive_fouls': 29,
             'half_court_heaves': 2,
             'percentage_three_to_ten_footers': 0.118,
             'passing_turnovers': 188,
             'value_over_replacement_player': 8.3,
             'blocking_fouls': 2,
             'field_goal_attempts': 1449,
             'free_throw_attempt_rate': 0.502,
             'effective_field_goal_percentage': 0.541,
             'total_rebounds': 389,
             'center_percentage': 0,
             'power_forward_percentage': 0,
             'nationality': 'United States of America',
             'offensive_win_shares': 11.6,
             'defensive_rebounds': 348,
             'total_rebound_percentage': 8.6,
             'assists': 630,
             'defensive_box_plus_minus': 1.3,
             'shooting_distance': 15.3,
             'height': '6-5',
             'true_shooting_percentage': 0.619,
             'small_forward_percentage': 6,
             'minutes_played': 2551,
             'on_court_plus_minus': 10.5,
             'games_started': 72,
             'win_shares_per_48_minutes': 0.289,
             'dunks': 19,
             'three_pointers_assisted_percentage': 0.26,
             'two_point_attempts': 727,
             'salary': 28299399,
             'offensive_box_plus_minus': 9.6,
             'lost_ball_turnovers': 87,
             'percentage_shots_two_pointers': 0.502,
             'shooting_guard_percentage': 75,
             'shots_blocked': 98,
             'and_ones': 55,
             'three_pointers': 265,
             'take_fouls': 5,
             'free_throws': 624,
             'usage_percentage': 36.1,
             'assist_percentage': 45.1,
             'three_point_attempts': 722,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.498,
             'percentage_field_goals_as_dunks': 0.013,
             'offensive_rebounds': 41,
             'other_turnovers': 40,
             'point_guard_percentage': 19,
             'half_court_heaves_made': 0,
             'blocks': 50,
             'two_pointers_assisted_percentage': 0.088,
             'win_shares': 15.4,
             'defensive_win_shares': 3.8,
             'games_played': 72,
             'percentage_zero_to_three_footers': 0.273,
             'steals': 126,
             'turnovers': 315,
             'field_goal_perc_zero_to_three_feet': 0.658,
             'shooting_fouls': 65,
             'team_abbreviation': 'HOU',
             'points': 2191,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.327},
            {'field_goal_perc_ten_to_sixteen_feet': 0.444,
             'field_goal_perc_sixteen_foot_plus_two_pointers': 0.402,
             'box_plus_minus': 2.3,
             'two_point_percentage': 0.514,
             'two_pointers': 185,
             'net_plus_minus': 2.7,
             'personal_fouls': 207,
             'three_point_percentage': 0.349,
             'player_efficiency_rating': 16.4,
             'offensive_rebound_percentage': 2.3,
             'percentage_sixteen_foot_plus_two_pointers': 0.127,
             'three_point_attempt_rate': 0.474,
             'field_goals': 298,
             'free_throw_attempts': 343,
             'shooting_fouls_drawn': 152,
             'defensive_rebound_percentage': 11.0,
             'steal_percentage': 2.2,
             'weight': 220,
             'field_goal_perc_three_to_ten_feet': 0.28,
             'percentage_ten_to_sixteen_footers': 0.026,
             'turnover_percentage': 11.3,
             'points_generated_by_assists': 419,
             'block_percentage': 0.8,
             'field_goal_percentage': 0.436,
             'percentage_of_three_pointers_from_corner': 0.182,
             'free_throw_percentage': 0.843,
             'offensive_fouls': 29,
             'half_court_heaves': 1,
             'percentage_three_to_ten_footers': 0.073,
             'passing_turnovers': 29,
             'value_over_replacement_player': 2.4,
             'blocking_fouls': 0,
             'field_goal_attempts': 684,
             'free_throw_attempt_rate': 0.501,
             'effective_field_goal_percentage': 0.518,
             'total_rebounds': 255,
             'center_percentage': 0,
             'power_forward_percentage': 1,
             'nationality': 'United States of America',
             'offensive_win_shares': 5.0,
             'defensive_rebounds': 213,
             'total_rebound_percentage': 6.8,
             'assists': 176,
             'defensive_box_plus_minus': -0.6,
             'shooting_distance': 15.4,
             'height': '6-5',
             'true_shooting_percentage': 0.598,
             'small_forward_percentage': 26,
             'minutes_played': 2189,
             'on_court_plus_minus': 5.5,
             'games_started': 5,
             'win_shares_per_48_minutes': 0.156,
             'dunks': 46,
             'three_pointers_assisted_percentage': 0.823,
             'two_point_attempts': 360,
             'salary': 4304520,
             'offensive_box_plus_minus': 2.9,
             'lost_ball_turnovers': 37,
             'percentage_shots_two_pointers': 0.526,
             'shooting_guard_percentage': 74,
             'shots_blocked': 46,
             'and_ones': 27,
             'three_pointers': 113,
             'take_fouls': 0,
             'free_throws': 289,
             'usage_percentage': 19.5,
             'assist_percentage': 12.8,
             'three_point_attempts': 324,
             'player_id': 'hardeja01',
             'percentage_shots_three_pointers': 0.474,
             'percentage_field_goals_as_dunks': 0.07,
             'offensive_rebounds': 42,
             'other_turnovers': 40,
             'point_guard_percentage': 0,
             'half_court_heaves_made': 0,
             'blocks': 24,
             'two_pointers_assisted_percentage': 0.422,
             'win_shares': 7.1,
             'defensive_win_shares': 2.1,
             'games_played': 82,
             'percentage_zero_to_three_footers': 0.3,
             'steals': 92,
             'turnovers': 106,
             'field_goal_perc_zero_to_three_feet': 0.624,
             'shooting_fouls': 81,
             'team_abbreviation': 'HOU',
             'points': 998,
             'position': 'SG',
             'three_point_shot_percentage_from_corner': 0.356}
        ]
        indices = ['2013-14', 'Career', '2014-15', '2016-17', '2009-10',
                   '2015-16', '2011-12', '2012-13', '2017-18', '2010-11']

        df = pd.DataFrame(dataframe, index=indices)
        player = self.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)

    def test_nba_player_with_no_stats_handled_without_error(self):
        player = Player('youngtr01')

        assert player.name == 'Trae Young'


class TestNBARoster:
    @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('HOU')

        assert len(roster.players) == 4

        for player in roster.players:
            assert player.name in ['James Harden', 'Tarik Black',
                                   'Ryan Anderson', 'Trevor Ariza']

    @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='HOU')
        type(team)._abbreviation = mock_abbreviation

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

        for player in team.roster.players:
            assert player.name in ['James Harden', 'Tarik Black',
                                   'Ryan Anderson', 'Trevor Ariza']

        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('HOU', slim=True)

        assert len(roster.players) == 4
        assert roster.players == {
            'hardeja01': 'James Harden',
            'blackta01': 'Tarik Black',
            'anderry01': 'Ryan Anderson',
            'arizatr01': 'Trevor Ariza'
        }
