Skip to content

Commit

Permalink
fix: adds page size validation (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
tdstein authored Feb 16, 2024
1 parent a7ea055 commit 9dfc965
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/posit/connect/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from .auth import Auth
from .config import Config
from .users import LazyUsers, Users
from .users import Users, CachedUsers


@contextmanager
Expand Down Expand Up @@ -54,7 +54,7 @@ def __init__(
session.hooks["response"].append(hooks.handle_errors)

# Initialize the Users instance.
self.users: Users = LazyUsers(config=config, session=session)
self.users: CachedUsers = Users(config=config, session=session)
# Store the Session object.
self._session = session

Expand Down
6 changes: 3 additions & 3 deletions src/posit/connect/client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test(self, Client: MagicMock):


class TestClient:
@patch("posit.connect.client.LazyUsers")
@patch("posit.connect.client.Users")
@patch("posit.connect.client.Session")
@patch("posit.connect.client.Config")
@patch("posit.connect.client.Auth")
Expand All @@ -22,7 +22,7 @@ def test_init(
Auth: MagicMock,
Config: MagicMock,
Session: MagicMock,
LazyUsers: MagicMock,
Users: MagicMock,
):
api_key = "foobar"
endpoint = "http://foo.bar"
Expand All @@ -31,7 +31,7 @@ def test_init(
Auth.assert_called_once_with(config=config)
Config.assert_called_once_with(api_key=api_key, endpoint=endpoint)
Session.assert_called_once()
LazyUsers.assert_called_once_with(config=config, session=Session.return_value)
Users.assert_called_once_with(config=config, session=Session.return_value)

@patch("posit.connect.client.Session")
@patch("posit.connect.client.Auth")
Expand Down
6 changes: 3 additions & 3 deletions src/posit/connect/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ class Resource(TypedDict):
T = TypeVar("T", bound=Resource)


class Resources(ABC, Generic[T], Iterator[T]):
class CachedResources(ABC, Generic[T], Iterator[T]):
def __init__(self, data: List[T] = []) -> None:
super().__init__()
self.data = data

@abstractmethod
def find(self, *args, **kwargs) -> Resources[T]:
def find(self, *args, **kwargs) -> CachedResources[T]:
raise NotImplementedError()

@abstractmethod
Expand Down Expand Up @@ -50,7 +50,7 @@ def to_pandas(self):
return None


class LazyResources(Resources[T]):
class Resources(CachedResources[T]):
def __init__(self, data: List[T] = []) -> None:
super().__init__(data)
self.data = data
Expand Down
12 changes: 6 additions & 6 deletions src/posit/connect/resources_test.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
from typing import Iterator, Tuple, Optional
from unittest.mock import Mock

from .resources import Resource, Resources, LazyResources
from .resources import Resource, CachedResources, Resources


class FakeResource(Resource):
pass


class FakeResources(Resources[FakeResource]):
def find(self) -> Resources[FakeResource]:
class FakeCachedResources(CachedResources[FakeResource]):
def find(self) -> CachedResources[FakeResource]:
return self

def find_one(self) -> Optional[FakeResource]:
Expand All @@ -21,20 +21,20 @@ def get(self, _: str) -> FakeResource:

class TestResources:
def test(self):
resources = FakeResources()
resources = FakeCachedResources()
assert resources == resources.find()
assert resources.find_one()
assert resources.get(None)


class FakeLazyResources(FakeResources, LazyResources):
class FakeResources(FakeCachedResources, Resources):
def fetch(self, index) -> Tuple[Optional[Iterator[FakeResource]], bool]:
return iter([FakeResource()]), len(self.data) > 0


class TestFakeLazyResources:
def test(self):
resources = FakeLazyResources()
resources = FakeResources()
assert resources == resources.find()
assert resources.find_one()
assert resources.get(None)
16 changes: 11 additions & 5 deletions src/posit/connect/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
from requests import Session

from .config import Config
from .resources import LazyResources, Resource, Resources
from .resources import Resources, Resource, CachedResources

# The maximum page size supported by the API.
_MAX_PAGE_SIZE = 500


Expand All @@ -27,9 +28,9 @@ class User(Resource, total=False):
locked: bool


class Users(Resources[User]):
def find(self, filter: Callable[[User], bool] = lambda _: True) -> Users:
return Users([user for user in self if filter(user)])
class CachedUsers(CachedResources[User]):
def find(self, filter: Callable[[User], bool] = lambda _: True) -> CachedUsers:
return CachedUsers([user for user in self if filter(user)])

def find_one(self, filter: Callable[[User], bool] = lambda _: True) -> User | None:
return next((user for user in self if filter(user)), None)
Expand All @@ -41,10 +42,15 @@ def get(self, id: str) -> User:
return user


class LazyUsers(Users, LazyResources[User]):
class Users(CachedUsers, Resources[User]):
def __init__(
self, config: Config, session: Session, *, page_size=_MAX_PAGE_SIZE
) -> None:
if page_size > _MAX_PAGE_SIZE:
raise ValueError(
f"page_size must be less than or equal to {_MAX_PAGE_SIZE}"
)

super().__init__()
self.config = config
self.session = session
Expand Down
23 changes: 23 additions & 0 deletions src/posit/connect/users_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import pytest

from unittest.mock import patch

from .users import Users


@pytest.fixture
def mock_config():
with patch("posit.connect.users.Config") as mock:
yield mock.return_value


@pytest.fixture
def mock_session():
with patch("posit.connect.users.Session") as mock:
yield mock.return_value


class TestUsers:
def test_init(self, mock_config, mock_session):
with pytest.raises(ValueError):
Users(mock_config, mock_session, page_size=9999)

0 comments on commit 9dfc965

Please sign in to comment.