def setup_verified_test(session):
    # Setup
    blocks = [
        Block(blockhash="0x1", number=1, parenthash="", is_current=False),
        Block(blockhash="0x2", number=2, parenthash="", is_current=True),
    ]
    users = [
        User(
            blockhash="0x1",
            blocknumber=1,
            user_id=1,
            is_current=True,
            wallet="0xFakeWallet1",
            created_at=datetime.now(),
            updated_at=datetime.now(),
            is_verified=False,
        ),
        User(
            blockhash="0x2",
            blocknumber=2,
            user_id=2,
            is_current=True,
            wallet="0xFakeWallet2",
            created_at=datetime.now(),
            updated_at=datetime.now(),
            is_verified=True,
        ),
    ]

    challenges = [
        Challenge(
            id="referrals",
            type=ChallengeType.aggregate,
            active=True,
            amount="1",
            step_count=5,
        ),
        Challenge(
            id="ref-v",
            type=ChallengeType.aggregate,
            active=True,
            amount="1",
            step_count=500,
        ),
    ]

    # Wipe any existing challenges in the DB from running migrations, etc
    session.query(Challenge).delete()
    session.commit()
    session.add_all(blocks)
    session.commit()
    session.add_all(users)
    session.add_all(challenges)
    session.commit()

    redis_conn = redis.Redis.from_url(url=REDIS_URL)
    bus = ChallengeEventBus(redis_conn)
    bus.register_listener(DEFAULT_EVENT, referral_challenge_manager)
    bus.register_listener(DEFAULT_EVENT, verified_referral_challenge_manager)
    return bus
def create_new_challenges(session, allowed_challenge_types=None):
    if not allowed_challenge_types:
        allowed_challenge_types = []
    challenges_dicts = get_challenges_dicts()
    challenges = []
    existing_challenges = session.query(Challenge).all()
    existing_ids = {c.id for c in existing_challenges}

    # filter to only new challenges
    new_challenges = list(
        filter(lambda c: c.get("id") not in existing_ids, challenges_dicts))

    # if allowed_challenge_typed defined, filter out non-type
    if allowed_challenge_types:
        new_challenges = [
            challenge for challenge in new_challenges
            if challenge.get("type") in allowed_challenge_types
        ]
    logger.info(f"Adding challenges: {new_challenges}")

    # Add all the new challenges
    for challenge_dict in new_challenges:
        challenge = Challenge(
            id=challenge_dict.get("id"),
            type=challenge_dict.get("type"),
            amount=challenge_dict.get("amount"),
            active=challenge_dict.get("active"),
            starting_block=challenge_dict.get("starting_block"),
            step_count=challenge_dict.get("step_count"),
        )
        challenges.append(challenge)
    session.add_all(challenges)

    # Update any challenges whose active state / amount / step count / starting block changed
    existing_challenge_map = {
        challenge.id: challenge
        for challenge in existing_challenges
    }
    for challenge_dict in challenges_dicts:
        existing = existing_challenge_map.get(challenge_dict["id"])
        if existing:
            existing.active = challenge_dict.get("active")
            existing.amount = challenge_dict.get("amount")
            existing.step_count = challenge_dict.get("step_count")
            existing.starting_block = challenge_dict.get("starting_block")
Esempio n. 3
0
def setup_challenges(app):
    with app.app_context():
        db = get_db()
        populate_mock_db_blocks(db, 99, 110)
        challenges = [
            Challenge(
                id="test_challenge_1",
                type=ChallengeType.numeric,
                amount="5",
                step_count=3,
                active=False,
                starting_block=100,
            ),
            Challenge(
                id="test_challenge_2",
                type=ChallengeType.boolean,
                amount="5",
                active=True,
                starting_block=100,
            ),
            Challenge(
                id="test_challenge_3",
                type=ChallengeType.aggregate,
                amount="5",
                active=True,
                starting_block=100,
            ),
        ]

        non_current_users = [
            User(
                blockhash=hex(99),
                blocknumber=99,
                txhash=f"xyz{i}",
                user_id=i,
                is_current=False,
                handle=f"TestHandle{i}",
                handle_lc=f"testhandle{i}",
                wallet=f"0x{i}",
                is_creator=False,
                is_verified=False,
                name=f"test_name{i}",
                created_at=datetime.now(),
                updated_at=datetime.now(),
            ) for i in range(7)
        ]
        users = [
            User(
                blockhash=hex(99),
                blocknumber=99,
                txhash=f"xyz{i}",
                user_id=i,
                is_current=True,
                handle=f"TestHandle{i}",
                handle_lc=f"testhandle{i}",
                wallet=f"0x{i}",
                is_creator=False,
                is_verified=False,
                name=f"test_name{i}",
                created_at=datetime.now(),
                updated_at=datetime.now(),
            ) for i in range(7)
        ]
        user_bank_accounts = [
            UserBankAccount(
                signature=f"0x{i}",
                ethereum_address=users[i].wallet,
                bank_account=f"0x{i}",
                created_at=datetime.now(),
            ) for i in range(7)
        ]

        user_challenges = [
            UserChallenge(
                challenge_id="test_challenge_1",
                user_id=1,
                specifier="1",
                is_complete=False,
                current_step_count=1,
            ),
            UserChallenge(
                challenge_id="test_challenge_1",
                user_id=2,
                specifier="2",
                is_complete=True,
                current_step_count=3,
                completed_blocknumber=100,
            ),
            UserChallenge(
                challenge_id="test_challenge_2",
                user_id=3,
                specifier="3",
                is_complete=False,
            ),
            UserChallenge(
                challenge_id="test_challenge_2",
                user_id=4,
                specifier="4",
                is_complete=True,
                completed_blocknumber=102,
            ),
            UserChallenge(
                challenge_id="test_challenge_2",
                user_id=5,
                specifier="5",
                is_complete=True,
                completed_blocknumber=102,
            ),
            UserChallenge(
                challenge_id="test_challenge_3",
                user_id=6,
                specifier="6",
                is_complete=True,
                completed_blocknumber=100,
            ),
        ]

        with db.scoped_session() as session:
            session.add_all(challenges)
            session.flush()
            session.add_all(non_current_users)
            session.add_all(users)
            session.add_all(user_bank_accounts)
            session.add_all(user_challenges)
def test_catches_exceptions_in_single_processor(app):
    """Ensure that if a single processor fails, the others still succeed"""
    with app.app_context():
        db = get_db()

    redis_conn = redis.Redis.from_url(url=REDIS_URL)

    bus = ChallengeEventBus(redis_conn)
    with db.scoped_session() as session:

        session.add_all([
            Challenge(
                id="test_challenge_1",
                type=ChallengeType.numeric,
                amount="5",
                step_count=3,
                active=True,
            ),
            Challenge(
                id="test_challenge_2",
                type=ChallengeType.numeric,
                amount="5",
                step_count=3,
                active=True,
            ),
        ])
        session.commit()

        correct_manager = ChallengeManager("test_challenge_1",
                                           DefaultUpdater())
        broken_manager = ChallengeManager("test_challenge_2", BrokenUpdater())
        TEST_EVENT = "TEST_EVENT"
        TEST_EVENT_2 = "TEST_EVENT_2"
        bus.register_listener(TEST_EVENT, correct_manager)
        bus.register_listener(TEST_EVENT_2, broken_manager)

        with bus.use_scoped_dispatch_queue():
            # dispatch the broken one first
            bus.dispatch(TEST_EVENT_2, 101, 1)
            bus.dispatch(TEST_EVENT, 101, 1)
        try:
            bus.process_events(session)
        except:
            # pylint: disable=W0707
            raise Exception("Shouldn't have propogated error!")
        challenge_1_state = correct_manager.get_user_challenge_state(
            session, ["1"])
        # Make sure that the 'correct_manager' still executes
        assert len(challenge_1_state) == 1
        assert challenge_1_state[0].current_step_count == 1
        # Make sure broken manager didn't do anything
        challenge_2_state = broken_manager.get_user_challenge_state(
            session, ["1"])
        assert len(challenge_2_state) == 0

        # Try the other order
        with bus.use_scoped_dispatch_queue():
            # dispatch the correct one first
            bus.dispatch(TEST_EVENT, 101, 1)
            bus.dispatch(TEST_EVENT_2, 101, 1)
        try:
            bus.process_events(session)
        except:
            # pylint: disable=W0707
            raise Exception("Shouldn't have propogated error!")
        challenge_1_state = correct_manager.get_user_challenge_state(
            session, ["1"])
        assert len(challenge_1_state) == 1
        assert challenge_1_state[0].current_step_count == 2
        # Make sure broken manager didn't do anything
        challenge_2_state = broken_manager.get_user_challenge_state(
            session, ["1"])
        assert len(challenge_2_state) == 0
def setup_challenges(app):
    with app.app_context():
        db = get_db()
        challenges = [
            Challenge(
                id="test_challenge_1",
                type=ChallengeType.numeric,
                amount="5",
                step_count=3,
                active=True,
                starting_block=100,
            ),
            Challenge(
                id="test_challenge_2",
                type=ChallengeType.boolean,
                amount="5",
                active=True,
                starting_block=100,
            ),
            Challenge(
                id="test_challenge_3",
                type=ChallengeType.aggregate,
                amount="5",
                step_count=5,
                active=True,
                starting_block=100,
            ),
            Challenge(
                id="some_inactive_challenge",
                type=ChallengeType.numeric,
                amount="5",
                step_count=5,
                active=False,
                starting_block=0,
            ),
        ]
        user_challenges = [
            UserChallenge(
                challenge_id="test_challenge_1",
                user_id=1,
                specifier="1",
                is_complete=False,
                current_step_count=1,
            ),
            UserChallenge(
                challenge_id="test_challenge_1",
                user_id=2,
                specifier="2",
                is_complete=True,
                current_step_count=3,
                completed_blocknumber=100,
            ),
            UserChallenge(
                challenge_id="test_challenge_1",
                user_id=3,
                specifier="3",
                current_step_count=2,
                is_complete=False,
            ),
            UserChallenge(
                challenge_id="test_challenge_2",
                user_id=4,
                specifier="4",
                is_complete=True,
            ),
            UserChallenge(
                challenge_id="test_challenge_1",
                user_id=5,
                specifier="5",
                is_complete=False,
                current_step_count=2,
            ),
        ]

        with db.scoped_session() as session:
            # Wipe any existing challenges in the DB from running migrations, etc
            session.query(Challenge).delete()
            session.add_all(challenges)
            session.flush()
            session.add_all(user_challenges)
def setup_db(session):
    blocks = [Block(blockhash="0x1", number=1, parenthash="", is_current=True)]
    users = [
        User(
            blockhash="0x1",
            blocknumber=1,
            user_id=1,
            is_current=True,
            wallet="0x38C68fF3926bf4E68289672F75ee1543117dD9B3",
            created_at=datetime.now(),
            updated_at=datetime.now(),
        )
    ]
    challenges = [
        Challenge(
            id="boolean_challenge_1",
            type=ChallengeType.boolean,
            active=True,
            amount="5",
        ),
        Challenge(
            id="boolean_challenge_2",
            type=ChallengeType.boolean,
            active=True,
            amount="5",
        ),
        Challenge(
            id="boolean_challenge_3",
            type=ChallengeType.boolean,
            active=True,
            amount="5",
        ),
        # No progress on this, but active
        # should be returned
        Challenge(
            id="boolean_challenge_4",
            type=ChallengeType.boolean,
            active=True,
            amount="5",
        ),
        # Inactive, with no progress
        Challenge(
            id="boolean_challenge_5",
            type=ChallengeType.boolean,
            active=False,
            amount="5",
        ),
        # Inactive, WITH progress
        Challenge(
            id="boolean_challenge_6",
            type=ChallengeType.boolean,
            active=False,
            amount="5",
        ),
        Challenge(
            id="trending_challenge_1",
            type=ChallengeType.trending,
            active=True,
            amount="5",
        ),
        Challenge(
            id="aggregate_challenge_1",
            type=ChallengeType.aggregate,
            active=True,
            amount="5",
            step_count=3,
        ),
        Challenge(
            id="aggregate_challenge_2",
            type=ChallengeType.aggregate,
            active=True,
            amount="5",
            step_count=2,
        ),
        Challenge(
            id="aggregate_challenge_3",
            type=ChallengeType.aggregate,
            active=True,
            amount="5",
            step_count=2,
        ),
        Challenge(id="trending_1",
                  type=ChallengeType.trending,
                  active=True,
                  amount="5"),
        Challenge(id="trending_2",
                  type=ChallengeType.trending,
                  active=True,
                  amount="5"),
        Challenge(id="trending_3",
                  type=ChallengeType.trending,
                  active=True,
                  amount="5"),
    ]
    user_challenges = [
        # Finished the first challenge, disbursed
        UserChallenge(
            challenge_id="boolean_challenge_1",
            user_id=1,
            specifier="1",
            is_complete=True,
        ),
        # Did finish the second challenge, did not disburse
        UserChallenge(
            challenge_id="boolean_challenge_2",
            user_id=1,
            specifier="1",
            is_complete=True,
        ),
        # Did not finish challenge 3
        UserChallenge(
            challenge_id="boolean_challenge_3",
            user_id=1,
            specifier="1",
            is_complete=False,
        ),
        # Inactive challenge
        UserChallenge(
            challenge_id="boolean_challenge_6",
            user_id=1,
            specifier="1",
            is_complete=True,
        ),
        UserChallenge(
            challenge_id="aggregate_challenge_1",
            user_id=1,
            specifier="1-2",  # compound specifiers, like if user1 invites user2
            is_complete=True,
        ),
        # Ensure that a non-complete user-challenge isn't counted towards
        # aggregate challenge score
        UserChallenge(
            challenge_id="aggregate_challenge_1",
            user_id=1,
            specifier="1-3",
            is_complete=False,
        ),
        UserChallenge(
            challenge_id="aggregate_challenge_2",
            user_id=1,
            specifier="1-2",
            is_complete=True,
        ),
        UserChallenge(
            challenge_id="aggregate_challenge_2",
            user_id=1,
            specifier="1-3",
            is_complete=True,
        ),
        # Trending 1 should be finished and included
        UserChallenge(
            challenge_id="trending_1",
            user_id=1,
            specifier="06-01-2020",
            is_complete=True,
        ),
        # Trending 2 should not be included
        UserChallenge(
            challenge_id="trending_2",
            user_id=1,
            specifier="06-01-2020",
            is_complete=False,
        ),
    ]
    disbursements = [
        ChallengeDisbursement(
            challenge_id="boolean_challenge_1",
            user_id=1,
            amount="5",
            signature="1",
            slot=1,
            specifier="1",
        )
    ]

    # Wipe any existing challenges in the DB from running migrations, etc
    session.query(Challenge).delete()
    session.commit()
    session.add_all(blocks)
    session.commit()
    session.add_all(users)
    session.commit()
    session.add_all(challenges)
    session.commit()
    session.add_all(user_challenges)
    session.commit()
    session.add_all(disbursements)

    redis_conn = redis.Redis.from_url(url=REDIS_URL)
    bus = ChallengeEventBus(redis_conn)
    challenge_types = [
        "boolean_challenge_1",
        "boolean_challenge_2",
        "boolean_challenge_3",
        "boolean_challenge_4",
        "boolean_challenge_5",
        "boolean_challenge_6",
        "trending_challenge_1",
        "aggregate_challenge_1",
        "aggregate_challenge_2",
        "aggregate_challenge_3",
        "trending_1",
        "trending_2",
        "trending_3",
    ]
    for ct in challenge_types:
        bus.register_listener(
            DEFAULT_EVENT,
            ChallengeManager(ct, DefaultUpdater()),
        )
    return bus
def setup_listen_streak_challenge(session):
    # Setup
    blocks = [
        Block(blockhash="0x1", number=1, parenthash="", is_current=False),
        Block(blockhash="0x2", number=2, parenthash="", is_current=True),
    ]
    users = [
        User(
            blockhash="0x1",
            blocknumber=1,
            user_id=1,
            is_current=True,
            wallet="0xFakeWallet1",
            created_at=datetime.now(),
            updated_at=datetime.now(),
            is_verified=False,
        ),
        User(
            blockhash="0x2",
            blocknumber=2,
            user_id=2,
            is_current=True,
            wallet="0xFakeWallet2",
            created_at=datetime.now(),
            updated_at=datetime.now(),
            is_verified=True,
        ),
    ]

    challenges = [
        Challenge(
            id="listen-streak",
            type=ChallengeType.numeric,
            active=True,
            amount="1",
            step_count=7,
        )
    ]

    user_challenges = [
        UserChallenge(
            challenge_id="listen-streak",
            user_id=1,
            specifier="1",
            is_complete=False,
            current_step_count=5,
        ),
        UserChallenge(
            challenge_id="listen-streak",
            user_id=2,
            specifier="2",
            is_complete=False,
            current_step_count=5,
        ),
    ]

    listen_streak_challenges = [
        ListenStreakChallenge(
            user_id=1,
            last_listen_date=datetime.now() - timedelta(hours=12),
            listen_streak=5,
        ),
        ListenStreakChallenge(
            user_id=2,
            last_listen_date=datetime.now() - timedelta(hours=50),
            listen_streak=5,
        ),
    ]

    # Wipe any existing challenges in the DB from running migrations, etc
    session.query(Challenge).delete()
    session.commit()
    session.add_all(blocks)
    session.commit()
    session.add_all(users)
    session.add_all(challenges)
    session.commit()
    session.add_all(user_challenges)
    session.commit()
    session.add_all(listen_streak_challenges)
    session.commit()

    redis_conn = redis.Redis.from_url(url=REDIS_URL)
    bus = ChallengeEventBus(redis_conn)
    bus.register_listener(DEFAULT_EVENT, listen_streak_challenge_manager)
    return bus
def setup_extra_metadata_test(session):
    blocks = [Block(blockhash="0x1", number=1, parenthash="", is_current=True)]
    users = [
        User(
            blockhash="0x1",
            blocknumber=1,
            user_id=1,
            is_current=True,
            wallet="0x38C68fF3926bf4E68289672F75ee1543117dD9B3",
            created_at=datetime.now(),
            updated_at=datetime.now(),
        )
    ]
    challenges = [
        # Test numeric challenges
        # Numeric 1 with default extra data, no completion
        Challenge(
            id="numeric_1",
            type=ChallengeType.numeric,
            active=True,
            amount="5",
            step_count=5,
        ),
        # Numeric 2 with some extra data
        Challenge(
            id="numeric_2",
            type=ChallengeType.numeric,
            active=True,
            amount="5",
            step_count=5,
        ),
    ]

    user_challenges = [
        UserChallenge(
            challenge_id="numeric_2",
            user_id=1,
            specifier="1",
            is_complete=False,
            current_step_count=5,
        ),
    ]

    session.query(Challenge).delete()
    session.commit()
    session.add_all(blocks)
    session.commit()
    session.add_all(users)
    session.commit()
    session.add_all(challenges)
    session.commit()
    session.add_all(user_challenges)
    session.commit()

    redis_conn = redis.Redis.from_url(url=REDIS_URL)
    bus = ChallengeEventBus(redis_conn)
    bus.register_listener(
        DEFAULT_EVENT, ChallengeManager("numeric_1", NumericCustomUpdater()))
    bus.register_listener(
        DEFAULT_EVENT, ChallengeManager("numeric_2", NumericCustomUpdater()))
    return bus