aboutsummaryrefslogtreecommitdiff
path: root/ihatemoney/tests
diff options
context:
space:
mode:
authorAlexis M <alexis@notmyidea.org>2019-10-11 20:20:13 +0200
committerAlexis Metaireau <alexis@notmyidea.org>2019-10-14 21:20:38 +0200
commitf260a2c9e7b2f34d49ef4c2e50ce83a2361cf343 (patch)
treededf02275cb089fb2d954a668de6f8eff794036a /ihatemoney/tests
parentf2a0b9f3f0e24617f698ce74943cdabdea01431e (diff)
downloadihatemoney-mirror-f260a2c9e7b2f34d49ef4c2e50ce83a2361cf343.zip
ihatemoney-mirror-f260a2c9e7b2f34d49ef4c2e50ce83a2361cf343.tar.gz
ihatemoney-mirror-f260a2c9e7b2f34d49ef4c2e50ce83a2361cf343.tar.bz2
Use black to refomat the files.
Diffstat (limited to 'ihatemoney/tests')
-rw-r--r--ihatemoney/tests/tests.py1600
1 files changed, 921 insertions, 679 deletions
diff --git a/ihatemoney/tests/tests.py b/ihatemoney/tests/tests.py
index 3ff8a72..1767475 100644
--- a/ihatemoney/tests/tests.py
+++ b/ihatemoney/tests/tests.py
@@ -16,13 +16,12 @@ from flask import session
from flask_testing import TestCase
from ihatemoney.run import create_app, db, load_configuration
-from ihatemoney.manage import (
- GenerateConfig, GeneratePasswordHash, DeleteProject)
+from ihatemoney.manage import GenerateConfig, GeneratePasswordHash, DeleteProject
from ihatemoney import models
from ihatemoney import utils
# Unset configuration file env var if previously set
-os.environ.pop('IHATEMONEY_SETTINGS_FILE_PATH', None)
+os.environ.pop("IHATEMONEY_SETTINGS_FILE_PATH", None)
__HERE__ = os.path.dirname(os.path.abspath(__file__))
@@ -46,25 +45,32 @@ class BaseTestCase(TestCase):
def login(self, project, password=None, test_client=None):
password = password or project
- return self.client.post('/authenticate', data=dict(
- id=project, password=password), follow_redirects=True)
+ return self.client.post(
+ "/authenticate",
+ data=dict(id=project, password=password),
+ follow_redirects=True,
+ )
def post_project(self, name):
"""Create a fake project"""
# create the project
- self.client.post("/create", data={
- 'name': name,
- 'id': name,
- 'password': name,
- 'contact_email': '%s@notmyidea.org' % name
- })
+ self.client.post(
+ "/create",
+ data={
+ "name": name,
+ "id": name,
+ "password": name,
+ "contact_email": "%s@notmyidea.org" % name,
+ },
+ )
def create_project(self, name):
project = models.Project(
id=name,
name=str(name),
password=generate_password_hash(name),
- contact_email="%s@notmyidea.org" % name)
+ contact_email="%s@notmyidea.org" % name,
+ )
models.db.session.add(project)
models.db.session.commit()
@@ -75,46 +81,53 @@ class IhatemoneyTestCase(BaseTestCase):
WTF_CSRF_ENABLED = False # Simplifies the tests.
def assertStatus(self, expected, resp, url=""):
- return self.assertEqual(expected, resp.status_code,
- "%s expected %s, got %s" % (url, expected, resp.status_code))
+ return self.assertEqual(
+ expected,
+ resp.status_code,
+ "%s expected %s, got %s" % (url, expected, resp.status_code),
+ )
class ConfigurationTestCase(BaseTestCase):
-
def test_default_configuration(self):
"""Test that default settings are loaded when no other configuration file is specified"""
- self.assertFalse(self.app.config['DEBUG'])
- self.assertEqual(self.app.config['SQLALCHEMY_DATABASE_URI'], 'sqlite:////tmp/ihatemoney.db')
- self.assertFalse(self.app.config['SQLALCHEMY_TRACK_MODIFICATIONS'])
- self.assertEqual(self.app.config['MAIL_DEFAULT_SENDER'],
- ("Budget manager", "budget@notmyidea.org"))
+ self.assertFalse(self.app.config["DEBUG"])
+ self.assertEqual(
+ self.app.config["SQLALCHEMY_DATABASE_URI"], "sqlite:////tmp/ihatemoney.db"
+ )
+ self.assertFalse(self.app.config["SQLALCHEMY_TRACK_MODIFICATIONS"])
+ self.assertEqual(
+ self.app.config["MAIL_DEFAULT_SENDER"],
+ ("Budget manager", "budget@notmyidea.org"),
+ )
def test_env_var_configuration_file(self):
"""Test that settings are loaded from the specified configuration file"""
- os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] = os.path.join(__HERE__,
- "ihatemoney_envvar.cfg")
+ os.environ["IHATEMONEY_SETTINGS_FILE_PATH"] = os.path.join(
+ __HERE__, "ihatemoney_envvar.cfg"
+ )
load_configuration(self.app)
- self.assertEqual(self.app.config['SECRET_KEY'], 'lalatra')
+ self.assertEqual(self.app.config["SECRET_KEY"], "lalatra")
# Test that the specified configuration file is loaded
# even if the default configuration file ihatemoney.cfg exists
- os.environ['IHATEMONEY_SETTINGS_FILE_PATH'] = os.path.join(__HERE__,
- "ihatemoney_envvar.cfg")
+ os.environ["IHATEMONEY_SETTINGS_FILE_PATH"] = os.path.join(
+ __HERE__, "ihatemoney_envvar.cfg"
+ )
self.app.config.root_path = __HERE__
load_configuration(self.app)
- self.assertEqual(self.app.config['SECRET_KEY'], 'lalatra')
+ self.assertEqual(self.app.config["SECRET_KEY"], "lalatra")
- os.environ.pop('IHATEMONEY_SETTINGS_FILE_PATH', None)
+ os.environ.pop("IHATEMONEY_SETTINGS_FILE_PATH", None)
def test_default_configuration_file(self):
"""Test that settings are loaded from the default configuration file"""
self.app.config.root_path = __HERE__
load_configuration(self.app)
- self.assertEqual(self.app.config['SECRET_KEY'], 'supersecret')
+ self.assertEqual(self.app.config["SECRET_KEY"], "supersecret")
class BudgetTestCase(IhatemoneyTestCase):
-
def test_notifications(self):
"""Test that the notifications are sent, and that email adresses
are checked properly.
@@ -126,8 +139,9 @@ class BudgetTestCase(IhatemoneyTestCase):
self.login("raclette")
self.post_project("raclette")
- self.client.post("/raclette/invite",
- data={"emails": 'alexis@notmyidea.org'})
+ self.client.post(
+ "/raclette/invite", data={"emails": "alexis@notmyidea.org"}
+ )
self.assertEqual(len(outbox), 2)
self.assertEqual(outbox[0].recipients, ["raclette@notmyidea.org"])
@@ -135,25 +149,28 @@ class BudgetTestCase(IhatemoneyTestCase):
# sending a message to multiple persons
with self.app.mail.record_messages() as outbox:
- self.client.post("/raclette/invite",
- data={"emails": 'alexis@notmyidea.org, toto@notmyidea.org'})
+ self.client.post(
+ "/raclette/invite",
+ data={"emails": "alexis@notmyidea.org, toto@notmyidea.org"},
+ )
# only one message is sent to multiple persons
self.assertEqual(len(outbox), 1)
- self.assertEqual(outbox[0].recipients,
- ["alexis@notmyidea.org", "toto@notmyidea.org"])
+ self.assertEqual(
+ outbox[0].recipients, ["alexis@notmyidea.org", "toto@notmyidea.org"]
+ )
# mail address checking
with self.app.mail.record_messages() as outbox:
- response = self.client.post("/raclette/invite",
- data={"emails": "toto"})
+ response = self.client.post("/raclette/invite", data={"emails": "toto"})
self.assertEqual(len(outbox), 0) # no message sent
- self.assertIn("The email toto is not valid", response.data.decode('utf-8'))
+ self.assertIn("The email toto is not valid", response.data.decode("utf-8"))
# mixing good and wrong adresses shouldn't send any messages
with self.app.mail.record_messages() as outbox:
- self.client.post("/raclette/invite",
- data={"emails": 'alexis@notmyidea.org, alexis'}) # not valid
+ self.client.post(
+ "/raclette/invite", data={"emails": "alexis@notmyidea.org, alexis"}
+ ) # not valid
# only one message is sent to multiple persons
self.assertEqual(len(outbox), 0)
@@ -164,25 +181,24 @@ class BudgetTestCase(IhatemoneyTestCase):
self.login("raclette")
self.post_project("raclette")
with self.app.mail.record_messages() as outbox:
- self.client.post("/raclette/invite",
- data={"emails": 'toto@notmyidea.org'})
+ self.client.post("/raclette/invite", data={"emails": "toto@notmyidea.org"})
self.assertEqual(len(outbox), 1)
- url_start = outbox[0].body.find('You can log in using this link: ') + 32
- url_end = outbox[0].body.find('.\n', url_start)
+ url_start = outbox[0].body.find("You can log in using this link: ") + 32
+ url_end = outbox[0].body.find(".\n", url_start)
url = outbox[0].body[url_start:url_end]
self.client.get("/exit")
# Test that we got a valid token
resp = self.client.get(url, follow_redirects=True)
self.assertIn(
'You probably want to <a href="/raclette/members/add"',
- resp.data.decode('utf-8')
+ resp.data.decode("utf-8"),
)
# Test empty and invalid tokens
self.client.get("/exit")
resp = self.client.get("/authenticate")
- self.assertIn("You either provided a bad token", resp.data.decode('utf-8'))
+ self.assertIn("You either provided a bad token", resp.data.decode("utf-8"))
resp = self.client.get("/authenticate?token=token")
- self.assertIn("You either provided a bad token", resp.data.decode('utf-8'))
+ self.assertIn("You either provided a bad token", resp.data.decode("utf-8"))
def test_password_reminder(self):
# test that it is possible to have an email cotaining the password of a
@@ -209,48 +225,58 @@ class BudgetTestCase(IhatemoneyTestCase):
with self.app.mail.record_messages() as outbox:
self.client.post("/password-reminder", data={"id": "raclette"})
self.assertEqual(len(outbox), 1)
- url_start = outbox[0].body.find('You can reset it here: ') + 23
- url_end = outbox[0].body.find('.\n', url_start)
+ url_start = outbox[0].body.find("You can reset it here: ") + 23
+ url_end = outbox[0].body.find(".\n", url_start)
url = outbox[0].body[url_start:url_end]
# Test that we got a valid token
resp = self.client.get(url)
- self.assertIn("Password confirmation</label>", resp.data.decode('utf-8'))
+ self.assertIn("Password confirmation</label>", resp.data.decode("utf-8"))
# Test that password can be changed
- self.client.post(url, data={'password': 'pass', 'password_confirmation': 'pass'})
- resp = self.login('raclette', password='pass')
- self.assertIn("<title>Account manager - raclette</title>", resp.data.decode('utf-8'))
+ self.client.post(
+ url, data={"password": "pass", "password_confirmation": "pass"}
+ )
+ resp = self.login("raclette", password="pass")
+ self.assertIn(
+ "<title>Account manager - raclette</title>", resp.data.decode("utf-8")
+ )
# Test empty and null tokens
resp = self.client.get("/reset-password")
- self.assertIn("No token provided", resp.data.decode('utf-8'))
+ self.assertIn("No token provided", resp.data.decode("utf-8"))
resp = self.client.get("/reset-password?token=token")
- self.assertIn("Invalid token", resp.data.decode('utf-8'))
+ self.assertIn("Invalid token", resp.data.decode("utf-8"))
def test_project_creation(self):
with self.app.test_client() as c:
# add a valid project
- c.post("/create", data={
- 'name': 'The fabulous raclette party',
- 'id': 'raclette',
- 'password': 'party',
- 'contact_email': 'raclette@notmyidea.org'
- })
+ c.post(
+ "/create",
+ data={
+ "name": "The fabulous raclette party",
+ "id": "raclette",
+ "password": "party",
+ "contact_email": "raclette@notmyidea.org",
+ },
+ )
# session is updated
- self.assertTrue(session['raclette'])
+ self.assertTrue(session["raclette"])
# project is created
self.assertEqual(len(models.Project.query.all()), 1)
# Add a second project with the same id
- models.Project.query.get('raclette')
+ models.Project.query.get("raclette")
- c.post("/create", data={
- 'name': 'Another raclette party',
- 'id': 'raclette', # already used !
- 'password': 'party',
- 'contact_email': 'raclette@notmyidea.org'
- })
+ c.post(
+ "/create",
+ data={
+ "name": "Another raclette party",
+ "id": "raclette", # already used !
+ "password": "party",
+ "contact_email": "raclette@notmyidea.org",
+ },
+ )
# no new project added
self.assertEqual(len(models.Project.query.all()), 1)
@@ -258,17 +284,20 @@ class BudgetTestCase(IhatemoneyTestCase):
def test_project_deletion(self):
with self.app.test_client() as c:
- c.post("/create", data={
- 'name': 'raclette party',
- 'id': 'raclette',
- 'password': 'party',
- 'contact_email': 'raclette@notmyidea.org'
- })
+ c.post(
+ "/create",
+ data={
+ "name": "raclette party",
+ "id": "raclette",
+ "password": "party",
+ "contact_email": "raclette@notmyidea.org",
+ },
+ )
# project added
self.assertEqual(len(models.Project.query.all()), 1)
- c.get('/raclette/delete')
+ c.get("/raclette/delete")
# project removed
self.assertEqual(len(models.Project.query.all()), 0)
@@ -282,18 +311,16 @@ class BudgetTestCase(IhatemoneyTestCase):
# Empty bill list and no members, should now propose to add members first
self.assertIn(
'You probably want to <a href="/raclette/members/add"',
- result.data.decode('utf-8')
+ result.data.decode("utf-8"),
)
- result = self.client.post("/raclette/members/add",
- data={'name': 'alexis'})
+ result = self.client.post("/raclette/members/add", data={"name": "alexis"})
result = self.client.get("/raclette/")
# Empty bill with member, list should now propose to add bills
self.assertIn(
- 'You probably want to <a href="/raclette/add"',
- result.data.decode('utf-8')
+ 'You probably want to <a href="/raclette/add"', result.data.decode("utf-8")
)
def test_membership(self):
@@ -301,92 +328,98 @@ class BudgetTestCase(IhatemoneyTestCase):
self.login("raclette")
# adds a member to this project
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
self.assertEqual(len(models.Project.query.get("raclette").members), 1)
# adds him twice
- result = self.client.post("/raclette/members/add",
- data={'name': 'alexis'})
+ result = self.client.post("/raclette/members/add", data={"name": "alexis"})
# should not accept him
self.assertEqual(len(models.Project.query.get("raclette").members), 1)
# add fred
- self.client.post("/raclette/members/add", data={'name': 'fred'})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
self.assertEqual(len(models.Project.query.get("raclette").members), 2)
# check fred is present in the bills page
result = self.client.get("/raclette/")
- self.assertIn("fred", result.data.decode('utf-8'))
+ self.assertIn("fred", result.data.decode("utf-8"))
# remove fred
- self.client.post("/raclette/members/%s/delete" %
- models.Project.query.get("raclette").members[-1].id)
+ self.client.post(
+ "/raclette/members/%s/delete"
+ % models.Project.query.get("raclette").members[-1].id
+ )
# as fred is not bound to any bill, he is removed
self.assertEqual(len(models.Project.query.get("raclette").members), 1)
# add fred again
- self.client.post("/raclette/members/add", data={'name': 'fred'})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
fred_id = models.Project.query.get("raclette").members[-1].id
# bound him to a bill
- result = self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': fred_id,
- 'payed_for': [fred_id, ],
- 'amount': '25',
- })
+ result = self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": fred_id,
+ "payed_for": [fred_id],
+ "amount": "25",
+ },
+ )
# remove fred
self.client.post("/raclette/members/%s/delete" % fred_id)
# he is still in the database, but is deactivated
self.assertEqual(len(models.Project.query.get("raclette").members), 2)
- self.assertEqual(
- len(models.Project.query.get("raclette").active_members), 1)
+ self.assertEqual(len(models.Project.query.get("raclette").active_members), 1)
# as fred is now deactivated, check that he is not listed when adding
# a bill or displaying the balance
result = self.client.get("/raclette/")
- self.assertNotIn(("/raclette/members/%s/delete" % fred_id), result.data.decode('utf-8'))
+ self.assertNotIn(
+ ("/raclette/members/%s/delete" % fred_id), result.data.decode("utf-8")
+ )
result = self.client.get("/raclette/add")
- self.assertNotIn("fred", result.data.decode('utf-8'))
+ self.assertNotIn("fred", result.data.decode("utf-8"))
# adding him again should reactivate him
- self.client.post("/raclette/members/add", data={'name': 'fred'})
- self.assertEqual(
- len(models.Project.query.get("raclette").active_members), 2)
+ self.client.post("/raclette/members/add", data={"name": "fred"})
+ self.assertEqual(len(models.Project.query.get("raclette").active_members), 2)
# adding an user with the same name as another user from a different
# project should not cause any troubles
self.post_project("randomid")
self.login("randomid")
- self.client.post("/randomid/members/add", data={'name': 'fred'})
- self.assertEqual(
- len(models.Project.query.get("randomid").active_members), 1)
+ self.client.post("/randomid/members/add", data={"name": "fred"})
+ self.assertEqual(len(models.Project.query.get("randomid").active_members), 1)
def test_person_model(self):
self.post_project("raclette")
self.login("raclette")
# adds a member to this project
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
alexis = models.Project.query.get("raclette").members[-1]
# should not have any bills
self.assertFalse(alexis.has_bills())
# bound him to a bill
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': alexis.id,
- 'payed_for': [alexis.id, ],
- 'amount': '25',
- })
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": alexis.id,
+ "payed_for": [alexis.id],
+ "amount": "25",
+ },
+ )
# should have a bill now
alexis = models.Project.query.get("raclette").members[-1]
@@ -397,7 +430,7 @@ class BudgetTestCase(IhatemoneyTestCase):
self.login("raclette")
# adds a member to this project
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
# try to remove the member using GET method
response = self.client.get("/raclette/members/1/delete")
@@ -405,8 +438,7 @@ class BudgetTestCase(IhatemoneyTestCase):
# delete user using POST method
self.client.post("/raclette/members/1/delete")
- self.assertEqual(
- len(models.Project.query.get("raclette").active_members), 0)
+ self.assertEqual(len(models.Project.query.get("raclette").active_members), 0)
# try to delete an user already deleted
self.client.post("/raclette/members/1/delete")
@@ -417,17 +449,17 @@ class BudgetTestCase(IhatemoneyTestCase):
self.assertTrue(models.Project.query.get("demo") is not None)
def test_deactivated_demo(self):
- self.app.config['ACTIVATE_DEMO_PROJECT'] = False
+ self.app.config["ACTIVATE_DEMO_PROJECT"] = False
# test redirection to the create project form when demo is deactivated
resp = self.client.get("/demo")
- self.assertIn('<a href="/create?project_id=demo">', resp.data.decode('utf-8'))
+ self.assertIn('<a href="/create?project_id=demo">', resp.data.decode("utf-8"))
def test_authentication(self):
# try to authenticate without credentials should redirect
# to the authentication page
resp = self.client.post("/authenticate")
- self.assertIn("Authentication", resp.data.decode('utf-8'))
+ self.assertIn("Authentication", resp.data.decode("utf-8"))
# raclette that the login / logout process works
self.create_project("raclette")
@@ -435,110 +467,128 @@ class BudgetTestCase(IhatemoneyTestCase):
# try to see the project while not being authenticated should redirect
# to the authentication page
resp = self.client.get("/raclette", follow_redirects=True)
- self.assertIn("Authentication", resp.data.decode('utf-8'))
+ self.assertIn("Authentication", resp.data.decode("utf-8"))
# try to connect with wrong credentials should not work
with self.app.test_client() as c:
- resp = c.post("/authenticate",
- data={'id': 'raclette', 'password': 'nope'})
+ resp = c.post("/authenticate", data={"id": "raclette", "password": "nope"})
- self.assertIn("Authentication", resp.data.decode('utf-8'))
- self.assertNotIn('raclette', session)
+ self.assertIn("Authentication", resp.data.decode("utf-8"))
+ self.assertNotIn("raclette", session)
# try to connect with the right credentials should work
with self.app.test_client() as c:
- resp = c.post("/authenticate",
- data={'id': 'raclette', 'password': 'raclette'})
+ resp = c.post(
+ "/authenticate", data={"id": "raclette", "password": "raclette"}
+ )
- self.assertNotIn("Authentication", resp.data.decode('utf-8'))
- self.assertIn('raclette', session)
- self.assertTrue(session['raclette'])
+ self.assertNotIn("Authentication", resp.data.decode("utf-8"))
+ self.assertIn("raclette", session)
+ self.assertTrue(session["raclette"])
# logout should wipe the session out
c.get("/exit")
- self.assertNotIn('raclette', session)
+ self.assertNotIn("raclette", session)
# test that with admin credentials, one can access every project
- self.app.config['ADMIN_PASSWORD'] = generate_password_hash("pass")
+ self.app.config["ADMIN_PASSWORD"] = generate_password_hash("pass")
with self.app.test_client() as c:
- resp = c.post("/admin?goto=%2Fraclette", data={'admin_password': 'pass'})
- self.assertNotIn("Authentication", resp.data.decode('utf-8'))
- self.assertTrue(session['is_admin'])
+ resp = c.post("/admin?goto=%2Fraclette", data={"admin_password": "pass"})
+ self.assertNotIn("Authentication", resp.data.decode("utf-8"))
+ self.assertTrue(session["is_admin"])
def test_admin_authentication(self):
- self.app.config['ADMIN_PASSWORD'] = generate_password_hash("pass")
+ self.app.config["ADMIN_PASSWORD"] = generate_password_hash("pass")
# Disable public project creation so we have an admin endpoint to test
- self.app.config['ALLOW_PUBLIC_PROJECT_CREATION'] = False
+ self.app.config["ALLOW_PUBLIC_PROJECT_CREATION"] = False
# test the redirection to the authentication page when trying to access admin endpoints
resp = self.client.get("/create")
- self.assertIn('<a href="/admin?goto=%2Fcreate">', resp.data.decode('utf-8'))
+ self.assertIn('<a href="/admin?goto=%2Fcreate">', resp.data.decode("utf-8"))
# test right password
- resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'pass'})
- self.assertIn('<a href="/create">/create</a>', resp.data.decode('utf-8'))
+ resp = self.client.post(
+ "/admin?goto=%2Fcreate", data={"admin_password": "pass"}
+ )
+ self.assertIn('<a href="/create">/create</a>', resp.data.decode("utf-8"))
# test wrong password
- resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
- self.assertNotIn('<a href="/create">/create</a>', resp.data.decode('utf-8'))
+ resp = self.client.post(
+ "/admin?goto=%2Fcreate", data={"admin_password": "wrong"}
+ )
+ self.assertNotIn('<a href="/create">/create</a>', resp.data.decode("utf-8"))
# test empty password
- resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': ''})
- self.assertNotIn('<a href="/create">/create</a>', resp.data.decode('utf-8'))
+ resp = self.client.post("/admin?goto=%2Fcreate", data={"admin_password": ""})
+ self.assertNotIn('<a href="/create">/create</a>', resp.data.decode("utf-8"))
def test_login_throttler(self):
- self.app.config['ADMIN_PASSWORD'] = generate_password_hash("pass")
+ self.app.config["ADMIN_PASSWORD"] = generate_password_hash("pass")
# Activate admin login throttling by authenticating 4 times with a wrong passsword
- self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
- self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
- self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
- resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
+ self.client.post("/admin?goto=%2Fcreate", data={"admin_password": "wrong"})
+ self.client.post("/admin?goto=%2Fcreate", data={"admin_password": "wrong"})
+ self.client.post("/admin?goto=%2Fcreate", data={"admin_password": "wrong"})
+ resp = self.client.post(
+ "/admin?goto=%2Fcreate", data={"admin_password": "wrong"}
+ )
- self.assertIn('Too many failed login attempts, please retry later.',
- resp.data.decode('utf-8'))
+ self.assertIn(
+ "Too many failed login attempts, please retry later.",
+ resp.data.decode("utf-8"),
+ )
# Change throttling delay
import gc
+
for obj in gc.get_objects():
if isinstance(obj, utils.LoginThrottler):
obj._delay = 0.005
break
# Wait for delay to expire and retry logging in
sleep(1)
- resp = self.client.post("/admin?goto=%2Fcreate", data={'admin_password': 'wrong'})
- self.assertNotIn('Too many failed login attempts, please retry later.',
- resp.data.decode('utf-8'))
+ resp = self.client.post(
+ "/admin?goto=%2Fcreate", data={"admin_password": "wrong"}
+ )
+ self.assertNotIn(
+ "Too many failed login attempts, please retry later.",
+ resp.data.decode("utf-8"),
+ )
def test_manage_bills(self):
self.post_project("raclette")
# add two persons
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- self.client.post("/raclette/members/add", data={'name': 'fred'})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
- members_ids = [m.id for m in
- models.Project.query.get("raclette").members]
+ members_ids = [m.id for m in models.Project.query.get("raclette").members]
# create a bill
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': members_ids[0],
- 'payed_for': members_ids,
- 'amount': '25',
- })
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": members_ids[0],
+ "payed_for": members_ids,
+ "amount": "25",
+ },
+ )
models.Project.query.get("raclette")
bill = models.Bill.query.one()
self.assertEqual(bill.amount, 25)
# edit the bill
- self.client.post("/raclette/edit/%s" % bill.id, data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': members_ids[0],
- 'payed_for': members_ids,
- 'amount': '10',
- })
+ self.client.post(
+ "/raclette/edit/%s" % bill.id,
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": members_ids[0],
+ "payed_for": members_ids,
+ "amount": "10",
+ },
+ )
bill = models.Bill.query.one()
self.assertEqual(bill.amount, 10, "bill edition")
@@ -548,81 +598,103 @@ class BudgetTestCase(IhatemoneyTestCase):
self.assertEqual(0, len(models.Bill.query.all()), "bill deletion")
# test balance
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': members_ids[0],
- 'payed_for': members_ids,
- 'amount': '19',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': members_ids[1],
- 'payed_for': members_ids[0],
- 'amount': '20',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': members_ids[1],
- 'payed_for': members_ids,
- 'amount': '17',
- })
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": members_ids[0],
+ "payed_for": members_ids,
+ "amount": "19",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": members_ids[1],
+ "payed_for": members_ids[0],
+ "amount": "20",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": members_ids[1],
+ "payed_for": members_ids,
+ "amount": "17",
+ },
+ )
balance = models.Project.query.get("raclette").balance
self.assertEqual(set(balance.values()), set([19.0, -19.0]))
# Bill with negative amount
- self.client.post("/raclette/add", data={
- 'date': '2011-08-12',
- 'what': 'fromage à raclette',
- 'payer': members_ids[0],
- 'payed_for': members_ids,
- 'amount': '-25'
- })
- bill = models.Bill.query.filter(models.Bill.date == '2011-08-12')[0]
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-12",
+ "what": "fromage à raclette",
+ "payer": members_ids[0],
+ "payed_for": members_ids,
+ "amount": "-25",
+ },
+ )
+ bill = models.Bill.query.filter(models.Bill.date == "2011-08-12")[0]
self.assertEqual(bill.amount, -25)
# add a bill with a comma
- self.client.post("/raclette/add", data={
- 'date': '2011-08-01',
- 'what': 'fromage à raclette',
- 'payer': members_ids[0],
- 'payed_for': members_ids,
- 'amount': '25,02',
- })
- bill = models.Bill.query.filter(models.Bill.date == '2011-08-01')[0]
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-01",
+ "what": "fromage à raclette",
+ "payer": members_ids[0],
+ "payed_for": members_ids,
+ "amount": "25,02",
+ },
+ )
+ bill = models.Bill.query.filter(models.Bill.date == "2011-08-01")[0]
self.assertEqual(bill.amount, 25.02)
def test_weighted_balance(self):
self.post_project("raclette")
# add two persons
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- self.client.post("/raclette/members/add", data={'name': 'freddy familly', 'weight': 4})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ self.client.post(
+ "/raclette/members/add", data={"name": "freddy familly", "weight": 4}
+ )
- members_ids = [m.id for m in
- models.Project.query.get("raclette").members]
+ members_ids = [m.id for m in models.Project.query.get("raclette").members]
# test balance
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': members_ids[0],
- 'payed_for': members_ids,
- 'amount': '10',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'pommes de terre',
- 'payer': members_ids[1],
- 'payed_for': members_ids,
- 'amount': '10',
- })
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": members_ids[0],
+ "payed_for": members_ids,
+ "amount": "10",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "pommes de terre",
+ "payer": members_ids[1],
+ "payed_for": members_ids,
+ "amount": "10",
+ },
+ )
balance = models.Project.query.get("raclette").balance
self.assertEqual(set(balance.values()), set([6, -6]))
@@ -631,8 +703,8 @@ class BudgetTestCase(IhatemoneyTestCase):
self.post_project("raclette")
# Add two times the same person (with a space at the end).
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- self.client.post("/raclette/members/add", data={'name': 'alexis '})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ self.client.post("/raclette/members/add", data={"name": "alexis "})
members = models.Project.query.get("raclette").members
self.assertEqual(len(members), 1)
@@ -641,61 +713,74 @@ class BudgetTestCase(IhatemoneyTestCase):
self.post_project("raclette")
# add two persons
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- self.client.post("/raclette/members/add", data={'name': 'tata', 'weight': 1})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ self.client.post("/raclette/members/add", data={"name": "tata", "weight": 1})
resp = self.client.get("/raclette/")
- self.assertIn('extra-info', resp.data.decode('utf-8'))
+ self.assertIn("extra-info", resp.data.decode("utf-8"))
- self.client.post("/raclette/members/add", data={'name': 'freddy familly', 'weight': 4})
+ self.client.post(
+ "/raclette/members/add", data={"name": "freddy familly", "weight": 4}
+ )
resp = self.client.get("/raclette/")
- self.assertNotIn('extra-info', resp.data.decode('utf-8'))
+ self.assertNotIn("extra-info", resp.data.decode("utf-8"))
def test_negative_weight(self):
self.post_project("raclette")
# Add one user and edit it to have a negative share
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- resp = self.client.post("/raclette/members/1/edit", data={'name': 'alexis', 'weight': -1})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ resp = self.client.post(
+ "/raclette/members/1/edit", data={"name": "alexis", "weight": -1}
+ )
# An error should be generated, and its weight should still be 1.
- self.assertIn('<p class="alert alert-danger">', resp.data.decode('utf-8'))
- self.assertEqual(len(models.Project.query.get('raclette').members), 1)
- self.assertEqual(models.Project.query.get('raclette').members[0].weight, 1)
+ self.assertIn('<p class="alert alert-danger">', resp.data.decode("utf-8"))
+ self.assertEqual(len(models.Project.query.get("raclette").members), 1)
+ self.assertEqual(models.Project.query.get("raclette").members[0].weight, 1)
def test_rounding(self):
self.post_project("raclette")
# add members
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- self.client.post("/raclette/members/add", data={'name': 'fred'})
- self.client.post("/raclette/members/add", data={'name': 'tata'})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
+ self.client.post("/raclette/members/add", data={"name": "tata"})
# create bills
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': 1,
- 'payed_for': [1, 2, 3],
- 'amount': '24.36',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'red wine',
- 'payer': 2,
- 'payed_for': [1],
- 'amount': '19.12',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'delicatessen',
- 'payer': 1,
- 'payed_for': [1, 2],
- 'amount': '22',
- })
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": 1,
+ "payed_for": [1, 2, 3],
+ "amount": "24.36",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "red wine",
+ "payer": 2,
+ "payed_for": [1],
+ "amount": "19.12",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "delicatessen",
+ "payer": 1,
+ "payed_for": [1, 2],
+ "amount": "22",
+ },
+ )
balance = models.Project.query.get("raclette").balance
result = {}
@@ -714,45 +799,46 @@ class BudgetTestCase(IhatemoneyTestCase):
self.post_project("raclette")
new_data = {
- 'name': 'Super raclette party!',
- 'contact_email': 'alexis@notmyidea.org',
- 'password': 'didoudida'
+ "name": "Super raclette party!",
+ "contact_email": "alexis@notmyidea.org",
+ "password": "didoudida",
}
- resp = self.client.post("/raclette/edit", data=new_data,
- follow_redirects=True)
+ resp = self.client.post("/raclette/edit", data=new_data, follow_redirects=True)
self.assertEqual(resp.status_code, 200)
project = models.Project.query.get("raclette")
- self.assertEqual(project.name, new_data['name'])
- self.assertEqual(project.contact_email, new_data['contact_email'])
- self.assertTrue(check_password_hash(project.password, new_data['password']))
+ self.assertEqual(project.name, new_data["name"])
+ self.assertEqual(project.contact_email, new_data["contact_email"])
+ self.assertTrue(check_password_hash(project.password, new_data["password"]))
# Editing a project with a wrong email address should fail
- new_data['contact_email'] = 'wrong_email'
+ new_data["contact_email"] = "wrong_email"
- resp = self.client.post("/raclette/edit", data=new_data,
- follow_redirects=True)
- self.assertIn("Invalid email address", resp.data.decode('utf-8'))
+ resp = self.client.post("/raclette/edit", data=new_data, follow_redirects=True)
+ self.assertIn("Invalid email address", resp.data.decode("utf-8"))
def test_dashboard(self):
# test that the dashboard is deactivated by default
resp = self.client.post(
"/admin?goto=%2Fdashboard",
- data={'admin_password': 'adminpass'},
- follow_redirects=True
+ data={"admin_password": "adminpass"},
+ follow_redirects=True,
)
- self.assertIn('<div class="alert alert-danger">', resp.data.decode('utf-8'))
+ self.assertIn('<div class="alert alert-danger">', resp.data.decode("utf-8"))
# test access to the dashboard when it is activated
- self.app.config['ACTIVATE_ADMIN_DASHBOARD'] = True
- self.app.config['ADMIN_PASSWORD'] = generate_password_hash("adminpass")
+ self.app.config["ACTIVATE_ADMIN_DASHBOARD"] = True
+ self.app.config["ADMIN_PASSWORD"] = generate_password_hash("adminpass")
resp = self.client.post(
"/admin?goto=%2Fdashboard",
- data={'admin_password': 'adminpass'},
- follow_redirects=True
+ data={"admin_password": "adminpass"},
+ follow_redirects=True,
+ )
+ self.assertIn(
+ "<thead><tr><th>Project</th><th>Number of members",
+ resp.data.decode("utf-8"),
)
- self.assertIn('<thead><tr><th>Project</th><th>Number of members', resp.data.decode('utf-8'))
def test_statistics_page(self):
self.post_project("raclette")
@@ -763,58 +849,75 @@ class BudgetTestCase(IhatemoneyTestCase):
self.post_project("raclette")
# add members
- self.client.post("/raclette/members/add", data={'name': 'alexis', 'weight': 2})
- self.client.post("/raclette/members/add", data={'name': 'fred'})
- self.client.post("/raclette/members/add", data={'name': 'tata'})
+ self.client.post("/raclette/members/add", data={"name": "alexis", "weight": 2})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
+ self.client.post("/raclette/members/add", data={"name": "tata"})
# Add a member with a balance=0 :
- self.client.post("/raclette/members/add", data={'name': 'toto'})
+ self.client.post("/raclette/members/add", data={"name": "toto"})
# create bills
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': 1,
- 'payed_for': [1, 2, 3],
- 'amount': '10.0',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'red wine',
- 'payer': 2,
- 'payed_for': [1],
- 'amount': '20',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'delicatessen',
- 'payer': 1,
- 'payed_for': [1, 2],
- 'amount': '10',
- })
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": 1,
+ "payed_for": [1, 2, 3],
+ "amount": "10.0",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "red wine",
+ "payer": 2,
+ "payed_for": [1],
+ "amount": "20",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "delicatessen",
+ "payer": 1,
+ "payed_for": [1, 2],
+ "amount": "10",
+ },
+ )
response = self.client.get("/raclette/statistics")
- self.assertIn("<td>alexis</td>\n "
- + "<td>20.00</td>\n "
- + "<td>31.67</td>\n "
- + "<td>-11.67</td>\n",
- response.data.decode('utf-8'))
- self.assertIn("<td>fred</td>\n "
- + "<td>20.00</td>\n "
- + "<td>5.83</td>\n "
- + "<td>14.17</td>\n",
- response.data.decode('utf-8'))
- self.assertIn("<td>tata</td>\n "
- + "<td>0.00</td>\n "
- + "<td>2.50</td>\n "
- + "<td>-2.50</td>\n",
- response.data.decode('utf-8'))
- self.assertIn("<td>toto</td>\n "
- + "<td>0.00</td>\n "
- + "<td>0.00</td>\n "
- + "<td>0.00</td>\n",
- response.data.decode('utf-8'))
+ self.assertIn(
+ "<td>alexis</td>\n "
+ + "<td>20.00</td>\n "
+ + "<td>31.67</td>\n "
+ + "<td>-11.67</td>\n",
+ response.data.decode("utf-8"),
+ )
+ self.assertIn(
+ "<td>fred</td>\n "
+ + "<td>20.00</td>\n "
+ + "<td>5.83</td>\n "
+ + "<td>14.17</td>\n",
+ response.data.decode("utf-8"),
+ )
+ self.assertIn(
+ "<td>tata</td>\n "
+ + "<td>0.00</td>\n "
+ + "<td>2.50</td>\n "
+ + "<td>-2.50</td>\n",
+ response.data.decode("utf-8"),
+ )
+ self.assertIn(
+ "<td>toto</td>\n "
+ + "<td>0.00</td>\n "
+ + "<td>0.00</td>\n "
+ + "<td>0.00</td>\n",
+ response.data.decode("utf-8"),
+ )
def test_settle_page(self):
self.post_project("raclette")
@@ -825,43 +928,52 @@ class BudgetTestCase(IhatemoneyTestCase):
self.post_project("raclette")
# add members
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- self.client.post("/raclette/members/add", data={'name': 'fred'})
- self.client.post("/raclette/members/add", data={'name': 'tata'})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
+ self.client.post("/raclette/members/add", data={"name": "tata"})
# Add a member with a balance=0 :
- self.client.post("/raclette/members/add", data={'name': 'toto'})
+ self.client.post("/raclette/members/add", data={"name": "toto"})
# create bills
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'fromage à raclette',
- 'payer': 1,
- 'payed_for': [1, 2, 3],
- 'amount': '10.0',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'red wine',
- 'payer': 2,
- 'payed_for': [1],
- 'amount': '20',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2011-08-10',
- 'what': 'delicatessen',
- 'payer': 1,
- 'payed_for': [1, 2],
- 'amount': '10',
- })
- project = models.Project.query.get('raclette')
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage à raclette",
+ "payer": 1,
+ "payed_for": [1, 2, 3],
+ "amount": "10.0",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "red wine",
+ "payer": 2,
+ "payed_for": [1],
+ "amount": "20",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2011-08-10",
+ "what": "delicatessen",
+ "payer": 1,
+ "payed_for": [1, 2],
+ "amount": "10",
+ },
+ )
+ project = models.Project.query.get("raclette")
transactions = project.get_transactions_to_settle_bill()
members = defaultdict(int)
# We should have the same values between transactions and project balances
for t in transactions:
- members[t['ower']] -= t['amount']
- members[t['receiver']] += t['amount']
+ members[t["ower"]] -= t["amount"]
+ members[t["receiver"]] += t["amount"]
balance = models.Project.query.get("raclette").balance
for m, a in members.items():
assert abs(a - balance[m.id]) < 0.01
@@ -871,116 +983,141 @@ class BudgetTestCase(IhatemoneyTestCase):
self.post_project("raclette")
# add members
- self.client.post("/raclette/members/add", data={'name': 'alexis'})
- self.client.post("/raclette/members/add", data={'name': 'fred'})
- self.client.post("/raclette/members/add", data={'name': 'tata'})
+ self.client.post("/raclette/members/add", data={"name": "alexis"})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
+ self.client.post("/raclette/members/add", data={"name": "tata"})
# create bills
- self.client.post("/raclette/add", data={
- 'date': '2016-12-31',
- 'what': 'fromage à raclette',
- 'payer': 1,
- 'payed_for': [1, 2, 3],
- 'amount': '10.0',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2016-12-31',
- 'what': 'red wine',
- 'payer': 2,
- 'payed_for': [1, 3],
- 'amount': '20',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2017-01-01',
- 'what': 'refund',
- 'payer': 3,
- 'payed_for': [2],
- 'amount': '13.33',
- })
- project = models.Project.query.get('raclette')
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2016-12-31",
+ "what": "fromage à raclette",
+ "payer": 1,
+ "payed_for": [1, 2, 3],
+ "amount": "10.0",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2016-12-31",
+ "what": "red wine",
+ "payer": 2,
+ "payed_for": [1, 3],
+ "amount": "20",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2017-01-01",
+ "what": "refund",
+ "payer": 3,
+ "payed_for": [2],
+ "amount": "13.33",
+ },
+ )
+ project = models.Project.query.get("raclette")
transactions = project.get_transactions_to_settle_bill()
# There should not be any zero-amount transfer after rounding
for t in transactions:
- rounded_amount = round(t['amount'], 2)
- self.assertNotEqual(0.0, rounded_amount,
- msg='%f is equal to zero after rounding' % t['amount'])
+ rounded_amount = round(t["amount"], 2)
+ self.assertNotEqual(
+ 0.0,
+ rounded_amount,
+ msg="%f is equal to zero after rounding" % t["amount"],
+ )
def test_export(self):
self.post_project("raclette")
# add members
- self.client.post("/raclette/members/add", data={'name': 'alexis', 'weight': 2})
- self.client.post("/raclette/members/add", data={'name': 'fred'})
- self.client.post("/raclette/members/add", data={'name': 'tata'})
- self.client.post("/raclette/members/add", data={'name': 'pépé'})
+ self.client.post("/raclette/members/add", data={"name": "alexis", "weight": 2})
+ self.client.post("/raclette/members/add", data={"name": "fred"})
+ self.client.post("/raclette/members/add", data={"name": "tata"})
+ self.client.post("/raclette/members/add", data={"name": "pépé"})
# create bills
- self.client.post("/raclette/add", data={
- 'date': '2016-12-31',
- 'what': 'fromage à raclette',
- 'payer': 1,
- 'payed_for': [1, 2, 3, 4],
- 'amount': '10.0',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2016-12-31',
- 'what': 'red wine',
- 'payer': 2,
- 'payed_for': [1, 3],
- 'amount': '200',
- })
-
- self.client.post("/raclette/add", data={
- 'date': '2017-01-01',
- 'what': 'refund',
- 'payer': 3,
- 'payed_for': [2],
- 'amount': '13.33',
- })
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2016-12-31",
+ "what": "fromage à raclette",
+ "payer": 1,
+ "payed_for": [1, 2, 3, 4],
+ "amount": "10.0",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2016-12-31",
+ "what": "red wine",
+ "payer": 2,
+ "payed_for": [1, 3],
+ "amount": "200",
+ },
+ )
+
+ self.client.post(
+ "/raclette/add",
+ data={
+ "date": "2017-01-01",
+ "what": "refund",
+ "payer": 3,
+ "payed_for": [2],
+ "amount": "13.33",
+ },
+ )
# generate json export of bills
resp = self.client.get("/raclette/export/bills.json")
- expected = [{
- 'date': '2017-01-01',
- 'what': 'refund',
- 'amount': 13.33,
- 'payer_name': 'tata',
- 'payer_weight': 1.0,
- 'owers': ['fred']
- }, {
- 'date': '2016-12-31',
- 'what': 'red wine',
- 'amount': 200.0,
- 'payer_name': 'fred',
- 'payer_weight': 1.0,
- 'owers': ['alexis', 'tata']
- }, {
- 'date': '2016-12-31',
- 'what': 'fromage \xe0 raclette',
- 'amount': 10.0,
- 'payer_name': 'alexis',
- 'payer_weight': 2.0,
- 'owers': ['alexis', 'fred', 'tata', 'p\xe9p\xe9']
- }]
- self.assertEqual(json.loads(resp.data.decode('utf-8')), expected)
+ expected = [
+ {
+ "date": "2017-01-01",
+ "what": "refund",
+ "amount": 13.33,
+ "payer_name": "tata",
+ "payer_weight": 1.0,
+ "owers": ["fred"],
+ },
+ {
+ "date": "2016-12-31",
+ "what": "red wine",
+ "amount": 200.0,
+ "payer_name": "fred",
+ "payer_weight": 1.0,
+ "owers": ["alexis", "tata"],
+ },
+ {
+ "date": "2016-12-31",
+ "what": "fromage \xe0 raclette",
+ "amount": 10.0,
+ "payer_name": "alexis",
+ "payer_weight": 2.0,
+ "owers": ["alexis", "fred", "tata", "p\xe9p\xe9"],
+ },
+ ]
+ self.assertEqual(json.loads(resp.data.decode("utf-8")), expected)
# generate csv export of bills
resp = self.client.get("/raclette/export/bills.csv")
expected = [
"date,what,amount,payer_name,payer_weight,owers",
"2017-01-01,refund,13.33,tata,1.0,fred",
- "2016-12-31,red wine,200.0,fred,1.0,\"alexis, tata\"",
- "2016-12-31,fromage à raclette,10.0,alexis,2.0,\"alexis, fred, tata, pépé\""]
- received_lines = resp.data.decode('utf-8').split("\n")
+ '2016-12-31,red wine,200.0,fred,1.0,"alexis, tata"',
+ '2016-12-31,fromage à raclette,10.0,alexis,2.0,"alexis, fred, tata, pépé"',
+ ]
+ received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected):
self.assertEqual(
- set(line.split(",")),
- set(received_lines[i].strip("\r").split(","))
+ set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
# generate json export of transactions
@@ -991,7 +1128,7 @@ class BudgetTestCase(IhatemoneyTestCase):
{"amount": 127.33, "receiver": "fred", "ower": "alexis"},
]
- self.assertEqual(json.loads(resp.data.decode('utf-8')), expected)
+ self.assertEqual(json.loads(resp.data.decode("utf-8")), expected)
# generate csv export of transactions
resp = self.client.get("/raclette/export/transactions.csv")
@@ -1002,12 +1139,11 @@ class BudgetTestCase(IhatemoneyTestCase):
"55.34,fred,tata",
"127.33,fred,alexis",
]
- received_lines = resp.data.decode('utf-8').split("\n")
+ received_lines = resp.data.decode("utf-8").split("\n")
for i, line in enumerate(expected):
self.assertEqual(
- set(line.split(",")),
- set(received_lines[i].strip("\r").split(","))
+ set(line.split(",")), set(received_lines[i].strip("\r").split(","))
)
# wrong export_format should return a 404
@@ -1024,22 +1160,30 @@ class APITestCase(IhatemoneyTestCase):
password = password or name
contact = contact or "%s@notmyidea.org" % name
- return self.client.post("/api/projects", data={
- 'name': name,
- 'id': id,
- 'password': password,
- 'contact_email': contact
- })
+ return self.client.post(
+ "/api/projects",
+ data={
+ "name": name,
+ "id": id,
+ "password": password,
+ "contact_email": contact,
+ },
+ )
def api_add_member(self, project, name, weight=1):
- self.client.post("/api/projects/%s/members" % project,
- data={"name": name, "weight": weight},
- headers=self.get_auth(project))
+ self.client.post(
+ "/api/projects/%s/members" % project,
+ data={"name": name, "weight": weight},
+ headers=self.get_auth(project),
+ )
def get_auth(self, username, password=None):
password = password or username
- base64string = base64.encodebytes(
- ('%s:%s' % (username, password)).encode('utf-8')).decode('utf-8').replace('\n', '')
+ base64string = (
+ base64.encodebytes(("%s:%s" % (username, password)).encode("utf-8"))
+ .decode("utf-8")
+ .replace("\n", "")
+ )
return {"Authorization": "Basic %s" % base64string}
def test_cors_requests(self):
@@ -1048,9 +1192,10 @@ class APITestCase(IhatemoneyTestCase):
self.assertStatus(201, resp)
# Try to do an OPTIONS requests and see if the headers are correct.
- resp = self.client.options("/api/projects/raclette",
- headers=self.get_auth("raclette"))
- self.assertEqual(resp.headers['Access-Control-Allow-Origin'], '*')
+ resp = self.client.options(
+ "/api/projects/raclette", headers=self.get_auth("raclette")
+ )
+ self.assertEqual(resp.headers["Access-Control-Allow-Origin"], "*")
def test_basic_auth(self):
# create a project
@@ -1063,32 +1208,33 @@ class APITestCase(IhatemoneyTestCase):
# PUT / POST / DELETE / GET on the different resources
# should also return a 401
- for verb in ('post',):
+ for verb in ("post",):
for resource in ("/raclette/members", "/raclette/bills"):
url = "/api/projects" + resource
- self.assertStatus(401, getattr(self.client, verb)(url),
- verb + resource)
+ self.assertStatus(401, getattr(self.client, verb)(url), verb + resource)
- for verb in ('get', 'delete', 'put'):
- for resource in ("/raclette", "/raclette/members/1",
- "/raclette/bills/1"):
+ for verb in ("get", "delete", "put"):
+ for resource in ("/raclette", "/raclette/members/1", "/raclette/bills/1"):
url = "/api/projects" + resource
- self.assertStatus(401, getattr(self.client, verb)(url),
- verb + resource)
+ self.assertStatus(401, getattr(self.client, verb)(url), verb + resource)
def test_project(self):
# wrong email should return an error
- resp = self.client.post("/api/projects", data={
- 'name': "raclette",
- 'id': "raclette",
- 'password': "raclette",
- 'contact_email': "not-an-email"
- })
+ resp = self.client.post(
+ "/api/projects",
+ data={
+ "name": "raclette",
+ "id": "raclette",
+ "password": "raclette",
+ "contact_email": "not-an-email",
+ },
+ )
self.assertTrue(400, resp.status_code)
- self.assertEqual('{"contact_email": ["Invalid email address."]}\n',
- resp.data.decode('utf-8'))
+ self.assertEqual(
+ '{"contact_email": ["Invalid email address."]}\n', resp.data.decode("utf-8")
+ )
# create it
resp = self.api_create("raclette")
@@ -1098,11 +1244,12 @@ class APITestCase(IhatemoneyTestCase):
resp = self.api_create("raclette")
self.assertTrue(400, resp.status_code)
- self.assertIn('id', json.loads(resp.data.decode('utf-8')))
+ self.assertIn("id", json.loads(resp.data.decode("utf-8")))
# get information about it
- resp = self.client.get("/api/projects/raclette",
- headers=self.get_auth("raclette"))
+ resp = self.client.get(
+ "/api/projects/raclette", headers=self.get_auth("raclette")
+ )
self.assertTrue(200, resp.status_code)
expected = {
@@ -1111,20 +1258,25 @@ class APITestCase(IhatemoneyTestCase):
"contact_email": "raclette@notmyidea.org",
"id": "raclette",
}
- decoded_resp = json.loads(resp.data.decode('utf-8'))
+ decoded_resp = json.loads(resp.data.decode("utf-8"))
self.assertDictEqual(decoded_resp, expected)
# edit should work
- resp = self.client.put("/api/projects/raclette", data={
- "contact_email": "yeah@notmyidea.org",
- "password": "raclette",
- "name": "The raclette party",
- }, headers=self.get_auth("raclette"))
+ resp = self.client.put(
+ "/api/projects/raclette",
+ data={
+ "contact_email": "yeah@notmyidea.org",
+ "password": "raclette",
+ "name": "The raclette party",
+ },
+ headers=self.get_auth("raclette"),
+ )
self.assertEqual(200, resp.status_code)
- resp = self.client.get("/api/projects/raclette",
- headers=self.get_auth("raclette"))
+ resp = self.client.get(
+ "/api/projects/raclette", headers=self.get_auth("raclette")
+ )
self.assertEqual(200, resp.status_code)
expected = {
@@ -1133,31 +1285,36 @@ class APITestCase(IhatemoneyTestCase):
"members": [],
"id": "raclette",
}
- decoded_resp = json.loads(resp.data.decode('utf-8'))
+ decoded_resp = json.loads(resp.data.decode("utf-8"))
self.assertDictEqual(decoded_resp, expected)
# password change is possible via API
- resp = self.client.put("/api/projects/raclette", data={
- "contact_email": "yeah@notmyidea.org",
- "password": "tartiflette",
- "name": "The raclette party",
- }, headers=self.get_auth("raclette"))
+ resp = self.client.put(
+ "/api/projects/raclette",
+ data={
+ "contact_email": "yeah@notmyidea.org",
+ "password": "tartiflette",
+ "name": "The raclette party",
+ },
+ headers=self.get_auth("raclette"),
+ )
self.assertEqual(200, resp.status_code)
- resp = self.client.get("/api/projects/raclette",
- headers=self.get_auth(
- "raclette", "tartiflette"))
+ resp = self.client.get(
+ "/api/projects/raclette", headers=self.get_auth("raclette", "tartiflette")
+ )
self.assertEqual(200, resp.status_code)
# delete should work
- resp = self.client.delete("/api/projects/raclette",
- headers=self.get_auth(
- "raclette", "tartiflette"))
+ resp = self.client.delete(
+ "/api/projects/raclette", headers=self.get_auth("raclette", "tartiflette")
+ )
# get should return a 401 on an unknown resource
- resp = self.client.get("/api/projects/raclette",
- headers=self.get_auth("raclette"))
+ resp = self.client.get(
+ "/api/projects/raclette", headers=self.get_auth("raclette")
+ )
self.assertEqual(401, resp.status_code)
def test_member(self):
@@ -1165,94 +1322,110 @@ class APITestCase(IhatemoneyTestCase):
self.api_create("raclette")
# get the list of members (should be empty)
- req = self.client.get("/api/projects/raclette/members",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/members", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual('[]\n', req.data.decode('utf-8'))
+ self.assertEqual("[]\n", req.data.decode("utf-8"))
# add a member
- req = self.client.post("/api/projects/raclette/members", data={
- "name": "Alexis"
- }, headers=self.get_auth("raclette"))
+ req = self.client.post(
+ "/api/projects/raclette/members",
+ data={"name": "Alexis"},
+ headers=self.get_auth("raclette"),
+ )
# the id of the new member should be returned
self.assertStatus(201, req)
- self.assertEqual("1\n", req.data.decode('utf-8'))
+ self.assertEqual("1\n", req.data.decode("utf-8"))
# the list of members should contain one member
- req = self.client.get("/api/projects/raclette/members",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/members", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual(len(json.loads(req.data.decode('utf-8'))), 1)
+ self.assertEqual(len(json.loads(req.data.decode("utf-8"))), 1)
# Try to add another member with the same name.
- req = self.client.post("/api/projects/raclette/members", data={
- "name": "Alexis"
- }, headers=self.get_auth("raclette"))
+ req = self.client.post(
+ "/api/projects/raclette/members",
+ data={"name": "Alexis"},
+ headers=self.get_auth("raclette"),
+ )
self.assertStatus(400, req)
# edit the member
- req = self.client.put("/api/projects/raclette/members/1", data={
- "name": "Fred",
- "weight": 2,
- }, headers=self.get_auth("raclette"))
+ req = self.client.put(
+ "/api/projects/raclette/members/1",
+ data={"name": "Fred", "weight": 2},
+ headers=self.get_auth("raclette"),
+ )
self.assertStatus(200, req)
# get should return the new name
- req = self.client.get("/api/projects/raclette/members/1",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/members/1", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual("Fred", json.loads(req.data.decode('utf-8'))["name"])
- self.assertEqual(2, json.loads(req.data.decode('utf-8'))["weight"])
+ self.assertEqual("Fred", json.loads(req.data.decode("utf-8"))["name"])
+ self.assertEqual(2, json.loads(req.data.decode("utf-8"))["weight"])
# edit this member with same information
# (test PUT idemopotence)
- req = self.client.put("/api/projects/raclette/members/1", data={
- "name": "Fred"
- }, headers=self.get_auth("raclette"))
+ req = self.client.put(
+ "/api/projects/raclette/members/1",
+ data={"name": "Fred"},
+ headers=self.get_auth("raclette"),
+ )
self.assertStatus(200, req)
# de-activate the user
- req = self.client.put("/api/projects/raclette/members/1", data={
- "name": "Fred",
- "activated": False,
- }, headers=self.get_auth("raclette"))
+ req = self.client.put(
+ "/api/projects/raclette/members/1",
+ data={"name": "Fred", "activated": False},
+ headers=self.get_auth("raclette"),
+ )
self.assertStatus(200, req)
- req = self.client.get("/api/projects/raclette/members/1",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/members/1", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual(False, json.loads(req.data.decode('utf-8'))["activated"])
+ self.assertEqual(False, json.loads(req.data.decode("utf-8"))["activated"])
# re-activate the user
- req = self.client.put("/api/projects/raclette/members/1", data={
- "name": "Fred",
- "activated": True,
- }, headers=self.get_auth("raclette"))
+ req = self.client.put(
+ "/api/projects/raclette/members/1",
+ data={"name": "Fred", "activated": True},
+ headers=self.get_auth("raclette"),
+ )
- req = self.client.get("/api/projects/raclette/members/1",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/members/1", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual(True, json.loads(req.data.decode('utf-8'))["activated"])
+ self.assertEqual(True, json.loads(req.data.decode("utf-8"))["activated"])
# delete a member
- req = self.client.delete("/api/projects/raclette/members/1",
- headers=self.get_auth("raclette"))
+ req = self.client.delete(
+ "/api/projects/raclette/members/1", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
# the list of members should be empty
- req = self.client.get("/api/projects/raclette/members",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/members", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual('[]\n', req.data.decode('utf-8'))
+ self.assertEqual("[]\n", req.data.decode("utf-8"))
def test_bills(self):
# create a project
@@ -1264,29 +1437,35 @@ class APITestCase(IhatemoneyTestCase):
self.api_add_member("raclette", "arnaud")
# get the list of bills (should be empty)
- req = self.client.get("/api/projects/raclette/bills",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/bills", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual("[]\n", req.data.decode('utf-8'))
+ self.assertEqual("[]\n", req.data.decode("utf-8"))
# add a bill
- req = self.client.post("/api/projects/raclette/bills", data={
- 'date': '2011-08-10',
- 'what': 'fromage',
- 'payer': "1",
- 'payed_for': ["1", "2"],
- 'amount': '25',
- 'external_link': "https://raclette.fr"
- }, headers=self.get_auth("raclette"))
+ req = self.client.post(
+ "/api/projects/raclette/bills",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage",
+ "payer": "1",
+ "payed_for": ["1", "2"],
+ "amount": "25",
+ "external_link": "https://raclette.fr",
+ },
+ headers=self.get_auth("raclette"),
+ )
# should return the id
self.assertStatus(201, req)
- self.assertEqual(req.data.decode('utf-8'), "1\n")
+ self.assertEqual(req.data.decode("utf-8"), "1\n")
# get this bill details
- req = self.client.get("/api/projects/raclette/bills/1",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/bills/1", headers=self.get_auth("raclette")
+ )
# compare with the added info
self.assertStatus(200, req)
@@ -1295,56 +1474,68 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1,
"owers": [
{"activated": True, "id": 1, "name": "alexis", "weight": 1},
- {"activated": True, "id": 2, "name": "fred", "weight": 1}],
+ {"activated": True, "id": 2, "name": "fred", "weight": 1},
+ ],
"amount": 25.0,
"date": "2011-08-10",
"id": 1,
- 'external_link': "https://raclette.fr"
+ "external_link": "https://raclette.fr",
}
- got = json.loads(req.data.decode('utf-8'))
+ got = json.loads(req.data.decode("utf-8"))
self.assertEqual(
datetime.date.today(),
- datetime.datetime.strptime(got["creation_date"], '%Y-%m-%d').date()
+ datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(),
)
del got["creation_date"]
self.assertDictEqual(expected, got)
# the list of bills should length 1
- req = self.client.get("/api/projects/raclette/bills",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/bills", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual(1, len(json.loads(req.data.decode('utf-8'))))
+ self.assertEqual(1, len(json.loads(req.data.decode("utf-8"))))
# edit with errors should return an error
- req = self.client.put("/api/projects/raclette/bills/1", data={
- 'date': '201111111-08-10', # not a date
- 'what': 'fromage',
- 'payer': "1",
- 'payed_for': ["1", "2"],
- 'amount': '25',
- 'external_link': "https://raclette.fr",
- }, headers=self.get_auth("raclette"))
+ req = self.client.put(
+ "/api/projects/raclette/bills/1",
+ data={
+ "date": "201111111-08-10", # not a date
+ "what": "fromage",
+ "payer": "1",
+ "payed_for": ["1", "2"],
+ "amount": "25",
+ "external_link": "https://raclette.fr",
+ },
+ headers=self.get_auth("raclette"),
+ )
self.assertStatus(400, req)
- self.assertEqual('{"date": ["This field is required."]}\n', req.data.decode('utf-8'))
+ self.assertEqual(
+ '{"date": ["This field is required."]}\n', req.data.decode("utf-8")
+ )
# edit a bill
- req = self.client.put("/api/projects/raclette/bills/1", data={
- 'date': '2011-09-10',
- 'what': 'beer',
- 'payer': "2",
- 'payed_for': ["1", "2"],
- 'amount': '25',
- 'external_link': "https://raclette.fr",
- }, headers=self.get_auth("raclette"))
+ req = self.client.put(
+ "/api/projects/raclette/bills/1",
+ data={
+ "date": "2011-09-10",
+ "what": "beer",
+ "payer": "2",
+ "payed_for": ["1", "2"],
+ "amount": "25",
+ "external_link": "https://raclette.fr",
+ },
+ headers=self.get_auth("raclette"),
+ )
# check its fields
- req = self.client.get("/api/projects/raclette/bills/1",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/bills/1", headers=self.get_auth("raclette")
+ )
creation_date = datetime.datetime.strptime(
- json.loads(req.data.decode('utf-8'))["creation_date"],
- '%Y-%m-%d'
+ json.loads(req.data.decode("utf-8"))["creation_date"], "%Y-%m-%d"
).date()
expected = {
@@ -1352,29 +1543,32 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 2,
"owers": [
{"activated": True, "id": 1, "name": "alexis", "weight": 1},
- {"activated": True, "id": 2, "name": "fred", "weight": 1}],
+ {"activated": True, "id": 2, "name": "fred", "weight": 1},
+ ],
"amount": 25.0,
"date": "2011-09-10",
- 'external_link': "https://raclette.fr",
- "id": 1
- }
+ "external_link": "https://raclette.fr",
+ "id": 1,
+ }
- got = json.loads(req.data.decode('utf-8'))
+ got = json.loads(req.data.decode("utf-8"))
self.assertEqual(
creation_date,
- datetime.datetime.strptime(got["creation_date"], '%Y-%m-%d').date()
+ datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(),
)
del got["creation_date"]
self.assertDictEqual(expected, got)
# delete a bill
- req = self.client.delete("/api/projects/raclette/bills/1",
- headers=self.get_auth("raclette"))
+ req = self.client.delete(
+ "/api/projects/raclette/bills/1", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
# getting it should return a 404
- req = self.client.get("/api/projects/raclette/bills/1",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/bills/1", headers=self.get_auth("raclette")
+ )
self.assertStatus(404, req)
def test_bills_with_calculation(self):
@@ -1399,23 +1593,23 @@ class APITestCase(IhatemoneyTestCase):
req = self.client.post(
"/api/projects/raclette/bills",
data={
- 'date': '2011-08-10',
- 'what': 'fromage',
- 'payer': "1",
- 'payed_for': ["1", "2"],
- 'amount': input_amount,
+ "date": "2011-08-10",
+ "what": "fromage",
+ "payer": "1",
+ "payed_for": ["1", "2"],
+ "amount": input_amount,
},
- headers=self.get_auth("raclette")
+ headers=self.get_auth("raclette"),
)
# should return the id
self.assertStatus(201, req)
- self.assertEqual(req.data.decode('utf-8'), "{}\n".format(id))
+ self.assertEqual(req.data.decode("utf-8"), "{}\n".format(id))
# get this bill's details
req = self.client.get(
"/api/projects/raclette/bills/{}".format(id),
- headers=self.get_auth("raclette")
+ headers=self.get_auth("raclette"),
)
# compare with the added info
@@ -1425,17 +1619,18 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1,
"owers": [
{"activated": True, "id": 1, "name": "alexis", "weight": 1},
- {"activated": True, "id": 2, "name": "fred", "weight": 1}],
+ {"activated": True, "id": 2, "name": "fred", "weight": 1},
+ ],
"amount": expected_amount,
"date": "2011-08-10",
"id": id,
- "external_link": '',
+ "external_link": "",
}
- got = json.loads(req.data.decode('utf-8'))
+ got = json.loads(req.data.decode("utf-8"))
self.assertEqual(
datetime.date.today(),
- datetime.datetime.strptime(got["creation_date"], '%Y-%m-%d').date()
+ datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(),
)
del got["creation_date"]
self.assertDictEqual(expected, got)
@@ -1450,13 +1645,17 @@ class APITestCase(IhatemoneyTestCase):
]
for amount in erroneous_amounts:
- req = self.client.post("/api/projects/raclette/bills", data={
- 'date': '2011-08-10',
- 'what': 'fromage',
- 'payer': "1",
- 'payed_for': ["1", "2"],
- 'amount': amount,
- }, headers=self.get_auth("raclette"))
+ req = self.client.post(
+ "/api/projects/raclette/bills",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage",
+ "payer": "1",
+ "payed_for": ["1", "2"],
+ "amount": amount,
+ },
+ headers=self.get_auth("raclette"),
+ )
self.assertStatus(400, req)
def test_statistics(self):
@@ -1468,30 +1667,50 @@ class APITestCase(IhatemoneyTestCase):
self.api_add_member("raclette", "fred")
# add a bill
- req = self.client.post("/api/projects/raclette/bills", data={
- 'date': '2011-08-10',
- 'what': 'fromage',
- 'payer': "1",
- 'payed_for': ["1", "2"],
- 'amount': '25',
- }, headers=self.get_auth("raclette"))
+ req = self.client.post(
+ "/api/projects/raclette/bills",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage",
+ "payer": "1",
+ "payed_for": ["1", "2"],
+ "amount": "25",
+ },
+ headers=self.get_auth("raclette"),
+ )
# get the list of bills (should be empty)
- req = self.client.get("/api/projects/raclette/statistics",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/statistics", headers=self.get_auth("raclette")
+ )
self.assertStatus(200, req)
- self.assertEqual([
- {'balance': 12.5,
- 'member': {'activated': True, 'id': 1,
- 'name': 'alexis', 'weight': 1.0},
- 'paid': 25.0,
- 'spent': 12.5},
- {'balance': -12.5,
- 'member': {'activated': True, 'id': 2,
- 'name': 'fred', 'weight': 1.0},
- 'paid': 0,
- 'spent': 12.5}],
- json.loads(req.data.decode('utf-8')))
+ self.assertEqual(
+ [
+ {
+ "balance": 12.5,
+ "member": {
+ "activated": True,
+ "id": 1,
+ "name": "alexis",
+ "weight": 1.0,
+ },
+ "paid": 25.0,
+ "spent": 12.5,
+ },
+ {
+ "balance": -12.5,
+ "member": {
+ "activated": True,
+ "id": 2,
+ "name": "fred",
+ "weight": 1.0,
+ },
+ "paid": 0,
+ "spent": 12.5,
+ },
+ ],
+ json.loads(req.data.decode("utf-8")),
+ )
def test_username_xss(self):
# create a project
@@ -1502,8 +1721,8 @@ class APITestCase(IhatemoneyTestCase):
# add members
self.api_add_member("raclette", "<script>")
- result = self.client.get('/raclette/')
- self.assertNotIn("<script>", result.data.decode('utf-8'))
+ result = self.client.get("/raclette/")
+ self.assertNotIn("<script>", result.data.decode("utf-8"))
def test_weighted_bills(self):
# create a project
@@ -1515,20 +1734,24 @@ class APITestCase(IhatemoneyTestCase):
self.api_add_member("raclette", "arnaud")
# add a bill
- req = self.client.post("/api/projects/raclette/bills", data={
- 'date': '2011-08-10',
- 'what': "fromage",
- 'payer': "1",
- 'payed_for': ["1", "2"],
- 'amount': '25',
- }, headers=self.get_auth("raclette"))
+ req = self.client.post(
+ "/api/projects/raclette/bills",
+ data={
+ "date": "2011-08-10",
+ "what": "fromage",
+ "payer": "1",
+ "payed_for": ["1", "2"],
+ "amount": "25",
+ },
+ headers=self.get_auth("raclette"),
+ )
# get this bill details
- req = self.client.get("/api/projects/raclette/bills/1",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette/bills/1", headers=self.get_auth("raclette")
+ )
creation_date = datetime.datetime.strptime(
- json.loads(req.data.decode('utf-8'))["creation_date"],
- '%Y-%m-%d'
+ json.loads(req.data.decode("utf-8"))["creation_date"], "%Y-%m-%d"
).date()
# compare with the added info
@@ -1538,30 +1761,49 @@ class APITestCase(IhatemoneyTestCase):
"payer_id": 1,
"owers": [
{"activated": True, "id": 1, "name": "alexis", "weight": 1},
- {"activated": True, "id": 2, "name": "freddy familly", "weight": 4}],
+ {"activated": True, "id": 2, "name": "freddy familly", "weight": 4},
+ ],
"amount": 25.0,
"date": "2011-08-10",
"id": 1,
- "external_link": ''
+ "external_link": "",
}
- got = json.loads(req.data.decode('utf-8'))
+ got = json.loads(req.data.decode("utf-8"))
self.assertEqual(
creation_date,
- datetime.datetime.strptime(got["creation_date"], '%Y-%m-%d').date()
+ datetime.datetime.strptime(got["creation_date"], "%Y-%m-%d").date(),
)
del got["creation_date"]
self.assertDictEqual(expected, got)
# getting it should return a 404
- req = self.client.get("/api/projects/raclette",
- headers=self.get_auth("raclette"))
+ req = self.client.get(
+ "/api/projects/raclette", headers=self.get_auth("raclette")
+ )
expected = {
"members": [
- {"activated": True, "id": 1, "name": "alexis", "weight": 1.0, "balance": 20.0},
- {"activated": True, "id": 2, "name": "freddy familly", "weight": 4.0,
- "balance": -20.0},
- {"activated": True, "id": 3, "name": "arnaud", "weight": 1.0, "balance": 0},
+ {
+ "activated": True,
+ "id": 1,
+ "name": "alexis",
+ "weight": 1.0,
+ "balance": 20.0,
+ },
+ {
+ "activated": True,
+ "id": 2,
+ "name": "freddy familly",
+ "weight": 4.0,
+ "balance": -20.0,
+ },
+ {
+ "activated": True,
+ "id": 3,
+ "name": "arnaud",
+ "weight": 1.0,
+ "balance": 0,
+ },
],
"contact_email": "raclette@notmyidea.org",
"id": "raclette",
@@ -1569,25 +1811,24 @@ class APITestCase(IhatemoneyTestCase):
}
self.assertStatus(200, req)
- decoded_req = json.loads(req.data.decode('utf-8'))
+ decoded_req = json.loads(req.data.decode("utf-8"))
self.assertDictEqual(decoded_req, expected)
class ServerTestCase(IhatemoneyTestCase):
-
def test_homepage(self):
# See https://github.com/spiral-project/ihatemoney/pull/358
- self.app.config['APPLICATION_ROOT'] = '/'
+ self.app.config["APPLICATION_ROOT"] = "/"
req = self.client.get("/")
self.assertStatus(200, req)
def test_unprefixed(self):
- self.app.config['APPLICATION_ROOT'] = '/'
+ self.app.config["APPLICATION_ROOT"] = "/"
req = self.client.get("/foo/")
self.assertStatus(303, req)
def test_prefixed(self):
- self.app.config['APPLICATION_ROOT'] = '/foo'
+ self.app.config["APPLICATION_ROOT"] = "/foo"
req = self.client.get("/foo/")
self.assertStatus(200, req)
@@ -1599,26 +1840,27 @@ class CommandTestCase(BaseTestCase):
- produce something non-empty
"""
cmd = GenerateConfig()
- for config_file in cmd.get_options()[0].kwargs['choices']:
- with patch('sys.stdout', new=io.StringIO()) as stdout:
+ for config_file in cmd.get_options()[0].kwargs["choices"]:
+ with patch("sys.stdout", new=io.StringIO()) as stdout:
cmd.run(config_file)
print(stdout.getvalue())
self.assertNotEqual(len(stdout.getvalue().strip()), 0)
def test_generate_password_hash(self):
cmd = GeneratePasswordHash()
- with patch('sys.stdout', new=io.StringIO()) as stdout, \
- patch('getpass.getpass', new=lambda prompt: 'secret'): # NOQA
+ with patch("sys.stdout", new=io.StringIO()) as stdout, patch(
+ "getpass.getpass", new=lambda prompt: "secret"
+ ): # NOQA
cmd.run()
print(stdout.getvalue())
self.assertEqual(len(stdout.getvalue().strip()), 189)
def test_demo_project_deletion(self):
- self.create_project('demo')
- self.assertEquals(models.Project.query.get('demo').name, 'demo')
+ self.create_project("demo")
+ self.assertEquals(models.Project.query.get("demo").name, "demo")
cmd = DeleteProject()
- cmd.run('demo')
+ cmd.run("demo")
self.assertEqual(len(models.Project.query.all()), 0)