From 761720b712b7e8b3f386bcbaecc795ead96ac18d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lu=C3=ADs=20Murta?= Date: Sun, 23 Apr 2023 00:51:22 +0100 Subject: [PATCH] [Fix] Add typing information to tests And fix caught errors. --- pfbudget/extract/extract.py | 12 ++++++++---- pfbudget/extract/psd2.py | 9 ++++----- pfbudget/transform/categorizer.py | 4 ++-- pfbudget/transform/tagger.py | 6 +++--- pfbudget/transform/transform.py | 4 ++-- tests/test_psd2.py | 32 +++++++++++++++++-------------- tests/test_transform.py | 3 +-- 7 files changed, 38 insertions(+), 32 deletions(-) diff --git a/pfbudget/extract/extract.py b/pfbudget/extract/extract.py index dbde1de..a3daa50 100644 --- a/pfbudget/extract/extract.py +++ b/pfbudget/extract/extract.py @@ -1,9 +1,13 @@ from abc import ABC, abstractmethod +from datetime import date +from typing import Sequence -from pfbudget.db.model import Transaction +from pfbudget.db.model import Bank, Transaction -class Extract(ABC): +class Extractor(ABC): @abstractmethod - def extract(self) -> list[Transaction]: - return NotImplementedError + def extract( + self, bank: Bank, start: date = date.min, end: date = date.max + ) -> Sequence[Transaction]: + raise NotImplementedError diff --git a/pfbudget/extract/psd2.py b/pfbudget/extract/psd2.py index 6bffafc..6c8318d 100644 --- a/pfbudget/extract/psd2.py +++ b/pfbudget/extract/psd2.py @@ -1,21 +1,20 @@ -import datetime as dt - +from datetime import date from typing import Sequence from pfbudget.db.model import Bank, BankTransaction from pfbudget.utils.converters import convert from .exceptions import BankError, DownloadError, ExtractError -from .extract import Extract +from .extract import Extractor from .nordigen import NordigenClient -class PSD2Extractor(Extract): +class PSD2Extractor(Extractor): def __init__(self, client: NordigenClient): self.__client = client def extract( - self, bank: Bank, start=dt.date.min, end=dt.date.max + self, bank: Bank, start: date = date.min, end: date = date.max ) -> Sequence[BankTransaction]: if not bank.nordigen: raise BankError("Bank doesn't have Nordigen info") diff --git a/pfbudget/transform/categorizer.py b/pfbudget/transform/categorizer.py index 0de970c..c66fcf5 100644 --- a/pfbudget/transform/categorizer.py +++ b/pfbudget/transform/categorizer.py @@ -1,5 +1,5 @@ from copy import deepcopy -from typing import Sequence +from typing import Iterable, Sequence from pfbudget.db.model import ( CategoryRule, @@ -13,7 +13,7 @@ from .transform import Transformer class Categorizer(Transformer): - def __init__(self, rules: Sequence[CategoryRule]): + def __init__(self, rules: Iterable[CategoryRule]): self.rules = rules def transform(self, transactions: Sequence[Transaction]) -> Sequence[Transaction]: diff --git a/pfbudget/transform/tagger.py b/pfbudget/transform/tagger.py index 5e2dd81..ae44717 100644 --- a/pfbudget/transform/tagger.py +++ b/pfbudget/transform/tagger.py @@ -1,12 +1,12 @@ from copy import deepcopy -from typing import Sequence +from typing import Iterable, Sequence from pfbudget.db.model import TagRule, Transaction, TransactionTag from .transform import Transformer class Tagger(Transformer): - def __init__(self, rules: Sequence[TagRule]): + def __init__(self, rules: Iterable[TagRule]): self.rules = rules def transform(self, transactions: Sequence[Transaction]) -> Sequence[Transaction]: @@ -18,7 +18,7 @@ class Tagger(Transformer): def transform_inplace(self, transactions: Sequence[Transaction]) -> None: for rule in self.rules: for transaction in transactions: - if rule.tag in transaction.tags: + if rule.tag in [tag.tag for tag in transaction.tags]: continue if not rule.matches(transaction): diff --git a/pfbudget/transform/transform.py b/pfbudget/transform/transform.py index 585be05..9428a27 100644 --- a/pfbudget/transform/transform.py +++ b/pfbudget/transform/transform.py @@ -6,9 +6,9 @@ from pfbudget.db.model import Transaction class Transformer(ABC): @abstractmethod - def transform(self, _: Sequence[Transaction]) -> Sequence[Transaction]: + def transform(self, transactions: Sequence[Transaction]) -> Sequence[Transaction]: raise NotImplementedError @abstractmethod - def transform_inplace(self, _: Sequence[Transaction]) -> None: + def transform_inplace(self, transactions: Sequence[Transaction]) -> None: raise NotImplementedError diff --git a/tests/test_psd2.py b/tests/test_psd2.py index 0265432..efc25b2 100644 --- a/tests/test_psd2.py +++ b/tests/test_psd2.py @@ -1,30 +1,32 @@ import datetime as dt from decimal import Decimal +from typing import Any, Optional import pytest import requests import mocks.nordigen as mock -from pfbudget.db.model import Bank, BankTransaction, Nordigen +from pfbudget.db.model import AccountType, Bank, BankTransaction, Nordigen from pfbudget.extract.exceptions import BankError, CredentialsError +from pfbudget.extract.extract import Extractor from pfbudget.extract.nordigen import NordigenClient, NordigenCredentials from pfbudget.extract.psd2 import PSD2Extractor class MockGet: - def __init__(self, mock_exception=None): + def __init__(self, mock_exception: Optional[Exception] = None): self._status_code = 200 self._mock_exception = mock_exception - def __call__(self, *args, **kwargs): + def __call__(self, *args: Any, **kwargs: Any): if self._mock_exception: raise self._mock_exception - self._headers = kwargs["headers"] + self._headers: dict[str, str] = kwargs["headers"] if "Authorization" not in self._headers or not self._headers["Authorization"]: self._status_code = 401 - self.url = kwargs["url"] + self.url: str = kwargs["url"] return self @property @@ -47,7 +49,7 @@ class MockGet: @pytest.fixture(autouse=True) -def mock_requests(monkeypatch): +def mock_requests(monkeypatch: pytest.MonkeyPatch): monkeypatch.setattr("requests.get", MockGet()) monkeypatch.delattr("requests.post") monkeypatch.delattr("requests.put") @@ -55,14 +57,14 @@ def mock_requests(monkeypatch): @pytest.fixture -def extractor() -> NordigenClient: +def extractor() -> Extractor: credentials = NordigenCredentials("ID", "KEY", "TOKEN") return PSD2Extractor(NordigenClient(credentials)) @pytest.fixture -def bank() -> list[Bank]: - bank = Bank("Bank#1", "", "") +def bank() -> Bank: + bank = Bank("Bank#1", "", AccountType.checking) bank.nordigen = Nordigen("", "", mock.id, False) return bank @@ -73,18 +75,20 @@ class TestExtractPSD2: with pytest.raises(CredentialsError): NordigenClient(cred) - def test_no_psd2_bank(self, extractor): + def test_no_psd2_bank(self, extractor: Extractor): with pytest.raises(BankError): - extractor.extract(Bank("", "", "")) + extractor.extract(Bank("", "", AccountType.checking)) - def test_timeout(self, monkeypatch, extractor, bank): + def test_timeout( + self, monkeypatch: pytest.MonkeyPatch, extractor: Extractor, bank: Bank + ): monkeypatch.setattr( - "requests.get", MockGet(mock_exception=requests.ReadTimeout) + "requests.get", MockGet(mock_exception=requests.ReadTimeout()) ) with pytest.raises(requests.Timeout): extractor.extract(bank) - def test_extract(self, extractor, bank): + def test_extract(self, extractor: Extractor, bank: Bank): assert extractor.extract(bank) == [ BankTransaction( dt.date(2023, 1, 14), "string", Decimal("328.18"), "Bank#1" diff --git a/tests/test_transform.py b/tests/test_transform.py index e6b21bd..ae9eb81 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -4,7 +4,6 @@ from decimal import Decimal import mocks.categories as mock from pfbudget.db.model import ( - Bank, BankTransaction, CategoryRule, CategorySelector, @@ -102,7 +101,7 @@ class TestTransform: assert not t.category categorizer: Transformer = Categorizer(mock.category1.rules) - transactions: Transformer = categorizer.transform(transactions) + transactions = categorizer.transform(transactions) for t in transactions: assert t.category == TransactionCategory(