def test_verified_referrals_invisible_to_nonverified_user(app):
    with app.app_context():
        db = get_db()
        with db.scoped_session() as session:
            bus = setup_verified_test(session)

            verified = get_challenges(2, False, session, bus)
            assert len(verified) == 1
            assert verified[0]["challenge_id"] == "ref-v"
def test_get_challenges_with_override_step_count(app):
    with app.app_context():
        db = get_db()
        with db.scoped_session() as session:
            bus = setup_listen_streak_challenge(session)

            challenges = get_challenges(2, False, session, bus)
            assert len(challenges) == 1
            assert challenges[0]["challenge_id"] == "listen-streak"
            assert challenges[0]["current_step_count"] == 0
예제 #3
0
    def get(self, id: str):
        args = get_challenges_route_parser.parse_args()
        show_historical = args.get("show_historical")
        decoded_id = decode_with_abort(id, ns)
        db = get_db_read_replica()

        with db.scoped_session() as session:
            bus = setup_challenge_bus()
            challenges = get_challenges(decoded_id, show_historical, session, bus)
            challenges = list(map(extend_challenge_response, challenges))

            return success_response(challenges)
def test_extra_metadata(app):
    with app.app_context():
        db = get_db()
        with db.scoped_session() as session:
            bus = setup_extra_metadata_test(session)

            res = get_challenges(1, False, session, bus)
            challenge_1 = [r for r in res
                           if r["challenge_id"] == "numeric_1"][0]
            challenge_2 = [r for r in res
                           if r["challenge_id"] == "numeric_2"][0]
            assert challenge_1["metadata"] == {"default_state": True}
            assert challenge_2["metadata"] == {"special_metadata": "1"}
def test_in_memory_queue(app):
    setup_challenges(app)

    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, bus.use_scoped_dispatch_queue():
        agg_challenge = ChallengeManager("test_challenge_3",
                                         AggregateUpdater())
        agg_challenge.process(session, "test_event", [])
        TEST_EVENT = "TEST_EVENT"

        bus.register_listener(
            TEST_EVENT, ChallengeManager("test_challenge_1", DefaultUpdater()))
        bus.register_listener(
            TEST_EVENT, ChallengeManager("test_challenge_2", DefaultUpdater()))
        # - Multiple events with the same user_id but diff specifiers get created
        bus.register_listener(TEST_EVENT, agg_challenge)
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 2})
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 3})
        bus.process_events(session)

        # no events should be processed because we haven't dispatched yet
        state = agg_challenge.get_user_challenge_state(session, ["1-2", "1-3"])
        assert len(state) == 0

    bus.process_events(session)
    state = agg_challenge.get_user_challenge_state(session, ["1-2", "1-3"])
    assert len(state) == 2
    # Also make sure the thing is incomplete
    res = get_challenges(1, False, session, bus)
    agg_chal = {c["challenge_id"]: c for c in res}["test_challenge_3"]
    assert agg_chal["is_complete"] == False

    redis_conn = redis.Redis.from_url(url=REDIS_URL)
def test_aggregates(app):

    setup_challenges(app)

    with app.app_context():
        db = get_db()

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

    with db.scoped_session() as session:
        bus = ChallengeEventBus(redis_conn)
        agg_challenge = ChallengeManager("test_challenge_3",
                                         AggregateUpdater())
        agg_challenge.process(session, "test_event", [])
        TEST_EVENT = "TEST_EVENT"

        bus.register_listener(
            TEST_EVENT, ChallengeManager("test_challenge_1", DefaultUpdater()))
        bus.register_listener(
            TEST_EVENT, ChallengeManager("test_challenge_2", DefaultUpdater()))
        # - Multiple events with the same user_id but diff specifiers get created
        bus.register_listener(TEST_EVENT, agg_challenge)
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 2})
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 3})
        bus.flush()
        bus.process_events(session)
        state = agg_challenge.get_user_challenge_state(session, ["1-2", "1-3"])
        assert len(state) == 2
        # Also make sure the thing is incomplete
        res = get_challenges(1, False, session, bus)
        agg_chal = {c["challenge_id"]: c for c in res}["test_challenge_3"]
        assert agg_chal["is_complete"] == False

        # - Multiple events with the same specifier get deduped
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 4})
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 4})
        bus.flush()
        bus.process_events(session)
        state = agg_challenge.get_user_challenge_state(session, ["1-4"])
        assert len(state) == 1

        # - If we've maxed the # of challenges, don't create any more
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 5})
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 6})
        bus.flush()
        bus.process_events(session)

        def get_user_challenges():
            return (session.query(UserChallenge).filter(
                UserChallenge.challenge_id == "test_challenge_3",
                UserChallenge.user_id == 1,
            ).all())

        assert len(get_user_challenges()) == 5
        bus.dispatch(TEST_EVENT, 100, 1, {"referred_id": 7})
        bus.flush()
        bus.process_events(session)
        assert len(get_user_challenges()) == 5

        # Test get_challenges
        res = get_challenges(1, False, session, bus)
        agg_chal = {c["challenge_id"]: c for c in res}["test_challenge_3"]
        assert agg_chal["is_complete"] == True
        # Assert all user challenges have proper finishing block #
        user_challenges = get_user_challenges()
        for uc in user_challenges:
            assert uc.completed_blocknumber == 100
def test_get_challenges(app):
    with app.app_context():
        db = get_db()
        with db.scoped_session() as session:
            bus = setup_db(session)

            # Setup registry

            # Try to get the challenges, not historical
            res = get_challenges(1, False, session, bus)

            # We don't care about the order of the challenges returned
            # so make a map
            res_map = {
                challenge["challenge_id"]: challenge
                for challenge in res
            }
            # Ensure correct num of challenges
            # not returned are:
            # - inactive, with no user_challenge
            # - inactive, with user_challenge
            # - trending, with no user_challenge
            # - trending, with one unfinished user challenge (doesn't even make sense, but it could happen)
            assert len(res) == 8

            # Base case - an active, completed, disbursed chal
            chal_1 = res_map["boolean_challenge_1"]
            assert chal_1["is_disbursed"]
            assert chal_1["is_active"]
            assert chal_1["is_complete"]

            # Active, complete, non disbursed
            chal_2 = res_map["boolean_challenge_2"]
            assert chal_2["is_disbursed"] == False
            assert chal_2["is_active"]
            assert chal_2["is_complete"]

            # active, incomplete, nondisbursed
            chal_3 = res_map["boolean_challenge_3"]
            assert chal_3["is_disbursed"] == False
            assert chal_3["is_active"]
            assert chal_3["is_complete"] == False

            # no user progress, but active, so should be returned
            chal_4 = res_map["boolean_challenge_4"]
            assert chal_4["is_disbursed"] == False
            assert chal_4["is_active"]
            assert chal_4["is_complete"] == False

            # aggregate challenge with one completion, so not fully complete
            chal_agg_1 = res_map["aggregate_challenge_1"]
            assert (
                chal_agg_1["is_disbursed"] == False
            )  # This field doesn't matter since we can't roll up disbursions
            assert chal_agg_1["is_active"]
            assert chal_agg_1["is_complete"] == False
            assert chal_agg_1["current_step_count"] == 1
            assert chal_agg_1["max_steps"] == 3

            # aggregate challenge with 2 completions, FULLY complete
            chal_agg_2 = res_map["aggregate_challenge_2"]
            assert (
                chal_agg_2["is_disbursed"] == False
            )  # This field doesn't matter since we can't roll up disbursions
            assert chal_agg_2["is_active"]
            assert chal_agg_2["is_complete"] == True
            assert chal_agg_2["current_step_count"] == 2
            assert chal_agg_2["max_steps"] == 2

            # aggregate challenge with no completions
            chal_agg_3 = res_map["aggregate_challenge_3"]
            assert (
                chal_agg_3["is_disbursed"] == False
            )  # This field doesn't matter since we can't roll up disbursions
            assert chal_agg_3["is_active"]
            assert chal_agg_3["is_complete"] == False
            assert chal_agg_3["current_step_count"] == 0
            assert chal_agg_3["max_steps"] == 2

            # complete trending challenge
            chal_trend_1 = res_map["trending_1"]
            assert chal_trend_1["is_disbursed"] == False
            assert chal_trend_1["is_active"]
            assert chal_trend_1["is_complete"]

            # Try to get the challenges, this time historical
            res = get_challenges(1, True, session, bus)

            # The only difference is that we should have shown
            # inactive but complete challenges
            assert len(res) == 9
            res_map = {
                challenge["challenge_id"]: challenge
                for challenge in res
            }
            historical = res_map["boolean_challenge_6"]
            assert historical["is_active"] == False
            assert historical["is_complete"]
            assert historical["is_disbursed"] == False