def test_add_credit(self): """ We can add credit to a subscriber's balance. """ increment = randrange(1, 1000) prior = subscriber.get_account_balance(self.TEST_IMSI) subscriber.add_credit(self.TEST_IMSI, increment) after = subscriber.get_account_balance(self.TEST_IMSI) self.assertEqual(prior + increment, after)
def process_confirm(from_imsi, code): """Process a confirmation request. Args: from_imsi: sender's IMSI code: the input confirmation code string """ # Step one: delete all the confirm codes older than some time. db = sqlite3.connect(config_db['pending_transfer_db_path']) db.execute("DELETE FROM pending_transfers" " WHERE time - ? > 600", (time.time(),)) db.commit() # Step two: check if this (from_imsi, code) combo is valid. r = db.execute("SELECT from_acct, to_acct, amount FROM pending_transfers" " WHERE code=? AND from_acct=?", (code, from_imsi)) res = r.fetchone() if res and len(res) == 3: from_imsi, to_imsi, amount = res from_num = subscriber.get_numbers_from_imsi(from_imsi)[0] to_num = subscriber.get_numbers_from_imsi(to_imsi)[0] reason = "SMS transfer from %s to %s" % (from_num, to_num) # Deduct credit from the sender. from_imsi_old_credit = subscriber.get_account_balance(from_imsi) from_imsi_new_credit = int(from_imsi_old_credit) - int(amount) events.create_transfer_event(from_imsi, from_imsi_old_credit, from_imsi_new_credit, reason, from_number=from_num, to_number=to_num) subscriber.subtract_credit(from_imsi, str(int(amount))) # Add credit to the recipient. to_imsi_old_credit = subscriber.get_account_balance(to_imsi) to_imsi_new_credit = int(to_imsi_old_credit) + int(amount) events.create_transfer_event(to_imsi, to_imsi_old_credit, to_imsi_new_credit, reason, from_number=from_num, to_number=to_num) subscriber.add_credit(to_imsi, str(int(amount))) # Humanize credit strings amount_str = freeswitch_strings.humanize_credits(amount) to_balance_str = freeswitch_strings.humanize_credits( to_imsi_new_credit) from_balance_str = freeswitch_strings.humanize_credits( from_imsi_new_credit) # Let the recipient know they got credit. message = gt("You've received %(amount)s credits from %(from_num)s!" " Your new balance is %(new_balance)s.") % { 'amount': amount_str, 'from_num': from_num, 'new_balance': to_balance_str} sms.send(str(to_num), str(config_db['app_number']), str(message)) # Remove this particular the transfer as it's no longer pending. db.execute("DELETE FROM pending_transfers WHERE code=?" " AND from_acct=?", (code, from_imsi)) db.commit() # Tell the sender that the operation succeeded. return True, gt("You've transferred %(amount)s to %(to_num)s. " "Your new balance is %(new_balance)s.") % { 'amount': amount_str, 'to_num': to_num, 'new_balance': from_balance_str} return False, gt("That transfer confirmation code doesn't exist" " or has expired.")
def test_subtract_credit(self): """ We can subtract credit from a subscriber's balance. """ prior = randrange(1, 1000) # add some credit first subscriber.add_credit(self.TEST_IMSI, prior) decrement = randrange(0, prior) subscriber.subtract_credit(self.TEST_IMSI, decrement) after = subscriber.get_account_balance(self.TEST_IMSI) self.assertEqual(prior - int(decrement), after)
def adjust_credits(self, data): required_fields = ["imsi", "change"] if not all([_ in data for _ in required_fields]): return web.BadRequest() imsi = data["imsi"] try: change = int(data["change"]) except ValueError: return web.BadRequest() old_credit = subscriber.get_account_balance(imsi) if change > 0: subscriber.add_credit(imsi, str(abs(change))) elif change < 0: subscriber.subtract_credit(imsi, str(abs(change))) new_credit = subscriber.get_account_balance(imsi) # Codeship is stupid. These imports break CI and this is an untested # method :) from core import freeswitch_interconnect, freeswitch_strings # Send a confirmation to the subscriber number = subscriber.get_caller_id(imsi) change_frmt = freeswitch_strings.humanize_credits(change) balance_frmt = freeswitch_strings.humanize_credits(new_credit) fs_ic = freeswitch_interconnect.freeswitch_ic(self.conf) fs_ic.send_to_number( number, '000', freeswitch_strings.gt( "The network operator adjusted your credit by %(change)s. " "Your balance is now %(balance)s.") % { 'change': change_frmt, 'balance': balance_frmt }) # TODO(matt): all credit adjustments are of the kind "add_money," even # if they actually subtract credit. reason = 'Update from web UI (add_money)' events.create_add_money_event(imsi, old_credit, new_credit, reason, to_number=number) return web.ok()
def test_credit_delta_type_enforcement(self): """The convention is to pass credit changes as a string. It should be possible to convert the string to an int and the value should be greater than zero in all cases, even when subtracting credit. """ # Each of these values should cause a TypeError. invalid_values = ['one thousand', '93f'] for value in invalid_values: with self.assertRaises(ValueError): subscriber.add_credit(self.TEST_IMSI, value) with self.assertRaises(ValueError): subscriber.subtract_credit(self.TEST_IMSI, value) # These increments should be allowed. valid_values = ['0', '2', '1000', 1000, 0.1, 999.9, -1000.4] for value in valid_values: subscriber.add_credit(self.TEST_IMSI, value) subscriber.subtract_credit(self.TEST_IMSI, value)