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")
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