Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

📈 Fix #29 Added test coverage on everything, codecov at 100% #36

Merged
merged 1 commit into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified assets/database.db
Binary file not shown.
6 changes: 4 additions & 2 deletions conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ def create_test_user():
add_person(session, models.Person(**USER_TEST))
session.commit()
filtro = session.exec(
select(models.User).where(models.Person.email == user)
select(models.Person, models.User)
.join(models.User)
.where(models.Person.email == user)
).first()
return user, filtro.password
return user, filtro[1].password


def create_test_database(func):
Expand Down
2 changes: 1 addition & 1 deletion dundie/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.2.dev1+g136dc97.d20240420
1.1.1.dev1+g136dc97.d20240420
4 changes: 2 additions & 2 deletions dundie/__main__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from dundie.cli import main
from dundie.cli import main # pragma: no cover

if __name__ == "__main__":
if __name__ == "__main__": # pragma: no cover
main()
19 changes: 10 additions & 9 deletions dundie/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from dundie.database import get_session
from dundie.models import Movement, Person
from dundie.settings import DATEFMT
from dundie.settings import API_BASE_URL, DATEFMT
from dundie.utils.db import add_movement, add_person
from dundie.utils.exchange import get_rates
from dundie.utils.json_serealizer import DecimalEncoder
Expand All @@ -27,15 +27,11 @@


class InvalidBeneficiaryError(Exception):
"""
Exceção personalizada para erros de autenticação.
"""
pass


class InsufficientBalanceError(Exception):
"""
Exceção personalizada para erros de autenticação.
"""
pass


@check_login
Expand Down Expand Up @@ -94,7 +90,7 @@ def read(show=False, **query: Query) -> ResultDict:
select(Person.currency).distinct(Person.currency)
)

rates = get_rates(currencies)
rates = get_rates(currencies=currencies, url=API_BASE_URL)

results = session.exec(sql)
for person in results:
Expand Down Expand Up @@ -163,11 +159,16 @@ def transfer(value: int, **to: Query) -> tuple[int, list]:
"\n❌ [ERROR] Insufficient balance to complete the transfer.\n"
)

except (InsufficientBalanceError, InvalidBeneficiaryError) as e:
except InsufficientBalanceError as e:
log.error(str(e).strip())
console.print(e, style="danger")
sys.exit(3)

except InvalidBeneficiaryError as e:
log.error(str(e).strip())
console.print(e, style="danger")
sys.exit(7)

with get_session() as session:
email = os.getenv("DUNDIE_EMAIL")
instance_user = session.exec(
Expand Down
8 changes: 2 additions & 6 deletions dundie/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,6 @@


class InvalidEmailError(Exception):
"""
Exceção personalizada para erros de autenticação.
"""

pass


Expand All @@ -34,8 +30,8 @@ def validate_email(cls, v: str) -> str:
raise InvalidEmailError(f"Invalid email for {v!r}")
return v

def __str__(self) -> str:
return f"{self.name} - {self.role}"
# def __str__(self) -> str:
# return f"{self.name} - {self.role}"


class Balance(SQLModel, table=True):
Expand Down
5 changes: 2 additions & 3 deletions dundie/utils/exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import httpx
from pydantic import BaseModel, Field

from dundie.settings import API_BASE_URL
from dundie.utils.log import log


Expand All @@ -15,14 +14,14 @@ class USDRate(BaseModel):
value: Decimal = Field(alias="high")


def get_rates(currencies: List[str]) -> Dict[str, USDRate]:
def get_rates(currencies: List[str], url: str) -> Dict[str, USDRate]:
"""get current rate for USD vs Currency"""
return_data = {}
for currency in currencies:
if currency == "USD":
return_data[currency] = USDRate(high=1)
else:
response = httpx.get(API_BASE_URL.format(currency=currency))
response = httpx.get(url.format(currency=currency))
if response.status_code == 200:
data = response.json()[f"USD{currency}"]
return_data[currency] = USDRate(**data)
Expand Down
2 changes: 1 addition & 1 deletion dundie/utils/json_serealizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ class DecimalEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, Decimal):
return str(obj)
return super().default(obj)
# return super().default(obj)
21 changes: 17 additions & 4 deletions dundie/utils/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@


class AuthenticationLimitError(Exception):
"""
Exceção personalizada para erros de autenticação.
"""
pass


def access_allowed() -> bool:
Expand All @@ -26,6 +24,10 @@ def access_allowed() -> bool:
"""
email = os.getenv("DUNDIE_EMAIL")
senha = os.getenv("DUNDIE_PASSWORD")

if (email and senha) is None:
return None

with get_session() as session:
filter_user = session.exec(
select(Person)
Expand Down Expand Up @@ -105,9 +107,20 @@ def wrapper(*args, **kwargs):
# Se o usuário estiver logado a função original é executada
return func(*args, **kwargs)

else:
if access_allowed() is None:
attempts += login_attempts(attempts)
continue

if not access_allowed():
message_attempt_error = (
"\n❌ [ERROR] email or password exported in"
"environment variables are incorrect\n"
)
console.print(message_attempt_error, style="danger")
log.error(message_attempt_error.strip())
attempts += login_attempts(attempts)
continue

raise AuthenticationLimitError(
"\n❌ [ERROR] You have reached the authentication limit,"
" please try again later..."
Expand Down
4 changes: 1 addition & 3 deletions dundie/utils/permission.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@


class PermissionDenied(Exception):
"""
Exceção personalizada para erros de autenticação.
"""
pass


def get_user_role_dept():
Expand Down
56 changes: 56 additions & 0 deletions integration/test_add.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import pytest
from click.testing import CliRunner
from conftest import create_test_database

from dundie.cli import load, main

from .constants import PEOPLE_FILE

cmd = CliRunner()


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_add_positive_call_add_command_filter_dept():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(main, ["add", "200", "--dept=Sales"])
assert "Dunder Mifflin Report" in out.output
assert "Sales" in out.output
assert "Direct" not in out.output


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_add_negative_call_add_command_filter_dept():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(main, ["add", "sdasd", "--dept=Sales"])
assert "'sdasd' is not a valid integer" in out.output
assert 2 == out.exit_code


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_add_positive_call_add_command_filter_email():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(main, ["add", "200", "[email protected]"])
assert "Dunder Mifflin Report" in out.output
assert "jim@du" in out.output
assert "Dwight" not in out.output


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_add_negative_call_add_command_filter_email():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(main, ["add", "-200", "[email protected]"])
assert "No such option:" in out.output
assert "-2" in out.output
assert 2 == out.exit_code
18 changes: 18 additions & 0 deletions integration/test_movements.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import pytest
from click.testing import CliRunner
from conftest import create_test_database

from dundie.cli import movements

cmd = CliRunner()


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_movements_positive_call():
out = cmd.invoke(movements)
assert "Dunder Mifflin Movements" in out.output
assert "500" in out.output
assert "Date" in out.output
assert "system" in out.output
58 changes: 58 additions & 0 deletions integration/test_remove.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import pytest
from click.testing import CliRunner
from conftest import create_test_database

from dundie.cli import load, main

from .constants import PEOPLE_FILE

cmd = CliRunner()


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_remove_positive_call_add_command_filter_dept():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(main, ["remove", "200", "--dept=Sales"])
assert "Dunder Mifflin Report" in out.output
assert "Sales" in out.output
assert "Direct" not in out.output


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_remove_negative_call_add_command_filter_dept():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(main, ["remove", "sdasd", "--dept=Sales"])
assert "'sdasd' is not a valid integer" in out.output
assert 2 == out.exit_code


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_remove_positive_call_add_command_filter_email():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(main, ["remove", "200", "[email protected]"])
assert "Dunder Mifflin Report" in out.output
assert "jim@du" in out.output
assert "Dwight" not in out.output


@pytest.mark.integration
@pytest.mark.medium
@create_test_database
def test_remove_negative_call_add_command_filter_email():
"""test command load"""
cmd.invoke(load, PEOPLE_FILE)
out = cmd.invoke(
main, ["remove", "-200", "[email protected]"]
)
assert "No such option:" in out.output
assert "-2" in out.output
assert 2 == out.exit_code
Loading
Loading