Beispiel #1
0
 def test_get_coins_with_invalid_time_span(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     GameProfile.create(game=1, profile=profile, cash=10000)
     res = self.client.get(
         '/game/1/coins?timeSpan=6&sortBy=0&numPerPage=10&pageNum=1',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.BAD_REQUEST), res._status_code)
Beispiel #2
0
def register(username: str, password: str):
    profile = Profile.get_or_none(Profile.username == username)
    if profile is not None:
        raise BadRequest('A user with this username already exists')
    hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt()).decode()
    profile = Profile.create(
        username=username,
        hashed_password=hashed,
    )
    global_game = Game.get_or_none(Game.name == 'Global Indefinite')
    GameProfile.create(game=global_game,
                       profile=profile,
                       cash=global_game.starting_cash)
    global_game = Game.get_or_none(Game.name == 'Global Timed')
    GameProfile.create(game=global_game,
                       profile=profile,
                       cash=global_game.starting_cash)
    send_notification(profile, 'Welcome to Fortune!')
    send_notification(
        profile,
        'Click the Play button in the menubar on top to create a new game.')
    send_notification(
        profile,
        'To adjust account options, see achiements, and add friends, click on your username on the top and select Profile'
    )
    return create_auth_token(profile)
Beispiel #3
0
    def test_user_automatically_joins_new_global_time_game(self):
        # register user
        res = self.client.post('/auth/register',
                               data=json.dumps({
                                   'username': '******',
                                   'password': '******',
                                   'password': '******',
                               }),
                               headers={'Content-Type': 'application/json'})
        self.assertEqual(200, res._status_code)
        game_before_check = Game.get(Game.name == 'Global Timed')
        game_before_check.ends_at = datetime.utcnow()
        game_before_check.save()
        # assert deletes old GameProfile
        profile = Profile.get_by_id(1)
        qry = GameProfile.select().join(Game).where(
            (GameProfile.profile == profile) & (Game.name == 'Global Timed'))
        self.assertEqual(2, len(profile.game_profiles)
                         )  # should have 2: global timed and indefinite
        self.assertEqual(1, qry.count())  # just to make sure
        gp_old = qry.get()

        check_global_timed_game()

        # assert creates new GameProfile
        qry = GameProfile.select().join(Game).where(
            (GameProfile.profile == profile) & (Game.name == 'Global Timed'))
        self.assertEqual(1, qry.count())
        gp_new = qry.get()

        # but the ids should not be the same
        self.assertNotEqual(gp_old.id, gp_new.id)
Beispiel #4
0
def add_to_game(profile_id, game):
    game_profile = GameProfile.select().where(GameProfile.profile == profile_id,
                                              GameProfile.game == game.id)
    if game_profile.count() == 0:
        GameProfile.create(
            game=game.id,
            profile=profile_id,
            cash=game.starting_cash
        )
Beispiel #5
0
def up(db):
    with db.atomic():
        migrator = PostgresqlMigrator(db)
        db.bind(MODELS, bind_refs=False, bind_backrefs=False)
        db.create_tables(MODELS)
        if Coin.get_or_none(Coin.id == 1) is None:
            Coin.create(name='Bitcoin', symbol='BTC')
            Coin.create(name='Ethereum', symbol='ETH')
            Coin.create(name='Litecoin', symbol='LTC')
            Coin.create(name='Coin 3', symbol='CO3')
            Coin.create(name='Coin 4', symbol='CO4')
            Coin.create(name='Coin 5', symbol='CO5')

        global_indef = Game.create(name='Global Indefinite',
                                   starting_cash=10000.00,
                                   shareable_link='INDEF',
                                   shareable_code='INDEF',
                                   ends_at=None)

        # insert achievements into database
        Achievement.create(
            name="Win", description="Finish in first place in a private game")
        Achievement.create(
            name="Double net worth",
            description="Achieved by doubling your net worth in a game")
        Achievement.create(name="Identity Crisis",
                           description="Change your username")

        # insert goals into database
        Goal.create(name="Entrepreneur", description="Create a private game")

        all_coins = Coin.select()
        for coin in all_coins:
            GameCoin.create(game=global_indef, coin=coin)

        global_timed = Game.create(name='Global Timed',
                                   starting_cash=10000.00,
                                   shareable_link='TIMED',
                                   shareable_code='TIMED',
                                   ends_at=datetime.utcnow() +
                                   timedelta(minutes=1))
        # CHANGEME for devel purposes, making it 1 min for now
        GameCoin.create(game=global_timed, coin=Coin.get())

        # from auth.services import register
        hashed = bcrypt.hashpw("admin".encode(), bcrypt.gensalt()).decode()
        admin = Profile.create(username="******",
                               hashed_password=hashed,
                               is_admin=True)
        # Required so that admin can still view graphs in the landing page
        GameProfile.create(profile=admin, game=global_indef, cash=0.0)
Beispiel #6
0
 def test_buy_coin_without_cash(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     GameProfile.create(game=1, profile=profile, cash=0)
     GameCoin.create(game=1, coin=1)
     Ticker.create(coin=1, price=10, price_change_day_pct=1.1)
     res = self.client.post(
         '/game/1/coin',
         data=json.dumps({
             'coinId': '1',
             'coinAmount': '1',
         }),
         content_type='application/json',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.BAD_REQUEST), res._status_code)
Beispiel #7
0
def sell_coin(coin_id, coin_amount, game_profile):
    gameProfileCoin = GameProfileCoin.get_or_none(
        GameProfileCoin.game_profile == game_profile.id,
        GameProfileCoin.coin == coin_id)
    if gameProfileCoin is None or gameProfileCoin.coin_amount < coin_amount:
        raise BadRequest('Not enough of these coins to sell')
    ticker = Ticker.select().where(Ticker.coin == coin_id).order_by(
        Ticker.captured_at.desc())
    if ticker.count() == 0:
        raise BadRequest('Coin has no prices')
    ticker = ticker.get()
    new_cash = game_profile.cash + (ticker.price * coin_amount)
    new_coin_amount = gameProfileCoin.coin_amount - coin_amount
    GameProfileCoin.update(coin_amount=new_coin_amount).where(
        GameProfileCoin.id == gameProfileCoin.id).execute()
    GameProfile.update(cash=new_cash).where(
        GameProfile.id == game_profile.id).execute()
    return new_coin_amount
Beispiel #8
0
 def test_get_coins_success(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     GameProfile.create(game=1, profile=profile, cash=10000)
     GameCoin.create(
         game=1,
         coin=1,
     )
     for coin in Coin.select():
         Ticker.create(
             coin=coin,
             price=30.0,
             captured_at=(datetime.utcnow()).isoformat(),
             price_change_day_pct=1.1,
         )
     res = self.client.get(
         '/game/1/coins?timeSpan=1&sortBy=0&numPerPage=10&pageNum=1',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.OK), res._status_code)
Beispiel #9
0
def create_game(name, starting_cash, shareable_link, shareable_code, ends_at,
                active_coins, profile):
    # bounds check, validate
    if ends_at < datetime.utcnow().replace(tzinfo=pytz.utc):
        raise BadRequest('Invalid game ending date')
    if starting_cash <= Decimal(0):
        raise BadRequest('Starting cash must be positive')
    game = Game.create(
        name=name,
        starting_cash=starting_cash,
        shareable_link=shareable_link,
        shareable_code=shareable_code,
        ends_at=ends_at,
    )
    create_gamecoins_for_game(game, active_coins)
    GameProfile.create(
        game=game,
        profile=profile,
        cash=game.starting_cash,
    )
    return game
Beispiel #10
0
 def setUp(self):
     super().setUp()
     with db.atomic() as txn:
         self.game = Game.create(
             name='Game',
             starting_cash=10000.00,
             shareable_link='aaaabbbbccccdddd',
             shareable_code='aaaa',
             ends_at=(datetime.utcnow().replace(tzinfo=pytz.utc) +
                      timedelta(days=7)).isoformat())
         profile = Profile.create(username='******',
                                  hashed_password='******')
         GameProfile.create(game=self.game, profile=profile, cash=-1.0)
         Message.create(
             game=self.game.id,
             profile=profile.id,
             content="first message",
             # use default value for created_on
         )
         self.token = AuthToken.create(profile=profile,
                                       token='thevalidtoken').token
Beispiel #11
0
def check_global_timed_game():
    game = Game.get(Game.shareable_link == 'TIMED')
    if game.ends_at < datetime.utcnow():
        # end global timed game, and start another
        profiles = []
        for game_profile in GameProfile.select().where(GameProfile.game == game):
            profiles.append(game_profile.profile)
            send_notification(game_profile.profile, 'The global timed game has expired')
            game_profile.delete_instance(recursive=True)
        game.delete_instance(recursive=True)
        global_timed = Game.create(name='Global Timed',
                        starting_cash=10000.00,
                        shareable_link='TIMED',
                        shareable_code='TIMED',
                        ends_at=datetime.utcnow() + timedelta(minutes=1))
        # CHANGEME for devel purposes, making it 1 min for now
        GameCoin.create(game=global_timed, coin=Coin.get())
        for profile in profiles:
            GameProfile.create(
                game=global_timed,
                profile=profile,
                cash=global_timed.starting_cash
            )
Beispiel #12
0
def buy_coin(coin_id, coin_amount, game_profile):
    ticker = Ticker.select().where(Ticker.coin == coin_id).order_by(
        Ticker.captured_at.desc())
    if ticker.count() == 0:
        raise BadRequest('Coin has no prices')
    ticker = ticker.get()
    new_cash = game_profile.cash - (ticker.price * coin_amount)
    if new_cash < 0:
        raise BadRequest('Not enough cash to buy this coin amount')
    game_coin = GameCoin.get_or_none(GameCoin.game == game_profile.game,
                                     GameCoin.coin == coin_id)
    if game_coin is None:
        raise BadRequest('Coin does not exist in this game')
    gameProfileCoin = GameProfileCoin.get_or_none(
        GameProfileCoin.game_profile == game_profile.id,
        GameProfileCoin.coin == coin_id)

    if gameProfileCoin is None:
        GameProfileCoin.create(game_profile=game_profile.id,
                               coin=coin_id,
                               coin_amount=coin_amount)

        rows = GameProfile.update(cash=new_cash).where(
            GameProfile == game_profile).execute()

        if rows == 0:
            raise BadRequest('Money could not be removed from your account')
        return coin_amount
    else:
        new_coin_amount = gameProfileCoin.coin_amount + coin_amount
        rows = GameProfile.update(cash=new_cash).where(
            GameProfile == game_profile).execute()
        if rows == 0:
            raise BadRequest('Money could not be removed from your account')
        GameProfileCoin.update(coin_amount=new_coin_amount).where(
            GameProfileCoin.id == gameProfileCoin.id).execute()
        return new_coin_amount
Beispiel #13
0
 def test_liquefy_success(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     game_profile = GameProfile.create(game=1, profile=profile, cash=0)
     GameCoin.create(game=1, coin=1)
     GameProfileCoin.create(game_profile=game_profile,
                            coin=1,
                            coin_amount=2)
     Ticker.create(
         coin=1,
         price=10,
         captured_at=(datetime.utcnow()).isoformat(),
         price_change_day_pct=1.1,
     )
     res = self.client.delete(
         '/game/1/coins', headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.OK), res._status_code)
Beispiel #14
0
def get_net_worth_by_game_profile_id(game_profile_id):
    gameProfile = GameProfile.get_or_none(GameProfile.id == game_profile_id)
    if not gameProfile:
        raise BadRequest('User not in game')

    netWorth = gameProfile.cash

    gameProfileCoins = get_game_profile_coins_by_game_profile_id(
        game_profile_id)
    for gameProfileCoin in gameProfileCoins:
        ticker = Ticker.select().where(
            Ticker.coin == gameProfileCoin.coin).order_by(
                Ticker.captured_at.desc())
        if ticker.count() == 0:
            raise BadRequest('One coin did not have prices')
        ticker = ticker.get()
        if not ticker:
            raise BadRequest('One coin did not exist')
        netWorth += ticker.price * gameProfileCoin.coin_amount
    return netWorth
Beispiel #15
0
 def test_sell_coin_success(self):
     profile = Profile.get_or_none(Profile.username == 'theusername')
     game_profile = GameProfile.create(game=1, profile=profile, cash=0)
     GameCoin.create(game=1, coin=1)
     GameProfileCoin.create(game_profile=game_profile,
                            coin=1,
                            coin_amount=2)
     Ticker.create(
         coin=1,
         price=10,
         captured_at=(datetime.utcnow()).isoformat(),
         price_change_day_pct=1.1,
     )
     res = self.client.post(
         '/game/1/coin',
         data=json.dumps({
             'coinId': '1',
             'coinAmount': '-1',
         }),
         content_type='application/json',
         headers={'Authorization': 'Bearer ' + self.token})
     self.assertEqual(int(HTTPStatus.OK), res._status_code)
Beispiel #16
0
def get_players_in_a_game(game_id: int):
    game_profiles = GameProfile.select(
        GameProfile,
        Profile).join(Profile).where(GameProfile.game == game_id).execute()
    return [gp.profile for gp in game_profiles]
def get_game_profile_by_game_id(game_id):
    return GameProfile.selcet(profile).where(GameProfile.game == game_id)
Beispiel #18
0
def get_game_profile_by_profile_id_and_game_id(profile_id, game_id):
    game_profile = GameProfile.get_or_none(GameProfile.game == game_id,
                                           GameProfile.profile == profile_id)
    if not game_profile:
        raise BadRequest('User not in game')
    return game_profile
Beispiel #19
0
 def test_joining_game_more_than_once_is_idempotent(self):
     game = Game.get(Game.name == 'Global Timed')
     before = GameProfile.select().count()
     self.client.get(f'/join?code={game.shareable_code}')
     after = GameProfile.select().count()
     self.assertEqual(before, after)