├── .github └── workflows │ └── main.yml ├── .gitignore ├── LICENSE ├── README.md ├── cartolafc ├── __init__.py ├── api.py ├── constants.py ├── errors.py ├── models.py └── util.py ├── examples ├── .gitignore ├── examples.py └── requirements.txt ├── pyproject.toml ├── requirements ├── common.txt └── development.txt └── tests ├── __init__.py ├── test_api.py ├── test_utils.py └── testdata ├── clubes.json ├── game_over.json ├── ligas.json ├── mercado_atletas.json ├── mercado_destaques.json ├── mercado_destaques_reservas.json ├── mercado_status_aberto.json ├── mercado_status_fechado.json ├── parciais.json ├── partidas.json ├── patrocinadores.json ├── pos_rodada_destaques.json ├── time.json └── times.json /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - dev 8 | - master 9 | 10 | jobs: 11 | test: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | fail-fast: false 15 | matrix: 16 | python-version: ["3.8", "3.9", "3.10"] 17 | 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Set up Python ${{ matrix.python-version }} 21 | uses: actions/setup-python@v3 22 | with: 23 | python-version: ${{ matrix.python-version }} 24 | - name: Install dependencies 25 | run: | 26 | python -m pip install --upgrade pip 27 | python -m pip install pytest 28 | pip install -r requirements/development.txt 29 | - name: Test with pytest 30 | run: | 31 | python -m pytest 32 | 33 | lint: 34 | name: black 35 | runs-on: ubuntu-latest 36 | 37 | steps: 38 | - uses: actions/checkout@v3 39 | - name: Set up Python ${{ matrix.python-version }} 40 | uses: actions/setup-python@v3 41 | with: 42 | python-version: ${{ matrix.python-version }} 43 | - name: Install dependencies 44 | run: | 45 | python -m pip install --upgrade pip 46 | python -m pip install black 47 | pip install -r requirements/development.txt 48 | - name: Black test 49 | run: | 50 | black --check . 51 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | .DS_Store 6 | *~ 7 | .sass-cache 8 | 9 | # PyCharm 10 | .idea/ 11 | 12 | # VirtualEnv dir 13 | .venv/ 14 | 15 | # Coverage 16 | .coverage 17 | cover/ 18 | 19 | # PyPi 20 | Python_CartolaFC.egg-info/ 21 | build/ 22 | dist/ 23 | 24 | # Tox 25 | .tox/ 26 | 27 | # Pytest 28 | .pytest_cache/ 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-, Vicente Neto 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Cartola FC API 2 | 3 | [![PyPi Version](https://img.shields.io/pypi/v/python-cartolafc.svg)](https://pypi.org/project/python-cartolafc/) 4 | [![Build Status](https://github.com/vicenteneto/python-cartolafc/actions/workflows/main.yml/badge.svg)](https://github.com/vicenteneto/python-cartolafc/actions/workflows/main.yml) 5 | [![Development Status](http://img.shields.io/:status-production/stable-brightgreen.svg)](https://github.com/vicenteneto/python-cartolafc) 6 | [![License](http://img.shields.io/:license-mit-blue.svg)](https://github.com/vicenteneto/python-cartolafc/blob/main/LICENSE) 7 | 8 | Uma interface em Python para a API Rest do Cartola FC. 9 | 10 | 11 | # Índice 12 | 13 | - [Sobre este projeto](#sobre-este-projeto) 14 | - [Versões](#versoes) 15 | - [Instalação](#instalacao) 16 | - [Exemplo](#exemplo) 17 | - [Contribuintes](#contribuintes) 18 | - [Direitos autorais e licença](#direitos-autorais-e-licenca) 19 | 20 | 21 | ## Sobre este projeto 22 | 23 | Este projeto é uma interface em Python para a API REST do Cartola FC. [Cartola FC](https://cartolafc.globo.com/) é um 24 | esporte fantasy sobre futebol, ou seja, é um jogo fictício no qual as pessoas montam seus times com jogadores de futebol 25 | da vida real. Foi lançado no ano de 2005. 26 | 27 | Criado e mantido por [Globo.com](http://www.globo.com/) e promovido pelo canal de TV por assinatura 28 | [Sportv](http://sportv.globo.com/), este jogo de futebol virtual conta com mais de 5 milhões de usuários registrados. 29 | Logo na abertura da temporada 2016, o jogo registrou a sua melhor marca entre times escalados em uma única rodada em 12 30 | anos de história do fantasy, incríveis 2.723.915 de usuários montaram as suas equipes para a primeira rodada do 31 | Campeonato Brasileiro de 2016. A 10ª rodada do Campeonato Brasileiro de 2017 instituiu um novo recorde, onde 5.540.835 32 | times foram escalados no jogo. 33 | 34 | 35 | ## Versões 36 | 37 | Este projeto foi testado e funciona em Python 3.8, 3.9 e 3.10. 38 | 39 | 40 | ## Instalação 41 | 42 | PyPI: 43 | 44 | ```bash 45 | $ pip install Python-CartolaFC 46 | ``` 47 | 48 | Ou baixando o código fonte e executando: 49 | 50 | ```bash 51 | $ python setup.py install 52 | ``` 53 | 54 | Versão em desenvolvimento: 55 | 56 | ```bash 57 | $ pip install git+https://github.com/vicenteneto/python-cartolafc.git#egg=Python-CartolaFC 58 | ``` 59 | 60 | 61 | ## Exemplo 62 | 63 | A API Python-CartolaFC destina-se a mapear os objetos no CartolaFC (por exemplo, Atleta, Clube, Liga, Equipe) em objetos 64 | Python facilmente gerenciados: 65 | 66 | ```python 67 | >>> import cartolafc 68 | >>> api = cartolafc.Api() 69 | >>> time = api.time(nome='Falydos FC') 70 | >>> time.ultima_pontuacao 71 | 48.889892578125 72 | >>> time.info.nome 73 | 'Falydos FC' 74 | ``` 75 | 76 | Mais exemplos disponíveis no Github: 77 | [https://github.com/vicenteneto/python-cartolafc/tree/main/examples](https://github.com/vicenteneto/python-cartolafc/tree/main/examples) 78 | 79 | 80 | ## Contribuintes 81 | 82 | Identificou algum bug ou tem alguma requisição de funcionalidade nova? 83 | [Por favor, abra uma nova issue](https://github.com/vicenteneto/python-cartolafc/issues/new>). 84 | 85 | 86 | ## Direitos autorais e licença 87 | 88 | Copyright 2017-, Vicente Neto. Este projeto é licenciado sob a 89 | [Licença MIT](https://github.com/vicenteneto/python-cartolafc/blob/main/LICENSE). 90 | -------------------------------------------------------------------------------- /cartolafc/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | cartolafc 3 | ~~~~~~~~~ 4 | 5 | Uma API em Python para o Cartola FC. 6 | 7 | :copyright: (c) 2023 por Vicente Ramos. 8 | :license: MIT, veja LICENSE para mais detalhes. 9 | """ 10 | 11 | from .api import Api 12 | from .errors import CartolaFCError, CartolaFCGameOverError, CartolaFCOverloadError 13 | 14 | __all__ = [ 15 | "Api", 16 | "CartolaFCError", 17 | "CartolaFCGameOverError", 18 | "CartolaFCOverloadError", 19 | ] 20 | -------------------------------------------------------------------------------- /cartolafc/api.py: -------------------------------------------------------------------------------- 1 | import logging 2 | from typing import Any, Dict, List, Optional 3 | 4 | import requests 5 | 6 | from .constants import MERCADO_ABERTO, MERCADO_FECHADO 7 | from .errors import CartolaFCError, CartolaFCOverloadError 8 | from .models import ( 9 | Atleta, 10 | AtletaDestaque, 11 | Clube, 12 | DestaqueRodada, 13 | Liga, 14 | Patrocinador, 15 | Mercado, 16 | Partida, 17 | ) 18 | from .models import Time, TimeInfo 19 | from .util import parse_and_check_cartolafc 20 | 21 | logging.basicConfig( 22 | format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO 23 | ) 24 | 25 | 26 | class Api(object): 27 | """Uma API em Python para o Cartola FC 28 | 29 | Exemplo de uso: 30 | Para criar uma instância da classe cartolafc.Api, sem autenticação: 31 | >>> import cartolafc 32 | >>> api = cartolafc.Api() 33 | 34 | Para obter o status atual do mercado 35 | >>> mercado = api.mercado() 36 | >>> print(mercado.rodada_atual, mercado.status.nome) 37 | 38 | python-cartolafc é massa!!! E possui muitos outros métodos, como: 39 | >>> api.mercado() 40 | >>> api.time(123) 41 | >>> api.times('termo') 42 | """ 43 | 44 | def __init__(self, attempts: int = 1) -> None: 45 | """Instancia um novo objeto de cartolafc.Api. 46 | 47 | Args: 48 | attempts (int): Quantidade de tentativas que serão efetuadas se os servidores estiverem sobrecarregados. 49 | """ 50 | 51 | self._api_url = "https://api.cartola.globo.com" 52 | self._attempts = attempts if attempts > 0 else 1 53 | 54 | def clubes(self) -> Dict[int, Clube]: 55 | url = f"{self._api_url}/clubes" 56 | data = self._request(url) 57 | return { 58 | int(clube_id): Clube.from_dict(clube) for clube_id, clube in data.items() 59 | } 60 | 61 | def ligas(self, query: str) -> List[Liga]: 62 | """Retorna o resultado da busca ao Cartola por um determinado termo de pesquisa. 63 | 64 | Args: 65 | query (str): Termo para utilizar na busca. 66 | 67 | Returns: 68 | Uma lista de instâncias de cartolafc.Liga, uma para cada liga contento o termo utilizado na busca. 69 | """ 70 | 71 | url = f"{self._api_url}/ligas" 72 | data = self._request(url, params=dict(q=query)) 73 | return [Liga.from_dict(liga_info) for liga_info in data] 74 | 75 | def patrocinadores(self) -> Dict[int, Patrocinador]: 76 | url = f"{self._api_url}/patrocinadores" 77 | data = self._request(url) 78 | return { 79 | int(patrocinador_id): Patrocinador.from_dict(patrocinador) 80 | for patrocinador_id, patrocinador in data.items() 81 | } 82 | 83 | def mercado(self) -> Mercado: 84 | """Obtém o status do mercado na rodada atual. 85 | 86 | Returns: 87 | Uma instância de cartolafc.Mercado representando o status do mercado na rodada atual. 88 | """ 89 | 90 | url = f"{self._api_url}/mercado/status" 91 | data = self._request(url) 92 | return Mercado.from_dict(data) 93 | 94 | def mercado_atletas(self) -> List[Atleta]: 95 | url = f"{self._api_url}/atletas/mercado" 96 | data = self._request(url) 97 | clubes = { 98 | clube["id"]: Clube.from_dict(clube) for clube in data["clubes"].values() 99 | } 100 | return [Atleta.from_dict(atleta, clubes=clubes) for atleta in data["atletas"]] 101 | 102 | def parciais(self) -> Dict[int, Atleta]: 103 | """Obtém um mapa com todos os atletas que já pontuaram na rodada atual (aberta). 104 | 105 | Returns: 106 | Uma mapa, onde a key é um inteiro representando o id do atleta e o valor é uma instância de cartolafc.Atleta 107 | 108 | Raises: 109 | CartolaFCError: Se o mercado atual estiver com o status fechado. 110 | """ 111 | 112 | if self.mercado().status.id == MERCADO_FECHADO: 113 | url = f"{self._api_url}/atletas/pontuados" 114 | data = self._request(url) 115 | clubes = { 116 | clube["id"]: Clube.from_dict(clube) for clube in data["clubes"].values() 117 | } 118 | return { 119 | int(atleta_id): Atleta.from_dict( 120 | atleta, clubes=clubes, atleta_id=int(atleta_id) 121 | ) 122 | for atleta_id, atleta in data["atletas"].items() 123 | if atleta["clube_id"] > 0 124 | } 125 | 126 | raise CartolaFCError( 127 | "As pontuações parciais só ficam disponíveis com o mercado fechado." 128 | ) 129 | 130 | def partidas(self, rodada: Optional[int] = 0) -> List[Partida]: 131 | url = f"{self._api_url}/partidas" 132 | if rodada: 133 | url += f"/{rodada}" 134 | 135 | data = self._request(url) 136 | clubes = { 137 | clube["id"]: Clube.from_dict(clube) for clube in data["clubes"].values() 138 | } 139 | return sorted( 140 | [Partida.from_dict(partida, clubes=clubes) for partida in data["partidas"]], 141 | key=lambda p: p.data, 142 | ) 143 | 144 | def destaques(self) -> List[AtletaDestaque]: 145 | """Obtém os destaques do mercado na rodada atual. 146 | 147 | Returns: 148 | Uma lista de Atletas. 149 | """ 150 | 151 | url = f"{self._api_url}/mercado/destaques" 152 | data = self._request(url) 153 | return [AtletaDestaque.from_dict(destaque) for destaque in data] 154 | 155 | def destaques_reservas(self) -> List[AtletaDestaque]: 156 | """Obtém os destaques resservas do mercado na rodada atual. 157 | 158 | Returns: 159 | Uma lista de Atletas. 160 | """ 161 | 162 | url = f"{self._api_url}/mercado/destaques/reservas" 163 | data = self._request(url) 164 | return [AtletaDestaque.from_dict(destaque) for destaque in data] 165 | 166 | def pos_rodada_destaques(self) -> DestaqueRodada: 167 | mercado = self.mercado() 168 | if mercado.rodada_atual == 1: 169 | raise CartolaFCError( 170 | "Os destaques de pós-rodada só ficam disponíveis após a primeira rodada." 171 | ) 172 | 173 | if mercado.status.id == MERCADO_ABERTO: 174 | url = f"{self._api_url}/pos-rodada/destaques" 175 | data = self._request(url) 176 | return DestaqueRodada.from_dict(data) 177 | 178 | raise CartolaFCError( 179 | "Os destaques de pós-rodada só ficam disponíveis com o mercado aberto." 180 | ) 181 | 182 | def time(self, time_id: int, rodada: Optional[int] = 0) -> Time: 183 | """Obtém um time específico, baseando-se no nome ou no slug utilizado. 184 | Ao menos um dos dois devem ser informado. 185 | 186 | Args: 187 | time_id (int): Id to time que se deseja obter. 188 | rodada (int): Número da rodada. Se não for informado, será retornado sempre a última rodada. 189 | 190 | Returns: 191 | Uma instância de cartolafc.Time se o time foi encontrado. 192 | 193 | Raises: 194 | cartolafc.CartolaFCError: Se algum erro aconteceu, como por exemplo: Nenhum time foi encontrado. 195 | """ 196 | 197 | url = f"{self._api_url}/time/id/{time_id}" 198 | if rodada: 199 | url += f"/{rodada}" 200 | 201 | data = self._request(url) 202 | return Time.from_dict(data, clubes=self.clubes(), capitao=data["capitao_id"]) 203 | 204 | def time_parcial( 205 | self, 206 | time_id: int, 207 | parciais: Optional[Dict[int, Atleta]] = None, 208 | ) -> Time: 209 | if parciais is None and self.mercado().status.id != MERCADO_FECHADO: 210 | raise CartolaFCError( 211 | "As pontuações parciais só ficam disponíveis com o mercado fechado." 212 | ) 213 | 214 | parciais = parciais if isinstance(parciais, dict) else self.parciais() 215 | time = self.time(time_id) 216 | return self._calculate_parcial(time, parciais) 217 | 218 | def times(self, query: str) -> List[TimeInfo]: 219 | """Retorna o resultado da busca ao Cartola por um determinado termo de pesquisa. 220 | 221 | Args: 222 | query (str): Termo para utilizar na busca. 223 | 224 | Returns: 225 | Uma lista de instâncias de cartolafc.TimeInfo, uma para cada time contento o termo utilizado na busca. 226 | """ 227 | url = f"{self._api_url}/times" 228 | data = self._request(url, params=dict(q=query)) 229 | return [TimeInfo.from_dict(time_info) for time_info in data] 230 | 231 | @staticmethod 232 | def _calculate_parcial(time: Time, parciais: Dict[int, Atleta]) -> Time: 233 | if any( 234 | not isinstance(key, int) or not isinstance(parciais[key], Atleta) 235 | for key in parciais.keys() 236 | ) or not isinstance(time, Time): 237 | raise CartolaFCError("Time ou parciais não são válidos.") 238 | 239 | time.pontos = 0 240 | time.jogados = 0 241 | for atleta in time.atletas: 242 | atleta_parcial = parciais.get(atleta.id) 243 | tem_parcial = isinstance(atleta_parcial, Atleta) 244 | 245 | atleta.pontos = atleta_parcial.pontos if tem_parcial else 0 246 | atleta.scout = atleta_parcial.scout if tem_parcial else {} 247 | time.jogados += 1 if tem_parcial else 0 248 | 249 | if atleta.is_capitao: 250 | atleta.pontos *= 2 251 | 252 | time.pontos += atleta.pontos 253 | 254 | return time 255 | 256 | def _request(self, url: str, params: Optional[Dict[str, Any]] = None) -> dict: 257 | attempts = self._attempts 258 | while attempts: 259 | try: 260 | response = requests.get(url, params=params) 261 | return parse_and_check_cartolafc(response.content.decode("utf-8")) 262 | except CartolaFCOverloadError as error: 263 | attempts -= 1 264 | if not attempts: 265 | raise error 266 | -------------------------------------------------------------------------------- /cartolafc/constants.py: -------------------------------------------------------------------------------- 1 | MERCADO_ABERTO = 1 2 | MERCADO_FECHADO = 2 3 | -------------------------------------------------------------------------------- /cartolafc/errors.py: -------------------------------------------------------------------------------- 1 | class CartolaFCError(Exception): 2 | """Classe base para os erros da API do Cartola FC""" 3 | 4 | pass 5 | 6 | 7 | class CartolaFCOverloadError(CartolaFCError): 8 | """Erro lançado quando o servidores estão sobrecarregados e a biblioteca não consegue obter os dados 9 | requisitados""" 10 | 11 | pass 12 | 13 | 14 | class CartolaFCGameOverError(CartolaFCError): 15 | """Erro lançado quando o jogo termina e a biblioteca não consegue obter os dados requisitados""" 16 | 17 | pass 18 | -------------------------------------------------------------------------------- /cartolafc/models.py: -------------------------------------------------------------------------------- 1 | import json 2 | from collections import namedtuple 3 | from datetime import datetime 4 | from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar 5 | 6 | from .util import json_default 7 | 8 | Posicao = namedtuple("Posicao", ["id", "nome", "abreviacao"]) 9 | Status = namedtuple("Status", ["id", "nome"]) 10 | 11 | _posicoes = { 12 | 1: Posicao(1, "Goleiro", "gol"), 13 | 2: Posicao(2, "Lateral", "lat"), 14 | 3: Posicao(3, "Zagueiro", "zag"), 15 | 4: Posicao(4, "Meia", "mei"), 16 | 5: Posicao(5, "Atacante", "ata"), 17 | 6: Posicao(6, "Técnico", "tec"), 18 | } 19 | 20 | _atleta_status = { 21 | 2: Status(2, "Dúvida"), 22 | 3: Status(3, "Suspenso"), 23 | 5: Status(5, "Contundido"), 24 | 6: Status(6, "Nulo"), 25 | 7: Status(7, "Provável"), 26 | } 27 | 28 | _mercado_status = { 29 | 1: Status(1, "Mercado aberto"), 30 | 2: Status(2, "Mercado fechado"), 31 | 3: Status(3, "Mercado em atualização"), 32 | 4: Status(4, "Mercado em manutenção"), 33 | 6: Status(6, "Final de temporada"), 34 | } 35 | 36 | T = TypeVar("T", bound="BaseModel") 37 | 38 | 39 | class BaseModel(object): 40 | def __repr__(self) -> str: 41 | return json.dumps(self, default=json_default) 42 | 43 | @classmethod 44 | def from_dict(cls: Type[T], *args: Tuple[Any], **kwargs: Dict[str, Any]) -> T: 45 | raise NotImplementedError 46 | 47 | 48 | class TimeInfo(BaseModel): 49 | """Time Info""" 50 | 51 | def __init__( 52 | self, 53 | time_id: int, 54 | nome: str, 55 | nome_cartola: str, 56 | slug: str, 57 | assinante: bool, 58 | pontos: float, 59 | ) -> None: 60 | self.id = time_id 61 | self.nome = nome 62 | self.nome_cartola = nome_cartola 63 | self.slug = slug 64 | self.assinante = assinante 65 | self.pontos = pontos 66 | 67 | @classmethod 68 | def from_dict(cls, data: dict, ranking: str = None) -> "TimeInfo": 69 | pontos = ( 70 | data["pontos"][ranking] if ranking and ranking in data["pontos"] else None 71 | ) 72 | return cls( 73 | data["time_id"], 74 | data["nome"], 75 | data["nome_cartola"], 76 | data["slug"], 77 | data["assinante"], 78 | pontos, 79 | ) 80 | 81 | 82 | class Clube(BaseModel): 83 | """Representa um dos 20 clubes presentes no campeonato, e possui informações como o nome e a abreviação""" 84 | 85 | def __init__(self, clube_id: int, nome: str, abreviacao: str) -> None: 86 | self.id = clube_id 87 | self.nome = nome 88 | self.abreviacao = abreviacao 89 | 90 | @classmethod 91 | def from_dict(cls, data: dict) -> "Clube": 92 | return cls(data["id"], data["nome"], data["abreviacao"]) 93 | 94 | 95 | class Atleta(BaseModel): 96 | """Representa um atleta (jogador ou técnico), e possui informações como o apelido, clube e pontuação obtida""" 97 | 98 | def __init__( 99 | self, 100 | atleta_id: int, 101 | apelido: str, 102 | pontos: float, 103 | scout: Dict[str, int], 104 | posicao_id: int, 105 | clube: Clube, 106 | status_id: Optional[int] = None, 107 | is_capitao: Optional[bool] = None, 108 | ) -> None: 109 | self.id = atleta_id 110 | self.apelido = apelido 111 | self.pontos = pontos 112 | self.scout = scout 113 | self.posicao = _posicoes[posicao_id] 114 | self.clube = clube 115 | self.status = _atleta_status[status_id] if status_id else None 116 | self.is_capitao = is_capitao 117 | 118 | @classmethod 119 | def from_dict( 120 | cls, 121 | data: dict, 122 | clubes: Dict[int, Clube], 123 | atleta_id: Optional[int] = None, 124 | is_capitao: Optional[bool] = None, 125 | ) -> "Atleta": 126 | atleta_id = atleta_id if atleta_id else data["atleta_id"] 127 | pontos = data["pontos_num"] if "pontos_num" in data else data["pontuacao"] 128 | if data["clube_id"] in clubes: 129 | clube = clubes[data["clube_id"]] 130 | else: 131 | clube = Clube(0, "Sem Clube", "Sem Clube") 132 | return cls( 133 | atleta_id, 134 | data["apelido"], 135 | pontos, 136 | data["scout"], 137 | data["posicao_id"], 138 | clube, 139 | data.get("status_id", None), 140 | is_capitao, 141 | ) 142 | 143 | 144 | class AtletaDestaque(BaseModel): 145 | """Representa um atleta destaque, e possui informações como o apelido, clube e pontuação obtida""" 146 | 147 | def __init__( 148 | self, 149 | atleta_id: int, 150 | apelido: str, 151 | posicao: Posicao, 152 | preco: int, 153 | clube: Clube, 154 | escalacoes: int, 155 | ) -> None: 156 | self.id = atleta_id 157 | self.apelido = apelido 158 | self.posicao = posicao 159 | self.preco = preco 160 | self.clube = clube 161 | self.escalacoes = escalacoes 162 | 163 | @classmethod 164 | def from_dict( 165 | cls, 166 | data: dict, 167 | ) -> "AtletaDestaque": 168 | posicao = None 169 | for pos in _posicoes.values(): 170 | if pos.abreviacao == str.lower(data["posicao_abreviacao"]): 171 | posicao = pos 172 | 173 | return cls( 174 | data["Atleta"]["atleta_id"], 175 | data["Atleta"]["apelido"], 176 | posicao, 177 | data["Atleta"]["preco_editorial"], 178 | Clube(data["clube_id"], data["clube_nome"], data["clube"]), 179 | data["escalacoes"], 180 | ) 181 | 182 | 183 | class DestaqueRodada(BaseModel): 184 | """Destaque Rodada""" 185 | 186 | def __init__( 187 | self, media_cartoletas: float, media_pontos: float, mito_rodada: TimeInfo 188 | ) -> None: 189 | self.media_cartoletas = media_cartoletas 190 | self.media_pontos = media_pontos 191 | self.mito_rodada = mito_rodada 192 | 193 | @classmethod 194 | def from_dict(cls, data: dict) -> "DestaqueRodada": 195 | mito_rodada = TimeInfo.from_dict(data["mito_rodada"]) 196 | return cls(data["media_cartoletas"], data["media_pontos"], mito_rodada) 197 | 198 | 199 | class Liga(BaseModel): 200 | """Liga""" 201 | 202 | def __init__( 203 | self, liga_id: int, nome: str, slug: str, descricao: str, times: List[TimeInfo] 204 | ) -> None: 205 | self.id = liga_id 206 | self.nome = nome 207 | self.slug = slug 208 | self.descricao = descricao 209 | self.times = times 210 | 211 | @classmethod 212 | def from_dict(cls, data: dict, ranking: Optional[str] = None) -> "Liga": 213 | data_liga = data.get("liga", data) 214 | times = ( 215 | [TimeInfo.from_dict(time, ranking=ranking) for time in data["times"]] 216 | if "times" in data 217 | else None 218 | ) 219 | return cls( 220 | data_liga["liga_id"], 221 | data_liga["nome"], 222 | data_liga["slug"], 223 | data_liga["descricao"], 224 | times, 225 | ) 226 | 227 | 228 | class Patrocinador(BaseModel): 229 | """Patrocinador""" 230 | 231 | def __init__(self, liga_id: int, nome: str, url_link: str) -> None: 232 | self.id = liga_id 233 | self.nome = nome 234 | self.url_link = url_link 235 | 236 | @classmethod 237 | def from_dict(cls, data: dict) -> "Patrocinador": 238 | return cls(data["liga_id"], data["nome"], data["url_link"]) 239 | 240 | 241 | class Mercado(BaseModel): 242 | """Mercado""" 243 | 244 | def __init__( 245 | self, 246 | rodada_atual: int, 247 | status_mercado: int, 248 | times_escalados: int, 249 | fechamento: datetime, 250 | ) -> None: 251 | self.rodada_atual = rodada_atual 252 | self.status = _mercado_status[status_mercado] 253 | self.times_escalados = times_escalados 254 | self.fechamento = fechamento 255 | 256 | @classmethod 257 | def from_dict(cls, data: dict) -> "Mercado": 258 | fechamento = datetime( 259 | data["fechamento"]["ano"], 260 | data["fechamento"]["mes"], 261 | data["fechamento"]["dia"], 262 | data["fechamento"]["hora"], 263 | data["fechamento"]["minuto"], 264 | ) 265 | return cls( 266 | data["rodada_atual"], 267 | data["status_mercado"], 268 | data["times_escalados"], 269 | fechamento, 270 | ) 271 | 272 | 273 | class Partida(BaseModel): 274 | """Partida""" 275 | 276 | def __init__( 277 | self, 278 | data: datetime, 279 | local: str, 280 | clube_casa: Clube, 281 | placar_casa: int, 282 | clube_visitante: Clube, 283 | placar_visitante: int, 284 | ) -> None: 285 | self.data = data 286 | self.local = local 287 | self.clube_casa = clube_casa 288 | self.placar_casa = placar_casa 289 | self.clube_visitante = clube_visitante 290 | self.placar_visitante = placar_visitante 291 | 292 | @classmethod 293 | def from_dict(cls, data: dict, clubes: Dict[int, Clube]) -> "Partida": 294 | data_ = datetime.strptime(data["partida_data"], "%Y-%m-%d %H:%M:%S") 295 | local = data["local"] 296 | clube_casa = clubes[data["clube_casa_id"]] 297 | placar_casa = data["placar_oficial_mandante"] 298 | clube_visitante = clubes[data["clube_visitante_id"]] 299 | placar_visitante = data["placar_oficial_visitante"] 300 | return cls( 301 | data_, local, clube_casa, placar_casa, clube_visitante, placar_visitante 302 | ) 303 | 304 | 305 | class Time(BaseModel): 306 | """Time""" 307 | 308 | def __init__( 309 | self, 310 | patrimonio: float, 311 | valor_time: float, 312 | ultima_pontuacao: float, 313 | atletas: List[Atleta], 314 | info: TimeInfo, 315 | ) -> None: 316 | self.patrimonio = patrimonio 317 | self.valor_time = valor_time 318 | self.ultima_pontuacao = ultima_pontuacao 319 | self.atletas = atletas 320 | self.info = info 321 | self.pontos = None 322 | 323 | @classmethod 324 | def from_dict(cls, data: dict, clubes: Dict[int, Clube], capitao: int) -> "Time": 325 | data["atletas"].sort(key=lambda a: a["posicao_id"]) 326 | atletas = [ 327 | Atleta.from_dict(atleta, clubes, is_capitao=atleta["atleta_id"] == capitao) 328 | for atleta in data["atletas"] 329 | ] 330 | info = TimeInfo.from_dict(data["time"]) 331 | return cls( 332 | data["patrimonio"], data["valor_time"], data["pontos"], atletas, info 333 | ) 334 | -------------------------------------------------------------------------------- /cartolafc/util.py: -------------------------------------------------------------------------------- 1 | import datetime 2 | import json 3 | import logging 4 | from typing import Any 5 | 6 | from .errors import CartolaFCError, CartolaFCGameOverError, CartolaFCOverloadError 7 | 8 | 9 | def json_default(value: Any) -> dict: 10 | if isinstance(value, datetime.datetime): 11 | return dict( 12 | year=value.year, 13 | month=value.month, 14 | day=value.day, 15 | hour=value.hour, 16 | minute=value.minute, 17 | second=value.second, 18 | microsecond=value.microsecond, 19 | tzinfo=value.tzinfo, 20 | ) 21 | return value.__dict__ 22 | 23 | 24 | def parse_and_check_cartolafc(json_data: str) -> dict: 25 | try: 26 | data = json.loads(json_data) 27 | if "game_over" in data and data["game_over"]: 28 | logging.info( 29 | "Desculpe-nos, o jogo acabou e não podemos obter os dados solicitados" 30 | ) 31 | raise CartolaFCGameOverError( 32 | "Desculpe-nos, o jogo acabou e não podemos obter os dados solicitados" 33 | ) 34 | if "mensagem" in data and data["mensagem"]: 35 | logging.error(data["mensagem"]) 36 | raise CartolaFCError(data["mensagem"].encode("utf-8")) 37 | return data 38 | except ValueError as error: 39 | logging.error("Error parsing and checking json data: %s", json_data) 40 | logging.error(error) 41 | raise CartolaFCOverloadError( 42 | "Globo.com - Desculpe-nos, nossos servidores estão sobrecarregados." 43 | ) 44 | -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | # VirtualEnv dir 2 | .venv/ 3 | -------------------------------------------------------------------------------- /examples/examples.py: -------------------------------------------------------------------------------- 1 | import cartolafc 2 | 3 | api = cartolafc.Api(attempts=5) 4 | 5 | print(api.clubes()) 6 | print(api.ligas(query="Teste")) 7 | print(api.patrocinadores()) 8 | print(api.mercado()) 9 | print(api.mercado_atletas()) 10 | print(api.parciais()) 11 | print(api.partidas(1)) 12 | print(api.pos_rodada_destaques()) 13 | print(api.time(time_id=471815)) 14 | print(api.time_parcial(time_id=471815)) 15 | print(api.times(query="Falydos FC")) 16 | -------------------------------------------------------------------------------- /examples/requirements.txt: -------------------------------------------------------------------------------- 1 | Python-CartolaFC 2 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools>=61.0"] 3 | build-backend = "setuptools.build_meta" 4 | 5 | [project] 6 | name = "Python-CartolaFC" 7 | version = "3.2.0" 8 | authors = [ 9 | { name="Vicente Ramos", email="sneto.vicente@gmail.com" }, 10 | ] 11 | description = "Uma interface em Python para a API Rest do Cartola FC" 12 | readme = "README.md" 13 | dependencies = ["requests"] 14 | requires-python = ">=3.7" 15 | keywords = ["python", "cartolafc", "api"] 16 | classifiers = [ 17 | "Development Status :: 5 - Production/Stable", 18 | "Intended Audience :: Developers", 19 | "License :: OSI Approved :: MIT License", 20 | "Operating System :: OS Independent", 21 | "Programming Language :: Python :: 3", 22 | "Topic :: Software Development :: Libraries :: Python Modules", 23 | ] 24 | 25 | [project.urls] 26 | "Homepage" = "https://github.com/vicenteneto/python-cartolafc" 27 | "Bug Tracker" = "https://github.com/vicenteneto/python-cartolafc/issues" 28 | -------------------------------------------------------------------------------- /requirements/common.txt: -------------------------------------------------------------------------------- 1 | requests==2.28.2 2 | -------------------------------------------------------------------------------- /requirements/development.txt: -------------------------------------------------------------------------------- 1 | -r common.txt 2 | black==23.1.0 3 | coverage==7.2.2 4 | pytest==7.2.2 5 | requests_mock==1.10.0 6 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vicenteneto/python-cartolafc/fe0715b2e816aed4500153db60d2d5d9667fc8ad/tests/__init__.py -------------------------------------------------------------------------------- /tests/test_api.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from datetime import datetime 3 | 4 | import requests_mock 5 | from requests.status_codes import codes 6 | 7 | import cartolafc 8 | from cartolafc.constants import MERCADO_ABERTO 9 | from cartolafc.models import ( 10 | Atleta, 11 | AtletaDestaque, 12 | Clube, 13 | DestaqueRodada, 14 | Liga, 15 | Patrocinador, 16 | Mercado, 17 | Partida, 18 | ) 19 | from cartolafc.models import Time, TimeInfo 20 | from cartolafc.models import _atleta_status, _posicoes 21 | 22 | 23 | class ApiAttemptsTest(unittest.TestCase): 24 | def test_api_attempts_menor_que_1(self): 25 | # Arrange and Act 26 | api = cartolafc.Api(attempts=0) 27 | 28 | # Assert 29 | self.assertEqual(api._attempts, 1) 30 | 31 | def test_api_attempts_com_erros(self): 32 | # Arrange and Act 33 | with requests_mock.mock() as m: 34 | api = cartolafc.Api(attempts=2) 35 | 36 | url = f"{api._api_url}/mercado/status" 37 | error_message = "Mensagem de erro" 38 | m.get(url, status_code=codes.ok, text='{"mensagem": "%s"}' % error_message) 39 | 40 | with self.assertRaisesRegex(cartolafc.CartolaFCError, error_message): 41 | api.mercado() 42 | 43 | def test_api_attempts_com_servidores_sobrecarregados(self): 44 | # Arrange and Act 45 | with requests_mock.mock() as m: 46 | api = cartolafc.Api(attempts=2) 47 | 48 | url = f"{api._api_url}/mercado/status" 49 | error_message = ( 50 | "Globo.com - Desculpe-nos, nossos servidores estão sobrecarregados." 51 | ) 52 | m.get( 53 | url, 54 | response_list=[ 55 | dict( 56 | status_code=codes.ok, text='{"mensagem": "%s"}}' % error_message 57 | ), 58 | dict( 59 | status_code=codes.ok, text='{"mensagem": "%s"}}' % error_message 60 | ), 61 | ], 62 | ) 63 | 64 | with self.assertRaisesRegex(cartolafc.CartolaFCError, error_message): 65 | api.mercado() 66 | 67 | 68 | class ApiTest(unittest.TestCase): 69 | with open("tests/testdata/clubes.json", "rb") as f: 70 | CLUBES = f.read().decode("utf8") 71 | with open("tests/testdata/ligas.json", "rb") as f: 72 | LIGAS = f.read().decode("utf8") 73 | with open("tests/testdata/patrocinadores.json", "rb") as f: 74 | PATROCINADORES = f.read().decode("utf8") 75 | with open("tests/testdata/mercado_atletas.json", "rb") as f: 76 | MERCADO_ATLETAS = f.read().decode("utf8") 77 | with open("tests/testdata/mercado_status_aberto.json", "rb") as f: 78 | MERCADO_STATUS_ABERTO = f.read().decode("utf8") 79 | with open("tests/testdata/mercado_status_fechado.json", "rb") as f: 80 | MERCADO_STATUS_FECHADO = f.read().decode("utf8") 81 | with open("tests/testdata/partidas.json", "rb") as f: 82 | PARTIDAS = f.read().decode("utf8") 83 | with open("tests/testdata/parciais.json", "rb") as f: 84 | PARCIAIS = f.read().decode("utf8") 85 | with open("tests/testdata/pos_rodada_destaques.json", "rb") as f: 86 | POS_RODADA_DESTAQUES = f.read().decode("utf8") 87 | with open("tests/testdata/time.json", "rb") as f: 88 | TIME = f.read().decode("utf8") 89 | with open("tests/testdata/times.json", "rb") as f: 90 | TIMES = f.read().decode("utf-8") 91 | with open("tests/testdata/game_over.json", "rb") as f: 92 | GAME_OVER = f.read().decode("utf-8") 93 | with open("tests/testdata/mercado_destaques.json", "rb") as f: 94 | DESTAQUES = f.read().decode("utf-8") 95 | with open("tests/testdata/mercado_destaques_reservas.json", "rb") as f: 96 | DESTAQUES_RESERVAS = f.read().decode("utf-8") 97 | 98 | def setUp(self): 99 | self.api = cartolafc.Api() 100 | self.api_url = self.api._api_url 101 | 102 | def test_clubes(self): 103 | # Arrange and Act 104 | with requests_mock.mock() as m: 105 | url = f"{self.api_url}/clubes" 106 | m.get(url, text=self.CLUBES) 107 | clubes = self.api.clubes() 108 | clube_flamengo = clubes[262] 109 | 110 | # Assert 111 | self.assertIsInstance(clubes, dict) 112 | self.assertIsInstance(clube_flamengo, Clube) 113 | self.assertEqual(clube_flamengo.id, 262) 114 | self.assertEqual(clube_flamengo.nome, "Flamengo") 115 | self.assertEqual(clube_flamengo.abreviacao, "FLA") 116 | 117 | def test_ligas(self): 118 | # Arrange and Act 119 | with requests_mock.mock() as m: 120 | url = f"{self.api_url}/ligas" 121 | m.get(url, text=self.LIGAS) 122 | ligas = self.api.ligas(query="premiere") 123 | primeira_liga = ligas[0] 124 | 125 | # Assert 126 | self.assertIsInstance(ligas, list) 127 | self.assertIsInstance(primeira_liga, Liga) 128 | self.assertEqual(primeira_liga.id, 2362309) 129 | self.assertEqual(primeira_liga.nome, "Time Cartola Oficial") 130 | self.assertEqual(primeira_liga.slug, "time-cartola-oficial") 131 | self.assertEqual(primeira_liga.descricao, "Valendo um card no board") 132 | self.assertIsNone(primeira_liga.times) 133 | 134 | def test_mercado(self): 135 | # Arrange and Act 136 | with requests_mock.mock() as m: 137 | url = f"{self.api_url}/mercado/status" 138 | m.get(url, text=self.MERCADO_STATUS_ABERTO) 139 | status = self.api.mercado() 140 | 141 | # Assert 142 | fechamento = datetime(2023, 4, 15, 23, 59) 143 | 144 | self.assertIsInstance(status, Mercado) 145 | self.assertEqual(status.rodada_atual, 3) 146 | self.assertEqual(status.status.id, MERCADO_ABERTO) 147 | self.assertEqual(status.times_escalados, 3601523) 148 | self.assertIsInstance(status.fechamento, datetime) 149 | self.assertEqual(status.fechamento, fechamento) 150 | 151 | def test_mercado_atletas(self): 152 | # Arrange and Act 153 | with requests_mock.mock() as m: 154 | url = f"{self.api_url}/atletas/mercado" 155 | m.get(url, text=self.MERCADO_ATLETAS) 156 | mercado = self.api.mercado_atletas() 157 | primeiro_atleta = mercado[0] 158 | 159 | # Assert 160 | self.assertIsInstance(mercado, list) 161 | self.assertIsInstance(primeiro_atleta, Atleta) 162 | self.assertEqual(primeiro_atleta.id, 63013) 163 | self.assertEqual(primeiro_atleta.apelido, "Marcos Rocha") 164 | self.assertEqual(primeiro_atleta.pontos, 0) 165 | self.assertEqual( 166 | # TODO: Teste com scouts 167 | primeiro_atleta.scout, 168 | {}, 169 | ) 170 | self.assertEqual(primeiro_atleta.posicao, _posicoes[2]) 171 | self.assertIsInstance(primeiro_atleta.clube, Clube) 172 | self.assertEqual(primeiro_atleta.clube.id, 275) 173 | self.assertEqual(primeiro_atleta.clube.nome, "Palmeiras") 174 | self.assertEqual(primeiro_atleta.clube.abreviacao, "PAL") 175 | self.assertEqual(primeiro_atleta.status, _atleta_status[7]) 176 | 177 | def test_parciais_mercado_aberto(self): 178 | # Arrange 179 | with requests_mock.mock() as m: 180 | url = f"{self.api_url}/mercado/status" 181 | m.get(url, text=self.MERCADO_STATUS_ABERTO) 182 | 183 | # Act and Assert 184 | with self.assertRaisesRegex( 185 | cartolafc.CartolaFCError, 186 | "As pontuações parciais só ficam disponíveis com o mercado fechado.", 187 | ): 188 | self.api.parciais() 189 | 190 | def test_parciais_mercado_fechado(self): 191 | # Arrange 192 | with requests_mock.mock() as m: 193 | url = f"{self.api_url}/mercado/status" 194 | m.get(url, text=self.MERCADO_STATUS_FECHADO) 195 | 196 | url = f"{self.api_url}/atletas/pontuados" 197 | m.get(url, text=self.PARCIAIS) 198 | 199 | # Act 200 | parciais = self.api.parciais() 201 | parcial_juan = parciais[36540] 202 | 203 | # Assert 204 | self.assertIsInstance(parciais, dict) 205 | self.assertIsInstance(parcial_juan, Atleta) 206 | self.assertEqual(parcial_juan.id, 36540) 207 | self.assertEqual(parcial_juan.apelido, "Juan") 208 | self.assertEqual(parcial_juan.pontos, 2.9) 209 | self.assertEqual( 210 | parcial_juan.scout, {"CA": 1, "FC": 1, "FS": 2, "PE": 2, "SG": 1} 211 | ) 212 | self.assertEqual(parcial_juan.posicao, _posicoes[3]) 213 | self.assertIsInstance(parcial_juan.clube, Clube) 214 | self.assertEqual(parcial_juan.clube.id, 262) 215 | self.assertEqual(parcial_juan.clube.nome, "Flamengo") 216 | self.assertEqual(parcial_juan.clube.abreviacao, "FLA") 217 | 218 | def test_partidas(self): 219 | # Arrange and Act 220 | with requests_mock.mock() as m: 221 | url = f"{self.api_url}/partidas" 222 | m.get(url, text=self.PARTIDAS) 223 | partidas = self.api.partidas() 224 | primeira_partida = partidas[0] 225 | 226 | # Assert 227 | self.assertIsInstance(partidas, list) 228 | self.assertIsInstance(primeira_partida, Partida) 229 | self.assertIsInstance(primeira_partida.data, datetime) 230 | # TODO: Teste partidas com local e placar 231 | # self.assertEqual(primeira_partida.local, "Maracanã") 232 | self.assertEqual(primeira_partida.clube_casa.nome, "Flamengo") 233 | # self.assertEqual(primeira_partida.placar_casa, 1) 234 | self.assertEqual(primeira_partida.clube_visitante.nome, "Coritiba") 235 | # self.assertEqual(primeira_partida.placar_visitante, 1) 236 | 237 | def test_partidas_com_rodada(self): 238 | # Arrange and Act 239 | with requests_mock.mock() as m: 240 | url = f"{self.api_url}/partidas/1" 241 | m.get(url, text=self.PARTIDAS) 242 | partidas = self.api.partidas(1) 243 | primeira_partida = partidas[0] 244 | 245 | # Assert 246 | self.assertIsInstance(partidas, list) 247 | self.assertIsInstance(primeira_partida, Partida) 248 | self.assertIsInstance(primeira_partida.data, datetime) 249 | # TODO: Teste partidas com local e placar 250 | # self.assertEqual(primeira_partida.local, "Maracanã") 251 | self.assertEqual(primeira_partida.clube_casa.nome, "Flamengo") 252 | # self.assertEqual(primeira_partida.placar_casa, 1) 253 | self.assertEqual(primeira_partida.clube_visitante.nome, "Coritiba") 254 | # self.assertEqual(primeira_partida.placar_visitante, 1) 255 | 256 | def test_patrocinadores(self): 257 | # Arrange and Act 258 | with requests_mock.mock() as m: 259 | url = f"{self.api_url}/patrocinadores" 260 | m.get(url, text=self.PATROCINADORES) 261 | ligas = self.api.patrocinadores() 262 | liga_gato_mestre = ligas[62] 263 | 264 | # Assert 265 | self.assertIsInstance(ligas, dict) 266 | self.assertIsInstance(liga_gato_mestre, Patrocinador) 267 | self.assertEqual(liga_gato_mestre.id, 62) 268 | self.assertEqual(liga_gato_mestre.nome, "Liga Gato Mestre") 269 | self.assertEqual( 270 | liga_gato_mestre.url_link, "https://gatomestre.ge.globo.com/" 271 | ) 272 | 273 | def test_pos_rodada_destaques_com_mercado_aberto(self): 274 | # Arrange and Act 275 | with requests_mock.mock() as m: 276 | url = f"{self.api_url}/mercado/status" 277 | m.get(url, text=self.MERCADO_STATUS_ABERTO) 278 | 279 | url = f"{self.api_url}/pos-rodada/destaques" 280 | m.get(url, text=self.POS_RODADA_DESTAQUES) 281 | destaque_rodada = self.api.pos_rodada_destaques() 282 | 283 | # Assert 284 | self.assertIsInstance(destaque_rodada, DestaqueRodada) 285 | self.assertEqual(destaque_rodada.media_cartoletas, 115.8235753058391) 286 | self.assertEqual(destaque_rodada.media_pontos, 46.6480728839843) 287 | self.assertIsInstance(destaque_rodada.mito_rodada, TimeInfo) 288 | self.assertEqual(destaque_rodada.mito_rodada.id, 896224) 289 | self.assertEqual(destaque_rodada.mito_rodada.nome, "gama campos fc") 290 | self.assertEqual(destaque_rodada.mito_rodada.nome_cartola, "malmal") 291 | self.assertEqual(destaque_rodada.mito_rodada.slug, "gama-campos-fc") 292 | self.assertFalse(destaque_rodada.mito_rodada.assinante) 293 | 294 | def test_pos_rodada_destaques_com_mercado_fechado(self): 295 | # Arrange 296 | with requests_mock.mock() as m: 297 | url = f"{self.api_url}/mercado/status" 298 | m.get(url, text=self.MERCADO_STATUS_FECHADO) 299 | 300 | # Act and Assert 301 | with self.assertRaisesRegex(cartolafc.CartolaFCError, ""): 302 | self.api.pos_rodada_destaques() 303 | 304 | def test_time_com_id(self): 305 | # Arrange and Act 306 | with requests_mock.mock() as m: 307 | time_url = f"{self.api_url}/time/id/471815" 308 | clubes_url = f"{self.api_url}/clubes" 309 | 310 | m.get(time_url, text=self.TIME) 311 | m.get(clubes_url, text=self.CLUBES) 312 | 313 | time = self.api.time(time_id=471815) 314 | primeiro_atleta = time.atletas[0] if len(time.atletas) else None 315 | 316 | # Assert 317 | self.assertIsInstance(time, Time) 318 | self.assertEqual(time.patrimonio, 100) 319 | self.assertEqual(time.valor_time, 0) 320 | # TODO: Revisar depois que a primeira rodada fechar 321 | # self.assertEqual(time.ultima_pontuacao, 70.02978515625) 322 | self.assertIsInstance(time.atletas, list) 323 | 324 | # TODO: Revisar depois que a primeira rodada fechar 325 | if primeiro_atleta: 326 | self.assertIsInstance(primeiro_atleta, Atleta) 327 | self.assertEqual(primeiro_atleta.id, 38140) 328 | self.assertEqual(primeiro_atleta.apelido, "Fernando Prass") 329 | self.assertEqual(primeiro_atleta.pontos, 7.5) 330 | self.assertEqual(primeiro_atleta.scout, {"DD": 3, "FS": 1, "GS": 1}) 331 | self.assertEqual(primeiro_atleta.posicao, _posicoes[1]) 332 | self.assertIsInstance(primeiro_atleta.clube, Clube) 333 | self.assertEqual(primeiro_atleta.clube.id, 275) 334 | self.assertEqual(primeiro_atleta.clube.nome, "Palmeiras") 335 | self.assertEqual(primeiro_atleta.clube.abreviacao, "PAL") 336 | self.assertEqual(primeiro_atleta.status, _atleta_status[7]) 337 | 338 | self.assertIsInstance(time.info, TimeInfo) 339 | self.assertEqual(time.info.id, 471815) 340 | self.assertEqual(time.info.nome, "Falydos FC") 341 | self.assertEqual(time.info.nome_cartola, "Vicente Neto") 342 | self.assertEqual(time.info.slug, "falydos-fc") 343 | self.assertTrue(time.info.assinante) 344 | 345 | def test_time_parcial_mercado_aberto(self): 346 | # Arrange 347 | with requests_mock.mock() as m: 348 | url = f"{self.api_url}/mercado/status" 349 | m.get(url, text=self.MERCADO_STATUS_ABERTO) 350 | 351 | # Act and Assert 352 | with self.assertRaisesRegex( 353 | cartolafc.CartolaFCError, 354 | "As pontuações parciais só ficam disponíveis com o mercado fechado.", 355 | ): 356 | self.api.time_parcial(471815) 357 | 358 | def test_time_parcial_mercado_fechado(self): 359 | # Arrange 360 | with requests_mock.mock() as m: 361 | mercado_url = f"{self.api_url}/mercado/status" 362 | parciais_url = f"{self.api_url}/atletas/pontuados" 363 | time_url = f"{self.api_url}/time/id/471815" 364 | clubes_url = f"{self.api_url}/clubes" 365 | 366 | m.get(mercado_url, text=self.MERCADO_STATUS_FECHADO) 367 | m.get(parciais_url, text=self.PARCIAIS) 368 | m.get(time_url, text=self.TIME) 369 | m.get(clubes_url, text=self.CLUBES) 370 | 371 | time = self.api.time_parcial(471815) 372 | primeiro_atleta = time.atletas[0] if len(time.atletas) else None 373 | 374 | # Assert 375 | self.assertIsInstance(time, Time) 376 | self.assertEqual(time.patrimonio, 100) 377 | self.assertEqual(time.valor_time, 0) 378 | # TODO: Revisar depois que a primeira rodada fechar 379 | # self.assertEqual(time.ultima_pontuacao, 70.02978515625) 380 | # self.assertEqual(time.pontos, 13.299999999999999) 381 | self.assertIsInstance(time.atletas, list) 382 | 383 | # TODO: Revisar depois que a primeira rodada fechar 384 | if primeiro_atleta: 385 | self.assertIsInstance(primeiro_atleta, Atleta) 386 | self.assertEqual(primeiro_atleta.id, 38140) 387 | self.assertEqual(primeiro_atleta.apelido, "Fernando Prass") 388 | self.assertEqual(primeiro_atleta.pontos, 0) 389 | self.assertEqual(primeiro_atleta.scout, {}) 390 | self.assertEqual(primeiro_atleta.posicao, _posicoes[1]) 391 | self.assertIsInstance(primeiro_atleta.clube, Clube) 392 | self.assertEqual(primeiro_atleta.clube.id, 275) 393 | self.assertEqual(primeiro_atleta.clube.nome, "Palmeiras") 394 | self.assertEqual(primeiro_atleta.clube.abreviacao, "PAL") 395 | self.assertEqual(primeiro_atleta.status, _atleta_status[7]) 396 | 397 | self.assertIsInstance(time.info, TimeInfo) 398 | self.assertEqual(time.info.id, 471815) 399 | self.assertEqual(time.info.nome, "Falydos FC") 400 | self.assertEqual(time.info.nome_cartola, "Vicente Neto") 401 | self.assertEqual(time.info.slug, "falydos-fc") 402 | self.assertTrue(time.info.assinante) 403 | 404 | def test_time_parcial_key_invalida(self): 405 | # Arrange 406 | with requests_mock.mock() as m: 407 | error_message = "Time ou parciais não são válidos." 408 | time_url = f"{self.api_url}/time/id/471815" 409 | clubes_url = f"{self.api_url}/clubes" 410 | 411 | m.get(time_url, text=self.TIME) 412 | m.get(clubes_url, text=self.CLUBES) 413 | 414 | with self.assertRaisesRegex(cartolafc.CartolaFCError, error_message): 415 | self.api.time_parcial(time_id=471815, parciais=dict(key="valor")) 416 | 417 | def test_time_parcial_valor_invalido(self): 418 | # Arrange 419 | with requests_mock.mock() as m: 420 | error_message = "Time ou parciais não são válidos." 421 | time_url = f"{self.api_url}/time/id/471815" 422 | clubes_url = f"{self.api_url}/clubes" 423 | 424 | m.get(time_url, text=self.TIME) 425 | m.get(clubes_url, text=self.CLUBES) 426 | 427 | with self.assertRaisesRegex(cartolafc.CartolaFCError, error_message): 428 | self.api.time_parcial(time_id=471815, parciais={1: "valor"}) 429 | 430 | def test_times(self): 431 | # Arrange and Act 432 | with requests_mock.mock() as m: 433 | url = f"{self.api_url}/times" 434 | m.get(url, text=self.TIMES) 435 | times = self.api.times(query="Faly") 436 | primeiro_time = times[0] 437 | 438 | # Assert 439 | self.assertIsInstance(times, list) 440 | self.assertIsInstance(primeiro_time, TimeInfo) 441 | self.assertEqual(primeiro_time.id, 471815) 442 | self.assertEqual(primeiro_time.nome, "Falydos FC") 443 | self.assertEqual(primeiro_time.nome_cartola, "Vicente Neto") 444 | self.assertEqual(primeiro_time.slug, "falydos-fc") 445 | self.assertTrue(primeiro_time.assinante) 446 | 447 | def test_servidores_sobrecarregados(self): 448 | # Arrange 449 | with requests_mock.mock() as m: 450 | url = f"{self.api_url}/mercado/status" 451 | m.get(url) 452 | 453 | # Act and Assert 454 | with self.assertRaises(cartolafc.CartolaFCOverloadError): 455 | self.api.mercado() 456 | 457 | def test_game_over(self): 458 | # Arrange 459 | with requests_mock.mock() as m: 460 | url = f"{self.api_url}/mercado/status" 461 | m.get(url, text=self.GAME_OVER) 462 | 463 | # Act and Assert 464 | with self.assertRaises(cartolafc.CartolaFCGameOverError): 465 | self.api.mercado() 466 | 467 | def test_destaques(self): 468 | # Arrange and Act 469 | with requests_mock.mock() as m: 470 | url = f"{self.api_url}/mercado/destaques" 471 | m.get(url, text=self.DESTAQUES) 472 | destaques = self.api.destaques() 473 | primeiro_destaque = destaques[0] 474 | 475 | # Assert 476 | self.assertIsInstance(destaques, list) 477 | self.assertIsInstance(primeiro_destaque, AtletaDestaque) 478 | self.assertEqual(primeiro_destaque.id, 63013) 479 | self.assertEqual(primeiro_destaque.apelido, "Marcos Rocha") 480 | print(primeiro_destaque) 481 | self.assertEqual(primeiro_destaque.posicao.nome, "Lateral") 482 | self.assertEqual(primeiro_destaque.preco, 5) 483 | self.assertEqual(primeiro_destaque.clube.nome, "Palmeiras") 484 | self.assertEqual(primeiro_destaque.escalacoes, 118020) 485 | 486 | def test_destaques_reservas(self): 487 | # Arrange and Act 488 | with requests_mock.mock() as m: 489 | url = f"{self.api_url}/mercado/destaques/reservas" 490 | m.get(url, text=self.DESTAQUES_RESERVAS) 491 | destaques = self.api.destaques_reservas() 492 | primeiro_destaque = destaques[0] 493 | 494 | # Assert 495 | self.assertIsInstance(destaques, list) 496 | self.assertIsInstance(primeiro_destaque, AtletaDestaque) 497 | self.assertEqual(primeiro_destaque.id, 70449) 498 | self.assertEqual(primeiro_destaque.apelido, "Gabriel") 499 | self.assertEqual(primeiro_destaque.posicao.nome, "Goleiro") 500 | self.assertEqual(primeiro_destaque.preco, 5) 501 | self.assertEqual(primeiro_destaque.clube.nome, "Coritiba") 502 | self.assertEqual(primeiro_destaque.escalacoes, 62746) 503 | -------------------------------------------------------------------------------- /tests/test_utils.py: -------------------------------------------------------------------------------- 1 | import json 2 | import unittest 3 | from datetime import datetime 4 | 5 | from cartolafc.models import Mercado 6 | from cartolafc.util import json_default 7 | 8 | 9 | class ApiAttemptsTest(unittest.TestCase): 10 | with open("tests/testdata/mercado_status_aberto.json", "rb") as f: 11 | MERCADO = f.read().decode("utf8") 12 | 13 | def test_json_default_datetime(self): 14 | date = datetime( 15 | year=2019, 16 | month=10, 17 | day=10, 18 | hour=0, 19 | minute=0, 20 | second=0, 21 | microsecond=0, 22 | ) 23 | result = json_default(date) 24 | assert isinstance(result, dict) 25 | 26 | def test_json_default_cartolafc_model(self): 27 | mercado = Mercado.from_dict(json.loads(self.MERCADO)) 28 | result = json_default(mercado) 29 | assert isinstance(result, dict) 30 | -------------------------------------------------------------------------------- /tests/testdata/clubes.json: -------------------------------------------------------------------------------- 1 | { 2 | "1": { 3 | "id": 1, 4 | "nome": "Outros", 5 | "abreviacao": "OUT", 6 | "escudos": { 7 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 8 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 9 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 10 | }, 11 | "nome_fantasia": "Outros" 12 | }, 13 | "1349": { 14 | "id": 1349, 15 | "nome": "Ipatinga", 16 | "abreviacao": "IPA", 17 | "escudos": { 18 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 19 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 20 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 21 | }, 22 | "nome_fantasia": "Ipatinga" 23 | }, 24 | "1371": { 25 | "id": 1371, 26 | "nome": "Cuiabá", 27 | "abreviacao": "CUI", 28 | "escudos": { 29 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/16/cuiaba65.png", 30 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/16/cuiaba45.png", 31 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/16/cuiaba30_.png" 32 | }, 33 | "nome_fantasia": "Cuiabá" 34 | }, 35 | "1390": { 36 | "id": 1390, 37 | "nome": "Icasa", 38 | "abreviacao": "ICA", 39 | "escudos": { 40 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 41 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 42 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 43 | }, 44 | "nome_fantasia": "Icasa" 45 | }, 46 | "2190": { 47 | "id": 2190, 48 | "nome": "Oeste", 49 | "abreviacao": "OES", 50 | "escudos": { 51 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 52 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 53 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 54 | }, 55 | "nome_fantasia": "Oeste" 56 | }, 57 | "2193": { 58 | "id": 2193, 59 | "nome": "Duque de Caxias", 60 | "abreviacao": "DUQ", 61 | "escudos": { 62 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 63 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 64 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 65 | }, 66 | "nome_fantasia": "Duque de Caxias" 67 | }, 68 | "2197": { 69 | "id": 2197, 70 | "nome": "Americana", 71 | "abreviacao": "AME", 72 | "escudos": { 73 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 74 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 75 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 76 | }, 77 | "nome_fantasia": "Americana" 78 | }, 79 | "2554": { 80 | "id": 2554, 81 | "nome": "Grêmio Prudente", 82 | "abreviacao": "PRU", 83 | "escudos": { 84 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 85 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 86 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 87 | }, 88 | "nome_fantasia": "Grêmio Prudente" 89 | }, 90 | "2565": { 91 | "id": 2565, 92 | "nome": "Luverdense", 93 | "abreviacao": "LUV", 94 | "escudos": { 95 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 96 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 97 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 98 | }, 99 | "nome_fantasia": "Luverdense" 100 | }, 101 | "262": { 102 | "id": 262, 103 | "nome": "Flamengo", 104 | "abreviacao": "FLA", 105 | "escudos": { 106 | "60x60": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-65.png", 107 | "45x45": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-45.png", 108 | "30x30": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-30.png" 109 | }, 110 | "nome_fantasia": "Flamengo" 111 | }, 112 | "263": { 113 | "id": 263, 114 | "nome": "Botafogo", 115 | "abreviacao": "BOT", 116 | "escudos": { 117 | "60x60": "https://s.sde.globo.com/media/organizations/2019/02/04/botafogo-65.png", 118 | "45x45": "https://s.sde.globo.com/media/organizations/2019/02/04/botafogo-45.png", 119 | "30x30": "https://s.sde.globo.com/media/organizations/2019/02/04/botafogo-30.png" 120 | }, 121 | "nome_fantasia": "Botafogo" 122 | }, 123 | "264": { 124 | "id": 264, 125 | "nome": "Corinthians", 126 | "abreviacao": "COR", 127 | "escudos": { 128 | "60x60": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_65.png", 129 | "45x45": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_45.png", 130 | "30x30": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_30.png" 131 | }, 132 | "nome_fantasia": "Corinthians" 133 | }, 134 | "265": { 135 | "id": 265, 136 | "nome": "Bahia", 137 | "abreviacao": "BAH", 138 | "escudos": { 139 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/bahia_60x60.png", 140 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/bahia_45x45.png", 141 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/bahia_30x30.png" 142 | }, 143 | "nome_fantasia": "Bahia" 144 | }, 145 | "266": { 146 | "id": 266, 147 | "nome": "Fluminense", 148 | "abreviacao": "FLU", 149 | "escudos": { 150 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/fluminense_60x60.png", 151 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/fluminense_45x45.png", 152 | "30x30": "https://s.sde.globo.com/media/organizations/2015/01/12/Fluminense-escudo.png" 153 | }, 154 | "nome_fantasia": "Fluminense" 155 | }, 156 | "267": { 157 | "id": 267, 158 | "nome": "Vasco", 159 | "abreviacao": "VAS", 160 | "escudos": { 161 | "60x60": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_65px.png", 162 | "45x45": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_45px.png", 163 | "30x30": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_30px.png" 164 | }, 165 | "nome_fantasia": "Vasco" 166 | }, 167 | "275": { 168 | "id": 275, 169 | "nome": "Palmeiras", 170 | "abreviacao": "PAL", 171 | "escudos": { 172 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_60x60.png", 173 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_45x45.png", 174 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_30x30.png" 175 | }, 176 | "nome_fantasia": "Palmeiras" 177 | }, 178 | "276": { 179 | "id": 276, 180 | "nome": "São Paulo", 181 | "abreviacao": "SAO", 182 | "escudos": { 183 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/sao_paulo_60x60.png", 184 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/sao_paulo_45x45.png", 185 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/sao_paulo_30x30.png" 186 | }, 187 | "nome_fantasia": "São Paulo" 188 | }, 189 | "277": { 190 | "id": 277, 191 | "nome": "Santos", 192 | "abreviacao": "SAN", 193 | "escudos": { 194 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/santos_60x60.png", 195 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/santos_45x45.png", 196 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/santos_30x30.png" 197 | }, 198 | "nome_fantasia": "Santos" 199 | }, 200 | "278": { 201 | "id": 278, 202 | "nome": "Portuguesa", 203 | "abreviacao": "POR", 204 | "escudos": { 205 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 206 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 207 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 208 | }, 209 | "nome_fantasia": "Portuguesa" 210 | }, 211 | "279": { 212 | "id": 279, 213 | "nome": "Guarani", 214 | "abreviacao": "GUA", 215 | "escudos": { 216 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 217 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 218 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 219 | }, 220 | "nome_fantasia": "Guarani" 221 | }, 222 | "280": { 223 | "id": 280, 224 | "nome": "Bragantino", 225 | "abreviacao": "BGT", 226 | "escudos": { 227 | "60x60": "https://s.sde.globo.com/media/organizations/2020/01/01/65.png", 228 | "45x45": "https://s.sde.globo.com/media/organizations/2020/01/01/45.png", 229 | "30x30": "https://s.sde.globo.com/media/organizations/2020/01/01/30.png" 230 | }, 231 | "nome_fantasia": "Bragantino" 232 | }, 233 | "282": { 234 | "id": 282, 235 | "nome": "Atlético-MG", 236 | "abreviacao": "CAM", 237 | "escudos": { 238 | "60x60": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo65px.png", 239 | "45x45": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo45px.png", 240 | "30x30": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo30px.png" 241 | }, 242 | "nome_fantasia": "Atlético-MG" 243 | }, 244 | "283": { 245 | "id": 283, 246 | "nome": "Cruzeiro", 247 | "abreviacao": "CRU", 248 | "escudos": { 249 | "60x60": "https://s.sde.globo.com/media/organizations/2021/02/13/65_cruzeiro-2021.png", 250 | "45x45": "https://s.sde.globo.com/media/organizations/2021/02/13/45_cruzeiro-2021.png", 251 | "30x30": "https://s.sde.globo.com/media/organizations/2021/02/13/30_cruzeiro-2021.png" 252 | }, 253 | "nome_fantasia": "Cruzeiro" 254 | }, 255 | "284": { 256 | "id": 284, 257 | "nome": "Grêmio", 258 | "abreviacao": "GRE", 259 | "escudos": { 260 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_60x60.png", 261 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_45x45.png", 262 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_30x30.png" 263 | }, 264 | "nome_fantasia": "Grêmio" 265 | }, 266 | "285": { 267 | "id": 285, 268 | "nome": "Internacional", 269 | "abreviacao": "INT", 270 | "escudos": { 271 | "60x60": "https://s.sde.globo.com/media/organizations/2016/05/03/inter65.png", 272 | "45x45": "https://s.sde.globo.com/media/organizations/2016/05/03/inter45.png", 273 | "30x30": "https://s.sde.globo.com/media/organizations/2016/05/03/inter30.png" 274 | }, 275 | "nome_fantasia": "Internacional" 276 | }, 277 | "286": { 278 | "id": 286, 279 | "nome": "Juventude", 280 | "abreviacao": "JUV", 281 | "escudos": { 282 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 283 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 284 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 285 | }, 286 | "nome_fantasia": "Juventude" 287 | }, 288 | "287": { 289 | "id": 287, 290 | "nome": "Vitória", 291 | "abreviacao": "VIT", 292 | "escudos": { 293 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 294 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 295 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 296 | }, 297 | "nome_fantasia": "Vitória" 298 | }, 299 | "288": { 300 | "id": 288, 301 | "nome": "Criciúma", 302 | "abreviacao": "CRI", 303 | "escudos": { 304 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 305 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 306 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 307 | }, 308 | "nome_fantasia": "Criciúma" 309 | }, 310 | "289": { 311 | "id": 289, 312 | "nome": "Paraná", 313 | "abreviacao": "PAR", 314 | "escudos": { 315 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 316 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 317 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 318 | }, 319 | "nome_fantasia": "Paraná" 320 | }, 321 | "290": { 322 | "id": 290, 323 | "nome": "Goiás", 324 | "abreviacao": "GOI", 325 | "escudos": { 326 | "60x60": "https://s.sde.globo.com/media/organizations/2021/03/01/goias-65.png", 327 | "45x45": "https://s.sde.globo.com/media/organizations/2021/03/01/goias-45.png", 328 | "30x30": "https://s.sde.globo.com/media/organizations/2021/03/01/goias-30.png" 329 | }, 330 | "nome_fantasia": "Goiás" 331 | }, 332 | "291": { 333 | "id": 291, 334 | "nome": "Paysandu", 335 | "abreviacao": "PAY", 336 | "escudos": { 337 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 338 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 339 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 340 | }, 341 | "nome_fantasia": "Paysandu" 342 | }, 343 | "292": { 344 | "id": 292, 345 | "nome": "Sport", 346 | "abreviacao": "SPT", 347 | "escudos": { 348 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 349 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 350 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 351 | }, 352 | "nome_fantasia": "Sport" 353 | }, 354 | "293": { 355 | "id": 293, 356 | "nome": "Athlético-PR", 357 | "abreviacao": "CAP", 358 | "escudos": { 359 | "60x60": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-65x65.png", 360 | "45x45": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-45x45.png", 361 | "30x30": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-30x30.png" 362 | }, 363 | "nome_fantasia": "Athlético-PR" 364 | }, 365 | "294": { 366 | "id": 294, 367 | "nome": "Coritiba", 368 | "abreviacao": "CFC", 369 | "escudos": { 370 | "60x60": "https://s.sde.globo.com/media/organizations/2017/03/29/coritiba65.png", 371 | "45x45": "https://s.sde.globo.com/media/organizations/2017/03/29/coritiba45.png", 372 | "30x30": "https://s.sde.globo.com/media/organizations/2017/03/29/coritiba30.png" 373 | }, 374 | "nome_fantasia": "Coritiba" 375 | }, 376 | "296": { 377 | "id": 296, 378 | "nome": "Botafogo-SP", 379 | "abreviacao": "BOT", 380 | "escudos": { 381 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 382 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 383 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 384 | }, 385 | "nome_fantasia": "Botafogo-SP" 386 | }, 387 | "303": { 388 | "id": 303, 389 | "nome": "Ponte Preta", 390 | "abreviacao": "PON", 391 | "escudos": { 392 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 393 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 394 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 395 | }, 396 | "nome_fantasia": "Ponte Preta" 397 | }, 398 | "3057": { 399 | "id": 3057, 400 | "nome": "Boa Esporte", 401 | "abreviacao": "BEC", 402 | "escudos": { 403 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 404 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 405 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 406 | }, 407 | "nome_fantasia": "Boa Esporte" 408 | }, 409 | "306": { 410 | "id": 306, 411 | "nome": "Santo André", 412 | "abreviacao": "SAN", 413 | "escudos": { 414 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 415 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 416 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 417 | }, 418 | "nome_fantasia": "Santo André" 419 | }, 420 | "307": { 421 | "id": 307, 422 | "nome": "São Bento", 423 | "abreviacao": "SBE", 424 | "escudos": { 425 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 426 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 427 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 428 | }, 429 | "nome_fantasia": "São Bento" 430 | }, 431 | "309": { 432 | "id": 309, 433 | "nome": "Brasil de Pelotas", 434 | "abreviacao": "BRA", 435 | "escudos": { 436 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 437 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 438 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 439 | }, 440 | "nome_fantasia": "Brasil de Pelotas" 441 | }, 442 | "314": { 443 | "id": 314, 444 | "nome": "Avaí", 445 | "abreviacao": "AVA", 446 | "escudos": { 447 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 448 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 449 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 450 | }, 451 | "nome_fantasia": "Avaí" 452 | }, 453 | "315": { 454 | "id": 315, 455 | "nome": "Chapecoense", 456 | "abreviacao": "CHA", 457 | "escudos": { 458 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 459 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 460 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 461 | }, 462 | "nome_fantasia": "Chapecoense" 463 | }, 464 | "316": { 465 | "id": 316, 466 | "nome": "Figueirense", 467 | "abreviacao": "FIG", 468 | "escudos": { 469 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 470 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 471 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 472 | }, 473 | "nome_fantasia": "Figueirense" 474 | }, 475 | "317": { 476 | "id": 317, 477 | "nome": "Joinville", 478 | "abreviacao": "JEC", 479 | "escudos": { 480 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 481 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 482 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 483 | }, 484 | "nome_fantasia": "Joinville" 485 | }, 486 | "319": { 487 | "id": 319, 488 | "nome": "Londrina", 489 | "abreviacao": "LON", 490 | "escudos": { 491 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 492 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 493 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 494 | }, 495 | "nome_fantasia": "Londrina" 496 | }, 497 | "321": { 498 | "id": 321, 499 | "nome": "Operário-PR", 500 | "abreviacao": "OPE", 501 | "escudos": { 502 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 503 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 504 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 505 | }, 506 | "nome_fantasia": "Operário-PR" 507 | }, 508 | "327": { 509 | "id": 327, 510 | "nome": "América-MG", 511 | "abreviacao": "AME", 512 | "escudos": { 513 | "60x60": "https://s.sde.globo.com/media/organizations/2019/02/28/escudo65_1.png", 514 | "45x45": "https://s.sde.globo.com/media/organizations/2019/02/28/escudo45_1.png", 515 | "30x30": "https://s.sde.globo.com/media/organizations/2019/02/28/escudo30.png" 516 | }, 517 | "nome_fantasia": "América-MG" 518 | }, 519 | "337": { 520 | "id": 337, 521 | "nome": "Confiança", 522 | "abreviacao": "CON", 523 | "escudos": { 524 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 525 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 526 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 527 | }, 528 | "nome_fantasia": "Confiança" 529 | }, 530 | "340": { 531 | "id": 340, 532 | "nome": "CRB", 533 | "abreviacao": "CRB", 534 | "escudos": { 535 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 536 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 537 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 538 | }, 539 | "nome_fantasia": "CRB" 540 | }, 541 | "341": { 542 | "id": 341, 543 | "nome": "CSA", 544 | "abreviacao": "CSA", 545 | "escudos": { 546 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 547 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 548 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 549 | }, 550 | "nome_fantasia": "CSA" 551 | }, 552 | "342": { 553 | "id": 342, 554 | "nome": "ASA Arapiraca", 555 | "abreviacao": "ASA", 556 | "escudos": { 557 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 558 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 559 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 560 | }, 561 | "nome_fantasia": "ASA Arapiraca" 562 | }, 563 | "343": { 564 | "id": 343, 565 | "nome": "Náutico", 566 | "abreviacao": "NAU", 567 | "escudos": { 568 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 569 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 570 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 571 | }, 572 | "nome_fantasia": "Náutico" 573 | }, 574 | "344": { 575 | "id": 344, 576 | "nome": "Santa Cruz", 577 | "abreviacao": "STC", 578 | "escudos": { 579 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 580 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 581 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 582 | }, 583 | "nome_fantasia": "Santa Cruz" 584 | }, 585 | "346": { 586 | "id": 346, 587 | "nome": "Treze", 588 | "abreviacao": "TRZ", 589 | "escudos": { 590 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 591 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 592 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 593 | }, 594 | "nome_fantasia": "Treze" 595 | }, 596 | "347": { 597 | "id": 347, 598 | "nome": "Botafogo-PB", 599 | "abreviacao": "BOT", 600 | "escudos": { 601 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 602 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 603 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 604 | }, 605 | "nome_fantasia": "Botafogo-PB" 606 | }, 607 | "349": { 608 | "id": 349, 609 | "nome": "Campinense", 610 | "abreviacao": "CAM", 611 | "escudos": { 612 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 613 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 614 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 615 | }, 616 | "nome_fantasia": "Campinense" 617 | }, 618 | "350": { 619 | "id": 350, 620 | "nome": "ABC", 621 | "abreviacao": "ABC", 622 | "escudos": { 623 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 624 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 625 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 626 | }, 627 | "nome_fantasia": "ABC" 628 | }, 629 | "351": { 630 | "id": 351, 631 | "nome": "América-RN", 632 | "abreviacao": "AME", 633 | "escudos": { 634 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 635 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 636 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 637 | }, 638 | "nome_fantasia": "América-RN" 639 | }, 640 | "354": { 641 | "id": 354, 642 | "nome": "Ceará", 643 | "abreviacao": "CEA", 644 | "escudos": { 645 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 646 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 647 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 648 | }, 649 | "nome_fantasia": "Ceará" 650 | }, 651 | "356": { 652 | "id": 356, 653 | "nome": "Fortaleza", 654 | "abreviacao": "FOR", 655 | "escudos": { 656 | "60x60": "https://s.sde.globo.com/media/organizations/2021/09/19/65_0000_Fortaleza-2021.png", 657 | "45x45": "https://s.sde.globo.com/media/organizations/2021/09/19/45_0000_Fortaleza-2021.png", 658 | "30x30": "https://s.sde.globo.com/media/organizations/2021/09/19/30_0000_Fortaleza-2021.png" 659 | }, 660 | "nome_fantasia": "Fortaleza" 661 | }, 662 | "362": { 663 | "id": 362, 664 | "nome": "Moto Club", 665 | "abreviacao": "MOT", 666 | "escudos": { 667 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 668 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 669 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 670 | }, 671 | "nome_fantasia": "Moto Club" 672 | }, 673 | "363": { 674 | "id": 363, 675 | "nome": "Sampaio Corrêa", 676 | "abreviacao": "SAM", 677 | "escudos": { 678 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 679 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 680 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 681 | }, 682 | "nome_fantasia": "Sampaio Corrêa" 683 | }, 684 | "364": { 685 | "id": 364, 686 | "nome": "Remo", 687 | "abreviacao": "REM", 688 | "escudos": { 689 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 690 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 691 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 692 | }, 693 | "nome_fantasia": "Remo" 694 | }, 695 | "373": { 696 | "id": 373, 697 | "nome": "Atlético-GO", 698 | "abreviacao": "ACG", 699 | "escudos": { 700 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 701 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 702 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 703 | }, 704 | "nome_fantasia": "Atlético-GO" 705 | }, 706 | "375": { 707 | "id": 375, 708 | "nome": "Vila Nova", 709 | "abreviacao": "VIL", 710 | "escudos": { 711 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 712 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 713 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 714 | }, 715 | "nome_fantasia": "Vila Nova" 716 | }, 717 | "386": { 718 | "id": 386, 719 | "nome": "São Caetano", 720 | "abreviacao": "SAO", 721 | "escudos": { 722 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 723 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 724 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 725 | }, 726 | "nome_fantasia": "São Caetano" 727 | }, 728 | "388": { 729 | "id": 388, 730 | "nome": "Brasiliense", 731 | "abreviacao": "BRA", 732 | "escudos": { 733 | "60x60": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_65x65.png", 734 | "45x45": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_45x45.png", 735 | "30x30": "https://s.glbimg.com/es/sde/f/organizacoes/escudo_default_30x30.png" 736 | }, 737 | "nome_fantasia": "Brasiliense" 738 | } 739 | } 740 | -------------------------------------------------------------------------------- /tests/testdata/game_over.json: -------------------------------------------------------------------------------- 1 | { 2 | "rodada_atual": 38, 3 | "status_mercado": 6, 4 | "esquema_default_id": 4, 5 | "cartoleta_inicial": 100, 6 | "max_ligas_free": 1, 7 | "max_ligas_pro": 10, 8 | "max_ligas_matamata_free": 5, 9 | "max_criar_ligas_matamata_free": 1, 10 | "max_ligas_matamata_pro": 10, 11 | "max_ligas_patrocinadas_free": 2, 12 | "max_ligas_patrocinadas_pro_num": 2, 13 | "game_over": true, 14 | "temporada": 2023, 15 | "reativar": true, 16 | "exibe_sorteio_pro": false, 17 | "fechamento": { 18 | "dia": 15, 19 | "mes": 4, 20 | "ano": 2023, 21 | "hora": 23, 22 | "minuto": 59, 23 | "timestamp": 1681613940 24 | }, 25 | "limites_competicao": { 26 | "total_confronto_pro": 10, 27 | "total_confronto_free": 3, 28 | "criacao_confronto_pro": 10, 29 | "criacao_confronto_free": 1 30 | }, 31 | "times_escalados": 194879, 32 | "mercado_pos_rodada": false, 33 | "novo_mes_ranking": false, 34 | "degustacao_gatomestre": false, 35 | "nome_rodada": "Rodada 1" 36 | } 37 | -------------------------------------------------------------------------------- /tests/testdata/ligas.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "slug": "time-cartola-oficial", 4 | "imagem": "https://s2.glbimg.com/i1qL4qWfmbtmWmMlfScx3Ry30uw=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/09/00/00/00236230920230310150000", 5 | "tipo": "Fechada", 6 | "criacao": "2022-03-10 13:08:26", 7 | "nome": "Time Cartola Oficial", 8 | "descricao": "Valendo um card no board", 9 | "quantidade_times": null, 10 | "vagas_restantes": null, 11 | "liga_id": 2362309, 12 | "mata_mata": false, 13 | "sem_capitao": false 14 | }, 15 | { 16 | "slug": "amigos-do-bella-torre", 17 | "imagem": "https://s2.glbimg.com/lPss8A7OBOOJ0Hdagamjt6LRnbg=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/25/15/16/00236232520230312171516", 18 | "tipo": "Fechada", 19 | "criacao": "2023-03-12 17:14:47", 20 | "nome": "Amigos do Bella Torre", 21 | "descricao": null, 22 | "quantidade_times": 1, 23 | "vagas_restantes": null, 24 | "liga_id": 2362325, 25 | "mata_mata": false, 26 | "sem_capitao": false 27 | }, 28 | { 29 | "slug": "teste", 30 | "imagem": "https://s2.glbimg.com/HDJXvHa6nNMw1wdy1F_p4Kl_n40=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/15/43/48/00236231520230310154348", 31 | "tipo": "Aberta", 32 | "criacao": "2023-03-10 15:43:46", 33 | "nome": "Teste", 34 | "descricao": null, 35 | "quantidade_times": 1, 36 | "vagas_restantes": null, 37 | "liga_id": 2362315, 38 | "mata_mata": false, 39 | "sem_capitao": false 40 | }, 41 | { 42 | "slug": "amigos-do-dandan", 43 | "imagem": "", 44 | "tipo": "Aberta", 45 | "criacao": "2023-03-14 20:29:23", 46 | "nome": "Amigos do Dandan", 47 | "descricao": "Liga onde os melhores amigos do Daniel Pereira se encontram para jogar e mitar", 48 | "quantidade_times": null, 49 | "vagas_restantes": null, 50 | "liga_id": 2362351, 51 | "mata_mata": false, 52 | "sem_capitao": false 53 | }, 54 | { 55 | "slug": "celi-e-amigos-2023", 56 | "imagem": "https://s2.glbimg.com/wwNBPrZuF2gQ5Tog2vh48lkaCGM=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_188/flamula/51/11/25/0069625120210525151125", 57 | "tipo": "Fechada", 58 | "criacao": "2019-05-31 16:30:13", 59 | "nome": "CELI E AMIGOS 2023", 60 | "descricao": "Celi e amigos 2023", 61 | "quantidade_times": null, 62 | "vagas_restantes": null, 63 | "liga_id": 2362367, 64 | "mata_mata": false, 65 | "sem_capitao": false 66 | }, 67 | { 68 | "slug": "tropa-do-salve", 69 | "imagem": "https://s2.glbimg.com/RoESrTphzhcU9pjZi4fSNlPb1vs=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/06/34/35/00236240620230316113435", 70 | "tipo": "Moderada", 71 | "criacao": "2023-03-16 11:34:26", 72 | "nome": "Tropa Do Salve", 73 | "descricao": null, 74 | "quantidade_times": 1, 75 | "vagas_restantes": null, 76 | "liga_id": 2362406, 77 | "mata_mata": false, 78 | "sem_capitao": false 79 | }, 80 | { 81 | "slug": "dh-cartola", 82 | "imagem": "https://s2.glbimg.com/eRj5KGw8sPyiC9-gtCb5hKXgFrc=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/13/35/02/00236241320230316113502", 83 | "tipo": "Moderada", 84 | "criacao": "2023-03-16 11:35:02", 85 | "nome": "DH Cartola", 86 | "descricao": "Campeões :\n2019 - Lorenzo \n2020 - Schmitz \n2021 - Lolo \n2022 - Lolo ", 87 | "quantidade_times": null, 88 | "vagas_restantes": null, 89 | "liga_id": 2362413, 90 | "mata_mata": false, 91 | "sem_capitao": false 92 | }, 93 | { 94 | "slug": "cornetas-da-reta-2023", 95 | "imagem": "https://s2.glbimg.com/U9iSF5TGdY_1dY6c4ogifIjGmNs=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/12/35/13/00236241220230316113513", 96 | "tipo": "Fechada", 97 | "criacao": "2023-03-16 11:35:02", 98 | "nome": "Cornetas da Reta 2023", 99 | "descricao": "Simbora pra mais uma!!! ", 100 | "quantidade_times": null, 101 | "vagas_restantes": null, 102 | "liga_id": 2362412, 103 | "mata_mata": false, 104 | "sem_capitao": false 105 | }, 106 | { 107 | "slug": "familia-gato-cartoleiro", 108 | "imagem": "https://s2.glbimg.com/kwjY1zazVq6ZzvgspkIBz-Q7T1E=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/38/36/33/00236243820230316113633", 109 | "tipo": "Fechada", 110 | "criacao": "2023-03-16 11:36:33", 111 | "nome": "Família Gato Cartoleiro ", 112 | "descricao": "a liga mais competitiva do Cartola ", 113 | "quantidade_times": null, 114 | "vagas_restantes": null, 115 | "liga_id": 2362438, 116 | "mata_mata": false, 117 | "sem_capitao": false 118 | }, 119 | { 120 | "slug": "piores-de-brasilia", 121 | "imagem": "https://s2.glbimg.com/sa3xNrk6z8Fx1ynsLrsU31mVSZQ=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_200/flamula/95/59/47/00165239520220311105947", 122 | "tipo": "Moderada", 123 | "criacao": "2021-04-28 13:21:07", 124 | "nome": "Piores de Brasília ", 125 | "descricao": "ONDE APENAS OS PIORES SAO BEM VINDOS", 126 | "quantidade_times": null, 127 | "vagas_restantes": null, 128 | "liga_id": 2362426, 129 | "mata_mata": false, 130 | "sem_capitao": false 131 | }, 132 | { 133 | "slug": "liga-newlog-amigos-do-charao-9-temp", 134 | "imagem": "https://s2.glbimg.com/6Lts3NKOzFuQDRRYn_JfOtI9ew0=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/41/36/50/00236244120230316113650", 135 | "tipo": "Moderada", 136 | "criacao": "2023-03-16 11:36:49", 137 | "nome": "Liga NewLoG - Amigos do Charão - 9°Temp.", 138 | "descricao": "A nona edição da Liga começa com uma disputa aberta pelo troféu!", 139 | "quantidade_times": null, 140 | "vagas_restantes": null, 141 | "liga_id": 2362441, 142 | "mata_mata": false, 143 | "sem_capitao": false 144 | }, 145 | { 146 | "slug": "fura-s-league", 147 | "imagem": "https://s2.glbimg.com/j2YzGClGDvKugdgvAB71jvCk274=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_150/flamula/42/01/43/0044220190522180143", 148 | "tipo": "Moderada", 149 | "criacao": "2017-04-25 11:49:38", 150 | "nome": "FURA'S LEAGUE", 151 | "descricao": "Só tem pudim de pinga!!!", 152 | "quantidade_times": null, 153 | "vagas_restantes": null, 154 | "liga_id": 2362444, 155 | "mata_mata": false, 156 | "sem_capitao": false 157 | }, 158 | { 159 | "slug": "liga-ouvidor-2023", 160 | "imagem": "https://s2.glbimg.com/KtddC6bDVzhuCLguCDg1FDw7WFs=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_209/flamula/26/21/08/00225652620220730112108", 161 | "tipo": "Moderada", 162 | "criacao": "2022-07-30 11:20:30", 163 | "nome": "Liga Ouvidor 2023", 164 | "descricao": "Liga de amigos, com premiação, 1 e 2 Turno !", 165 | "quantidade_times": null, 166 | "vagas_restantes": null, 167 | "liga_id": 2362433, 168 | "mata_mata": false, 169 | "sem_capitao": true 170 | }, 171 | { 172 | "slug": "os-feras-do-cartola-2023", 173 | "imagem": "https://s2.glbimg.com/bYAAMdEnMt5VpdnqULDEMs2oir8=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/76/34/09/00236237620230316113409", 174 | "tipo": "Fechada", 175 | "criacao": "2023-03-16 11:31:52", 176 | "nome": "OS FERAS DO CARTOLA 2023", 177 | "descricao": "A Liga Mais Bolada Do Cartola 2023", 178 | "quantidade_times": null, 179 | "vagas_restantes": null, 180 | "liga_id": 2362376, 181 | "mata_mata": false, 182 | "sem_capitao": false 183 | }, 184 | { 185 | "slug": "liga-matao-2023", 186 | "imagem": "https://s2.glbimg.com/9YvxTUp1vXVY0R5HjmrTmZxp0qc=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/15/38/51/00236241520230316113851", 187 | "tipo": "Moderada", 188 | "criacao": "2022-04-07 10:47:42", 189 | "nome": "Liga Matão 2023", 190 | "descricao": null, 191 | "quantidade_times": null, 192 | "vagas_restantes": null, 193 | "liga_id": 2362415, 194 | "mata_mata": false, 195 | "sem_capitao": false 196 | }, 197 | { 198 | "slug": "pessimos", 199 | "imagem": "https://s2.glbimg.com/Ydyvxd__WQBBVLe-IjqvA-MdtFY=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_162/flamula/82/40/17/0068958220200721134017", 200 | "tipo": "Fechada", 201 | "criacao": "2019-04-27 20:11:14", 202 | "nome": "péssimos", 203 | "descricao": "...", 204 | "quantidade_times": null, 205 | "vagas_restantes": null, 206 | "liga_id": 2362497, 207 | "mata_mata": false, 208 | "sem_capitao": false 209 | }, 210 | { 211 | "slug": "tropa-do-rede", 212 | "imagem": "https://s2.glbimg.com/3la4zVpBQ97eHkl8GbSHY9I1hiw=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_199/flamula/47/24/09/00164164720220310112409", 213 | "tipo": "Fechada", 214 | "criacao": "2022-03-10 11:24:09", 215 | "nome": "TROPA DO REDE", 216 | "descricao": " ", 217 | "quantidade_times": null, 218 | "vagas_restantes": null, 219 | "liga_id": 2362509, 220 | "mata_mata": false, 221 | "sem_capitao": false 222 | }, 223 | { 224 | "slug": "almeida-s-champions", 225 | "imagem": "https://s2.glbimg.com/QFfMdB4j5SIvqUcYUClRTEhrbAw=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/18/40/43/00236251820230316114043", 226 | "tipo": "Moderada", 227 | "criacao": "2023-03-16 11:40:42", 228 | "nome": "ALMEIDA'S CHAMPIONS ", 229 | "descricao": "a liga mais acirrada do mundo", 230 | "quantidade_times": null, 231 | "vagas_restantes": null, 232 | "liga_id": 2362518, 233 | "mata_mata": false, 234 | "sem_capitao": false 235 | }, 236 | { 237 | "slug": "macacos-do-monteiro", 238 | "imagem": "https://s2.glbimg.com/XFLqiIBecnyw_NKkqfVIX8ydTfw=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/17/40/42/00236251720230316114042", 239 | "tipo": "Moderada", 240 | "criacao": "2023-03-16 11:40:42", 241 | "nome": "Macacos do Monteiro", 242 | "descricao": "nois eh liso igual neymar ", 243 | "quantidade_times": null, 244 | "vagas_restantes": null, 245 | "liga_id": 2362517, 246 | "mata_mata": false, 247 | "sem_capitao": false 248 | }, 249 | { 250 | "slug": "copa-talitinha-2021", 251 | "imagem": "https://s2.glbimg.com/-UW6Q_QdYUIQ_qH_teoNZG6-grs=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_188/flamula/16/35/32/0086401620210523193532", 252 | "tipo": "Fechada", 253 | "criacao": "2021-05-23 17:28:17", 254 | "nome": "COPA TALITINHA 2021", 255 | "descricao": "o 1⁰ colocado ganha 50$ e o troféu TALITINHA 2021", 256 | "quantidade_times": null, 257 | "vagas_restantes": null, 258 | "liga_id": 2362523, 259 | "mata_mata": false, 260 | "sem_capitao": false 261 | }, 262 | { 263 | "slug": "jd-miriam-fc", 264 | "imagem": "https://s2.glbimg.com/tF_J78faA0YgUZscvPgAGa_h7Ck=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_164/flamula/88/34/46/0069408820200722153446", 265 | "tipo": "Moderada", 266 | "criacao": "2019-04-16 16:32:24", 267 | "nome": "Jd Miriam FC", 268 | "descricao": "Vem pro fut ! ", 269 | "quantidade_times": null, 270 | "vagas_restantes": null, 271 | "liga_id": 2362526, 272 | "mata_mata": false, 273 | "sem_capitao": false 274 | }, 275 | { 276 | "slug": "tecnoportas", 277 | "imagem": "https://s2.glbimg.com/xuDOqDVs8o_bK4kxFbI77Ucs7Lw=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_209/flamula/06/00/56/00225000620220727170056", 278 | "tipo": "Fechada", 279 | "criacao": "2022-07-27 17:00:56", 280 | "nome": "Tecnoportas", 281 | "descricao": "Vender porta ngm quer, agora jogar joguinho seis querem né", 282 | "quantidade_times": null, 283 | "vagas_restantes": null, 284 | "liga_id": 2362551, 285 | "mata_mata": false, 286 | "sem_capitao": false 287 | }, 288 | { 289 | "slug": "cruz-legue", 290 | "imagem": "https://s2.glbimg.com/kHKsDd1JxXYmnAT_QtdJEU715Vw=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/29/41/55/00236252920230316114155", 291 | "tipo": "Moderada", 292 | "criacao": "2022-04-08 13:59:13", 293 | "nome": "Cruz Legue", 294 | "descricao": "Cruz League cartola 2023", 295 | "quantidade_times": null, 296 | "vagas_restantes": null, 297 | "liga_id": 2362529, 298 | "mata_mata": false, 299 | "sem_capitao": false 300 | }, 301 | { 302 | "slug": "aifd-2023-oficial", 303 | "imagem": "https://s2.glbimg.com/A7QYZjepOtUI8Mnca4ZO533ajgg=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/61/43/09/00236256120230316114309", 304 | "tipo": "Fechada", 305 | "criacao": "2023-03-16 11:43:09", 306 | "nome": "AIFD 2023 OFICIAL", 307 | "descricao": null, 308 | "quantidade_times": null, 309 | "vagas_restantes": null, 310 | "liga_id": 2362561, 311 | "mata_mata": false, 312 | "sem_capitao": false 313 | }, 314 | { 315 | "slug": "league-apt", 316 | "imagem": "https://s2.glbimg.com/fuodgWX3XNQk7e3IefzKd-3wI8M=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_165/flamula/57/53/59/0080855720200724115359", 317 | "tipo": "Moderada", 318 | "criacao": "2020-07-24 11:53:59", 319 | "nome": "League APT", 320 | "descricao": " ", 321 | "quantidade_times": null, 322 | "vagas_restantes": null, 323 | "liga_id": 2362573, 324 | "mata_mata": false, 325 | "sem_capitao": false 326 | }, 327 | { 328 | "slug": "laluvadepredero", 329 | "imagem": "https://s2.glbimg.com/OO1rZNpXEbKKLzMJ6pbN8QbiJTk=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_204/flamula/65/34/51/00188896520220409103451", 330 | "tipo": "Aberta", 331 | "criacao": "2022-04-09 10:34:51", 332 | "nome": "LaLuvaDePredero", 333 | "descricao": " ", 334 | "quantidade_times": null, 335 | "vagas_restantes": null, 336 | "liga_id": 2362574, 337 | "mata_mata": false, 338 | "sem_capitao": false 339 | }, 340 | { 341 | "slug": "master-liga-2023", 342 | "imagem": "https://s2.glbimg.com/Z-pl5bL7kTuqWr8pIQtrQbvNDIE=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/84/43/53/00236258420230316114353", 343 | "tipo": "Fechada", 344 | "criacao": "2023-03-16 11:43:53", 345 | "nome": "Master Liga 2023", 346 | "descricao": "Campeão ", 347 | "quantidade_times": null, 348 | "vagas_restantes": null, 349 | "liga_id": 2362584, 350 | "mata_mata": false, 351 | "sem_capitao": false 352 | }, 353 | { 354 | "slug": "parca-futebol-club", 355 | "imagem": "https://s2.glbimg.com/3a7ir0SJgThUYdyP_Q3rKCj4QoM=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_209/flamula/15/18/46/00217081520220617131846", 356 | "tipo": "Moderada", 357 | "criacao": "2022-06-17 13:17:45", 358 | "nome": "Parça Futebol Club", 359 | "descricao": "Campeonato de pontos corridos mais competitivo que a Premier League", 360 | "quantidade_times": null, 361 | "vagas_restantes": null, 362 | "liga_id": 2362581, 363 | "mata_mata": false, 364 | "sem_capitao": false 365 | }, 366 | { 367 | "slug": "aleph-champions-legue", 368 | "imagem": "https://s2.glbimg.com/OVIDDGZbANmkc5pvRii3m75QHkc=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_183/flamula/81/57/26/0068478120210427135726", 369 | "tipo": "Fechada", 370 | "criacao": "2021-04-27 13:56:09", 371 | "nome": "Aleph Champions Legue", 372 | "descricao": "Melhor que a UEFA Champions Legue", 373 | "quantidade_times": null, 374 | "vagas_restantes": null, 375 | "liga_id": 2362590, 376 | "mata_mata": false, 377 | "sem_capitao": false 378 | }, 379 | { 380 | "slug": "street-fc", 381 | "imagem": "https://s2.glbimg.com/Nae0BzyN0XXiYcOjGr-9st-lAz0=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/95/44/36/00236259520230316114436", 382 | "tipo": "Moderada", 383 | "criacao": "2023-03-16 11:44:19", 384 | "nome": "Street Fc", 385 | "descricao": null, 386 | "quantidade_times": 1, 387 | "vagas_restantes": null, 388 | "liga_id": 2362595, 389 | "mata_mata": false, 390 | "sem_capitao": false 391 | }, 392 | { 393 | "slug": "lampions-league-rn-2022", 394 | "imagem": "https://s2.glbimg.com/t34JrFfwGvfsHYNzADzAsKPJCBs=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_200/flamula/34/44/46/00165953420220312154446", 395 | "tipo": "Moderada", 396 | "criacao": "2021-06-02 22:26:08", 397 | "nome": "LAMPIONS LEAGUE RN 2022", 398 | "descricao": "liga macaiba rn", 399 | "quantidade_times": null, 400 | "vagas_restantes": null, 401 | "liga_id": 2362609, 402 | "mata_mata": false, 403 | "sem_capitao": false 404 | }, 405 | { 406 | "slug": "1-turno-da-liga", 407 | "imagem": "https://s2.glbimg.com/2FVJK_DyLgdMAX06a5QN0SW_Y44=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_209/flamula/85/37/49/00224418520220726133749", 408 | "tipo": "Moderada", 409 | "criacao": "2022-07-26 13:37:49", 410 | "nome": "1° Turno da liga", 411 | "descricao": "....", 412 | "quantidade_times": null, 413 | "vagas_restantes": null, 414 | "liga_id": 2362568, 415 | "mata_mata": false, 416 | "sem_capitao": false 417 | }, 418 | { 419 | "slug": "mangueirao-fc", 420 | "imagem": "https://s2.glbimg.com/d08IxUXFEIO27hQpCR8YC3aT72c=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_208/flamula/22/25/13/00206822220220504192513", 421 | "tipo": "Fechada", 422 | "criacao": "2022-05-04 19:24:22", 423 | "nome": "mangueirão FC", 424 | "descricao": "A mas badalada ", 425 | "quantidade_times": null, 426 | "vagas_restantes": null, 427 | "liga_id": 2362628, 428 | "mata_mata": false, 429 | "sem_capitao": true 430 | }, 431 | { 432 | "slug": "brasileirao2023-amigos-do-fael", 433 | "imagem": "https://s2.glbimg.com/e_98qfLj7ERtsZZrXm6JhtNIRYM=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_199/flamula/28/52/08/00164972820220310215208", 434 | "tipo": "Moderada", 435 | "criacao": "2022-03-10 21:51:02", 436 | "nome": "BRASILEIRÃO2023-AMIGOS DO FAEL", 437 | "descricao": "Nossa liga está de volta, e esse ano a disputa promete ser mais acirrada, novos times, com novas premiações", 438 | "quantidade_times": null, 439 | "vagas_restantes": null, 440 | "liga_id": 2362582, 441 | "mata_mata": false, 442 | "sem_capitao": false 443 | }, 444 | { 445 | "slug": "sk-league", 446 | "imagem": "https://s2.glbimg.com/2z2U0pTa28Qq8BJVqmuL4Pp5_gU=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_199/flamula/67/11/50/00165036720220310231150", 447 | "tipo": "Moderada", 448 | "criacao": "2022-03-10 23:11:35", 449 | "nome": "SK League", 450 | "descricao": "Liga do SK 2022 ", 451 | "quantidade_times": null, 452 | "vagas_restantes": null, 453 | "liga_id": 2362637, 454 | "mata_mata": false, 455 | "sem_capitao": false 456 | }, 457 | { 458 | "slug": "amigos-do-lebrao", 459 | "imagem": "https://s2.glbimg.com/wjEPpKDRUrX-3v-YXcG5EWMnPd4=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_186/flamula/44/12/10/0075674420210507131210", 460 | "tipo": "Moderada", 461 | "criacao": "2017-04-29 15:11:44", 462 | "nome": "AMIGOS DO LEBRAO ", 463 | "descricao": "since 14/04/2014..\nPremiação!!!\nCampeão da liga\n1ao10 lugar\nCampeão do 1 turno\nCampeão do 2 turno\n1 colocado de cada mês \nMaior pontuação na liga!!", 464 | "quantidade_times": null, 465 | "vagas_restantes": null, 466 | "liga_id": 2362644, 467 | "mata_mata": false, 468 | "sem_capitao": false 469 | }, 470 | { 471 | "slug": "liga-do-essence", 472 | "imagem": "https://s2.glbimg.com/T8RS72R_1HSGwB6vSWWsefhP_ck=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/34/45/36/00236263420230316114536", 473 | "tipo": "Moderada", 474 | "criacao": "2023-03-16 11:45:36", 475 | "nome": "Liga Do Essence", 476 | "descricao": "A mais braba ", 477 | "quantidade_times": null, 478 | "vagas_restantes": null, 479 | "liga_id": 2362634, 480 | "mata_mata": false, 481 | "sem_capitao": false 482 | }, 483 | { 484 | "slug": "valle-league", 485 | "imagem": "https://s2.glbimg.com/AQ-Gg00KnwaJKvjv0MLp_qNkR7Q=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/49/46/15/00236264920230316114615", 486 | "tipo": "Moderada", 487 | "criacao": "2023-03-16 11:46:15", 488 | "nome": "Valle League", 489 | "descricao": "uma liga criada para se divertir escalando o seu próprio time.\n\nque vença o melhor!", 490 | "quantidade_times": null, 491 | "vagas_restantes": null, 492 | "liga_id": 2362649, 493 | "mata_mata": false, 494 | "sem_capitao": false 495 | }, 496 | { 497 | "slug": "donos-da-bola-geral", 498 | "imagem": "https://s2.glbimg.com/rpGnRB3Uhvc0YqTYU9wpFDcmndA=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_202/flamula/59/33/04/00177775920220405093304", 499 | "tipo": "Moderada", 500 | "criacao": "2022-04-05 09:33:04", 501 | "nome": "Donos da bola geral", 502 | "descricao": " ", 503 | "quantidade_times": null, 504 | "vagas_restantes": null, 505 | "liga_id": 2362671, 506 | "mata_mata": false, 507 | "sem_capitao": false 508 | }, 509 | { 510 | "slug": "cartola22-83-84-85", 511 | "imagem": "https://s2.glbimg.com/B7s13vhKIgLVo6VL2-PupLPg4Q8=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_210/flamula/63/46/47/00236266320230316114647", 512 | "tipo": "Moderada", 513 | "criacao": "2022-03-31 17:52:18", 514 | "nome": "Cartola22 83/84/85", 515 | "descricao": "A Melhor!", 516 | "quantidade_times": null, 517 | "vagas_restantes": null, 518 | "liga_id": 2362663, 519 | "mata_mata": false, 520 | "sem_capitao": false 521 | } 522 | ] 523 | -------------------------------------------------------------------------------- /tests/testdata/mercado_destaques.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "posicao": "Lateral", 4 | "posicao_abreviacao": "LAT", 5 | "clube": "PAL", 6 | "clube_nome": "Palmeiras", 7 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_60x60.png", 8 | "Atleta": { 9 | "nome": "Marcos Luis Rocha Aquino", 10 | "apelido": "Marcos Rocha", 11 | "apelido_abreviado": "M. Rocha", 12 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/15/photo_FORMATO_OnxH8aq.png", 13 | "atleta_id": 63013, 14 | "preco_editorial": 5 15 | }, 16 | "clube_id": 275, 17 | "escalacoes": 118020 18 | }, 19 | { 20 | "posicao": "Zagueiro", 21 | "posicao_abreviacao": "ZAG", 22 | "clube": "CAP", 23 | "clube_nome": "Athlético-PR", 24 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-65x65.png", 25 | "Atleta": { 26 | "nome": "Pedro Henrique Ribeiro Gonçalves", 27 | "apelido": "Pedro Henrique", 28 | "apelido_abreviado": "P. Henrique", 29 | "foto": "https://s.sde.globo.com/media/person_role/2023/02/28/photo_FORMATO_Pmz9ta0.png", 30 | "atleta_id": 87225, 31 | "preco_editorial": 5 32 | }, 33 | "clube_id": 293, 34 | "escalacoes": 97309 35 | }, 36 | { 37 | "posicao": "Atacante", 38 | "posicao_abreviacao": "ATA", 39 | "clube": "BGT", 40 | "clube_nome": "Bragantino", 41 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2020/01/01/65.png", 42 | "Atleta": { 43 | "nome": "Artur Victor Guimarães", 44 | "apelido": "Artur", 45 | "apelido_abreviado": "Artur", 46 | "foto": "https://s.sde.globo.com/media/person_role/2022/05/05/5c98a0d6cc76edfef83280072bbd3832_FORMATO.png", 47 | "atleta_id": 95799, 48 | "preco_editorial": 7 49 | }, 50 | "clube_id": 280, 51 | "escalacoes": 89654 52 | }, 53 | { 54 | "posicao": "Atacante", 55 | "posicao_abreviacao": "ATA", 56 | "clube": "CAM", 57 | "clube_nome": "Atlético-MG", 58 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo65px.png", 59 | "Atleta": { 60 | "nome": "Paulo Henrique Sampaio Filho", 61 | "apelido": "Paulinho", 62 | "apelido_abreviado": "Paulinho", 63 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/01/photo_FORMATO_WoByTJE.png", 64 | "atleta_id": 99818, 65 | "preco_editorial": 8 66 | }, 67 | "clube_id": 282, 68 | "escalacoes": 85976 69 | }, 70 | { 71 | "posicao": "Goleiro", 72 | "posicao_abreviacao": "GOL", 73 | "clube": "CAM", 74 | "clube_nome": "Atlético-MG", 75 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo65px.png", 76 | "Atleta": { 77 | "nome": "Everson Felipe Marques Pires", 78 | "apelido": "Everson", 79 | "apelido_abreviado": "Everson", 80 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/01/photo_FORMATO_XhJDp6n.png", 81 | "atleta_id": 72294, 82 | "preco_editorial": 5 83 | }, 84 | "clube_id": 282, 85 | "escalacoes": 83757 86 | }, 87 | { 88 | "posicao": "Técnico", 89 | "posicao_abreviacao": "TEC", 90 | "clube": "CAP", 91 | "clube_nome": "Athlético-PR", 92 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-65x65.png", 93 | "Atleta": { 94 | "nome": "Paulo César Turra", 95 | "apelido": "Paulo Turra", 96 | "apelido_abreviado": "P. Turra", 97 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/06/photo_FORMATO_L21KedQ.png", 98 | "atleta_id": 82747, 99 | "preco_editorial": 5 100 | }, 101 | "clube_id": 293, 102 | "escalacoes": 80364 103 | }, 104 | { 105 | "posicao": "Lateral", 106 | "posicao_abreviacao": "LAT", 107 | "clube": "FLA", 108 | "clube_nome": "Flamengo", 109 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-65.png", 110 | "Atleta": { 111 | "nome": "Guillermo Varela Olivera", 112 | "apelido": "Varela", 113 | "apelido_abreviado": "Varela", 114 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/01/photo_FORMATO_NeDa74S.png", 115 | "atleta_id": 84816, 116 | "preco_editorial": 5 117 | }, 118 | "clube_id": 262, 119 | "escalacoes": 56800 120 | }, 121 | { 122 | "posicao": "Meia", 123 | "posicao_abreviacao": "MEI", 124 | "clube": "COR", 125 | "clube_nome": "Corinthians", 126 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_65.png", 127 | "Atleta": { 128 | "nome": "Adson Ferreira Soares", 129 | "apelido": "Adson", 130 | "apelido_abreviado": "Adson", 131 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/02/photo_FORMATO_uzK3HTh.png", 132 | "atleta_id": 111682, 133 | "preco_editorial": 5 134 | }, 135 | "clube_id": 264, 136 | "escalacoes": 45686 137 | }, 138 | { 139 | "posicao": "Atacante", 140 | "posicao_abreviacao": "ATA", 141 | "clube": "PAL", 142 | "clube_nome": "Palmeiras", 143 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_60x60.png", 144 | "Atleta": { 145 | "nome": "Ronielson da Silva Barbosa", 146 | "apelido": "Rony", 147 | "apelido_abreviado": "Rony", 148 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/15/photo_FORMATO_eJOedW8.png", 149 | "atleta_id": 91607, 150 | "preco_editorial": 15 151 | }, 152 | "clube_id": 275, 153 | "escalacoes": 44915 154 | }, 155 | { 156 | "posicao": "Zagueiro", 157 | "posicao_abreviacao": "ZAG", 158 | "clube": "COR", 159 | "clube_nome": "Corinthians", 160 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_65.png", 161 | "Atleta": { 162 | "nome": "Bruno Méndez Cittadini", 163 | "apelido": "Bruno Méndez", 164 | "apelido_abreviado": "B. Méndez", 165 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/02/photo_FORMATO_VwEvkmY.png", 166 | "atleta_id": 103700, 167 | "preco_editorial": 6 168 | }, 169 | "clube_id": 264, 170 | "escalacoes": 44383 171 | }, 172 | { 173 | "posicao": "Meia", 174 | "posicao_abreviacao": "MEI", 175 | "clube": "PAL", 176 | "clube_nome": "Palmeiras", 177 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_60x60.png", 178 | "Atleta": { 179 | "nome": "Gabriel Vinícius Menino", 180 | "apelido": "Gabriel Menino", 181 | "apelido_abreviado": "G. Menino", 182 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/15/photo_FORMATO_a770SrF.png", 183 | "atleta_id": 103767, 184 | "preco_editorial": 8 185 | }, 186 | "clube_id": 275, 187 | "escalacoes": 43541 188 | }, 189 | { 190 | "posicao": "Atacante", 191 | "posicao_abreviacao": "ATA", 192 | "clube": "VAS", 193 | "clube_nome": "Vasco", 194 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_65px.png", 195 | "Atleta": { 196 | "nome": "Pedro Raul Garay da Silva", 197 | "apelido": "Pedro Raul", 198 | "apelido_abreviado": "P. Raul", 199 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/14/photo_FORMATO_IDn4App.png", 200 | "atleta_id": 98225, 201 | "preco_editorial": 5 202 | }, 203 | "clube_id": 267, 204 | "escalacoes": 42436 205 | }, 206 | { 207 | "posicao": "Atacante", 208 | "posicao_abreviacao": "ATA", 209 | "clube": "FLA", 210 | "clube_nome": "Flamengo", 211 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-65.png", 212 | "Atleta": { 213 | "nome": "Pedro Guilherme Abreu dos Santos", 214 | "apelido": "Pedro", 215 | "apelido_abreviado": "Pedro", 216 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/01/photo_FORMATO_r1M3bLz.png", 217 | "atleta_id": 94583, 218 | "preco_editorial": 19 219 | }, 220 | "clube_id": 262, 221 | "escalacoes": 40902 222 | }, 223 | { 224 | "posicao": "Atacante", 225 | "posicao_abreviacao": "ATA", 226 | "clube": "CAM", 227 | "clube_nome": "Atlético-MG", 228 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo65px.png", 229 | "Atleta": { 230 | "nome": "Givanildo Vieira de Souza", 231 | "apelido": "Hulk", 232 | "apelido_abreviado": "Hulk", 233 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/01/photo_FORMATO_HgdfwiM.png", 234 | "atleta_id": 39148, 235 | "preco_editorial": 16 236 | }, 237 | "clube_id": 282, 238 | "escalacoes": 40649 239 | }, 240 | { 241 | "posicao": "Goleiro", 242 | "posicao_abreviacao": "GOL", 243 | "clube": "GRE", 244 | "clube_nome": "Grêmio", 245 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_60x60.png", 246 | "Atleta": { 247 | "nome": "Adriel Vasconcelos Ramos", 248 | "apelido": "Adriel", 249 | "apelido_abreviado": "Adriel", 250 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/08/photo_FORMATO_WyxMzh5.png", 251 | "atleta_id": 107748, 252 | "preco_editorial": 6 253 | }, 254 | "clube_id": 284, 255 | "escalacoes": 35336 256 | }, 257 | { 258 | "posicao": "Meia", 259 | "posicao_abreviacao": "MEI", 260 | "clube": "CAP", 261 | "clube_nome": "Athlético-PR", 262 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-65x65.png", 263 | "Atleta": { 264 | "nome": "Vitor Frezarin Bueno", 265 | "apelido": "Vitor Bueno", 266 | "apelido_abreviado": "V. Bueno", 267 | "foto": "https://s.sde.globo.com/media/person_role/2023/02/28/photo_FORMATO_Vn5DBCR.png", 268 | "atleta_id": 87552, 269 | "preco_editorial": 5 270 | }, 271 | "clube_id": 293, 272 | "escalacoes": 32263 273 | }, 274 | { 275 | "posicao": "Meia", 276 | "posicao_abreviacao": "MEI", 277 | "clube": "PAL", 278 | "clube_nome": "Palmeiras", 279 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_60x60.png", 280 | "Atleta": { 281 | "nome": "Bruno Vinícius Souza Ramos", 282 | "apelido": "Bruno Tabata", 283 | "apelido_abreviado": "B. Tabata", 284 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/15/photo_FORMATO_g6CL75l.png", 285 | "atleta_id": 107174, 286 | "preco_editorial": 4 287 | }, 288 | "clube_id": 275, 289 | "escalacoes": 31716 290 | }, 291 | { 292 | "posicao": "Atacante", 293 | "posicao_abreviacao": "ATA", 294 | "clube": "GRE", 295 | "clube_nome": "Grêmio", 296 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_60x60.png", 297 | "Atleta": { 298 | "nome": "Luis Alberto Suárez Díaz", 299 | "apelido": "Luis Suárez", 300 | "apelido_abreviado": "L. Suárez", 301 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/08/photo_FORMATO_f8gCuyP.png", 302 | "atleta_id": 69318, 303 | "preco_editorial": 23 304 | }, 305 | "clube_id": 284, 306 | "escalacoes": 30133 307 | }, 308 | { 309 | "posicao": "Zagueiro", 310 | "posicao_abreviacao": "ZAG", 311 | "clube": "GRE", 312 | "clube_nome": "Grêmio", 313 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_60x60.png", 314 | "Atleta": { 315 | "nome": "Walter Kannemann", 316 | "apelido": "Kannemann", 317 | "apelido_abreviado": "Kannemann", 318 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/08/photo_FORMATO_q2fTOjY.png", 319 | "atleta_id": 87342, 320 | "preco_editorial": 7 321 | }, 322 | "clube_id": 284, 323 | "escalacoes": 29665 324 | }, 325 | { 326 | "posicao": "Meia", 327 | "posicao_abreviacao": "MEI", 328 | "clube": "GRE", 329 | "clube_nome": "Grêmio", 330 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_60x60.png", 331 | "Atleta": { 332 | "nome": "Vinícius Goes Barbosa de Souza", 333 | "apelido": "Vina", 334 | "apelido_abreviado": "Vina", 335 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/08/photo_FORMATO_q8oUM9e.png", 336 | "atleta_id": 71162, 337 | "preco_editorial": 9 338 | }, 339 | "clube_id": 284, 340 | "escalacoes": 26665 341 | } 342 | ] 343 | -------------------------------------------------------------------------------- /tests/testdata/mercado_destaques_reservas.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "posicao": "Goleiro", 4 | "posicao_abreviacao": "gol", 5 | "clube": "CFC", 6 | "clube_nome": "Coritiba", 7 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2017/03/29/coritiba65.png", 8 | "Atleta": { 9 | "nome": "Gabriel Vasconcelos Ferreira - Vasconcellos", 10 | "apelido": "Gabriel", 11 | "apelido_abreviado": "Gabriel", 12 | "foto": "https://s.sde.globo.com/media/person_role/2023/02/28/photo_FORMATO_ovYbvXA.png", 13 | "atleta_id": 70449, 14 | "preco_editorial": 5 15 | }, 16 | "clube_id": 294, 17 | "escalacoes": 62746 18 | }, 19 | { 20 | "posicao": "Atacante", 21 | "posicao_abreviacao": "ata", 22 | "clube": "VAS", 23 | "clube_nome": "Vasco", 24 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_65px.png", 25 | "Atleta": { 26 | "nome": "Pedro Raul Garay da Silva", 27 | "apelido": "Pedro Raul", 28 | "apelido_abreviado": "P. Raul", 29 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/14/photo_FORMATO_IDn4App.png", 30 | "atleta_id": 98225, 31 | "preco_editorial": 5 32 | }, 33 | "clube_id": 267, 34 | "escalacoes": 33207 35 | }, 36 | { 37 | "posicao": "Lateral", 38 | "posicao_abreviacao": "lat", 39 | "clube": "FLA", 40 | "clube_nome": "Flamengo", 41 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-65.png", 42 | "Atleta": { 43 | "nome": "Guillermo Varela Olivera", 44 | "apelido": "Varela", 45 | "apelido_abreviado": "Varela", 46 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/01/photo_FORMATO_NeDa74S.png", 47 | "atleta_id": 84816, 48 | "preco_editorial": 5 49 | }, 50 | "clube_id": 262, 51 | "escalacoes": 31379 52 | }, 53 | { 54 | "posicao": "Meia", 55 | "posicao_abreviacao": "mei", 56 | "clube": "PAL", 57 | "clube_nome": "Palmeiras", 58 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_60x60.png", 59 | "Atleta": { 60 | "nome": "Bruno Vinícius Souza Ramos", 61 | "apelido": "Bruno Tabata", 62 | "apelido_abreviado": "B. Tabata", 63 | "foto": "https://s.sde.globo.com/media/person_role/2023/03/15/photo_FORMATO_g6CL75l.png", 64 | "atleta_id": 107174, 65 | "preco_editorial": 4 66 | }, 67 | "clube_id": 275, 68 | "escalacoes": 17348 69 | }, 70 | { 71 | "posicao": "Zagueiro", 72 | "posicao_abreviacao": "zag", 73 | "clube": "FLU", 74 | "clube_nome": "Fluminense", 75 | "escudo_clube": "https://s.sde.globo.com/media/organizations/2014/04/14/fluminense_60x60.png", 76 | "Atleta": { 77 | "nome": "David Braz de Oliveira Filho", 78 | "apelido": "David Braz", 79 | "apelido_abreviado": "D. Braz", 80 | "foto": "https://s.sde.globo.com/media/person_role/2022/04/20/2787635c960a396f6aca8c8ff11b00d3_FORMATO.png", 81 | "atleta_id": 50317, 82 | "preco_editorial": 5 83 | }, 84 | "clube_id": 266, 85 | "escalacoes": 27580 86 | } 87 | ] 88 | -------------------------------------------------------------------------------- /tests/testdata/mercado_status_aberto.json: -------------------------------------------------------------------------------- 1 | { 2 | "rodada_atual": 3, 3 | "status_mercado": 1, 4 | "esquema_default_id": 4, 5 | "cartoleta_inicial": 100, 6 | "max_ligas_free": 1, 7 | "max_ligas_pro": 10, 8 | "max_ligas_matamata_free": 5, 9 | "max_criar_ligas_matamata_free": 1, 10 | "max_ligas_matamata_pro": 10, 11 | "max_ligas_patrocinadas_free": 2, 12 | "max_ligas_patrocinadas_pro_num": 2, 13 | "game_over": false, 14 | "temporada": 2023, 15 | "reativar": true, 16 | "exibe_sorteio_pro": false, 17 | "fechamento": { 18 | "dia": 15, 19 | "mes": 4, 20 | "ano": 2023, 21 | "hora": 23, 22 | "minuto": 59, 23 | "timestamp": 1681613940 24 | }, 25 | "limites_competicao": { 26 | "total_confronto_pro": 10, 27 | "total_confronto_free": 3, 28 | "criacao_confronto_pro": 10, 29 | "criacao_confronto_free": 1 30 | }, 31 | "times_escalados": 3601523, 32 | "mercado_pos_rodada": false, 33 | "novo_mes_ranking": false, 34 | "degustacao_gatomestre": false, 35 | "nome_rodada": "Rodada 1" 36 | } 37 | -------------------------------------------------------------------------------- /tests/testdata/mercado_status_fechado.json: -------------------------------------------------------------------------------- 1 | { 2 | "rodada_atual": 2, 3 | "status_mercado": 2, 4 | "esquema_default_id": 4, 5 | "cartoleta_inicial": 100, 6 | "max_ligas_free": 1, 7 | "max_ligas_pro": 10, 8 | "max_ligas_matamata_free": 5, 9 | "max_criar_ligas_matamata_free": 1, 10 | "max_ligas_matamata_pro": 10, 11 | "max_ligas_patrocinadas_free": 2, 12 | "max_ligas_patrocinadas_pro_num": 2, 13 | "game_over": false, 14 | "temporada": 2023, 15 | "reativar": true, 16 | "exibe_sorteio_pro": false, 17 | "fechamento": { 18 | "dia": 15, 19 | "mes": 4, 20 | "ano": 2023, 21 | "hora": 23, 22 | "minuto": 59, 23 | "timestamp": 1681613940 24 | }, 25 | "limites_competicao": { 26 | "total_confronto_pro": 10, 27 | "total_confronto_free": 3, 28 | "criacao_confronto_pro": 10, 29 | "criacao_confronto_free": 1 30 | }, 31 | "times_escalados": 194879, 32 | "mercado_pos_rodada": false, 33 | "novo_mes_ranking": false, 34 | "degustacao_gatomestre": false, 35 | "nome_rodada": "Rodada 1" 36 | } 37 | -------------------------------------------------------------------------------- /tests/testdata/partidas.json: -------------------------------------------------------------------------------- 1 | { 2 | "clubes": { 3 | "1371": { 4 | "id": 1371, 5 | "nome": "Cuiabá", 6 | "abreviacao": "CUI", 7 | "escudos": { 8 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/16/cuiaba65.png", 9 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/16/cuiaba45.png", 10 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/16/cuiaba30_.png" 11 | }, 12 | "nome_fantasia": "Cuiabá" 13 | }, 14 | "262": { 15 | "id": 262, 16 | "nome": "Flamengo", 17 | "abreviacao": "FLA", 18 | "escudos": { 19 | "60x60": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-65.png", 20 | "45x45": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-45.png", 21 | "30x30": "https://s.sde.globo.com/media/organizations/2018/04/09/Flamengo-30.png" 22 | }, 23 | "nome_fantasia": "Flamengo" 24 | }, 25 | "263": { 26 | "id": 263, 27 | "nome": "Botafogo", 28 | "abreviacao": "BOT", 29 | "escudos": { 30 | "60x60": "https://s.sde.globo.com/media/organizations/2019/02/04/botafogo-65.png", 31 | "45x45": "https://s.sde.globo.com/media/organizations/2019/02/04/botafogo-45.png", 32 | "30x30": "https://s.sde.globo.com/media/organizations/2019/02/04/botafogo-30.png" 33 | }, 34 | "nome_fantasia": "Botafogo" 35 | }, 36 | "264": { 37 | "id": 264, 38 | "nome": "Corinthians", 39 | "abreviacao": "COR", 40 | "escudos": { 41 | "60x60": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_65.png", 42 | "45x45": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_45.png", 43 | "30x30": "https://s.sde.globo.com/media/organizations/2019/09/30/Corinthians_30.png" 44 | }, 45 | "nome_fantasia": "Corinthians" 46 | }, 47 | "265": { 48 | "id": 265, 49 | "nome": "Bahia", 50 | "abreviacao": "BAH", 51 | "escudos": { 52 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/bahia_60x60.png", 53 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/bahia_45x45.png", 54 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/bahia_30x30.png" 55 | }, 56 | "nome_fantasia": "Bahia" 57 | }, 58 | "266": { 59 | "id": 266, 60 | "nome": "Fluminense", 61 | "abreviacao": "FLU", 62 | "escudos": { 63 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/fluminense_60x60.png", 64 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/fluminense_45x45.png", 65 | "30x30": "https://s.sde.globo.com/media/organizations/2015/01/12/Fluminense-escudo.png" 66 | }, 67 | "nome_fantasia": "Fluminense" 68 | }, 69 | "267": { 70 | "id": 267, 71 | "nome": "Vasco", 72 | "abreviacao": "VAS", 73 | "escudos": { 74 | "60x60": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_65px.png", 75 | "45x45": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_45px.png", 76 | "30x30": "https://s.sde.globo.com/media/organizations/2021/09/04/ESCUDO-VASCO-RGB_30px.png" 77 | }, 78 | "nome_fantasia": "Vasco" 79 | }, 80 | "275": { 81 | "id": 275, 82 | "nome": "Palmeiras", 83 | "abreviacao": "PAL", 84 | "escudos": { 85 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_60x60.png", 86 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_45x45.png", 87 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/palmeiras_30x30.png" 88 | }, 89 | "nome_fantasia": "Palmeiras" 90 | }, 91 | "276": { 92 | "id": 276, 93 | "nome": "São Paulo", 94 | "abreviacao": "SAO", 95 | "escudos": { 96 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/sao_paulo_60x60.png", 97 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/sao_paulo_45x45.png", 98 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/sao_paulo_30x30.png" 99 | }, 100 | "nome_fantasia": "São Paulo" 101 | }, 102 | "277": { 103 | "id": 277, 104 | "nome": "Santos", 105 | "abreviacao": "SAN", 106 | "escudos": { 107 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/santos_60x60.png", 108 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/santos_45x45.png", 109 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/santos_30x30.png" 110 | }, 111 | "nome_fantasia": "Santos" 112 | }, 113 | "280": { 114 | "id": 280, 115 | "nome": "Bragantino", 116 | "abreviacao": "BGT", 117 | "escudos": { 118 | "60x60": "https://s.sde.globo.com/media/organizations/2020/01/01/65.png", 119 | "45x45": "https://s.sde.globo.com/media/organizations/2020/01/01/45.png", 120 | "30x30": "https://s.sde.globo.com/media/organizations/2020/01/01/30.png" 121 | }, 122 | "nome_fantasia": "Bragantino" 123 | }, 124 | "282": { 125 | "id": 282, 126 | "nome": "Atlético-MG", 127 | "abreviacao": "CAM", 128 | "escudos": { 129 | "60x60": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo65px.png", 130 | "45x45": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo45px.png", 131 | "30x30": "https://s.sde.globo.com/media/organizations/2017/11/23/Atletico-Mineiro-escudo30px.png" 132 | }, 133 | "nome_fantasia": "Atlético-MG" 134 | }, 135 | "283": { 136 | "id": 283, 137 | "nome": "Cruzeiro", 138 | "abreviacao": "CRU", 139 | "escudos": { 140 | "60x60": "https://s.sde.globo.com/media/organizations/2021/02/13/65_cruzeiro-2021.png", 141 | "45x45": "https://s.sde.globo.com/media/organizations/2021/02/13/45_cruzeiro-2021.png", 142 | "30x30": "https://s.sde.globo.com/media/organizations/2021/02/13/30_cruzeiro-2021.png" 143 | }, 144 | "nome_fantasia": "Cruzeiro" 145 | }, 146 | "284": { 147 | "id": 284, 148 | "nome": "Grêmio", 149 | "abreviacao": "GRE", 150 | "escudos": { 151 | "60x60": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_60x60.png", 152 | "45x45": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_45x45.png", 153 | "30x30": "https://s.sde.globo.com/media/organizations/2014/04/14/gremio_30x30.png" 154 | }, 155 | "nome_fantasia": "Grêmio" 156 | }, 157 | "285": { 158 | "id": 285, 159 | "nome": "Internacional", 160 | "abreviacao": "INT", 161 | "escudos": { 162 | "60x60": "https://s.sde.globo.com/media/organizations/2016/05/03/inter65.png", 163 | "45x45": "https://s.sde.globo.com/media/organizations/2016/05/03/inter45.png", 164 | "30x30": "https://s.sde.globo.com/media/organizations/2016/05/03/inter30.png" 165 | }, 166 | "nome_fantasia": "Internacional" 167 | }, 168 | "290": { 169 | "id": 290, 170 | "nome": "Goiás", 171 | "abreviacao": "GOI", 172 | "escudos": { 173 | "60x60": "https://s.sde.globo.com/media/organizations/2021/03/01/goias-65.png", 174 | "45x45": "https://s.sde.globo.com/media/organizations/2021/03/01/goias-45.png", 175 | "30x30": "https://s.sde.globo.com/media/organizations/2021/03/01/goias-30.png" 176 | }, 177 | "nome_fantasia": "Goiás" 178 | }, 179 | "293": { 180 | "id": 293, 181 | "nome": "Athlético-PR", 182 | "abreviacao": "CAP", 183 | "escudos": { 184 | "60x60": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-65x65.png", 185 | "45x45": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-45x45.png", 186 | "30x30": "https://s.sde.globo.com/media/organizations/2019/09/09/Athletico-PR-30x30.png" 187 | }, 188 | "nome_fantasia": "Athlético-PR" 189 | }, 190 | "294": { 191 | "id": 294, 192 | "nome": "Coritiba", 193 | "abreviacao": "CFC", 194 | "escudos": { 195 | "60x60": "https://s.sde.globo.com/media/organizations/2017/03/29/coritiba65.png", 196 | "45x45": "https://s.sde.globo.com/media/organizations/2017/03/29/coritiba45.png", 197 | "30x30": "https://s.sde.globo.com/media/organizations/2017/03/29/coritiba30.png" 198 | }, 199 | "nome_fantasia": "Coritiba" 200 | }, 201 | "327": { 202 | "id": 327, 203 | "nome": "América-MG", 204 | "abreviacao": "AME", 205 | "escudos": { 206 | "60x60": "https://s.sde.globo.com/media/organizations/2019/02/28/escudo65_1.png", 207 | "45x45": "https://s.sde.globo.com/media/organizations/2019/02/28/escudo45_1.png", 208 | "30x30": "https://s.sde.globo.com/media/organizations/2019/02/28/escudo30.png" 209 | }, 210 | "nome_fantasia": "América-MG" 211 | }, 212 | "356": { 213 | "id": 356, 214 | "nome": "Fortaleza", 215 | "abreviacao": "FOR", 216 | "escudos": { 217 | "60x60": "https://s.sde.globo.com/media/organizations/2021/09/19/65_0000_Fortaleza-2021.png", 218 | "45x45": "https://s.sde.globo.com/media/organizations/2021/09/19/45_0000_Fortaleza-2021.png", 219 | "30x30": "https://s.sde.globo.com/media/organizations/2021/09/19/30_0000_Fortaleza-2021.png" 220 | }, 221 | "nome_fantasia": "Fortaleza" 222 | } 223 | }, 224 | "partidas": [ 225 | { 226 | "partida_id": 302571, 227 | "clube_casa_id": 262, 228 | "clube_casa_posicao": 1, 229 | "clube_visitante_id": 294, 230 | "aproveitamento_mandante": [ 231 | "", 232 | "", 233 | "", 234 | "", 235 | "" 236 | ], 237 | "aproveitamento_visitante": [ 238 | "", 239 | "", 240 | "", 241 | "", 242 | "" 243 | ], 244 | "clube_visitante_posicao": 1, 245 | "partida_data": "2023-04-16 00:00:00", 246 | "timestamp": 1681614000, 247 | "local": "", 248 | "valida": true, 249 | "placar_oficial_mandante": null, 250 | "placar_oficial_visitante": null, 251 | "status_transmissao_tr": "", 252 | "inicio_cronometro_tr": "", 253 | "status_cronometro_tr": "", 254 | "periodo_tr": "", 255 | "transmissao": { 256 | "label": "", 257 | "url": "" 258 | } 259 | }, 260 | { 261 | "partida_id": 302572, 262 | "clube_casa_id": 263, 263 | "clube_casa_posicao": 1, 264 | "clube_visitante_id": 276, 265 | "aproveitamento_mandante": [ 266 | "", 267 | "", 268 | "", 269 | "", 270 | "" 271 | ], 272 | "aproveitamento_visitante": [ 273 | "", 274 | "", 275 | "", 276 | "", 277 | "" 278 | ], 279 | "clube_visitante_posicao": 1, 280 | "partida_data": "2023-04-16 00:00:00", 281 | "timestamp": 1681614000, 282 | "local": "", 283 | "valida": true, 284 | "placar_oficial_mandante": null, 285 | "placar_oficial_visitante": null, 286 | "status_transmissao_tr": "", 287 | "inicio_cronometro_tr": "", 288 | "status_cronometro_tr": "", 289 | "periodo_tr": "", 290 | "transmissao": { 291 | "label": "", 292 | "url": "" 293 | } 294 | }, 295 | { 296 | "partida_id": 302573, 297 | "clube_casa_id": 275, 298 | "clube_casa_posicao": 1, 299 | "clube_visitante_id": 1371, 300 | "aproveitamento_mandante": [ 301 | "", 302 | "", 303 | "", 304 | "", 305 | "" 306 | ], 307 | "aproveitamento_visitante": [ 308 | "", 309 | "", 310 | "", 311 | "", 312 | "" 313 | ], 314 | "clube_visitante_posicao": 1, 315 | "partida_data": "2023-04-16 00:00:00", 316 | "timestamp": 1681614000, 317 | "local": "", 318 | "valida": true, 319 | "placar_oficial_mandante": null, 320 | "placar_oficial_visitante": null, 321 | "status_transmissao_tr": "", 322 | "inicio_cronometro_tr": "", 323 | "status_cronometro_tr": "", 324 | "periodo_tr": "", 325 | "transmissao": { 326 | "label": "", 327 | "url": "" 328 | } 329 | }, 330 | { 331 | "partida_id": 302574, 332 | "clube_casa_id": 264, 333 | "clube_casa_posicao": 1, 334 | "clube_visitante_id": 283, 335 | "aproveitamento_mandante": [ 336 | "", 337 | "", 338 | "", 339 | "", 340 | "" 341 | ], 342 | "aproveitamento_visitante": [ 343 | "", 344 | "", 345 | "", 346 | "", 347 | "" 348 | ], 349 | "clube_visitante_posicao": 1, 350 | "partida_data": "2023-04-16 00:00:00", 351 | "timestamp": 1681614000, 352 | "local": "", 353 | "valida": true, 354 | "placar_oficial_mandante": null, 355 | "placar_oficial_visitante": null, 356 | "status_transmissao_tr": "", 357 | "inicio_cronometro_tr": "", 358 | "status_cronometro_tr": "", 359 | "periodo_tr": "", 360 | "transmissao": { 361 | "label": "", 362 | "url": "" 363 | } 364 | }, 365 | { 366 | "partida_id": 302575, 367 | "clube_casa_id": 280, 368 | "clube_casa_posicao": 1, 369 | "clube_visitante_id": 265, 370 | "aproveitamento_mandante": [ 371 | "", 372 | "", 373 | "", 374 | "", 375 | "" 376 | ], 377 | "aproveitamento_visitante": [ 378 | "", 379 | "", 380 | "", 381 | "", 382 | "" 383 | ], 384 | "clube_visitante_posicao": 1, 385 | "partida_data": "2023-04-16 00:00:00", 386 | "timestamp": 1681614000, 387 | "local": "", 388 | "valida": true, 389 | "placar_oficial_mandante": null, 390 | "placar_oficial_visitante": null, 391 | "status_transmissao_tr": "", 392 | "inicio_cronometro_tr": "", 393 | "status_cronometro_tr": "", 394 | "periodo_tr": "", 395 | "transmissao": { 396 | "label": "", 397 | "url": "" 398 | } 399 | }, 400 | { 401 | "partida_id": 302576, 402 | "clube_casa_id": 282, 403 | "clube_casa_posicao": 1, 404 | "clube_visitante_id": 267, 405 | "aproveitamento_mandante": [ 406 | "", 407 | "", 408 | "", 409 | "", 410 | "" 411 | ], 412 | "aproveitamento_visitante": [ 413 | "", 414 | "", 415 | "", 416 | "", 417 | "" 418 | ], 419 | "clube_visitante_posicao": 1, 420 | "partida_data": "2023-04-16 00:00:00", 421 | "timestamp": 1681614000, 422 | "local": "", 423 | "valida": true, 424 | "placar_oficial_mandante": null, 425 | "placar_oficial_visitante": null, 426 | "status_transmissao_tr": "", 427 | "inicio_cronometro_tr": "", 428 | "status_cronometro_tr": "", 429 | "periodo_tr": "", 430 | "transmissao": { 431 | "label": "", 432 | "url": "" 433 | } 434 | }, 435 | { 436 | "partida_id": 302577, 437 | "clube_casa_id": 284, 438 | "clube_casa_posicao": 1, 439 | "clube_visitante_id": 277, 440 | "aproveitamento_mandante": [ 441 | "", 442 | "", 443 | "", 444 | "", 445 | "" 446 | ], 447 | "aproveitamento_visitante": [ 448 | "", 449 | "", 450 | "", 451 | "", 452 | "" 453 | ], 454 | "clube_visitante_posicao": 1, 455 | "partida_data": "2023-04-16 00:00:00", 456 | "timestamp": 1681614000, 457 | "local": "", 458 | "valida": true, 459 | "placar_oficial_mandante": null, 460 | "placar_oficial_visitante": null, 461 | "status_transmissao_tr": "", 462 | "inicio_cronometro_tr": "", 463 | "status_cronometro_tr": "", 464 | "periodo_tr": "", 465 | "transmissao": { 466 | "label": "", 467 | "url": "" 468 | } 469 | }, 470 | { 471 | "partida_id": 302578, 472 | "clube_casa_id": 293, 473 | "clube_casa_posicao": 1, 474 | "clube_visitante_id": 290, 475 | "aproveitamento_mandante": [ 476 | "", 477 | "", 478 | "", 479 | "", 480 | "" 481 | ], 482 | "aproveitamento_visitante": [ 483 | "", 484 | "", 485 | "", 486 | "", 487 | "" 488 | ], 489 | "clube_visitante_posicao": 1, 490 | "partida_data": "2023-04-16 00:00:00", 491 | "timestamp": 1681614000, 492 | "local": "", 493 | "valida": true, 494 | "placar_oficial_mandante": null, 495 | "placar_oficial_visitante": null, 496 | "status_transmissao_tr": "", 497 | "inicio_cronometro_tr": "", 498 | "status_cronometro_tr": "", 499 | "periodo_tr": "", 500 | "transmissao": { 501 | "label": "", 502 | "url": "" 503 | } 504 | }, 505 | { 506 | "partida_id": 302579, 507 | "clube_casa_id": 356, 508 | "clube_casa_posicao": 1, 509 | "clube_visitante_id": 285, 510 | "aproveitamento_mandante": [ 511 | "", 512 | "", 513 | "", 514 | "", 515 | "" 516 | ], 517 | "aproveitamento_visitante": [ 518 | "", 519 | "", 520 | "", 521 | "", 522 | "" 523 | ], 524 | "clube_visitante_posicao": 1, 525 | "partida_data": "2023-04-16 00:00:00", 526 | "timestamp": 1681614000, 527 | "local": "", 528 | "valida": true, 529 | "placar_oficial_mandante": null, 530 | "placar_oficial_visitante": null, 531 | "status_transmissao_tr": "", 532 | "inicio_cronometro_tr": "", 533 | "status_cronometro_tr": "", 534 | "periodo_tr": "", 535 | "transmissao": { 536 | "label": "", 537 | "url": "" 538 | } 539 | }, 540 | { 541 | "partida_id": 302580, 542 | "clube_casa_id": 327, 543 | "clube_casa_posicao": 1, 544 | "clube_visitante_id": 266, 545 | "aproveitamento_mandante": [ 546 | "", 547 | "", 548 | "", 549 | "", 550 | "" 551 | ], 552 | "aproveitamento_visitante": [ 553 | "", 554 | "", 555 | "", 556 | "", 557 | "" 558 | ], 559 | "clube_visitante_posicao": 1, 560 | "partida_data": "2023-04-16 00:00:00", 561 | "timestamp": 1681614000, 562 | "local": "", 563 | "valida": true, 564 | "placar_oficial_mandante": null, 565 | "placar_oficial_visitante": null, 566 | "status_transmissao_tr": "", 567 | "inicio_cronometro_tr": "", 568 | "status_cronometro_tr": "", 569 | "periodo_tr": "", 570 | "transmissao": { 571 | "label": "", 572 | "url": "" 573 | } 574 | } 575 | ], 576 | "rodada": 1 577 | } 578 | -------------------------------------------------------------------------------- /tests/testdata/patrocinadores.json: -------------------------------------------------------------------------------- 1 | { 2 | "62": { 3 | "cor_nome_liga": "FFFFFF", 4 | "tipo_ranking": "rodada", 5 | "url_termo_uso": null, 6 | "descricao": "Entre na Liga Gato Mestre e receba dicas e estatísticas exclusivas!", 7 | "slug": "liga-gato-mestre", 8 | "url_link": "https://gatomestre.ge.globo.com/", 9 | "url_editoria_ge": null, 10 | "url_flamula_png": null, 11 | "autorizacao_promocao": null, 12 | "img_background": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/background-liga/background-gatomestre-2023.jpg", 13 | "img_marca_patrocinador": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/flamula/flamula_gato-mestre-23.svg", 14 | "img_marca_patrocinador_png": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/patrocinador/62/patrocinador-gato-mestre.png", 15 | "nome": "Liga Gato Mestre", 16 | "url_flamula_svg": null, 17 | "nome_patrocinador": "Gato Mestre", 18 | "servico_glive": null, 19 | "total_times": null, 20 | "posicao_inicial": 0, 21 | "liga_id": 62, 22 | "liga_editorial_id": 16, 23 | "destaque": true, 24 | "optin": false, 25 | "premiada": false 26 | }, 27 | "64": { 28 | "cor_nome_liga": "FFFFFF", 29 | "tipo_ranking": "rodada", 30 | "url_termo_uso": null, 31 | "descricao": "Liga Globoplay", 32 | "slug": "liga-globoplay", 33 | "url_link": "https://globoplay.globo.com", 34 | "url_editoria_ge": null, 35 | "url_flamula_png": null, 36 | "autorizacao_promocao": null, 37 | "img_background": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/background-liga/backgound-liga-globoplay-23.jpg", 38 | "img_marca_patrocinador": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/flamula/flamula_liga-globoplay-23.svg", 39 | "img_marca_patrocinador_png": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/patrocinador/64/patrocinador-globoplay.png", 40 | "nome": "Liga Globoplay", 41 | "url_flamula_svg": null, 42 | "nome_patrocinador": "Globoplay", 43 | "servico_glive": null, 44 | "total_times": null, 45 | "posicao_inicial": 0, 46 | "liga_id": 64, 47 | "liga_editorial_id": 21, 48 | "destaque": true, 49 | "optin": false, 50 | "premiada": false 51 | }, 52 | "67": { 53 | "cor_nome_liga": "FFFFFF", 54 | "tipo_ranking": "rodada", 55 | "url_termo_uso": null, 56 | "descricao": "Liga do canal Premiere. Para os mitos que sabem tudo de Brasileirão e curtem todos os jogos ao vivo!", 57 | "slug": "premiere", 58 | "url_link": "http://globosatplay.globo.com/premierefc/", 59 | "url_editoria_ge": null, 60 | "url_flamula_png": null, 61 | "autorizacao_promocao": null, 62 | "img_background": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/background-liga/background-premiere.jpg", 63 | "img_marca_patrocinador": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/flamula/flamula-premiere-02-1.svg", 64 | "img_marca_patrocinador_png": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/patrocinador/67.png", 65 | "nome": "Premiere", 66 | "url_flamula_svg": null, 67 | "nome_patrocinador": "Premiere", 68 | "servico_glive": null, 69 | "total_times": null, 70 | "posicao_inicial": 0, 71 | "liga_id": 67, 72 | "liga_editorial_id": 7, 73 | "destaque": false, 74 | "optin": false, 75 | "premiada": false 76 | }, 77 | "68": { 78 | "cor_nome_liga": "FFFFFF", 79 | "tipo_ranking": "rodada", 80 | "url_termo_uso": null, 81 | "descricao": "Essa é a liga de quem quer ficar por dentro de tudo que acontece no Brasileirão!", 82 | "slug": "liga-do-ge", 83 | "url_link": "http://ge.globo", 84 | "url_editoria_ge": null, 85 | "url_flamula_png": null, 86 | "autorizacao_promocao": null, 87 | "img_background": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/patrocinador/68/bg-ge-2020.png", 88 | "img_marca_patrocinador": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/patrocinador/68/flamula-ge-2020.svg", 89 | "img_marca_patrocinador_png": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/default/patrocinador/68/logo-ge-2020.png", 90 | "nome": "Liga do GE", 91 | "url_flamula_svg": null, 92 | "nome_patrocinador": "Globoesporte.com", 93 | "servico_glive": null, 94 | "total_times": null, 95 | "posicao_inicial": 0, 96 | "liga_id": 68, 97 | "liga_editorial_id": 8, 98 | "destaque": false, 99 | "optin": false, 100 | "premiada": false 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /tests/testdata/pos_rodada_destaques.json: -------------------------------------------------------------------------------- 1 | { 2 | "media_cartoletas": 115.8235753058391, 3 | "media_pontos": 46.6480728839843, 4 | "mito_rodada": { 5 | "time_id": 896224, 6 | "clube_id": 262, 7 | "esquema_id": 3, 8 | "cadun_id": 52857043, 9 | "facebook_id": 184159031978653, 10 | "foto_perfil": "https://graph.facebook.com/v2.2/184159031978653/picture?width=100&height=100", 11 | "nome": "gama campos fc", 12 | "nome_cartola": "malmal", 13 | "slug": "gama-campos-fc", 14 | "tipo_escudo": 1, 15 | "cor_fundo_escudo": "000000", 16 | "cor_borda_escudo": "ffcb00", 17 | "cor_primaria_estampa_escudo": "ff241d", 18 | "cor_secundaria_estampa_escudo": "ff241d", 19 | "url_escudo_svg": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_46/escudo/43/24/59/005285704320170430112459", 20 | "url_escudo_png": "https://s2.glbimg.com/dFQNZUmpdbqNrX9UGVxV3TzN5WM=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_46/escudo/43/24/59/005285704320170430112459", 21 | "url_camisa_svg": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_46/camisa/43/24/59/005285704320170430112459", 22 | "url_camisa_png": "https://s2.glbimg.com/3_4yMw5woWs7deT6YOa9hgH-RLs=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_46/camisa/43/24/59/005285704320170430112459", 23 | "url_escudo_placeholder_png": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/placeholder/escudo.png", 24 | "url_camisa_placeholder_png": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/placeholder/camisa.png", 25 | "tipo_estampa_escudo": 2, 26 | "tipo_adorno": 2, 27 | "tipo_camisa": 2, 28 | "tipo_estampa_camisa": 4, 29 | "cor_camisa": "000000", 30 | "cor_primaria_estampa_camisa": "ff241d", 31 | "cor_secundaria_estampa_camisa": "ff241d", 32 | "rodada_time_id": 2, 33 | "assinante": false, 34 | "cadastro_completo": true, 35 | "patrocinador1_id": 62, 36 | "patrocinador2_id": 66, 37 | "temporada_inicial": 2014, 38 | "simplificado": false 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/testdata/time.json: -------------------------------------------------------------------------------- 1 | { 2 | "atletas": [], 3 | "time": { 4 | "temporada_inicial": 2013, 5 | "cor_fundo_escudo": "ffffff", 6 | "cor_camisa": "ffffff", 7 | "cor_borda_escudo": "000000", 8 | "foto_perfil": "https://graph.facebook.com/v10.0/100000083906892/picture?width=100&height=100&access_token=289255557788943|p1h0FLxpyM0z4_NnY8WK5RM8k-A", 9 | "nome_cartola": "Vicente Neto", 10 | "globo_id": "", 11 | "nome": "Falydos FC", 12 | "url_escudo_svg": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_201/escudo/02/38/23/0087d7b2c9-e8cf-48a7-baa3-ee2340a2170220220328013823", 13 | "url_escudo_png": "https://s2.glbimg.com/0BH9mt4B0IdBJ_aAfmQ2dfH7O5E=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_201/escudo/02/38/23/0087d7b2c9-e8cf-48a7-baa3-ee2340a2170220220328013823", 14 | "url_camisa_svg": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_211/camisa/02/51/36/0087d7b2c9-e8cf-48a7-baa3-ee2340a2170220230318215136", 15 | "url_camisa_png": "https://s2.glbimg.com/GCpu_SziYe4IhvuGwkuoOWjJKNw=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_211/camisa/02/51/36/0087d7b2c9-e8cf-48a7-baa3-ee2340a2170220230318215136", 16 | "slug": "falydos-fc", 17 | "cor_secundaria_estampa_escudo": "ffffff", 18 | "sorteio_pro_num": null, 19 | "cor_primaria_estampa_camisa": "0066ff", 20 | "cor_secundaria_estampa_camisa": "ffffff", 21 | "cor_primaria_estampa_escudo": "0066ff", 22 | "rodada_time_id": 1, 23 | "facebook_id": 100000083906892, 24 | "tipo_escudo": 3, 25 | "time_id": 471815, 26 | "tipo_adorno": 1, 27 | "esquema_id": 3, 28 | "tipo_estampa_camisa": 6, 29 | "tipo_estampa_escudo": 3, 30 | "patrocinador1_id": 62, 31 | "clube_id": 262, 32 | "tipo_camisa": 1, 33 | "patrocinador2_id": 68, 34 | "assinante": true, 35 | "simplificado": false, 36 | "cadastro_completo": true, 37 | "lgpd_removido": false, 38 | "lgpd_quarentena": false 39 | }, 40 | "pontos_campeonato": null, 41 | "capitao_id": null, 42 | "pontos": null, 43 | "esquema_id": 3, 44 | "rodada_atual": 1, 45 | "patrimonio": 100, 46 | "valor_time": 0, 47 | "ranking": { 48 | "atual": { 49 | "ranking_id": 1, 50 | "mes": 0, 51 | "posicao": 0 52 | }, 53 | "anterior": { 54 | "ranking_id": 1, 55 | "mes": 0, 56 | "posicao": 0 57 | }, 58 | "melhor_ranking_id": 1 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /tests/testdata/times.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "nome_cartola": "Vicente Neto", 4 | "slug": "falydos-fc", 5 | "url_escudo_png": "https://s2.glbimg.com/0BH9mt4B0IdBJ_aAfmQ2dfH7O5E=/https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_201/escudo/02/38/23/0087d7b2c9-e8cf-48a7-baa3-ee2340a2170220220328013823", 6 | "url_escudo_svg": "https://s3.glbimg.com/v1/AUTH_58d78b787ec34892b5aaa0c7a146155f/cartola_svg_201/escudo/02/38/23/0087d7b2c9-e8cf-48a7-baa3-ee2340a2170220220328013823", 7 | "foto_perfil": "https://graph.facebook.com/v10.0/100000083906892/picture?width=100&height=100&access_token=289255557788943|p1h0FLxpyM0z4_NnY8WK5RM8k-A", 8 | "nome": "Falydos FC", 9 | "facebook_id": 100000083906892, 10 | "time_id": 471815, 11 | "assinante": true, 12 | "lgpd_removido": false, 13 | "lgpd_quarentena": false 14 | } 15 | ] 16 | --------------------------------------------------------------------------------