Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions espncricinfo/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,9 @@ def __init__(self, player_id):
self.json_url = "http://core.espnuk.org/v2/sports/cricket/athletes/{0}".format(
str(player_id)
)
self.new_json_url = "https://hs-consumer-api.espncricinfo.com/v1/pages/player/home?playerId={0}".format(
str(player_id)
)
self.headers = {"user-agent": "Mozilla/5.0"}
self.parsed_html = self.get_html()
self.json = self.get_json()
self.new_json = self.get_new_json()
self._major_teams_cache = None
self.cricinfo_id = str(player_id)
self.__unicode__ = self._full_name()
self.name = self._name()
Expand All @@ -33,7 +29,6 @@ def __init__(self, player_id):
self.playing_role = self._playing_role()
self.batting_style = self._batting_style()
self.bowling_style = self._bowling_style()
self.major_teams = self._major_teams()

def get_html(self):
r = requests.get(self.url, headers=self.headers)
Expand All @@ -46,15 +41,8 @@ def get_json(self):
r = requests.get(self.json_url, headers=self.headers)
if r.status_code == 404:
raise PlayerNotFoundError
else:
return r.json()

def get_new_json(self):
r = requests.get(self.new_json_url, headers=self.headers)
if r.status_code == 404:
raise PlayerNotFoundError
else:
return r.json()
r.raise_for_status()
return r.json()

def _name(self):
return self.json["name"]
Expand All @@ -77,8 +65,21 @@ def _date_of_birth(self):
def _current_age(self):
return self.json["age"]

def _major_teams(self):
return [x["team"]["longName"] for x in self.new_json["content"]["teams"]]
@property
def major_teams(self):
if self._major_teams_cache is None:
teams = []
for reference in self.json.get("majorTeams", []):
response = requests.get(reference["$ref"], headers=self.headers)
response.raise_for_status()
team = response.json()
name = (
team.get("longName") or team.get("displayName") or team.get("name")
)
if name:
teams.append(name)
self._major_teams_cache = teams
return self._major_teams_cache

def _playing_role(self):
return self.json["position"]
Expand Down
41 changes: 34 additions & 7 deletions tests/test_player.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from unittest.mock import MagicMock, patch

import pytest
from requests import HTTPError, Response

from espncricinfo.exceptions import PlayerNotFoundError
from espncricinfo.player import Player
Expand All @@ -31,18 +32,18 @@ def _mock_response(json_data=None, text=None, status_code=200):

def _make_player():
json_data = _load("player_253802.json")
new_json = _load("player_253802_new.json")

def side_effect(url, headers=None):
if "hs-consumer-api" in url:
return _mock_response(json_data=new_json)
elif "espnuk.org" in url:
if "/athletes/" in url:
return _mock_response(json_data=json_data)
else:
return _mock_response(text="<html><body></body></html>")
if "/teams/" in url:
return _mock_response(json_data={"name": f"Team {url.rsplit('/', 1)[-1]}"})
raise AssertionError(f"Unexpected request: {url}")

with patch("espncricinfo.player.requests.get", side_effect=side_effect):
return Player(253802)
player = Player(253802)
_ = player.major_teams
return player


class TestPlayerAttributes(unittest.TestCase):
Expand Down Expand Up @@ -91,6 +92,24 @@ def test_major_teams_are_strings(self):
for team in self.player.major_teams:
self.assertIsInstance(team, str)

def test_major_teams_resolve_core_references_once(self):
player_data = _load("player_253802.json")
player_data["majorTeams"] = [
{"$ref": "http://core.espnuk.org/v2/sports/cricket/teams/6"},
{"$ref": "http://core.espnuk.org/v2/sports/cricket/teams/1668"},
]
responses = [
_mock_response(json_data=player_data),
_mock_response(json_data={"displayName": "India"}),
_mock_response(json_data={"name": "Delhi"}),
]
with patch("espncricinfo.player.requests.get", side_effect=responses) as get:
player = Player(253802)
self.assertEqual(get.call_count, 1)
self.assertEqual(player.major_teams, ["India", "Delhi"])
self.assertEqual(player.major_teams, ["India", "Delhi"])
self.assertEqual(get.call_count, 3)


class TestPlayerErrors(unittest.TestCase):
def test_404_raises_player_not_found(self):
Expand All @@ -99,6 +118,14 @@ def test_404_raises_player_not_found(self):
with self.assertRaises(PlayerNotFoundError):
Player(999999)

def test_non_404_http_error_is_not_decoded_as_json(self):
denied = Response()
denied.status_code = 403
denied._content = b"<html>Access Denied</html>"
with patch("espncricinfo.player.requests.get", return_value=denied):
with self.assertRaises(HTTPError):
Player(253802)


class TestPlayerIntegration:
@pytest.mark.integration
Expand Down
Loading