Add tests for cryptowallet
This commit is contained in:
parent
f7990667eb
commit
9c6e1056d0
|
@ -33,7 +33,8 @@ class CryptoWallet(ModuleBase):
|
||||||
self.bot.act_PRIVMSG(msg.args[0], ".setaddr: '{}' is not a supported currency. Supported currencies are: {}"
|
self.bot.act_PRIVMSG(msg.args[0], ".setaddr: '{}' is not a supported currency. Supported currencies are: {}"
|
||||||
.format(cmd.args[0], supportedStr))
|
.format(cmd.args[0], supportedStr))
|
||||||
return
|
return
|
||||||
if len(cmd.args[1]) < 16 or len(cmd.args[1]) > 42:
|
client = rpc.getRpc(cmd.args[0])
|
||||||
|
if not client.validate_addr(cmd.args[1]):
|
||||||
self.bot.act_PRIVMSG(msg.args[0], ".setaddr: '{}' appears to be an invalid address.".format(cmd.args[1]))
|
self.bot.act_PRIVMSG(msg.args[0], ".setaddr: '{}' appears to be an invalid address.".format(cmd.args[1]))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -48,14 +49,9 @@ class CryptoWallet(ModuleBase):
|
||||||
@info("getbal <currency> retrieve your balance ", cmds=["getbal"])
|
@info("getbal <currency> retrieve your balance ", cmds=["getbal"])
|
||||||
@command("getbal", require_args=1, allow_private=True)
|
@command("getbal", require_args=1, allow_private=True)
|
||||||
def handle_getbal(self, msg, cmd):
|
def handle_getbal(self, msg, cmd):
|
||||||
usage = ".getbal <currency>"
|
|
||||||
if not self.check_login(msg.prefix, msg.args[0]):
|
if not self.check_login(msg.prefix, msg.args[0]):
|
||||||
return
|
return
|
||||||
attr, rpc = self.getMods()
|
attr, rpc = self.getMods()
|
||||||
# Check for args
|
|
||||||
if len(cmd.args) != 1:
|
|
||||||
self.bot.act_PRIVMSG(msg.args[0], ".getbal: usage: {}".format(usage))
|
|
||||||
return
|
|
||||||
# Check if currency is known
|
# Check if currency is known
|
||||||
if not rpc.isSupported(cmd.args[0]):
|
if not rpc.isSupported(cmd.args[0]):
|
||||||
supportedStr = ', '.join(rpc.getSupported())
|
supportedStr = ', '.join(rpc.getSupported())
|
||||||
|
@ -76,7 +72,7 @@ class CryptoWallet(ModuleBase):
|
||||||
self.bot.act_PRIVMSG(msg.args[0],
|
self.bot.act_PRIVMSG(msg.args[0],
|
||||||
"{}: your balance is: {} {}".format(msg.prefix.nick, amount, cmd.args[0].upper()))
|
"{}: your balance is: {} {}".format(msg.prefix.nick, amount, cmd.args[0].upper()))
|
||||||
|
|
||||||
@info("withdraw <currenyc> <amount> send coins to your withdraw address", cmds=["withdraw"])
|
@info("withdraw <currency> <amount> send coins to your withdraw address", cmds=["withdraw"])
|
||||||
@command("withdraw", require_args=2, allow_private=True)
|
@command("withdraw", require_args=2, allow_private=True)
|
||||||
def handle_withdraw(self, msg, cmd):
|
def handle_withdraw(self, msg, cmd):
|
||||||
if not self.check_login(msg.prefix, msg.args[0]):
|
if not self.check_login(msg.prefix, msg.args[0]):
|
||||||
|
@ -116,7 +112,7 @@ class CryptoWallet(ModuleBase):
|
||||||
self.bot.act_PRIVMSG(msg.args[0], ".withdraw: Withdrawing that much would put you below the reserve "
|
self.bot.act_PRIVMSG(msg.args[0], ".withdraw: Withdrawing that much would put you below the reserve "
|
||||||
"({} {}).".format(client.reserve, cmd.args[0].upper()))
|
"({} {}).".format(client.reserve, cmd.args[0].upper()))
|
||||||
self.bot.act_PRIVMSG(msg.args[0], ".withdraw: The reserve is to cover network transaction fees. To recover "
|
self.bot.act_PRIVMSG(msg.args[0], ".withdraw: The reserve is to cover network transaction fees. To recover "
|
||||||
"it you must close your account. (Talk to an admin)")
|
"it you must close your account. (Talk to my owner)")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Check if the precision is wrong
|
# Check if the precision is wrong
|
||||||
|
@ -128,8 +124,8 @@ class CryptoWallet(ModuleBase):
|
||||||
# Create a transaction
|
# Create a transaction
|
||||||
txn = client.send(walletname, withdrawaddr, withdrawamount)
|
txn = client.send(walletname, withdrawaddr, withdrawamount)
|
||||||
if txn:
|
if txn:
|
||||||
self.bot.act_PRIVMSG(msg.args[0], "{}: .withdraw: {} {} sent to {}. "
|
self.bot.act_PRIVMSG(msg.args[0], "{}: .withdraw: {} {} sent to {}."
|
||||||
.format(msg.prefix.nick, withdrawamount, client.name, withdrawaddr))
|
.format(msg.prefix.nick, withdrawamount, client.name.upper(), withdrawaddr))
|
||||||
self.bot.act_PRIVMSG(msg.prefix.nick, "Withdrawal: (You)->{}: Transaction ID: {}"
|
self.bot.act_PRIVMSG(msg.prefix.nick, "Withdrawal: (You)->{}: Transaction ID: {}"
|
||||||
.format(withdrawaddr, txn))
|
.format(withdrawaddr, txn))
|
||||||
else:
|
else:
|
||||||
|
@ -185,8 +181,8 @@ class CryptoWallet(ModuleBase):
|
||||||
# Create a transaction
|
# Create a transaction
|
||||||
txn = client.send(walletname, tx_dest, withdrawamount)
|
txn = client.send(walletname, tx_dest, withdrawamount)
|
||||||
if txn:
|
if txn:
|
||||||
self.bot.act_PRIVMSG(msg.args[0], "{}: .send: {} {} sent to {}. "
|
self.bot.act_PRIVMSG(msg.args[0], "{}: .send: {} {} sent to {}."
|
||||||
.format(msg.prefix.nick, withdrawamount, client.name, tx_dest))
|
.format(msg.prefix.nick, withdrawamount, client.name.upper(), tx_dest))
|
||||||
self.bot.act_PRIVMSG(msg.prefix.nick, "Send: (You)->{}: Transaction ID: {}".format(tx_dest, txn))
|
self.bot.act_PRIVMSG(msg.prefix.nick, "Send: (You)->{}: Transaction ID: {}".format(tx_dest, txn))
|
||||||
else:
|
else:
|
||||||
self.bot.act_PRIVMSG(msg.args[0], "{}: .send: Transaction create failed. Maybe the address is invalid "
|
self.bot.act_PRIVMSG(msg.args[0], "{}: .send: Transaction create failed. Maybe the address is invalid "
|
||||||
|
@ -196,7 +192,7 @@ class CryptoWallet(ModuleBase):
|
||||||
# Check if dest user has a password set
|
# Check if dest user has a password set
|
||||||
destUserPassword = attr.getKey(tx_dest, "password")
|
destUserPassword = attr.getKey(tx_dest, "password")
|
||||||
if destUserPassword is None:
|
if destUserPassword is None:
|
||||||
self.bot.act_PRIVMSG(msg.args[0], "{} .send: {} doesn't have a password set."
|
self.bot.act_PRIVMSG(msg.args[0], "{}: .send: {} doesn't have a password set."
|
||||||
.format(msg.prefix.nick, tx_dest))
|
.format(msg.prefix.nick, tx_dest))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -215,8 +211,8 @@ class CryptoWallet(ModuleBase):
|
||||||
print(destWalletName)
|
print(destWalletName)
|
||||||
if client.canMove(srcWalletName, destWalletName, withdrawamount):
|
if client.canMove(srcWalletName, destWalletName, withdrawamount):
|
||||||
if client.move(srcWalletName, destWalletName, withdrawamount):
|
if client.move(srcWalletName, destWalletName, withdrawamount):
|
||||||
self.bot.act_PRIVMSG(msg.args[0], "{} .send: {} {} sent to {}. "
|
self.bot.act_PRIVMSG(msg.args[0], "{}: .send: {} {} sent to {}."
|
||||||
.format(msg.prefix.nick, withdrawamount, client.name, tx_dest))
|
.format(msg.prefix.nick, withdrawamount, client.name.upper(), tx_dest))
|
||||||
else:
|
else:
|
||||||
self.bot.act_PRIVMSG(msg.args[0], "{}: uh-oh, something went wrong doing that."
|
self.bot.act_PRIVMSG(msg.args[0], "{}: uh-oh, something went wrong doing that."
|
||||||
.format(msg.prefix.nick))
|
.format(msg.prefix.nick))
|
||||||
|
@ -247,7 +243,7 @@ class CryptoWallet(ModuleBase):
|
||||||
attr, rpc = self.getMods()
|
attr, rpc = self.getMods()
|
||||||
if not cmd.args:
|
if not cmd.args:
|
||||||
self.bot.act_PRIVMSG(msg.args[0],
|
self.bot.act_PRIVMSG(msg.args[0],
|
||||||
".curinfo: supported currencies: {}. Use '.curinfo BTC' to see details. "
|
".curinfo: supported currencies: {}. Use '.curinfo BTC' to see details."
|
||||||
.format(', '.join([x.upper() for x in rpc.getSupported()])))
|
.format(', '.join([x.upper() for x in rpc.getSupported()])))
|
||||||
else:
|
else:
|
||||||
if not rpc.isSupported(cmd.args[0]):
|
if not rpc.isSupported(cmd.args[0]):
|
||||||
|
|
|
@ -11,6 +11,7 @@ from pyircbot.modulebase import ModuleBase
|
||||||
from bitcoinrpc.authproxy import AuthServiceProxy
|
from bitcoinrpc.authproxy import AuthServiceProxy
|
||||||
import re
|
import re
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
from decimal import Decimal
|
||||||
|
|
||||||
|
|
||||||
class CryptoWalletRPC(ModuleBase):
|
class CryptoWalletRPC(ModuleBase):
|
||||||
|
@ -24,7 +25,7 @@ class CryptoWalletRPC(ModuleBase):
|
||||||
# Create a dict of abbreviation=>BitcoinRPC objcet relation
|
# Create a dict of abbreviation=>BitcoinRPC objcet relation
|
||||||
self.log.info("CryptoWalletRPC: loadrpcservices: connecting to RPCs")
|
self.log.info("CryptoWalletRPC: loadrpcservices: connecting to RPCs")
|
||||||
for abbr, coin in self.config["types"].items():
|
for abbr, coin in self.config["types"].items():
|
||||||
self.rpcservices[abbr.lower()] = BitcoinRPC(self,
|
self.rpcservices[abbr.lower()] = BitcoinRPC(self.log,
|
||||||
abbr.lower(),
|
abbr.lower(),
|
||||||
coin["name"],
|
coin["name"],
|
||||||
coin["host"],
|
coin["host"],
|
||||||
|
@ -64,9 +65,8 @@ class CryptoWalletRPC(ModuleBase):
|
||||||
|
|
||||||
|
|
||||||
class BitcoinRPC(object):
|
class BitcoinRPC(object):
|
||||||
def __init__(self, parent, name, fullname, host, port, username, password, precision, reserve, addr_re):
|
def __init__(self, logger, name, fullname, host, port, username, password, precision, reserve, addr_re):
|
||||||
# Store info and connect
|
# Store info and connect
|
||||||
self.master = parent
|
|
||||||
self.name = name
|
self.name = name
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
|
@ -75,7 +75,7 @@ class BitcoinRPC(object):
|
||||||
self.precision = precision
|
self.precision = precision
|
||||||
self.reserve = reserve
|
self.reserve = reserve
|
||||||
self.addr_re = addr_re
|
self.addr_re = addr_re
|
||||||
self.log = self.master.log
|
self.log = logger
|
||||||
self.con = None # AuthServiceProxy (bitcoin json rpc client) stored here
|
self.con = None # AuthServiceProxy (bitcoin json rpc client) stored here
|
||||||
Thread(target=self.ping).start() # Initiate rpc connection
|
Thread(target=self.ping).start() # Initiate rpc connection
|
||||||
|
|
||||||
|
@ -89,11 +89,20 @@ class BitcoinRPC(object):
|
||||||
return True if type(addr) is str and self.addr_re.match(addr) else False
|
return True if type(addr) is str and self.addr_re.match(addr) else False
|
||||||
|
|
||||||
def getBal(self, acct):
|
def getBal(self, acct):
|
||||||
# get a balance of an address or an account
|
"""
|
||||||
|
Return the balance of the passed account
|
||||||
|
:param acct: account name
|
||||||
|
:type acct: str
|
||||||
|
:return: decimal.Decimal
|
||||||
|
"""
|
||||||
return self.getAcctBal(acct)
|
return self.getAcctBal(acct)
|
||||||
|
|
||||||
def getAcctAddr(self, acct):
|
def getAcctAddr(self, acct):
|
||||||
# returns the address for an account. creates if necessary
|
"""
|
||||||
|
Return the deposit address associated with the passed account
|
||||||
|
:param acct: account name
|
||||||
|
:type acct: str
|
||||||
|
"""
|
||||||
self.ping()
|
self.ping()
|
||||||
addrs = self.con.getaddressesbyaccount(acct)
|
addrs = self.con.getaddressesbyaccount(acct)
|
||||||
if len(addrs) == 0:
|
if len(addrs) == 0:
|
||||||
|
@ -103,7 +112,7 @@ class BitcoinRPC(object):
|
||||||
def getAcctBal(self, acct):
|
def getAcctBal(self, acct):
|
||||||
# returns an account's balance
|
# returns an account's balance
|
||||||
self.ping()
|
self.ping()
|
||||||
return float(self.con.getbalance(acct))
|
return Decimal(self.con.getbalance(acct))
|
||||||
|
|
||||||
def canMove(self, fromAcct, toAcct, amount):
|
def canMove(self, fromAcct, toAcct, amount):
|
||||||
# true or false if fromAcct can afford to give toAcct an amount of coins
|
# true or false if fromAcct can afford to give toAcct an amount of coins
|
||||||
|
|
|
@ -3,4 +3,4 @@
|
||||||
export PYTHONUNBUFFERED=1
|
export PYTHONUNBUFFERED=1
|
||||||
export PYTHONPATH=.
|
export PYTHONPATH=.
|
||||||
|
|
||||||
py.test --fulltrace --cov=pyircbot --cov-report html -n 4 tests/ $@
|
py.test --cov=pyircbot --cov-report html -n 4 tests/ $@
|
||||||
|
|
|
@ -168,3 +168,7 @@ def livebot(ircserver, tmpdir):
|
||||||
yield port, server, bot, bot_t, channel, nick
|
yield port, server, bot, bot_t, channel, nick
|
||||||
|
|
||||||
bot.kill(message="bye", forever=True)
|
bot.kill(message="bye", forever=True)
|
||||||
|
|
||||||
|
|
||||||
|
def pm(bot, line, nick="chatter"):
|
||||||
|
bot.feed_line(line, args=['bot'], sender=(nick, "root", "cia.gov"))
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
import pytest
|
||||||
|
from tests.lib import * # NOQA - fixtures
|
||||||
|
from unittest.mock import MagicMock, call
|
||||||
|
from tests.modules.test_nickuser import nickbot # NOQA - fixture
|
||||||
|
from decimal import Decimal
|
||||||
|
from tests.lib import pm
|
||||||
|
import re
|
||||||
|
from pyircbot.modules.CryptoWalletRPC import BitcoinRPC
|
||||||
|
|
||||||
|
|
||||||
|
class ReallyFakeBitcoinRPC(BitcoinRPC):
|
||||||
|
"""
|
||||||
|
Fake BitcoinRPC instance we mock into the test fakebot instances. We add the `balance` attribute which is used for
|
||||||
|
keeping track of the fake account's balance
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(logger=MagicMock(),
|
||||||
|
name="fake",
|
||||||
|
fullname="Fakecoin",
|
||||||
|
host="127.0.0.1",
|
||||||
|
port=12345,
|
||||||
|
username="foo",
|
||||||
|
password="bar",
|
||||||
|
precision=4,
|
||||||
|
reserve=5,
|
||||||
|
addr_re=re.compile("^FAKE[a-f0-9A-F]{12}$"))
|
||||||
|
self.balance = Decimal("666.0067")
|
||||||
|
|
||||||
|
def getAcctAddr(self, acct):
|
||||||
|
return "FOOADDRESS"
|
||||||
|
|
||||||
|
def getAcctBal(self, acct):
|
||||||
|
return self.balance
|
||||||
|
|
||||||
|
def send(self, fromAcct, toAddr, amount):
|
||||||
|
return "txidFOOBAR"
|
||||||
|
|
||||||
|
def move(self, fromAcct, toAcct, amount):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def cryptobot(nickbot):
|
||||||
|
"""
|
||||||
|
Provide a bot loaded with the CryptoWallet modules
|
||||||
|
. """
|
||||||
|
nickbot.botconfig["module_configs"]["CryptoWalletRPC"] = \
|
||||||
|
{"types": {
|
||||||
|
"FAKE": {
|
||||||
|
"name": "Fakecoin",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"username": "",
|
||||||
|
"password": "",
|
||||||
|
"port": 1234,
|
||||||
|
"precision": 4,
|
||||||
|
"reserve": 1.0,
|
||||||
|
"link": "http://fakecoin.com/",
|
||||||
|
"addrfmt": "^FAKE[a-f0-9A-F]{12}$"}}}
|
||||||
|
|
||||||
|
nickbot.loadmodule("CryptoWalletRPC")
|
||||||
|
nickbot.loadmodule("CryptoWallet")
|
||||||
|
nickbot.moduleInstances['CryptoWalletRPC'].rpcservices['fake'] = ReallyFakeBitcoinRPC()
|
||||||
|
return nickbot
|
||||||
|
|
||||||
|
|
||||||
|
def test_getbal_authed(cryptobot):
|
||||||
|
cryptobot.feed_line(".getbal fake")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: Please .login to use this command.')
|
||||||
|
|
||||||
|
|
||||||
|
def test_setup(cryptobot, mynick="chatter"):
|
||||||
|
pm(cryptobot, ".setpass foobar", nick=mynick)
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with(mynick, '.setpass: Your password has been set to "foobar".')
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
pm(cryptobot, ".login foobar", nick=mynick)
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with(mynick, '.login: You have been logged in from: cia.gov')
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_getbal(cryptobot):
|
||||||
|
test_setup(cryptobot)
|
||||||
|
cryptobot.feed_line(".getbal fake")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: your balance is: 666.0067 FAKE')
|
||||||
|
|
||||||
|
|
||||||
|
def test_setaddr(cryptobot):
|
||||||
|
# Must login
|
||||||
|
cryptobot.feed_line(".setaddr fake FAKE123456789012")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: Please .login to use this command.')
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
test_setup(cryptobot)
|
||||||
|
# Invalid currency
|
||||||
|
cryptobot.feed_line(".setaddr invalidcoin baz")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with(
|
||||||
|
'#test',
|
||||||
|
".setaddr: 'invalidcoin' is not a supported currency. Supported currencies are: fake")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Invalid address
|
||||||
|
cryptobot.feed_line(".setaddr fake baz")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', ".setaddr: 'baz' appears to be an invalid address.")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# OK
|
||||||
|
cryptobot.feed_line(".setaddr fake FAKE123456789012")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with(
|
||||||
|
'#test',
|
||||||
|
'.setaddr: Your address has been saved as: FAKE123456789012. Please verify that this is correct or your coins '
|
||||||
|
'could be lost.')
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_withdraw(cryptobot):
|
||||||
|
test_setup(cryptobot)
|
||||||
|
# Must set withdraw addr
|
||||||
|
cryptobot.feed_line(".withdraw FAKE 400")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with(
|
||||||
|
'#test',
|
||||||
|
'.withdraw: You need to set a withdraw address before withdrawing. Try .setaddr')
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Set withdraw addr
|
||||||
|
cryptobot.feed_line(".setaddr FAKE FAKE123456789012")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with(
|
||||||
|
'#test',
|
||||||
|
'.setaddr: Your address has been saved as: FAKE123456789012. Please verify that this is correct or '
|
||||||
|
'your coins could be lost.')
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Withdraw with wrong decimal precision
|
||||||
|
cryptobot.feed_line(".withdraw FAKE 400.00001")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', ".withdraw: FAKE has maximum 4 decimal places")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Withdraw too much
|
||||||
|
cryptobot.feed_line(".withdraw FAKE 800")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', ".withdraw: You don't have enough FAKE to withdraw 800")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Withdraw below reserve
|
||||||
|
cryptobot.feed_line(".withdraw FAKE 666")
|
||||||
|
cryptobot.act_PRIVMSG.assert_has_calls(
|
||||||
|
[call('#test', '.withdraw: Withdrawing that much would put you below the reserve (5 FAKE).'),
|
||||||
|
call('#test', '.withdraw: The reserve is to cover network transaction fees. To recover it you must close your '
|
||||||
|
'account. (Talk to my owner)')])
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Withdraw
|
||||||
|
cryptobot.feed_line(".withdraw FAKE 400")
|
||||||
|
cryptobot.act_PRIVMSG.assert_has_calls(
|
||||||
|
[call('#test', 'chatter: .withdraw: 400 FAKE sent to FAKE123456789012.'),
|
||||||
|
call('chatter', 'Withdrawal: (You)->FAKE123456789012: Transaction ID: txidFOOBAR')])
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_send(cryptobot):
|
||||||
|
test_setup(cryptobot)
|
||||||
|
# Send too much
|
||||||
|
cryptobot.feed_line(".send FAKE 800 FAKE123456789012")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', "chatter: .send: You don't have enough FAKE to send 800")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Send below reserve
|
||||||
|
cryptobot.feed_line(".send FAKE 666 FAKE123456789012")
|
||||||
|
cryptobot.act_PRIVMSG.assert_has_calls(
|
||||||
|
[call('#test', '.send: Sending that much would put you below the reserve (5 FAKE).'),
|
||||||
|
call('#test', '.send: The reserve is to cover network transaction fees. To recover it you must close your '
|
||||||
|
'account. (Talk to my owner)')])
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Send with wrong decimal precision
|
||||||
|
cryptobot.feed_line(".send FAKE 400.00001 FAKE123456789012")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', ".send: FAKE has maximum 4 decimal places")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
# Send
|
||||||
|
cryptobot.feed_line(".send FAKE 400 FAKE123456789012")
|
||||||
|
cryptobot.act_PRIVMSG.assert_has_calls(
|
||||||
|
[call('#test', 'chatter: .send: 400 FAKE sent to FAKE123456789012.'),
|
||||||
|
call('chatter', 'Send: (You)->FAKE123456789012: Transaction ID: txidFOOBAR')])
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_getaddr(cryptobot):
|
||||||
|
test_setup(cryptobot)
|
||||||
|
cryptobot.feed_line(".getaddr FAKE")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: your FAKE deposit address is: FOOADDRESS')
|
||||||
|
|
||||||
|
|
||||||
|
def test_send_local(cryptobot):
|
||||||
|
"""
|
||||||
|
Similar to test_send but we send to a mocked local account
|
||||||
|
"""
|
||||||
|
test_setup(cryptobot)
|
||||||
|
# Fails if chatter2 has password yet
|
||||||
|
cryptobot.feed_line(".send FAKE 400 chatter2")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', "chatter: .send: chatter2 doesn't have a password set.")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
test_setup(cryptobot, mynick="chatter2")
|
||||||
|
|
||||||
|
cryptobot.feed_line(".send FAKE 400 chatter2")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', 'chatter: .send: 400 FAKE sent to chatter2.')
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
|
||||||
|
|
||||||
|
def test_curinfo(cryptobot):
|
||||||
|
cryptobot.feed_line(".curinfo")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test', ".curinfo: supported currencies: FAKE. Use "
|
||||||
|
"'.curinfo BTC' to see details.")
|
||||||
|
cryptobot.act_PRIVMSG.reset_mock()
|
||||||
|
cryptobot.feed_line(".curinfo fake")
|
||||||
|
cryptobot.act_PRIVMSG.assert_called_once_with('#test',
|
||||||
|
".curinfo: fake - Fakecoin. More info: http://fakecoin.com/")
|
|
@ -1,5 +1,6 @@
|
||||||
import pytest
|
import pytest
|
||||||
from contextlib import closing
|
from contextlib import closing
|
||||||
|
from tests.lib import pm
|
||||||
from tests.lib import * # NOQA - fixtures
|
from tests.lib import * # NOQA - fixtures
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
|
@ -26,10 +27,6 @@ def nickbot(fakebot):
|
||||||
return fakebot
|
return fakebot
|
||||||
|
|
||||||
|
|
||||||
def pm(nickbot, line):
|
|
||||||
nickbot.feed_line(line, args=['bot'])
|
|
||||||
|
|
||||||
|
|
||||||
def test_blind_login(nickbot):
|
def test_blind_login(nickbot):
|
||||||
pm(nickbot, ".login foobar")
|
pm(nickbot, ".login foobar")
|
||||||
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.login: You must first set a password with .setpass')
|
nickbot.act_PRIVMSG.assert_called_once_with('chatter', '.login: You must first set a password with .setpass')
|
||||||
|
|
Loading…
Reference in New Issue