def test_legal_formats() -> None: d = Deck({'id': 0}) d.maindeck = [CardRef('Swamp', 59)] d.sideboard = [] assert len(d.all_cards()) == 59 formats = legality.legal_formats(d) assert len(formats) == 0 d.maindeck = [CardRef('Swamp', 60)] formats = legality.legal_formats(d) assert 'Penny Dreadful' in formats assert 'Legacy' in formats assert 'Penny Dreadful EMN' in formats formats = legality.legal_formats(d, {'Penny Dreadful'}) assert len(formats) == 1 assert 'Penny Dreadful' in formats assert 'Legacy' not in formats d.maindeck = [CardRef('Swamp', 55), CardRef('Think Twice', 5)] formats = legality.legal_formats(d) assert len(d.all_cards()) == 60 assert len(legality.legal_formats(d)) == 0 d.maindeck = [CardRef('Swamp', 56), CardRef('Think Twice', 4)] formats = legality.legal_formats(d) assert 'Legacy' in formats assert 'Modern' in formats d.sideboard = [CardRef('Swamp', 15), CardRef('Think Twice', 1)] formats = legality.legal_formats(d) assert len(legality.legal_formats(d)) == 0 d.maindeck = [CardRef('Swamp', 56), CardRef('Fork', 4)] d.sideboard = [CardRef('Swamp', 15)] formats = legality.legal_formats(d) assert 'Legacy' in formats assert 'Modern' not in formats d.maindeck = [CardRef('Swamp', 60)] d.sideboard = [CardRef('Swamp', 15)] formats = legality.legal_formats(d) assert 'Standard' in formats assert 'Modern' in formats assert 'Legacy' in formats assert 'Vintage' in formats assert 'Penny Dreadful' in formats assert 'Penny Dreadful EMN' in formats
def load_decks_heavy(where: str = '1 = 1', having: str = '1 = 1', order_by: Optional[str] = None, limit: str = '', season_id: Optional[int] = None ) -> List[Deck]: if order_by is None: order_by = 'active_date DESC, d.finish IS NULL, d.finish' sql = """ SELECT d.id, d.name AS original_name, d.created_date, d.updated_date, SUM(CASE WHEN dm.games > IFNULL(odm.games, 0) THEN 1 ELSE 0 END) AS wins, SUM(CASE WHEN dm.games < odm.games THEN 1 ELSE 0 END) AS losses, SUM(CASE WHEN dm.games = odm.games THEN 1 ELSE 0 END) AS draws, d.finish, d.archetype_id, d.url AS source_url, d.competition_id, c.name AS competition_name, c.end_date AS competition_end_date, c.top_n AS competition_top_n, ct.name AS competition_type_name, d.identifier, {person_query} AS person, p.id AS person_id, p.banned, p.discord_id, d.decklist_hash, d.retired, d.reviewed, s.name AS source_name, IFNULL(a.name, '') AS archetype_name, cache.normalized_name AS name, cache.colors, cache.colored_symbols, cache.legal_formats, ROUND(cache.omw * 100, 2) AS omw, season.id AS season_id, IFNULL(MAX(m.date), d.created_date) AS active_date FROM deck AS d LEFT JOIN person AS p ON d.person_id = p.id LEFT JOIN source AS s ON d.source_id = s.id LEFT JOIN archetype AS a ON d.archetype_id = a.id {competition_join} LEFT JOIN deck_cache AS cache ON d.id = cache.deck_id LEFT JOIN deck_match AS dm ON d.id = dm.deck_id LEFT JOIN `match` AS m ON dm.match_id = m.id LEFT JOIN deck_match AS odm ON odm.deck_id <> d.id AND dm.match_id = odm.match_id {season_join} WHERE ({where}) AND ({season_query}) GROUP BY d.id, d.competition_id, -- Every deck has only one competition_id but if we want to use competition_id in the HAVING clause we need this. season.id -- In theory this is not necessary as all decks are in a single season and we join on the date but MySQL cannot work that out so give it the hint it needs. HAVING {having} ORDER BY {order_by} {limit} """.format(person_query=query.person_query(), competition_join=query.competition_join(), season_join=query.season_join(), where=where, season_query=query.season_query(season_id, 'season.id'), having=having, order_by=order_by, limit=limit) db().execute('SET group_concat_max_len=100000') rows = db().select(sql) decks = [] for row in rows: d = Deck(row) d.maindeck = [] d.sideboard = [] d.competition_top_n = Top(d.competition_top_n or 0) d.colored_symbols = json.loads(d.colored_symbols or '[]') d.colors = json.loads(d.colors or '[]') d.legal_formats = set(json.loads(d.legal_formats or '[]')) d.active_date = dtutil.ts2dt(d.active_date) d.created_date = dtutil.ts2dt(d.created_date) d.updated_date = dtutil.ts2dt(d.updated_date) if d.competition_end_date: d.competition_end_date = dtutil.ts2dt(d.competition_end_date) d.can_draw = 'Divine Intervention' in [card.name for card in d.all_cards()] d.wins = int(d.wins) d.losses = int(d.losses) d.draws = int(d.draws) decks.append(d) load_cards(decks) load_competitive_stats(decks) for d in decks: expiry = 60 if d.is_in_current_run() else 3600 redis.store('decksite:deck:{id}'.format(id=d.id), d, ex=expiry) return decks