diff options
Diffstat (limited to 'test.py')
| -rwxr-xr-x | test.py | 903 |
1 files changed, 903 insertions, 0 deletions
@@ -0,0 +1,903 @@ +#!/usr/bin/env python3 + +from datetime import datetime, date, timedelta +import json +import os +from shutil import copyfile +from string import Template +import subprocess +import unittest + +alice, bob, charlie = "alice", "bob", "charlie" +num = {alice: "+49123456", bob: "+49654321", charlie: "+49615243"} +os.environ["GSB_GROUP_ID"] = "test" +os.environ["GSB_STATE_FILE"] = "test/state.json" +os.environ["GSB_SEND_CMD"] = "cat" +os.environ["GSB_SEND_GROUP"] = "cat" +os.environ["GSB_SEND_USER"] = "cat" +os.environ["GSB_MODULES"] = "geldschiebing.py" + +now = datetime.now().date() + +msg_template = Template(""" +{"envelope": + {"source":"$sender", + "sourceDevice":2, + "relay":null, + "timestamp":1544101248419, + "isReceipt":false, + "dataMessage": + {"timestamp":1544101248419, + "message":"$msg", + "expiresInSeconds":0, + "attachments":[], + "groupInfo": + {"groupId":"test", + "members":null, + "name":null, + "type":"DELIVER"} + }, + "syncMessage":null, + "callMessage":null} +}""".replace("\n", "")) + +scheduled_state_template = Template(""" +{"balance": {"alice": {"bob": -100, "charlie": -100}, + "bob": {"alice": 100, "charlie": 0}, + "charlie": {"alice": 100, "bob": 0}}, +"name2num": {"alice": "+49123456", "bob": "+49654321", "charlie": "+49615243"}, +"num2name": {"+49123456": "alice", "+49654321": "bob", "+49615243": "charlie"}, +"cars": {}, +"scheduled_cmds": {"stuff": {"schedule": "$schedule", "last_time": "$last_time", + "sender": "+49123456", "cmd": ["split", "3", "bob", "charlie"]}}, +"changes": {"alice": [], "bob": [], "charlie": []}}""") + +def run_bot(test, sender, cmd): + msg = msg_template.substitute(sender=sender, msg=cmd).replace("\n", "\\n") + "\n" + res = subprocess.run(["python3", "./geldschieberbot.py"], text=True, capture_output=True, + # res = subprocess.run(["python3", "./bot.py"], text=True, capture_output=True, + input=msg) + + if res.returncode != 0: + print(res.stdout) + print(res.stderr) + test.assertEqual(res.returncode, 0) + test.assertEqual(res.stderr, "") + return res + +def save_state(dest): + copyfile(os.environ["GSB_STATE_FILE"], dest) + +def reset_state(state=None): + if state: + copyfile(state, os.environ["GSB_STATE_FILE"]) + else: + state = os.environ["GSB_STATE_FILE"] + if os.path.isfile(state): + os.remove(state) + +def reset_state_string(string): + with open(os.environ["GSB_STATE_FILE"], "w") as f: + json.dump(json.loads(string), f) + +def compare_state(comp_state): + with open(comp_state, "r") as csf, \ + open(os.environ["GSB_STATE_FILE"], "r") as sf: + cs = csf.read() + s = sf.read() + return cs == s + +class TestRegCmd(unittest.TestCase): + + def setUp(self): + reset_state() + + def test_correct_reg(self): + res = run_bot(self, num[alice], "!reg "+alice) + self.assertEqual(res.stdout, 'Happy geldschiebing {}!'.format(alice)) + + def test_double_reg(self): + res = run_bot(self, num[alice], "!reg "+alice) + self.assertEqual(res.stdout, 'Happy geldschiebing {}!'.format(alice)) + res = run_bot(self, num[alice], "!reg "+alice) + self.assertEqual(res.stdout, 'ERROR: '+alice+' already registered') + + def test_invalid_reg(self): + res = run_bot(self, num[alice], "!reg nase 03") + self.assertEqual(res.stdout, 'ERROR: not in form "!reg name"') + + def test_additional_reg(self): + res = run_bot(self, num[alice], "!reg "+alice) + self.assertEqual(res.stdout, 'Happy geldschiebing {}!'.format(alice)) + res = run_bot(self, num[bob], "!reg "+bob) + self.assertEqual(res.stdout, 'Happy geldschiebing {}!'.format(bob)) + res = run_bot(self, num[charlie], "!reg "+charlie) + self.assertEqual(res.stdout, 'Happy geldschiebing {}!'.format(charlie)) + + self.assertTrue(compare_state("test/state.json_3users")) + + +class TestTransactionCmd(unittest.TestCase): + + @classmethod + def tearDownClass(cls): + reset_state() + + def setUp(self): + reset_state("test/state.json_3users") + + def test_correct_schieb(self): + res = run_bot(self, num[alice], "!schieb 10 "+bob) + self.assertEqual(res.stdout, 'New Balance: {} <- 10.00 {}\n'.format(alice, bob)) + + res = run_bot(self, num[bob], "!schieb 10 "+alice) + self.assertEqual(res.stdout, 'New Balance: {} <- 0.00 {}\n'.format(bob, alice)) + + def test_correct_gib(self): + res = run_bot(self, num[alice], "!gib 10 "+bob) + self.assertEqual(res.stdout, 'New Balance: {} <- 10.00 {}\n'.format(alice, bob)) + + res = run_bot(self, num[bob], "!gib 10 "+alice) + self.assertEqual(res.stdout, 'New Balance: {} <- 0.00 {}\n'.format(bob, alice)) + + def test_correct_amount(self): + res = run_bot(self, num[bob], "!schieb 1.1 "+alice) + self.assertEqual(res.stdout, 'New Balance: {} <- 1.10 {}\n'.format(bob, alice)) + + res = run_bot(self, num[bob], "!gib 1,1 "+alice) + self.assertEqual(res.stdout, 'New Balance: {} <- 2.20 {}\n'.format(bob, alice)) + + def test_invalid_amount(self): + res = run_bot(self, num[bob], "!schieb 1b1 "+alice) + self.assertEqual(res.stdout, 'ERROR: amount must be a positive number') + + res = run_bot(self, num[bob], "!schieb ä€ "+alice) + self.assertEqual(res.stdout, 'ERROR: amount must be a positive number') + + def test_correct_schieb_name_before_amount(self): + res = run_bot(self, num[alice], "!schieb "+bob+ " 10") + self.assertEqual(res.stdout, 'New Balance: {} <- 10.00 {}\n'.format(alice, bob)) + + res = run_bot(self, num[bob], "!schieb "+alice+ " 10") + self.assertEqual(res.stdout, 'New Balance: {} <- 0.00 {}\n'.format(bob, alice)) + + def test_correct_gib_name_before_amount(self): + res = run_bot(self, num[alice], "!gib "+charlie+ " 10") + self.assertEqual(res.stdout, 'New Balance: {} <- 10.00 {}\n'.format(alice, charlie)) + + res = run_bot(self, num[charlie], "!gib "+alice+ " 10") + self.assertEqual(res.stdout, 'New Balance: {} <- 0.00 {}\n'.format(charlie, alice)) + + def test_correct_nimm(self): + res = run_bot(self, num[alice], "!nimm 10 "+bob) + self.assertEqual(res.stdout, 'New Balance: {} -> 10.00 {}\n'.format(alice, bob)) + + res = run_bot(self, num[bob], "!nimm 10 "+alice) + self.assertEqual(res.stdout, 'New Balance: {} <- 0.00 {}\n'.format(bob, alice)) + + def test_correct_zieh_name_before_amount(self): + res = run_bot(self, num[alice], "!zieh "+charlie+ " 10") + self.assertEqual(res.stdout, 'New Balance: {} -> 10.00 {}\n'.format(alice, charlie)) + + res = run_bot(self, num[charlie], "!zieh "+alice+ " 10") + self.assertEqual(res.stdout, 'New Balance: {} <- 0.00 {}\n'.format(charlie, alice)) + + def test_transactions_complex(self): + res = run_bot(self, num[alice], "!schieb "+charlie+ " 1,1") + self.assertEqual(res.stdout, 'New Balance: {} <- 1.10 {}\n'.format(alice, charlie)) + + res = run_bot(self, num[alice], "!zieh "+charlie+ " 2.1") + self.assertEqual(res.stdout, 'New Balance: {} -> 1.00 {}\n'.format(alice, charlie)) + + res = run_bot(self, num[charlie], "!schieb "+bob+ " 42") + self.assertEqual(res.stdout, 'New Balance: {} <- 42.00 {}\n'.format(charlie, bob)) + + res = run_bot(self, num[alice], "!zieh "+bob+ " 0.01") + self.assertEqual(res.stdout, 'New Balance: {} -> 0.01 {}\n'.format(alice, bob)) + + compare_state("test/state.json_transactions1") + +class TestSumCmd(unittest.TestCase): + def test_summary_single_user(self): + reset_state("test/state.json_transactions1") + res = run_bot(self, num[alice], "!sum "+alice) + self.assertEqual(res.stdout, 'Summary:\nalice:\n\t-> bob 0.01\n\t-> charlie 1.00\n\tBalance: -1.01\n') + + def test_summary_invalide_single_user(self): + reset_state() + res = run_bot(self, num[alice], "!sum "+alice) + self.assertEqual(res.stdout, 'ERROR: name "alice" not registered') + + def test_summary_double_user(self): + reset_state("test/state.json_transactions1") + res = run_bot(self, num[alice], "!sum {} {}".format(alice, bob)) + summary = \ +"""Summary: +alice: +\t-> bob 0.01 +\t-> charlie 1.00 +\tBalance: -1.01 +bob: +\t<- alice 0.01 +\t-> charlie 42.00 +\tBalance: -41.99 +""" + self.assertEqual(res.stdout, summary) + + def test_summary(self): + reset_state("test/state.json_transactions1") + res = run_bot(self, num[alice], "!sum") + summary = \ +"""Summary: +alice: +\t-> bob 0.01 +\t-> charlie 1.00 +\tBalance: -1.01 +bob: +\t<- alice 0.01 +\t-> charlie 42.00 +\tBalance: -41.99 +charlie: +\t<- alice 1.00 +\t<- bob 42.00 +\tBalance: 43.00""" + self.assertEqual(res.stdout, summary) + +class TestMisc(unittest.TestCase): + + def test_unknown_command(self): + res = run_bot(self, num[alice], "!foo") + self.assertEqual(res.stdout, "ERROR: unknown cmd. Enter !help for a list of commands.") + + def test_no_command(self): + res = run_bot(self, num[alice], "Hi, how are you?") + self.assertEqual(res.stdout, "") + + +class TestListCmd(unittest.TestCase): + + def setUp(self): + reset_state("test/state.json_3users") + + def test_ls(self): + res = run_bot(self, num[alice], "!ls") + msg = "alice: {}\nbob: {}\ncharlie: {}\n".format(num[alice], num[bob], num[charlie]) + self.assertEqual(res.stdout, msg) + + def test_list(self): + res = run_bot(self, num[bob], "!list") + msg = "alice: {}\nbob: {}\ncharlie: {}\n".format(num[alice], num[bob], num[charlie]) + self.assertEqual(res.stdout, msg) + +class TestSplitCmd(unittest.TestCase): + + def setUp(self): + reset_state("test/state.json_3users") + + def test_split_unregistered(self): + res = run_bot(self, "+4971576357", "!split") + self.assertEqual(res.stdout, 'ERROR: you must register first') + + def test_split_invalid_args(self): + res = run_bot(self, num[alice], "!split") + self.assertEqual(res.stdout, 'ERROR: not in form "!split amount [name]+"') + + res = run_bot(self, num[alice], "!split 10") + self.assertEqual(res.stdout, 'ERROR: not in form "!split amount [name]+"') + + res = run_bot(self, num[alice], "!split foo 10") + self.assertEqual(res.stdout, 'ERROR: amount must be a positive number') + + + def test_split_one_unknown_user(self): + res = run_bot(self, num[alice], "!split 30 " + "foo" + " " + charlie) + msg = \ +"""Split 30.00 between 3 -> 10.00 each +foo not known. Please take care manually +New Balance: +alice: +\t<- charlie 10.00 +\tBalance: 10.00""" + self.assertEqual(res.stdout, msg) + + def test_split(self): + res = run_bot(self, num[alice], "!split 30 " + bob + " " + charlie) + msg = \ +"""Split 30.00 between 3 -> 10.00 each +New Balance: +alice: +\t<- bob 10.00 +\t<- charlie 10.00 +\tBalance: 20.00""" + self.assertEqual(res.stdout, msg) + + def test_split_whitespace(self): + res = run_bot(self, num[alice], "!split 30 " + bob + " " + charlie + " ") + msg = \ +"""Split 30.00 between 3 -> 10.00 each +New Balance: +alice: +\t<- bob 10.00 +\t<- charlie 10.00 +\tBalance: 20.00""" + self.assertEqual(res.stdout, msg) + +class TestCarsAddCmd(unittest.TestCase): + def setUp(self): + reset_state("test/state.json_3users") + + def test_add_success(self): + i = "!cars add foo 0.04" + res = run_bot(self, num[alice], i) + o = 'added "foo" as an available car' + self.assertEqual(res.stdout, o) + + i = "!cars new bar 0.02" + res = run_bot(self, num[alice], i) + o = 'added "bar" as an available car' + self.assertEqual(res.stdout, o) + + save_state("test/state.json_2cars") + + def test_add_invalid_service_charge(self): + i = "!cars add foo 0.04hut" + res = run_bot(self, num[alice], i) + o = "ERROR: service-charge must be a positive number" + self.assertEqual(res.stdout, o) + + i = "!cars new bar -5" + res = run_bot(self, num[alice], i) + o = "ERROR: service-charge must be a positive number" + self.assertEqual(res.stdout, o) + + def test_add_name_conflict(self): + i = "!cars add foo 0.04" + res = run_bot(self, num[alice], i) + o = 'added "foo" as an available car' + self.assertEqual(res.stdout, o) + + i = "!cars new alice 0.02" + res = run_bot(self, num[alice], i) + o = 'ERROR: A user named "alice" already exists. Please use a different name for this car' + self.assertEqual(res.stdout, o) + +class TestCarsTransactions(unittest.TestCase): + def setUp(self): + reset_state("test/state.json_2cars") + + def test_schieb_car(self): + i = "!schieb foo 20" + res = run_bot(self, num[alice], i) + o = "New Balance: alice <- 20.00 foo\n" + self.assertEqual(res.stdout, o) + +class TestCarPayCmd(unittest.TestCase): + def setUp(self): + reset_state("test/state.json_2cars") + + def test_alice_pays_exact(self): + run_bot(self, num[bob], "!zieh foo 20") + run_bot(self, num[charlie], "!zieh foo 10") + + i = "!cars pay foo 30" + res = run_bot(self, num[alice], i) + o = \ +"""alice payed 30.00 +Transferring 100.00% of everybody's charges +Transfere 20.00 from bob to alice +Transfere 10.00 from charlie to alice +New Balances: +alice: +\t<- bob 20.00 +\t<- charlie 10.00 +\tBalance: 30.00 +foo: +\tAll fine :)""" + self.assertEqual(res.stdout, o) + + def test_alice_pays_more(self): + run_bot(self, num[bob], "!zieh foo 20") + run_bot(self, num[charlie], "!zieh foo 10") + + i = "!cars pay foo 40" + res = run_bot(self, num[alice], i) + o = \ +"""alice payed 40.00 +Transferring 100.00% of everybody's charges +Transfere 20.00 from bob to alice +Transfere 10.00 from charlie to alice +New Balances: +alice: +\t<- bob 20.00 +\t<- charlie 10.00 +\tBalance: 30.00 +\tCars: +\t<- foo 10.00 +\tLiability: 10.00 +foo: +\t-> alice 10.00 +\tBalance: -10.00""" + self.assertEqual(res.stdout, o) + + + def test_alice_pays_half(self): + run_bot(self, num[bob], "!zieh foo 20") + run_bot(self, num[charlie], "!zieh foo 10") + + i = "!cars pay foo 15" + res = run_bot(self, num[alice], i) + o = \ +"""alice payed 15.00 +Transferring 50.00% of everybody's charges +Transfere 10.00 from bob to alice +Transfere 5.00 from charlie to alice +New Balances: +alice: +\t<- bob 10.00 +\t<- charlie 5.00 +\tBalance: 15.00 +foo: +\t<- bob 10.00 +\t<- charlie 5.00 +\tBalance: 15.00""" + self.assertEqual(res.stdout, o) + +class TestCarsListCmd(unittest.TestCase): + def setUp(self): + reset_state("test/state.json_2cars") + + def test_no_cars(self): + reset_state() + i = "!cars" + res = run_bot(self, num[alice], i) + o = "No cars registered yet." + self.assertEqual(res.stdout, o) + + def test_implicit_call(self): + i = "!cars" + res = run_bot(self, num[alice], i) + o = \ +"""foo - service charge 4ct/km +foo: +\tAll fine :) +bar - service charge 2ct/km +bar: +\tAll fine :)""" + self.assertEqual(res.stdout, o) + + def test_list_all(self): + i = "!cars ls" + res = run_bot(self, num[alice], i) + o = \ +"""foo - service charge 4ct/km +foo: +\tAll fine :) +bar - service charge 2ct/km +bar: +\tAll fine :)""" + self.assertEqual(res.stdout, o) + + i = "!cars list" + res = run_bot(self, num[alice], i) + o = \ +"""foo - service charge 4ct/km +foo: +\tAll fine :) +bar - service charge 2ct/km +bar: +\tAll fine :)""" + self.assertEqual(res.stdout, o) + + def test_list_explicit_car(self): + i = "!cars ls foo" + res = run_bot(self, num[alice], i) + o = \ +"""foo - service charge 4ct/km +foo: +\tAll fine :)""" + self.assertEqual(res.stdout, o) + + def test_list_invalid_explicit_car(self): + i = "!cars ls alice" + res = run_bot(self, num[alice], i) + o = 'ERROR: "alice" is no available car\n' + self.assertEqual(res.stdout, o) + +class TestTankenCmd(unittest.TestCase): + + def setUp(self): + reset_state("test/state.json_3users") + + def test_tanken_3users(self): + i = \ +"""!tanken 10 alice +20 alice bob +10 charlie""" + res = run_bot(self, num[alice], i) + o = \ +"""alice: 20km = fuel: 3.33, service charge: 0.00 +bob: 20km = fuel: 3.33, service charge: 0.00 +charlie: 10km = fuel: 3.33, service charge: 0.00 +New Balance: +alice: +\t<- bob 3.33 +\t<- charlie 3.33 +\tBalance: 6.66""" + self.assertEqual(res.stdout, o) + + def test_tanken_unknown_user(self): + i = \ +"""!tanken 10 alice +20 alice dieter +10 charlie""" + res = run_bot(self, num[alice], i) + o = \ +"""alice: 20km = fuel: 3.33, service charge: 0.00 +dieter: 20km = fuel: 3.33, service charge: 0.00 +dieter not known. Please collect fuel cost manually +charlie: 10km = fuel: 3.33, service charge: 0.00 +New Balance: +alice: +\t<- charlie 3.33 +\tBalance: 3.33""" + self.assertEqual(res.stdout, o) + + def test_tanken_3users_with_car(self): + i = "!cars add foo 0.04" + res = run_bot(self, num[alice], i) + o = 'added "foo" as an available car' + self.assertEqual(res.stdout, o) + + i = \ +"""!tanken 10 alice foo +20 alice bob +10 charlie""" + res = run_bot(self, num[alice], i) + o = \ +"""alice: 20km = fuel: 3.33, service charge: 0.40 +bob: 20km = fuel: 3.33, service charge: 0.40 +charlie: 10km = fuel: 3.33, service charge: 0.40 +New Balance: +alice: +\t<- bob 3.33 +\t<- charlie 3.33 +\tBalance: 6.66 +\tCars: +\t-> foo 0.40 +\tLiability: -0.40 +Car foo: +\t<- alice 0.40 +\t<- bob 0.40 +\t<- charlie 0.40 +\tBalance: 1.20""" + self.assertEqual(res.stdout, o) + + def test_tanken_unknown_user_with_car(self): + i = "!cars add foo 0.04" + res = run_bot(self, num[alice], i) + o = 'added "foo" as an available car' + self.assertEqual(res.stdout, o) + + i = \ +"""!tanken 10 alice foo +20 alice bob +10 dieter""" + res = run_bot(self, num[alice], i) + o = \ +"""alice: 20km = fuel: 3.33, service charge: 0.40 +bob: 20km = fuel: 3.33, service charge: 0.40 +dieter: 10km = fuel: 3.33, service charge: 0.40 +dieter not known. alice held accountable for service charge. Please collect fuel cost manually +New Balance: +alice: +\t<- bob 3.33 +\tBalance: 3.33 +\tCars: +\t-> foo 0.80 +\tLiability: -0.80 +Car foo: +\t<- alice 0.80 +\t<- bob 0.40 +\tBalance: 1.20""" + self.assertEqual(res.stdout, o) + + def test_tanken_3users_with_car(self): + i = "!cars add foo 0.04" + res = run_bot(self, num[alice], i) + o = 'added "foo" as an available car' + self.assertEqual(res.stdout, o) + + i = \ +"""!tanken 10 alice foo +20 alice bob +10 charlie""" + res = run_bot(self, num[alice], i) + o = \ +"""alice: 20km = fuel: 3.33, service charge: 0.40 +bob: 20km = fuel: 3.33, service charge: 0.40 +charlie: 10km = fuel: 3.33, service charge: 0.40 +New Balance: +alice: +\t<- bob 3.33 +\t<- charlie 3.33 +\tBalance: 6.66 +\tCars: +\t-> foo 0.40 +\tLiability: -0.40 +Car foo: +\t<- alice 0.40 +\t<- bob 0.40 +\t<- charlie 0.40 +\tBalance: 1.20""" + self.assertEqual(res.stdout, o) + + +class TestTransferCmd(unittest.TestCase): + + def setUp(self): + reset_state("test/state.json_3users") + + def test_transfer(self): + i = '!transfer 5 bob charlie' + res = run_bot(self, num[alice], i) + o = \ +"""New Balance: alice -> 5.00 bob +New Balance: alice <- 5.00 charlie +New Balance: bob -> 5.00 charlie +""" + self.assertEqual(res.stdout, o) + + def test_transfer_credit(self): + res = run_bot(self, num[alice], "!schieb bob 5") + + i = '!transfer 5 bob charlie' + res = run_bot(self, num[alice], i) + o = \ +"""New Balance: alice <- 0.00 bob +New Balance: alice <- 5.00 charlie +New Balance: bob -> 5.00 charlie +""" + self.assertEqual(res.stdout, o) + + def test_transfer_change_dept(self): + res = run_bot(self, num[alice], "!schieb bob 5") + + i = '!transfer 5 bob charlie' + res = run_bot(self, num[alice], i) + o = \ +"""New Balance: alice <- 0.00 bob +New Balance: alice <- 5.00 charlie +New Balance: bob -> 5.00 charlie +""" + self.assertEqual(res.stdout, o) + + +#TODO: tanken, transfer, cars pay +class TestFuckCmd(unittest.TestCase): + + def setUp(self): + reset_state("test/state.json_3users") + + def test_fuck_unregistered(self): + res = run_bot(self, "+4971576357", "!fuck") + self.assertEqual(res.stdout, 'ERROR: you must register first') + + def test_fuck_nothing(self): + res = run_bot(self, num[alice], "!fuck") + self.assertEqual(res.stdout, 'Nothing to rewind') + + def test_fuck_transaction(self): + for cmd in ["fuck", "undo", "rewind"]: + run_bot(self, num[alice], f"!schieb {bob} 10") + res = run_bot(self, num[alice], f"!{cmd}") + msg = \ +"""alice: sorry I fucked up! +Rewinding: +!schieb bob 10 +alice <- 10.00 bob +""" + self.assertEqual(res.stdout, msg) + compare_state("test/state.json_3users") + + def test_fuck_split(self): + run_bot(self, num[alice], "!split 3 bob charlie") + res = run_bot(self, num[alice], "!fuck") + msg = \ +"""alice: sorry I fucked up! +Rewinding: +!split 3 bob charlie +alice <- 1.00 bob +alice <- 1.00 charlie +""" + self.assertEqual(res.stdout, msg) + compare_state("test/state.json_3users") + + def test_fuck_transaction(self): + run_bot(self, num[alice], "!schieb "+bob+ " 10") + res = run_bot(self, num[alice], "!fuck") + msg = \ +"""alice: sorry I fucked up! +Rewinding: +!schieb bob 10 +alice <- 10.00 bob +""" + self.assertEqual(res.stdout, msg) + compare_state("test/state.json_3users") + +class TestScheduleCmd(unittest.TestCase): + + def setUp(self): + reset_state("test/state.json_3users") + + def test_weekly(self): + res = run_bot(self, num[alice], "!weekly stuff split 3 bob charlie") + msg = \ +"""Recorded the weekly command "split 3 bob charlie" as "stuff" +Running weekly command stuff for alice initially +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 1.00 +\t<- charlie 1.00 +\tBalance: 2.00""" + self.assertEqual(res.stdout, msg) + + save_state("test/state.json_schedule_weekly") + + res = run_bot(self, num[alice], "!fuck") + msg = \ +"""alice: sorry I fucked up! +Rewinding: +split 3 bob charlie +alice <- 1.00 bob +alice <- 1.00 charlie +Cancelled the weekly cmd "stuff\"""" + self.assertEqual(res.stdout, msg) + + # Last exec onw week ago + reset_state_string(scheduled_state_template.substitute(last_time=now-timedelta(7),schedule="weekly")) + + res = run_bot(self, num[alice], "!fuck") + # There is no new line because the real bot uses two Messages + msg = \ +"""Nothing to rewindRunning weekly command stuff for alice triggered on {} +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 2.00 +\t<- charlie 2.00 +\tBalance: 4.00""".format(now.isoformat()) + self.assertEqual(res.stdout, msg) + + compare_state("test/state.json_schedule_weekly") + + res = run_bot(self, num[alice], "!fuck") + self.assertEqual(res.stdout, 'Nothing to rewind') + + # Last exec two week ago + reset_state_string(scheduled_state_template.substitute(last_time=now-timedelta(14),schedule="weekly")) + + res = run_bot(self, num[alice], "!fuck") + # There is no new line because the real bot uses two Messages + msg = \ +"""Nothing to rewindRunning weekly command stuff for alice triggered on {} +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 2.00 +\t<- charlie 2.00 +\tBalance: 4.00Running weekly command stuff for alice triggered on {} +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 3.00 +\t<- charlie 3.00 +\tBalance: 6.00""".format((now - timedelta(7)).isoformat(), + now.isoformat()) + self.assertEqual(res.stdout, msg) + + os.remove("test/state.json_schedule_weekly") + + def test_monthly(self): + self.maxDiff = None + res = run_bot(self, num[alice], "!monthly stuff split 3 bob charlie") + msg = \ +"""Recorded the monthly command "split 3 bob charlie" as "stuff" +Running monthly command stuff for alice initially +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 1.00 +\t<- charlie 1.00 +\tBalance: 2.00""" + self.assertEqual(res.stdout, msg) + + save_state("test/state.json_schedule_monthly") + + res = run_bot(self, num[alice], "!fuck") + msg = \ +"""alice: sorry I fucked up! +Rewinding: +split 3 bob charlie +alice <- 1.00 bob +alice <- 1.00 charlie +Cancelled the monthly cmd "stuff\"""" + self.assertEqual(res.stdout, msg) + + # Last exec one month ago + if now.month > 1: + one_month_ago = date(now.year, now.month-1, now.day) + else: + one_month_ago = date(now.year-1, 12, now.day) + reset_state_string(scheduled_state_template.substitute(last_time=one_month_ago, + schedule="monthly")) + + res = run_bot(self, num[alice], "!fuck") + # There is no new line because the real bot uses two Messages + msg = \ +"""Nothing to rewindRunning monthly command stuff for alice triggered on {} +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 2.00 +\t<- charlie 2.00 +\tBalance: 4.00""".format(now.isoformat()) + self.assertEqual(res.stdout, msg) + + compare_state("test/state.json_schedule_monthly") + + res = run_bot(self, num[alice], "!fuck") + self.assertEqual(res.stdout, 'Nothing to rewind') + + # Last exec two month ago + if now.month > 2: + two_months_ago = date(now.year, now.month-2, now.day) + else: + two_months_ago = date(now.year-1, 12-now.month+1, now.day) + + reset_state_string(scheduled_state_template.substitute(last_time=two_months_ago, + schedule="monthly")) + + res = run_bot(self, num[alice], "!fuck") + # There is no new line because the real bot uses to Messages + msg = \ +"""Nothing to rewindRunning monthly command stuff for alice triggered on {} +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 2.00 +\t<- charlie 2.00 +\tBalance: 4.00Running monthly command stuff for alice triggered on {} +Split 3.00 between 3 -> 1.00 each +New Balance: +alice: +\t<- bob 3.00 +\t<- charlie 3.00 +\tBalance: 6.00""".format(one_month_ago.isoformat(), + now.isoformat()) + self.assertEqual(res.stdout, msg) + + os.remove("test/state.json_schedule_monthly") + + + def test_monthly_car(self): + run_bot(self, num[alice], "!cars add fiat 0.5") + res = run_bot(self, num[alice], "!monthly versicherung cars pay fiat 3") + msg = \ +"""Recorded the monthly command "cars pay fiat 3" as "versicherung" +Running monthly command versicherung for alice initially +alice payed 3.00 +Transferring 100.00% of everybody's charges +New Balances: +alice: +\tAll fine :) +\tCars: +\t<- fiat 3.00 +\tLiability: 3.00 +fiat: +\t-> alice 3.00 +\tBalance: -3.00""" + self.assertEqual(res.stdout, msg) + +if __name__ == '__main__': + unittest.main() |
