Skip to content

Commit

Permalink
tests: speed up unit tests (#1215)
Browse files Browse the repository at this point in the history
Adds two configuration parameters that are passed to
generate_password_hash:

- PASSWORD_HASH_METHOD
- PASSWORD_HASH_SALT_LENGTH

The unit tests use high-speed low-security values and
gain 50% speed.
  • Loading branch information
azmeuk authored Aug 12, 2023
1 parent 0187932 commit 857ca2d
Show file tree
Hide file tree
Showing 11 changed files with 40 additions and 9 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This document describes changes between each past release.

## 6.1.1 (unreleased)

- Nothing changed yet.
- Speed up unit tests (#1214)


## 6.1.0 (2023-07-29)
Expand Down
9 changes: 9 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,12 @@ project](https://pythonhosted.org/flask-mail/#configuring-flask-mail)
- **MAIL_USERNAME** : default **None**
- **MAIL_PASSWORD** : default **None**
- **DEFAULT_MAIL_SENDER** : default **None**

## Configuring password hashes

The werkzeug [generate_password_hash](https://werkzeug.palletsprojects.com/utils/#werkzeug.security.generate_password_hash)
is used to create password hashes. By default the default werkzeug values
are used, however you can customize those values with:

- **PASSWORD_HASH_METHOD** : default **None**
- **PASSWORD_HASH_SALT_LENGTH** : default **None**
3 changes: 2 additions & 1 deletion ihatemoney/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from flask_wtf.file import FileAllowed, FileField, FileRequired
from flask_wtf.form import FlaskForm
from markupsafe import Markup
from werkzeug.security import check_password_hash, generate_password_hash
from werkzeug.security import check_password_hash
from wtforms.fields import (
BooleanField,
DateField,
Expand Down Expand Up @@ -43,6 +43,7 @@
from ihatemoney.utils import (
em_surround,
eval_arithmetic_expression,
generate_password_hash,
render_localized_currency,
slugify,
)
Expand Down
3 changes: 1 addition & 2 deletions ihatemoney/manage.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,10 @@

import click
from flask.cli import FlaskGroup
from werkzeug.security import generate_password_hash

from ihatemoney.models import Project, db
from ihatemoney.run import create_app
from ihatemoney.utils import create_jinja_env
from ihatemoney.utils import create_jinja_env, generate_password_hash


@click.group(cls=FlaskGroup, create_app=create_app)
Expand Down
3 changes: 1 addition & 2 deletions ihatemoney/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@
from sqlalchemy.sql import func
from sqlalchemy_continuum import make_versioned, version_class
from sqlalchemy_continuum.plugins import FlaskPlugin
from werkzeug.security import generate_password_hash

from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.monkeypath_continuum import PatchedTransactionFactory
from ihatemoney.utils import get_members, same_bill
from ihatemoney.utils import generate_password_hash, get_members, same_bill
from ihatemoney.versioning import (
ConditionalVersioningManager,
LoggingMode,
Expand Down
3 changes: 2 additions & 1 deletion ihatemoney/tests/budget_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
from flask import session, url_for
from libfaketime import fake_time
import pytest
from werkzeug.security import check_password_hash, generate_password_hash
from werkzeug.security import check_password_hash

from ihatemoney import models
from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.tests.common.help_functions import extract_link
from ihatemoney.tests.common.ihatemoney_testcase import IhatemoneyTestCase
from ihatemoney.utils import generate_password_hash
from ihatemoney.versioning import LoggingMode
from ihatemoney.web import build_etag

Expand Down
4 changes: 3 additions & 1 deletion ihatemoney/tests/common/ihatemoney_testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
from unittest.mock import MagicMock

from flask_testing import TestCase
from werkzeug.security import generate_password_hash

from ihatemoney import models
from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.run import create_app, db
from ihatemoney.utils import generate_password_hash


class BaseTestCase(TestCase):
Expand All @@ -15,6 +15,8 @@ class BaseTestCase(TestCase):
"TESTING_SQLALCHEMY_DATABASE_URI", "sqlite://"
)
ENABLE_CAPTCHA = False
PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1

def create_app(self):
# Pass the test object as a configuration.
Expand Down
3 changes: 3 additions & 0 deletions ihatemoney/tests/ihatemoney.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ SQLACHEMY_ECHO = DEBUG
SECRET_KEY = "supersecret"

MAIL_DEFAULT_SENDER = "Budget manager <[email protected]>"

PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1
3 changes: 3 additions & 0 deletions ihatemoney/tests/ihatemoney_envvar.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ SQLACHEMY_ECHO = DEBUG
SECRET_KEY = "lalatra"

MAIL_DEFAULT_SENDER = "Budget manager <[email protected]>"

PASSWORD_HASH_METHOD = "pbkdf2:sha1:1"
PASSWORD_HASH_SALT_LENGTH = 1
13 changes: 13 additions & 0 deletions ihatemoney/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from markupsafe import Markup, escape
from werkzeug.exceptions import HTTPException
from werkzeug.routing import RoutingException
from werkzeug.security import generate_password_hash as werkzeug_generate_password_hash

limiter = limiter = Limiter(
current_app,
Expand Down Expand Up @@ -448,3 +449,15 @@ def format_form_errors(form, prefix):
errors = f"<ul><li>{error_list}</li></ul>"
# I18N: Form error with a list of errors
return Markup(_("{prefix}:<br />{errors}").format(prefix=prefix, errors=errors))


def generate_password_hash(*args, **kwargs):
if current_app.config.get("PASSWORD_HASH_METHOD"):
kwargs.setdefault("method", current_app.config["PASSWORD_HASH_METHOD"])

if current_app.config.get("PASSWORD_HASH_SALT_LENGTH"):
kwargs.setdefault(
"salt_length", current_app.config["PASSWORD_HASH_SALT_LENGTH"]
)

return werkzeug_generate_password_hash(*args, **kwargs)
3 changes: 2 additions & 1 deletion ihatemoney/web.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
import qrcode.image.svg
from sqlalchemy_continuum import Operation
from werkzeug.exceptions import NotFound
from werkzeug.security import check_password_hash, generate_password_hash
from werkzeug.security import check_password_hash

from ihatemoney.currency_convertor import CurrencyConverter
from ihatemoney.emails import send_creation_email
Expand All @@ -63,6 +63,7 @@
csv2list_of_dicts,
flash_email_error,
format_form_errors,
generate_password_hash,
limiter,
list_of_dicts2csv,
list_of_dicts2json,
Expand Down

0 comments on commit 857ca2d

Please sign in to comment.