From 4275e19fa60c0c9d5c75f830a3bf4f6494586323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felipe=20L=C3=B3pez?= Date: Tue, 22 Feb 2022 13:42:35 -0600 Subject: [PATCH] same logic as fast-agave --- agave/blueprints/rest_api.py | 11 +++- examples/chalicelib/models/__init__.py | 4 +- examples/chalicelib/models/billers.py | 12 ++++ examples/chalicelib/models/users.py | 13 ++++ examples/chalicelib/resources/__init__.py | 4 +- examples/chalicelib/resources/accounts.py | 3 +- examples/chalicelib/resources/billers.py | 12 ++++ examples/chalicelib/resources/users.py | 12 ++++ examples/chalicelib/validators.py | 8 +++ tests/blueprint/test_blueprint.py | 31 +++++++++- tests/conftest.py | 75 +++++++++++++++-------- 11 files changed, 152 insertions(+), 33 deletions(-) create mode 100644 examples/chalicelib/models/billers.py create mode 100644 examples/chalicelib/models/users.py create mode 100644 examples/chalicelib/resources/billers.py create mode 100644 examples/chalicelib/resources/users.py diff --git a/agave/blueprints/rest_api.py b/agave/blueprints/rest_api.py index 2e540861..0dbfd67b 100644 --- a/agave/blueprints/rest_api.py +++ b/agave/blueprints/rest_api.py @@ -235,9 +235,16 @@ def query(): if self.platform_id_filter_required(): query_params.platform_id = self.current_platform_id - # Set user_id request as query param - if self.user_id_filter_required(): + if self.user_id_filter_required() and hasattr( + cls.model, 'platform_id' + ): + query_params.platform_id = self.current_platform_id + + if self.user_id_filter_required() and hasattr( + cls.model, 'user_id' + ): query_params.user_id = self.current_user_id + filters = cls.get_query_filter(query_params) if ( hasattr(query_params, 'active') diff --git a/examples/chalicelib/models/__init__.py b/examples/chalicelib/models/__init__.py index fa6ee1ce..2435a9f1 100644 --- a/examples/chalicelib/models/__init__.py +++ b/examples/chalicelib/models/__init__.py @@ -1,6 +1,8 @@ -__all__ = ['Account', 'Card', 'Transaction', 'File'] +__all__ = ['Account', 'Biller', 'Card', 'Transaction', 'File', 'User'] from .accounts import Account +from .billers import Biller from .cards import Card from .files import File from .transactions import Transaction +from .users import User diff --git a/examples/chalicelib/models/billers.py b/examples/chalicelib/models/billers.py new file mode 100644 index 00000000..ded9bc08 --- /dev/null +++ b/examples/chalicelib/models/billers.py @@ -0,0 +1,12 @@ +import datetime as dt + +from mongoengine import DateTimeField, Document, StringField + +from agave.models import BaseModel +from agave.models.helpers import uuid_field + + +class Biller(BaseModel, Document): + id = StringField(primary_key=True, default=uuid_field('BL')) + created_at = DateTimeField(default=dt.datetime.utcnow) + name = StringField(required=True) diff --git a/examples/chalicelib/models/users.py b/examples/chalicelib/models/users.py new file mode 100644 index 00000000..f0305069 --- /dev/null +++ b/examples/chalicelib/models/users.py @@ -0,0 +1,13 @@ +import datetime as dt + +from mongoengine import DateTimeField, Document, StringField + +from agave.models import BaseModel +from agave.models.helpers import uuid_field + + +class User(BaseModel, Document): + id = StringField(primary_key=True, default=uuid_field('US')) + created_at = DateTimeField(default=dt.datetime.utcnow) + name = StringField(required=True) + platform_id = StringField(required=True) diff --git a/examples/chalicelib/resources/__init__.py b/examples/chalicelib/resources/__init__.py index 5e7cd57e..ccdd1452 100644 --- a/examples/chalicelib/resources/__init__.py +++ b/examples/chalicelib/resources/__init__.py @@ -1,7 +1,9 @@ -__all__ = ['app', 'Account', 'Card', 'File', 'Transaction'] +__all__ = ['app', 'Account', 'Biller', 'Card', 'File', 'Transaction', 'User'] from .accounts import Account from .base import app +from .billers import Biller from .cards import Card from .files import File from .transactions import Transaction +from .users import User diff --git a/examples/chalicelib/resources/accounts.py b/examples/chalicelib/resources/accounts.py index 87c8202f..cdbb11c1 100644 --- a/examples/chalicelib/resources/accounts.py +++ b/examples/chalicelib/resources/accounts.py @@ -1,7 +1,6 @@ import datetime as dt -from chalice import NotFoundError, Response -from mongoengine import DoesNotExist +from chalice import Response from agave.filters import generic_query diff --git a/examples/chalicelib/resources/billers.py b/examples/chalicelib/resources/billers.py new file mode 100644 index 00000000..03713fe2 --- /dev/null +++ b/examples/chalicelib/resources/billers.py @@ -0,0 +1,12 @@ +from agave.filters import generic_query + +from ..models import Biller as BillerModel +from ..validators import BillerQuery +from .base import app + + +@app.resource('/billers') +class Biller: + model = BillerModel + query_validator = BillerQuery + get_query_filter = generic_query diff --git a/examples/chalicelib/resources/users.py b/examples/chalicelib/resources/users.py new file mode 100644 index 00000000..1c32e80b --- /dev/null +++ b/examples/chalicelib/resources/users.py @@ -0,0 +1,12 @@ +from agave.filters import generic_query + +from ..models import User as UserModel +from ..validators import UserQuery +from .base import app + + +@app.resource('/users') +class User: + model = UserModel + query_validator = UserQuery + get_query_filter = generic_query diff --git a/examples/chalicelib/validators.py b/examples/chalicelib/validators.py index 826b1429..ab444d31 100644 --- a/examples/chalicelib/validators.py +++ b/examples/chalicelib/validators.py @@ -15,6 +15,14 @@ class TransactionQuery(QueryParams): user_id: Optional[str] = None +class BillerQuery(QueryParams): + name: str + + +class UserQuery(QueryParams): + platform_id: str + + class AccountRequest(BaseModel): name: str diff --git a/tests/blueprint/test_blueprint.py b/tests/blueprint/test_blueprint.py index d42cf11d..9d4d39bc 100644 --- a/tests/blueprint/test_blueprint.py +++ b/tests/blueprint/test_blueprint.py @@ -7,7 +7,11 @@ from mock import MagicMock, patch from examples.chalicelib.models import Account, Card, File -from examples.config import TEST_DEFAULT_PLATFORM_ID, TEST_DEFAULT_USER_ID +from examples.config import ( + TEST_DEFAULT_PLATFORM_ID, + TEST_DEFAULT_USER_ID, + TEST_SECOND_PLATFORM_ID, +) PLATFORM_ID_FILTER_REQUIRED = ( 'examples.chalicelib.blueprints.authed.' @@ -281,3 +285,28 @@ def test_download_resource(client: Client, file: File) -> None: resp = client.http.get(f'/files/{file.id}', headers={'Accept': mimetype}) assert resp.status_code == 200 assert resp.headers.get('Content-Type') == mimetype + + +@pytest.mark.usefixtures('users') +def test_filter_no_user_id_query(client: Client) -> None: + resp = client.http.get(f'/users?platform_id={TEST_DEFAULT_PLATFORM_ID}') + resp_json = resp.json_body + assert resp.status_code == 200 + assert len(resp_json['items']) == 1 + user1 = resp_json['items'][0] + resp = client.http.get(f'/users?platform_id={TEST_SECOND_PLATFORM_ID}') + resp_json = resp.json_body + assert resp.status_code == 200 + assert len(resp_json['items']) == 1 + user2 = resp_json['items'][0] + assert user1['id'] != user2['id'] + + +@pytest.mark.usefixtures('billers') +def test_filter_no_user_id_and_no_platform_id_query( + client: Client, +) -> None: + resp = client.http.get('/billers?name=ATT') + resp_json = resp.json_body + assert resp.status_code == 200 + assert len(resp_json['items']) == 1 diff --git a/tests/conftest.py b/tests/conftest.py index 9825b909..58cca2cd 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,10 +1,12 @@ import datetime as dt -from typing import Generator, List +import functools +from typing import Generator, List, Callable import pytest from chalice.test import Client +from mongoengine import Document -from examples.chalicelib.models import Account, Card, File +from examples.chalicelib.models import Account, Card, File, User, Biller from examples.config import ( TEST_DEFAULT_PLATFORM_ID, TEST_DEFAULT_USER_ID, @@ -15,6 +17,24 @@ from .helpers import accept_json +FuncDecorator = Callable[..., Generator] + + +def collection_fixture(model: Document) -> Callable[..., FuncDecorator]: + def collection_decorator(func: Callable) -> FuncDecorator: + @functools.wraps(func) + def wrapper(*args, **kwargs) -> Generator[List, None, None]: + items = func(*args, **kwargs) + for item in items: + item.save() + yield items + model.objects.delete() + + return wrapper + + return collection_decorator + + @pytest.fixture() def client() -> Generator[Client, None, None]: from examples import app @@ -34,8 +54,9 @@ def client() -> Generator[Client, None, None]: @pytest.fixture -def accounts() -> Generator[List[Account], None, None]: - accs = [ +@collection_fixture(Account) +def accounts() -> List[Account]: + return [ Account( name='Frida Kahlo', user_id=TEST_DEFAULT_USER_ID, @@ -74,12 +95,6 @@ def accounts() -> Generator[List[Account], None, None]: ), ] - for acc in accs: - acc.save() - yield accs - for acc in accs: - acc.delete() - @pytest.fixture def account(accounts: List[Account]) -> Generator[Account, None, None]: @@ -92,20 +107,15 @@ def other_account(accounts: List[Account]) -> Generator[Account, None, None]: @pytest.fixture -def files() -> Generator[List[File], None, None]: - accs = [ +@collection_fixture(File) +def files() -> List[File]: + return [ File( name='Frida Kahlo', user_id=TEST_DEFAULT_USER_ID, ), ] - for acc in accs: - acc.save() - yield accs - for acc in accs: - acc.delete() - @pytest.fixture def file(files: List[File]) -> Generator[File, None, None]: @@ -113,8 +123,9 @@ def file(files: List[File]) -> Generator[File, None, None]: @pytest.fixture -def cards() -> Generator[List[Card], None, None]: - cards = [ +@collection_fixture(Card) +def cards() -> List[Card]: + return [ Card( number='5434000000000001', user_id=TEST_DEFAULT_USER_ID, @@ -137,13 +148,25 @@ def cards() -> Generator[List[Card], None, None]: ), ] - for card in cards: - card.save() - yield cards - for card in cards: - card.delete() - @pytest.fixture def card(cards: List[Card]) -> Generator[Card, None, None]: yield cards[0] + + +@pytest.fixture +@collection_fixture(User) +def users() -> List[User]: + return [ + User(name='User1', platform_id=TEST_DEFAULT_PLATFORM_ID), + User(name='User2', platform_id=TEST_SECOND_PLATFORM_ID), + ] + + +@pytest.fixture +@collection_fixture(Biller) +def billers() -> List[Biller]: + return [ + Biller(name='Telcel'), + Biller(name='ATT'), + ]