From 0b59d469dd4d9aa9c9d92eea0702f6347edf7659 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Mon, 8 Dec 2025 21:04:26 +0900 Subject: [PATCH] fixup! WIP --- dibbler/queries/adjust_penalty.py | 14 +-- tests/queries/test_adjust_interest.py | 72 +++++++++++ tests/queries/test_adjust_penalty.py | 158 +++++++++++++++++++++++++ tests/queries/test_current_interest.py | 33 ++++++ tests/queries/test_current_penalty.py | 42 +++++++ 5 files changed, 309 insertions(+), 10 deletions(-) create mode 100644 tests/queries/test_adjust_interest.py create mode 100644 tests/queries/test_adjust_penalty.py create mode 100644 tests/queries/test_current_interest.py create mode 100644 tests/queries/test_current_penalty.py diff --git a/dibbler/queries/adjust_penalty.py b/dibbler/queries/adjust_penalty.py index b197dde..bd1dadb 100644 --- a/dibbler/queries/adjust_penalty.py +++ b/dibbler/queries/adjust_penalty.py @@ -9,21 +9,15 @@ from dibbler.queries.current_penalty import current_penalty def adjust_penalty( sql_session: Session, user_id: int, - new_penalty: int | None, - new_penalty_multiplier: int | None, + new_penalty: int | None = None, + new_penalty_multiplier: int | None = None, message: str | None = None, ) -> None: - """ - Adjust the penalty rate and/or penalty multiplier. - """ if new_penalty is None and new_penalty_multiplier is None: raise ValueError("At least one of new_penalty or new_penalty_multiplier must be provided") - if new_penalty is not None and new_penalty < 0: - raise ValueError("Penalty rate cannot be negative") - - if new_penalty_multiplier is not None and new_penalty_multiplier < 0: - raise ValueError("Penalty multiplier cannot be negative") + if new_penalty_multiplier is not None and new_penalty_multiplier < 100: + raise ValueError("Penalty multiplier cannot be less than 100%") if new_penalty is None or new_penalty_multiplier is None: existing_penalty, existing_penalty_multiplier = current_penalty(sql_session) diff --git a/tests/queries/test_adjust_interest.py b/tests/queries/test_adjust_interest.py new file mode 100644 index 0000000..294c24f --- /dev/null +++ b/tests/queries/test_adjust_interest.py @@ -0,0 +1,72 @@ +import pytest + +from datetime import datetime + +from sqlalchemy.orm import Session + +from dibbler.models import Transaction, User +from dibbler.queries.adjust_interest import adjust_interest +from dibbler.queries.current_interest import current_interest + + +def test_adjust_interest_no_history(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + adjust_interest( + sql_session, + user_id=user.id, + new_interest=3, + message="Setting initial interest rate", + ) + sql_session.commit() + + current_interest_rate = current_interest(sql_session) + + assert current_interest_rate == 3 + + +def test_adjust_interest_existing_history(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + transactions = [ + Transaction.adjust_interest( + time=datetime(2023, 10, 1, 9, 0, 0), + user_id=user.id, + interest_rate_percent=5, + message="Initial interest rate", + ), + ] + sql_session.add_all(transactions) + sql_session.commit() + + current_interest_rate = current_interest(sql_session) + assert current_interest_rate == 5 + + adjust_interest( + sql_session, + user_id=user.id, + new_interest=2, + message="Adjusting interest rate", + ) + sql_session.commit() + + current_interest_rate = current_interest(sql_session) + assert current_interest_rate == 2 + + +def test_adjust_interest_negative_failure(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + with pytest.raises(ValueError, match="Interest rate cannot be negative"): + adjust_interest( + sql_session, + user_id=user.id, + new_interest=-1, + message="Attempting to set negative interest rate", + ) diff --git a/tests/queries/test_adjust_penalty.py b/tests/queries/test_adjust_penalty.py new file mode 100644 index 0000000..c516947 --- /dev/null +++ b/tests/queries/test_adjust_penalty.py @@ -0,0 +1,158 @@ +from datetime import datetime + +import pytest +from sqlalchemy.orm import Session + +from dibbler.models import Transaction, User +from dibbler.models.Transaction import ( + DEFAULT_PENALTY_MULTIPLIER_PERCENTAGE, + DEFAULT_PENALTY_THRESHOLD, +) +from dibbler.queries.adjust_penalty import adjust_penalty +from dibbler.queries.current_penalty import current_penalty + + +def test_adjust_penalty_no_history(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + adjust_penalty( + sql_session, + user_id=user.id, + new_penalty=-200, + message="Setting initial interest rate", + ) + sql_session.commit() + + (penalty, multiplier) = current_penalty(sql_session) + + assert penalty == -200 + assert multiplier == DEFAULT_PENALTY_MULTIPLIER_PERCENTAGE + + +def test_adjust_penalty_multiplier_no_history(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + adjust_penalty( + sql_session, + user_id=user.id, + new_penalty_multiplier=125, + message="Setting initial interest rate", + ) + sql_session.commit() + + (penalty, multiplier) = current_penalty(sql_session) + + assert penalty == DEFAULT_PENALTY_THRESHOLD + assert multiplier == 125 + + +def test_adjust_penalty_multiplier_less_than_100_fail(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + adjust_penalty( + sql_session, + user_id=user.id, + new_penalty_multiplier=100, + message="Setting initial interest rate", + ) + sql_session.commit() + + (_, multiplier) = current_penalty(sql_session) + + assert multiplier == 100 + + with pytest.raises(ValueError, match="Penalty multiplier cannot be less than 100%"): + adjust_penalty( + sql_session, + user_id=user.id, + new_penalty_multiplier=99, + message="Setting initial interest rate", + ) + + +def test_adjust_penalty_existing_history(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + transactions = [ + Transaction.adjust_penalty( + time=datetime(2024, 1, 1, 10, 0, 0), + user_id=user.id, + penalty_threshold=-150, + penalty_multiplier_percent=110, + message="Initial penalty settings", + ), + ] + sql_session.add_all(transactions) + sql_session.commit() + + (penalty, _) = current_penalty(sql_session) + assert penalty == -150 + + adjust_penalty( + sql_session, + user_id=user.id, + new_penalty=-250, + message="Adjusting penalty threshold", + ) + sql_session.commit() + + (penalty, _) = current_penalty(sql_session) + assert penalty == -250 + + +def test_adjust_penalty_multiplier_existing_history(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + transactions = [ + Transaction.adjust_penalty( + time=datetime(2024, 1, 1, 10, 0, 0), + user_id=user.id, + penalty_threshold=-150, + penalty_multiplier_percent=110, + message="Initial penalty settings", + ), + ] + sql_session.add_all(transactions) + sql_session.commit() + + (_, multiplier) = current_penalty(sql_session) + assert multiplier == 110 + + adjust_penalty( + sql_session, + user_id=user.id, + new_penalty_multiplier=130, + message="Adjusting penalty multiplier", + ) + sql_session.commit() + (_, multiplier) = current_penalty(sql_session) + assert multiplier == 130 + + +def test_adjust_penalty_and_multiplier(sql_session: Session) -> None: + user = User("Test User") + sql_session.add(user) + sql_session.commit() + + adjust_penalty( + sql_session, + user_id=user.id, + new_penalty=-300, + new_penalty_multiplier=150, + message="Setting both penalty and multiplier", + ) + sql_session.commit() + + (penalty, multiplier) = current_penalty(sql_session) + assert penalty == -300 + assert multiplier == 150 diff --git a/tests/queries/test_current_interest.py b/tests/queries/test_current_interest.py new file mode 100644 index 0000000..3332890 --- /dev/null +++ b/tests/queries/test_current_interest.py @@ -0,0 +1,33 @@ +from datetime import datetime + +from sqlalchemy.orm import Session + +from dibbler.models.Transaction import DEFAULT_INTEREST_RATE_PERCENTAGE +from dibbler.models import Transaction, User +from dibbler.queries.current_interest import current_interest + +def test_current_interest_no_history(sql_session: Session) -> None: + assert current_interest(sql_session) == DEFAULT_INTEREST_RATE_PERCENTAGE + +def test_current_interest_with_history(sql_session: Session) -> None: + user = User("Admin User") + sql_session.add(user) + sql_session.commit() + + transactions = [ + Transaction.adjust_interest( + time=datetime(2023, 10, 1, 10, 0, 0), + interest_rate_percent=5, + user_id=user.id, + ), + Transaction.adjust_interest( + time=datetime(2023, 11, 1, 10, 0, 0), + interest_rate_percent=7, + user_id=user.id, + ), + ] + + sql_session.add_all(transactions) + sql_session.commit() + + assert current_interest(sql_session) == 7 diff --git a/tests/queries/test_current_penalty.py b/tests/queries/test_current_penalty.py new file mode 100644 index 0000000..3e28c2c --- /dev/null +++ b/tests/queries/test_current_penalty.py @@ -0,0 +1,42 @@ +from datetime import datetime + +from sqlalchemy.orm import Session + +from dibbler.models import Transaction, User +from dibbler.models.Transaction import ( + DEFAULT_PENALTY_MULTIPLIER_PERCENTAGE, + DEFAULT_PENALTY_THRESHOLD, +) +from dibbler.queries.current_penalty import current_penalty + + +def test_current_penalty_no_history(sql_session: Session) -> None: + assert current_penalty(sql_session) == ( + DEFAULT_PENALTY_THRESHOLD, + DEFAULT_PENALTY_MULTIPLIER_PERCENTAGE, + ) + + +def test_current_penalty_with_history(sql_session: Session) -> None: + user = User("Admin User") + sql_session.add(user) + sql_session.commit() + + transactions = [ + Transaction.adjust_penalty( + time=datetime(2023, 10, 1, 10, 0, 0), + penalty_threshold=200, + penalty_multiplier_percent=150, + user_id=user.id, + ), + Transaction.adjust_penalty( + time=datetime(2023, 10, 2, 10, 0, 0), + penalty_threshold=300, + penalty_multiplier_percent=200, + user_id=user.id, + ), + ] + sql_session.add_all(transactions) + sql_session.commit() + + assert current_penalty(sql_session) == (300, 200)