Skip to content

Commit b66d38e

Browse files
committed
Improve tests
1 parent b8ae001 commit b66d38e

File tree

5 files changed

+65
-5
lines changed

5 files changed

+65
-5
lines changed

fastapi_users_db_dynamodb/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,9 @@ async def delete(self, user: UP) -> None:
231231
try:
232232
await user.delete(condition=self.user_table.id.exists()) # type: ignore
233233
except DeleteError as e:
234-
raise ValueError("User account could not be deleted.") from e
234+
raise ValueError( # pragma: no cover
235+
"User account could not be deleted."
236+
) from e
235237
except PutError as e:
236238
if e.cause_response_code == "ConditionalCheckFailedException":
237239
raise ValueError(

fastapi_users_db_dynamodb/access_token.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,9 @@ async def delete(self, access_token: AP) -> None:
127127
try:
128128
await access_token.delete(condition=self.access_token_table.token.exists()) # type: ignore
129129
except DeleteError as e:
130-
raise ValueError("Access token could not be deleted.") from e
130+
raise ValueError( # pragma: no cover
131+
"Access token could not be deleted."
132+
) from e
131133
except PutError as e:
132134
if e.cause_response_code == "ConditionalCheckFailedException":
133135
raise ValueError(

fastapi_users_db_dynamodb/tables.py

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class CreatableTable(Protocol):
1818
@classmethod
1919
async def exists(cls) -> CoroutineType[Any, Any, bool] | bool: ...
2020

21+
@classmethod
22+
async def delete_table(cls) -> CoroutineType[Any, Any, Any] | Any: ...
23+
2124
@classmethod
2225
async def create_table(
2326
cls,
@@ -31,8 +34,14 @@ def __check_creatable_table(cls: type[Any]):
3134
"""Check if an object is of type `CreatableTable`"""
3235
if not issubclass(cls, Model):
3336
raise TypeError(f"{cls.__name__} must be a subclass of Model")
34-
if not hasattr(cls, "exists") or not hasattr(cls, "create_table"):
35-
raise TypeError(f"{cls.__name__} must implement exists() and create_table()")
37+
if (
38+
not hasattr(cls, "exists")
39+
or not hasattr(cls, "delete_table")
40+
or not hasattr(cls, "create_table")
41+
):
42+
raise TypeError(
43+
f"{cls.__name__} must implement exists(), delete_table() and create_table()"
44+
)
3645

3746

3847
async def ensure_tables_exist(*tables: type[CreatableTable]) -> None:
@@ -51,3 +60,17 @@ async def ensure_tables_exist(*tables: type[CreatableTable]) -> None:
5160
wait=True,
5261
)
5362
__tables_cache.add(table_cls)
63+
64+
65+
async def delete_tables(*tables: type[CreatableTable]) -> None:
66+
"""
67+
Delete all given DynamoDB tables, if existent.
68+
"""
69+
global __tables_cache
70+
71+
for table_cls in tables:
72+
__check_creatable_table(table_cls)
73+
if await table_cls.exists():
74+
await table_cls.delete_table()
75+
if table_cls in __tables_cache:
76+
__tables_cache.remove(table_cls)

tests/test_access_token.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,29 @@ async def test_queries(
9898
token_obj = await dynamodb_access_token_db.get_by_token("NOT_EXISTING_TOKEN")
9999
assert token_obj is None
100100

101+
# Create existing
102+
with pytest.raises(
103+
ValueError,
104+
match="Access token could not be created because it already exists.",
105+
):
106+
token = AccessToken()
107+
token.token = "TOKEN"
108+
token.user_id = user_id
109+
await dynamodb_access_token_db.create(token)
110+
101111
# Delete
102112
await dynamodb_access_token_db.delete(access_token)
103113
deleted_token = await dynamodb_access_token_db.get_by_token(access_token.token)
104114
assert deleted_token is None
105115

116+
# Update non-existent
117+
new_time = now_utc()
118+
with pytest.raises(
119+
ValueError,
120+
match="Access token could not be updated because it does not exist.",
121+
):
122+
await dynamodb_access_token_db.update(access_token, {"created_at": new_time})
123+
106124

107125
@pytest.mark.asyncio
108126
async def test_insert_existing_token(

tests/test_misc.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from fastapi_users_db_dynamodb import config
55
from fastapi_users_db_dynamodb.attributes import GUID
6-
from fastapi_users_db_dynamodb.tables import ensure_tables_exist
6+
from fastapi_users_db_dynamodb.tables import delete_tables, ensure_tables_exist
77

88

99
class NotAModel:
@@ -14,6 +14,13 @@ class IncompleteModel(Model):
1414
pass
1515

1616

17+
class ValidModel(Model):
18+
class Meta:
19+
table_name: str = "valid_model_test"
20+
region: str = config.get("DATABASE_REGION")
21+
billing_mode: str = config.get("DATABASE_BILLING_MODE").value
22+
23+
1724
@pytest.mark.asyncio
1825
async def test_tables_invalid_models(monkeypatch):
1926
with pytest.raises(TypeError, match="must be a subclass of Model"):
@@ -22,6 +29,14 @@ async def test_tables_invalid_models(monkeypatch):
2229
with pytest.raises(AttributeError, match="PynamoDB Models require a"):
2330
await ensure_tables_exist(IncompleteModel)
2431

32+
with pytest.raises(AttributeError, match="PynamoDB Models require a"):
33+
await delete_tables(IncompleteModel)
34+
35+
await ensure_tables_exist(ValidModel)
36+
assert await ValidModel.exists()
37+
await delete_tables(ValidModel)
38+
assert not await ValidModel.exists()
39+
2540
monkeypatch.delattr(Model, "exists", raising=True)
2641
with pytest.raises(TypeError):
2742
await ensure_tables_exist(IncompleteModel)

0 commit comments

Comments
 (0)