Example #1
0
    def test_divide_pool_uneven_5(self):
        POOL_BANK_ID = 14
        CHOICE_SET = [21, 22, 23]
        USER_IDS = [1, 2, 3, 4, 5]
        USER_BANK_IDS = [101, 102, 103, 104, 105]

        self.mock_cursor.fetchone.side_effect = [("poll1", True, 45),
                                                 (POOL_BANK_ID, 225)]

        self.mock_cursor.fetchall.side_effect = [[
            (1, 21, 101),
            (2, 22, 102),
            (3, 22, 103),
            (4, 22, 104),
            (5, 22, 105),
        ]]

        result = divide_pool(10, 22, self.mock_cursor, self.mock_conn)

        user1_transaction = Transaction(14, 101, 'payout', 0)
        user2_transaction = Transaction(14, 102, 'payout', 56)
        user3_transaction = Transaction(14, 103, 'payout', 57)
        user4_transaction = Transaction(14, 104, 'payout', 56)
        user5_transaction = Transaction(14, 105, 'payout', 56)

        expected_transactions = [
            user1_transaction, user2_transaction, user3_transaction,
            user4_transaction, user5_transaction
        ]

        self.assertTrue(check_equal(expected_transactions, result))
    def test_generate_sql(self):

        transaction = Transaction(self.from_id, self.to_id, self.category,
                                  self.amount)

        result = transaction.generate_sql()

        self.assertEqual(
            "INSERT INTO transactions (from_entity, to_entity, type, balance) "
            "values (31, 21, 'bet', 50)", result)
    def test_create_single_list(self):

        transaction1 = Transaction(self.from_id, self.to_id, self.category,
                                   self.amount)
        all_transactions = [transaction1]

        result = Transaction.create_list_sql(all_transactions)

        expected_result = "INSERT INTO transactions (from_entity, to_entity, type, balance) values " \
                          "(31, 21, 'bet', 50)"
        self.assertEqual(expected_result, result)
Example #4
0
def send_transactions(poll_id: int, correct_id: int, transactions: List[Transaction], cursor, connection):
    """
    this method takes transactions, puts them into the db and marks the poll as paid out.
    it also asks you to verify
    :param poll_id:
    :param transactions:
    :param cursor:
    :param connection:
    :return:
    """

    total = 0
    sys.stdout.write("\n\nThese are the transactions that are going to be written to the db:\n")
    for idx, transaction in enumerate(transactions):
        sys.stdout.write("%d) %s\n" % (idx+1, str(transaction)))
        total += transaction.amount

    sys.stdout.write("A total of %d coins are going to sent from the poll.\n\n" % total)
    result = input("Does this look correct to you? ")

    if result in no:
        sys.stderr.write("\nUser-initiated abort. Closing..\n\n")
        sys.exit()
    elif result in yes:
        pass
    else:
        sys.stderr.write("\nPlease respond with 'yes' or 'no'.\n\n")
        sys.exit()

    # write sql to insert these
    try:
        insert_query = Transaction.create_list_sql(transactions)
        print(insert_query)
        cursor.execute(insert_query)

        for transaction in transactions:
            update_user_bank_sql = "UPDATE banks SET balance=balance + %d WHERE id=%d" % (transaction.amount,
                                                                                          transaction.to_id)
            print(update_user_bank_sql)
            cursor.execute(update_user_bank_sql)

        update_poll_bank_sql = "UPDATE banks SET balance=0 WHERE id=%d" % transactions[0].from_id
        print(update_poll_bank_sql)
        cursor.execute(update_poll_bank_sql)

        update_poll_sql = "UPDATE polls SET has_paid=true, correct_answer=%d WHERE id=%d" % (correct_id, poll_id)
        print(update_poll_sql)
        cursor.execute(update_poll_sql)

    except Exception as e:
        connection.rollback()
        sys.stderr.write("\nCaught an error: %s" % e)
        sys.stderr.write("\nAborting now, and rolling back all changes..\n\n")
        sys.exit()
    # update poll balance, update balance of respective users

    # update poll to be paid out, along with correct choice id

    connection.commit()
    print("bomb")
    def test_transaction_constructor(self):

        transaction = Transaction(self.from_id, self.to_id, self.category,
                                  self.amount)

        self.assertEqual(self.from_id, transaction.from_id)
        self.assertEqual(self.to_id, transaction.to_id)
        self.assertEqual(self.category, transaction.category)
        self.assertEqual(self.amount, transaction.amount)
Example #6
0
    def test_from_user_transaction(self):
        test_transaction = Transaction(self.user_bank_id, self.poll_bank_id,
                                       'bet', 130)

        notification = Notification.from_transaction(test_transaction,
                                                     self.mock_cursor,
                                                     self.mock_connection)

        self.assertIsNone(notification)
        self.mock_cursor.execute.assert_not_called()
Example #7
0
    def test_divide_pool_two_winners(self):
        POOL_BANK_ID = 14
        CHOICE_SET = [21, 22, 23]
        USER_IDS = [1, 2, 3, 4, 5]
        USER_BANK_IDS = [101, 102, 103, 104, 105]

        self.mock_cursor.fetchone.side_effect = [("poll1", True, 100),
                                                 (POOL_BANK_ID, 200)]

        self.mock_cursor.fetchall.side_effect = [[
            (1, 22, 101),
            (2, 22, 102),
        ]]

        result = divide_pool(10, 22, self.mock_cursor, self.mock_conn)

        user1_transaction = Transaction(14, 101, 'payout', 100)
        user2_transaction = Transaction(14, 102, 'payout', 100)
        expected_transactions = [user1_transaction, user2_transaction]

        self.assertTrue(check_equal(expected_transactions, result))
Example #8
0
    def test_from_transaction(self):
        test_transaction = Transaction(self.poll_bank_id, self.user_bank_id,
                                       'payout', 121)
        self.mock_cursor.fetchone.side_effect = [[21]]

        notification = Notification.from_transaction(test_transaction,
                                                     self.mock_cursor,
                                                     self.mock_connection)

        self.mock_cursor.execute.assert_called_once_with(
            "SELECT entity_id FROM banks WHERE id=%s and type='user'",
            (self.user_bank_id, ))
        self.assertEqual(21, notification.user_id)
        self.assertEqual("You just won 121 coins from your latest bet!",
                         notification.message)
    def test_batch_generate_sql(self):
        transaction = Transaction(self.from_id, self.to_id, self.category,
                                  self.amount)

        result = transaction.generate_sql(is_batch=True)
        self.assertEqual("(31, 21, 'bet', 50)", result)
Example #10
0
def divide_pool(poll_id: int, correct_id: int, cursor, conn) -> List[Transaction]:
    """
    this method collects all the bets and divides up
    :param poll_id: integer poll id
    :param correct_id: int choice id
    :param cursor: psycopg2 cursor
    :param conn: psycopg2 connection
     :return: list of transaction objects
    """
    poll_query = "SELECT title, finished, buy_in FROM polls WHERE id=%d" % poll_id
    cursor.execute(poll_query)
    poll_result = cursor.fetchone()
    poll_buyin = poll_result[2]

    banks_query = "SELECT id, balance FROM banks WHERE entity_id=%d and type='poll' limit 1" % poll_id
    cursor.execute(banks_query)
    bank_result = cursor.fetchone()

    poll_bank_id = bank_result[0]
    balance_pool_size = bank_result[1]

    transactions_query = "SELECT user_id, choice_id, banks.id FROM bets left join banks on " \
                         "banks.entity_id=bets.user_id where banks.type='user' and poll_id=%d" % poll_id
    cursor.execute(transactions_query)
    transactions_results = cursor.fetchall()

    pool_size = len(transactions_results) * poll_buyin

    print("balance pool size: %d" % balance_pool_size)
    print("pool size: %d" % pool_size)

    if pool_size != balance_pool_size:
        print("the balance records don't match.. womp womp")
        raise Exception("transaction mismatch")

    answer_sums = {}
    payout_map = {}  # a dict with bank ids with their respective balances
    winner_payout_array = []
    loser_payout_array = []

    for bet in transactions_results:
        answer_sums[bet[1]] = answer_sums.get(bet[1], 0) + 1

        if bet[1] == correct_id:
            payout_map[bet[2]] = 0
            winner_payout_array.append(bet[2])
        else:
            loser_payout_array.append(bet[2])

    if len(winner_payout_array) < 1:
        # no winners... return all the money to the losers
        losing_transactions = []
        loser_total = 0
        for loser in loser_payout_array:
            new_lose_transaction = Transaction(poll_bank_id, loser, 'payout', poll_buyin)
            losing_transactions.append(new_lose_transaction)
            loser_total += poll_buyin

        if loser_total != pool_size:
            print('we got a problem, no winners, and loser transactions didn\'t add up')
            raise Exception("transaction mismatch")

        return losing_transactions

    for coin in range(1, pool_size+1):
        bank_id = winner_payout_array[coin % len(winner_payout_array)]
        payout_map[bank_id] += 1

    print(payout_map)

    new_total = 0
    transactions = []
    # add the winner transactions
    for key in payout_map:
        new_transactions = Transaction(poll_bank_id, key, 'payout', payout_map[key])
        new_total += payout_map[key]
        transactions.append(new_transactions)

    # add the loser transactions
    for loser in loser_payout_array:
        new_transaction = Transaction(poll_bank_id, loser, 'payout', 0)
        transactions.append(new_transaction)

    if new_total != pool_size:
        sys.stderr.write("transactions distribution doesn't match up.. expected %d but got %d" % (
            pool_size, new_total
        ))
        sys.exit()

    return transactions