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
Exemplo n.º 2
0
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