split tests into packages
This commit is contained in:
0
tests/test_exclude_include_dict/__init__.py
Normal file
0
tests/test_exclude_include_dict/__init__.py
Normal file
142
tests/test_exclude_include_dict/test_dumping_model_to_dict.py
Normal file
142
tests/test_exclude_include_dict/test_dumping_model_to_dict.py
Normal file
@ -0,0 +1,142 @@
|
||||
from typing import Optional
|
||||
|
||||
import databases
|
||||
import pytest
|
||||
import sqlalchemy
|
||||
|
||||
import ormar
|
||||
from tests.settings import DATABASE_URL
|
||||
|
||||
metadata = sqlalchemy.MetaData()
|
||||
database = databases.Database(DATABASE_URL, force_rollback=True)
|
||||
|
||||
|
||||
class User(ormar.Model):
|
||||
class Meta:
|
||||
tablename: str = "users"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
email: str = ormar.String(max_length=255, nullable=False)
|
||||
password: str = ormar.String(max_length=255, nullable=True)
|
||||
first_name: str = ormar.String(max_length=255, nullable=False)
|
||||
|
||||
|
||||
class Tier(ormar.Model):
|
||||
class Meta:
|
||||
tablename = "tiers"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100)
|
||||
|
||||
|
||||
class Category(ormar.Model):
|
||||
class Meta:
|
||||
tablename = "categories"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100)
|
||||
tier: Optional[Tier] = ormar.ForeignKey(Tier)
|
||||
|
||||
|
||||
class Item(ormar.Model):
|
||||
class Meta:
|
||||
tablename = "items"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100)
|
||||
category: Optional[Category] = ormar.ForeignKey(Category, nullable=True)
|
||||
created_by: Optional[User] = ormar.ForeignKey(User)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def sample_data():
|
||||
user = User(email="test@test.com", password="ijacids7^*&", first_name="Anna")
|
||||
tier = Tier(name="Tier I")
|
||||
category1 = Category(name="Toys", tier=tier)
|
||||
category2 = Category(name="Weapons", tier=tier)
|
||||
item1 = Item(name="Teddy Bear", category=category1, created_by=user)
|
||||
item2 = Item(name="M16", category=category2, created_by=user)
|
||||
return item1, item2
|
||||
|
||||
|
||||
def test_dumping_to_dict_no_exclusion(sample_data):
|
||||
item1, item2 = sample_data
|
||||
|
||||
dict1 = item1.dict()
|
||||
assert dict1["name"] == "Teddy Bear"
|
||||
assert dict1["category"]["name"] == "Toys"
|
||||
assert dict1["category"]["tier"]["name"] == "Tier I"
|
||||
assert dict1["created_by"]["email"] == "test@test.com"
|
||||
|
||||
dict2 = item2.dict()
|
||||
assert dict2["name"] == "M16"
|
||||
assert dict2["category"]["name"] == "Weapons"
|
||||
assert dict2["created_by"]["email"] == "test@test.com"
|
||||
|
||||
|
||||
def test_dumping_to_dict_exclude_set(sample_data):
|
||||
item1, item2 = sample_data
|
||||
dict3 = item2.dict(exclude={"name"})
|
||||
assert "name" not in dict3
|
||||
assert dict3["category"]["name"] == "Weapons"
|
||||
assert dict3["created_by"]["email"] == "test@test.com"
|
||||
|
||||
dict4 = item2.dict(exclude={"category"})
|
||||
assert dict4["name"] == "M16"
|
||||
assert "category" not in dict4
|
||||
assert dict4["created_by"]["email"] == "test@test.com"
|
||||
|
||||
dict5 = item2.dict(exclude={"category", "name"})
|
||||
assert "name" not in dict5
|
||||
assert "category" not in dict5
|
||||
assert dict5["created_by"]["email"] == "test@test.com"
|
||||
|
||||
|
||||
def test_dumping_to_dict_exclude_dict(sample_data):
|
||||
item1, item2 = sample_data
|
||||
dict6 = item2.dict(exclude={"category": {"name"}, "name": ...})
|
||||
assert "name" not in dict6
|
||||
assert "category" in dict6
|
||||
assert "name" not in dict6["category"]
|
||||
assert dict6["created_by"]["email"] == "test@test.com"
|
||||
|
||||
|
||||
def test_dumping_to_dict_exclude_nested_dict(sample_data):
|
||||
item1, item2 = sample_data
|
||||
dict1 = item2.dict(exclude={"category": {"tier": {"name"}}, "name": ...})
|
||||
assert "name" not in dict1
|
||||
assert "category" in dict1
|
||||
assert dict1["category"]["name"] == "Weapons"
|
||||
assert dict1["created_by"]["email"] == "test@test.com"
|
||||
assert dict1["category"]["tier"].get("name") is None
|
||||
|
||||
|
||||
def test_dumping_to_dict_exclude_and_include_nested_dict(sample_data):
|
||||
item1, item2 = sample_data
|
||||
dict1 = item2.dict(
|
||||
exclude={"category": {"tier": {"name"}}}, include={"name", "category"}
|
||||
)
|
||||
assert dict1.get("name") == "M16"
|
||||
assert "category" in dict1
|
||||
assert dict1["category"]["name"] == "Weapons"
|
||||
assert "created_by" not in dict1
|
||||
assert dict1["category"]["tier"].get("name") is None
|
||||
|
||||
dict2 = item1.dict(
|
||||
exclude={"id": ...},
|
||||
include={"name": ..., "category": {"name": ..., "tier": {"id"}}},
|
||||
)
|
||||
assert dict2.get("name") == "Teddy Bear"
|
||||
assert dict2.get("id") is None # models not saved
|
||||
assert dict2["category"]["name"] == "Toys"
|
||||
assert "created_by" not in dict1
|
||||
assert dict1["category"]["tier"].get("name") is None
|
||||
assert dict1["category"]["tier"]["id"] is None
|
||||
218
tests/test_exclude_include_dict/test_excludable_items.py
Normal file
218
tests/test_exclude_include_dict/test_excludable_items.py
Normal file
@ -0,0 +1,218 @@
|
||||
from typing import List, Optional
|
||||
|
||||
import databases
|
||||
import sqlalchemy
|
||||
|
||||
import ormar
|
||||
from ormar.models.excludable import ExcludableItems
|
||||
from tests.settings import DATABASE_URL
|
||||
|
||||
database = databases.Database(DATABASE_URL, force_rollback=True)
|
||||
metadata = sqlalchemy.MetaData()
|
||||
|
||||
|
||||
class BaseMeta(ormar.ModelMeta):
|
||||
database = database
|
||||
metadata = metadata
|
||||
|
||||
|
||||
class NickNames(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
tablename = "nicks"
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100, nullable=False, name="hq_name")
|
||||
is_lame: bool = ormar.Boolean(nullable=True)
|
||||
|
||||
|
||||
class NicksHq(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
tablename = "nicks_x_hq"
|
||||
|
||||
|
||||
class HQ(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
pass
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100, nullable=False, name="hq_name")
|
||||
nicks: List[NickNames] = ormar.ManyToMany(NickNames, through=NicksHq)
|
||||
|
||||
|
||||
class Company(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
tablename = "companies"
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100, nullable=False, name="company_name")
|
||||
founded: int = ormar.Integer(nullable=True)
|
||||
hq: HQ = ormar.ForeignKey(HQ)
|
||||
|
||||
|
||||
class Car(ormar.Model):
|
||||
class Meta(BaseMeta):
|
||||
pass
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
manufacturer: Optional[Company] = ormar.ForeignKey(Company)
|
||||
name: str = ormar.String(max_length=100)
|
||||
year: int = ormar.Integer(nullable=True)
|
||||
gearbox_type: str = ormar.String(max_length=20, nullable=True)
|
||||
gears: int = ormar.Integer(nullable=True)
|
||||
aircon_type: str = ormar.String(max_length=20, nullable=True)
|
||||
|
||||
|
||||
def compare_results(excludable):
|
||||
car_excludable = excludable.get(Car)
|
||||
assert car_excludable.exclude == {"year", "gearbox_type", "gears", "aircon_type"}
|
||||
assert car_excludable.include == set()
|
||||
|
||||
assert car_excludable.is_excluded("year")
|
||||
|
||||
alias = Company.Meta.alias_manager.resolve_relation_alias(Car, "manufacturer")
|
||||
manu_excludable = excludable.get(Company, alias=alias)
|
||||
assert manu_excludable.exclude == {"founded"}
|
||||
assert manu_excludable.include == set()
|
||||
|
||||
assert manu_excludable.is_excluded("founded")
|
||||
|
||||
|
||||
def compare_results_include(excludable):
|
||||
manager = Company.Meta.alias_manager
|
||||
car_excludable = excludable.get(Car)
|
||||
assert car_excludable.include == {"id", "name"}
|
||||
assert car_excludable.exclude == set()
|
||||
|
||||
assert car_excludable.is_included("name")
|
||||
assert not car_excludable.is_included("gears")
|
||||
|
||||
alias = manager.resolve_relation_alias(Car, "manufacturer")
|
||||
manu_excludable = excludable.get(Company, alias=alias)
|
||||
assert manu_excludable.include == {"name"}
|
||||
assert manu_excludable.exclude == set()
|
||||
|
||||
assert manu_excludable.is_included("name")
|
||||
assert not manu_excludable.is_included("founded")
|
||||
|
||||
alias = manager.resolve_relation_alias(Company, "hq")
|
||||
hq_excludable = excludable.get(HQ, alias=alias)
|
||||
assert hq_excludable.include == {"name"}
|
||||
assert hq_excludable.exclude == set()
|
||||
|
||||
alias = manager.resolve_relation_alias(NicksHq, "nicknames")
|
||||
nick_excludable = excludable.get(NickNames, alias=alias)
|
||||
assert nick_excludable.include == {"name"}
|
||||
assert nick_excludable.exclude == set()
|
||||
|
||||
|
||||
def test_excluding_fields_from_list():
|
||||
fields = [
|
||||
"gearbox_type",
|
||||
"gears",
|
||||
"aircon_type",
|
||||
"year",
|
||||
"manufacturer__founded",
|
||||
]
|
||||
excludable = ExcludableItems()
|
||||
excludable.build(items=fields, model_cls=Car, is_exclude=True)
|
||||
compare_results(excludable)
|
||||
|
||||
|
||||
def test_excluding_fields_from_dict():
|
||||
fields = {
|
||||
"gearbox_type": ...,
|
||||
"gears": ...,
|
||||
"aircon_type": ...,
|
||||
"year": ...,
|
||||
"manufacturer": {"founded": ...},
|
||||
}
|
||||
excludable = ExcludableItems()
|
||||
excludable.build(items=fields, model_cls=Car, is_exclude=True)
|
||||
compare_results(excludable)
|
||||
|
||||
|
||||
def test_excluding_fields_from_dict_with_set():
|
||||
fields = {
|
||||
"gearbox_type": ...,
|
||||
"gears": ...,
|
||||
"aircon_type": ...,
|
||||
"year": ...,
|
||||
"manufacturer": {"founded"},
|
||||
}
|
||||
excludable = ExcludableItems()
|
||||
excludable.build(items=fields, model_cls=Car, is_exclude=True)
|
||||
compare_results(excludable)
|
||||
|
||||
|
||||
def test_gradual_build_from_lists():
|
||||
fields_col = [
|
||||
"year",
|
||||
["gearbox_type", "gears"],
|
||||
"aircon_type",
|
||||
["manufacturer__founded"],
|
||||
]
|
||||
excludable = ExcludableItems()
|
||||
for fields in fields_col:
|
||||
excludable.build(items=fields, model_cls=Car, is_exclude=True)
|
||||
compare_results(excludable)
|
||||
|
||||
|
||||
def test_nested_includes():
|
||||
fields = [
|
||||
"id",
|
||||
"name",
|
||||
"manufacturer__name",
|
||||
"manufacturer__hq__name",
|
||||
"manufacturer__hq__nicks__name",
|
||||
]
|
||||
excludable = ExcludableItems()
|
||||
excludable.build(items=fields, model_cls=Car, is_exclude=False)
|
||||
compare_results_include(excludable)
|
||||
|
||||
|
||||
def test_nested_includes_from_dict():
|
||||
fields = {
|
||||
"id": ...,
|
||||
"name": ...,
|
||||
"manufacturer": {"name": ..., "hq": {"name": ..., "nicks": {"name": ...}},},
|
||||
}
|
||||
excludable = ExcludableItems()
|
||||
excludable.build(items=fields, model_cls=Car, is_exclude=False)
|
||||
compare_results_include(excludable)
|
||||
|
||||
|
||||
def test_nested_includes_from_dict_with_set():
|
||||
fields = {
|
||||
"id": ...,
|
||||
"name": ...,
|
||||
"manufacturer": {"name": ..., "hq": {"name": ..., "nicks": {"name"}},},
|
||||
}
|
||||
excludable = ExcludableItems()
|
||||
excludable.build(items=fields, model_cls=Car, is_exclude=False)
|
||||
compare_results_include(excludable)
|
||||
|
||||
|
||||
def test_includes_and_excludes_combo():
|
||||
fields_inc1 = ["id", "name", "year", "gearbox_type", "gears"]
|
||||
fields_inc2 = {"manufacturer": {"name"}}
|
||||
fields_exc1 = {"manufacturer__founded"}
|
||||
fields_exc2 = "aircon_type"
|
||||
excludable = ExcludableItems()
|
||||
excludable.build(items=fields_inc1, model_cls=Car, is_exclude=False)
|
||||
excludable.build(items=fields_inc2, model_cls=Car, is_exclude=False)
|
||||
excludable.build(items=fields_exc1, model_cls=Car, is_exclude=True)
|
||||
excludable.build(items=fields_exc2, model_cls=Car, is_exclude=True)
|
||||
|
||||
car_excludable = excludable.get(Car)
|
||||
assert car_excludable.include == {"id", "name", "year", "gearbox_type", "gears"}
|
||||
assert car_excludable.exclude == {"aircon_type"}
|
||||
|
||||
assert car_excludable.is_excluded("aircon_type")
|
||||
assert car_excludable.is_included("name")
|
||||
|
||||
alias = Company.Meta.alias_manager.resolve_relation_alias(Car, "manufacturer")
|
||||
manu_excludable = excludable.get(Company, alias=alias)
|
||||
assert manu_excludable.include == {"name"}
|
||||
assert manu_excludable.exclude == {"founded"}
|
||||
|
||||
assert manu_excludable.is_excluded("founded")
|
||||
@ -0,0 +1,300 @@
|
||||
import datetime
|
||||
import string
|
||||
import random
|
||||
|
||||
import databases
|
||||
import pydantic
|
||||
import pytest
|
||||
import sqlalchemy
|
||||
from fastapi import FastAPI
|
||||
from starlette.testclient import TestClient
|
||||
|
||||
import ormar
|
||||
from ormar import post_save, property_field
|
||||
from tests.settings import DATABASE_URL
|
||||
|
||||
app = FastAPI()
|
||||
metadata = sqlalchemy.MetaData()
|
||||
database = databases.Database(DATABASE_URL, force_rollback=True)
|
||||
app.state.database = database
|
||||
|
||||
|
||||
@app.on_event("startup")
|
||||
async def startup() -> None:
|
||||
database_ = app.state.database
|
||||
if not database_.is_connected:
|
||||
await database_.connect()
|
||||
|
||||
|
||||
@app.on_event("shutdown")
|
||||
async def shutdown() -> None:
|
||||
database_ = app.state.database
|
||||
if database_.is_connected:
|
||||
await database_.disconnect()
|
||||
|
||||
|
||||
# note that you can set orm_mode here
|
||||
# and in this case UserSchema become unnecessary
|
||||
class UserBase(pydantic.BaseModel):
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
email: str
|
||||
first_name: str
|
||||
last_name: str
|
||||
|
||||
|
||||
class UserCreateSchema(UserBase):
|
||||
password: str
|
||||
category: str
|
||||
|
||||
|
||||
class UserSchema(UserBase):
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
def gen_pass():
|
||||
choices = string.ascii_letters + string.digits + "!@#$%^&*()"
|
||||
return "".join(random.choice(choices) for _ in range(20))
|
||||
|
||||
|
||||
class RandomModel(ormar.Model):
|
||||
class Meta:
|
||||
tablename: str = "random_users"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
password: str = ormar.String(max_length=255, default=gen_pass)
|
||||
first_name: str = ormar.String(max_length=255, default="John")
|
||||
last_name: str = ormar.String(max_length=255)
|
||||
created_date: datetime.datetime = ormar.DateTime(
|
||||
server_default=sqlalchemy.func.now()
|
||||
)
|
||||
|
||||
@property_field
|
||||
def full_name(self) -> str:
|
||||
return " ".join([self.first_name, self.last_name])
|
||||
|
||||
|
||||
class User(ormar.Model):
|
||||
class Meta:
|
||||
tablename: str = "users"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
email: str = ormar.String(max_length=255)
|
||||
password: str = ormar.String(max_length=255, nullable=True)
|
||||
first_name: str = ormar.String(max_length=255)
|
||||
last_name: str = ormar.String(max_length=255)
|
||||
category: str = ormar.String(max_length=255, nullable=True)
|
||||
|
||||
|
||||
class User2(ormar.Model):
|
||||
class Meta:
|
||||
tablename: str = "users2"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
email: str = ormar.String(max_length=255, nullable=False)
|
||||
password: str = ormar.String(max_length=255)
|
||||
first_name: str = ormar.String(max_length=255)
|
||||
last_name: str = ormar.String(max_length=255)
|
||||
category: str = ormar.String(max_length=255, nullable=True)
|
||||
timestamp: datetime.datetime = ormar.DateTime(
|
||||
pydantic_only=True, default=datetime.datetime.now
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def create_test_database():
|
||||
engine = sqlalchemy.create_engine(DATABASE_URL)
|
||||
metadata.create_all(engine)
|
||||
yield
|
||||
metadata.drop_all(engine)
|
||||
|
||||
|
||||
@app.post("/users/", response_model=User, response_model_exclude={"password"})
|
||||
async def create_user(user: User):
|
||||
return await user.save()
|
||||
|
||||
|
||||
@app.post("/users2/", response_model=User)
|
||||
async def create_user2(user: User):
|
||||
user = await user.save()
|
||||
return user.dict(exclude={"password"})
|
||||
|
||||
|
||||
@app.post("/users3/", response_model=UserBase)
|
||||
async def create_user3(user: User2):
|
||||
return await user.save()
|
||||
|
||||
|
||||
@app.post("/users4/")
|
||||
async def create_user4(user: User2):
|
||||
return (await user.save()).dict(exclude={"password"})
|
||||
|
||||
|
||||
@app.post("/random/", response_model=RandomModel)
|
||||
async def create_user5(user: RandomModel):
|
||||
return await user.save()
|
||||
|
||||
|
||||
@app.post("/random2/", response_model=RandomModel)
|
||||
async def create_user6(user: RandomModel):
|
||||
return await user.save()
|
||||
|
||||
|
||||
@app.post("/random3/", response_model=RandomModel, response_model_exclude={"full_name"})
|
||||
async def create_user7(user: RandomModel):
|
||||
return await user.save()
|
||||
|
||||
|
||||
def test_excluding_fields_in_endpoints():
|
||||
client = TestClient(app)
|
||||
with client as client:
|
||||
user = {
|
||||
"email": "test@domain.com",
|
||||
"password": "^*^%A*DA*IAAA",
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
}
|
||||
response = client.post("/users/", json=user)
|
||||
created_user = User(**response.json())
|
||||
assert created_user.pk is not None
|
||||
assert created_user.password is None
|
||||
|
||||
user2 = {
|
||||
"email": "test@domain.com",
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
}
|
||||
|
||||
response = client.post("/users/", json=user2)
|
||||
created_user = User(**response.json())
|
||||
assert created_user.pk is not None
|
||||
assert created_user.password is None
|
||||
|
||||
response = client.post("/users2/", json=user)
|
||||
created_user2 = User(**response.json())
|
||||
assert created_user2.pk is not None
|
||||
assert created_user2.password is None
|
||||
|
||||
# response has only 3 fields from UserBase
|
||||
response = client.post("/users3/", json=user)
|
||||
assert list(response.json().keys()) == ["email", "first_name", "last_name"]
|
||||
|
||||
timestamp = datetime.datetime.now()
|
||||
|
||||
user3 = {
|
||||
"email": "test@domain.com",
|
||||
"password": "^*^%A*DA*IAAA",
|
||||
"first_name": "John",
|
||||
"last_name": "Doe",
|
||||
"timestamp": str(timestamp),
|
||||
}
|
||||
response = client.post("/users4/", json=user3)
|
||||
assert list(response.json().keys()) == [
|
||||
"id",
|
||||
"email",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"category",
|
||||
"timestamp",
|
||||
]
|
||||
assert response.json().get("timestamp") == str(timestamp).replace(" ", "T")
|
||||
resp_dict = response.json()
|
||||
resp_dict.update({"password": "random"})
|
||||
user_instance = User2(**resp_dict)
|
||||
assert user_instance.timestamp is not None
|
||||
assert isinstance(user_instance.timestamp, datetime.datetime)
|
||||
assert user_instance.timestamp == timestamp
|
||||
|
||||
response = client.post("/users4/", json=user3)
|
||||
assert list(response.json().keys()) == [
|
||||
"id",
|
||||
"email",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"category",
|
||||
"timestamp",
|
||||
]
|
||||
assert (
|
||||
datetime.datetime.strptime(
|
||||
response.json().get("timestamp"), "%Y-%m-%dT%H:%M:%S.%f"
|
||||
)
|
||||
== timestamp
|
||||
)
|
||||
|
||||
|
||||
def test_adding_fields_in_endpoints():
|
||||
client = TestClient(app)
|
||||
with client as client:
|
||||
user3 = {"last_name": "Test", "full_name": "deleted"}
|
||||
response = client.post("/random/", json=user3)
|
||||
assert list(response.json().keys()) == [
|
||||
"id",
|
||||
"password",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"created_date",
|
||||
"full_name",
|
||||
]
|
||||
assert response.json().get("full_name") == "John Test"
|
||||
|
||||
user3 = {"last_name": "Test"}
|
||||
response = client.post("/random/", json=user3)
|
||||
assert list(response.json().keys()) == [
|
||||
"id",
|
||||
"password",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"created_date",
|
||||
"full_name",
|
||||
]
|
||||
assert response.json().get("full_name") == "John Test"
|
||||
|
||||
|
||||
def test_adding_fields_in_endpoints2():
|
||||
client = TestClient(app)
|
||||
with client as client:
|
||||
user3 = {"last_name": "Test"}
|
||||
response = client.post("/random2/", json=user3)
|
||||
assert list(response.json().keys()) == [
|
||||
"id",
|
||||
"password",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"created_date",
|
||||
"full_name",
|
||||
]
|
||||
assert response.json().get("full_name") == "John Test"
|
||||
|
||||
|
||||
def test_excluding_property_field_in_endpoints2():
|
||||
|
||||
dummy_registry = {}
|
||||
|
||||
@post_save(RandomModel)
|
||||
async def after_save(sender, instance, **kwargs):
|
||||
dummy_registry[instance.pk] = instance.dict()
|
||||
|
||||
client = TestClient(app)
|
||||
with client as client:
|
||||
user3 = {"last_name": "Test"}
|
||||
response = client.post("/random3/", json=user3)
|
||||
assert list(response.json().keys()) == [
|
||||
"id",
|
||||
"password",
|
||||
"first_name",
|
||||
"last_name",
|
||||
"created_date",
|
||||
]
|
||||
assert response.json().get("full_name") is None
|
||||
assert len(dummy_registry) == 1
|
||||
check_dict = dummy_registry.get(response.json().get("id"))
|
||||
check_dict.pop("full_name")
|
||||
assert response.json().get("password") == check_dict.get("password")
|
||||
@ -0,0 +1,113 @@
|
||||
import random
|
||||
from typing import Optional
|
||||
|
||||
import databases
|
||||
import pytest
|
||||
import sqlalchemy
|
||||
|
||||
import ormar
|
||||
from tests.settings import DATABASE_URL
|
||||
|
||||
database = databases.Database(DATABASE_URL, force_rollback=True)
|
||||
metadata = sqlalchemy.MetaData()
|
||||
|
||||
|
||||
def get_position() -> int:
|
||||
return random.randint(1, 10)
|
||||
|
||||
|
||||
class Album(ormar.Model):
|
||||
class Meta:
|
||||
tablename = "albums"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100)
|
||||
is_best_seller: bool = ormar.Boolean(default=False, nullable=True)
|
||||
|
||||
|
||||
class Track(ormar.Model):
|
||||
class Meta:
|
||||
tablename = "tracks"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
album: Optional[Album] = ormar.ForeignKey(Album)
|
||||
title: str = ormar.String(max_length=100)
|
||||
position: int = ormar.Integer(default=get_position)
|
||||
play_count: int = ormar.Integer(nullable=True, default=0)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def create_test_database():
|
||||
engine = sqlalchemy.create_engine(DATABASE_URL)
|
||||
metadata.drop_all(engine)
|
||||
metadata.create_all(engine)
|
||||
yield
|
||||
metadata.drop_all(engine)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_excluding_field_with_default():
|
||||
async with database:
|
||||
async with database.transaction(force_rollback=True):
|
||||
album = await Album.objects.create(name="Miami")
|
||||
await Track.objects.create(title="Vice City", album=album, play_count=10)
|
||||
await Track.objects.create(title="Beach Sand", album=album, play_count=20)
|
||||
await Track.objects.create(title="Night Lights", album=album)
|
||||
|
||||
album = await Album.objects.fields("name").get()
|
||||
assert album.is_best_seller is None
|
||||
|
||||
album = await Album.objects.exclude_fields({"is_best_seller", "id"}).get()
|
||||
assert album.is_best_seller is None
|
||||
|
||||
album = await Album.objects.exclude_fields({"is_best_seller": ...}).get()
|
||||
assert album.is_best_seller is None
|
||||
|
||||
tracks = await Track.objects.all()
|
||||
for track in tracks:
|
||||
assert track.play_count is not None
|
||||
assert track.position is not None
|
||||
|
||||
album = (
|
||||
await Album.objects.select_related("tracks")
|
||||
.exclude_fields({"is_best_seller": ..., "tracks": {"play_count"}})
|
||||
.get(name="Miami")
|
||||
)
|
||||
assert album.is_best_seller is None
|
||||
assert len(album.tracks) == 3
|
||||
for track in album.tracks:
|
||||
assert track.play_count is None
|
||||
assert track.position is not None
|
||||
|
||||
album = (
|
||||
await Album.objects.select_related("tracks")
|
||||
.exclude_fields(
|
||||
{
|
||||
"is_best_seller": ...,
|
||||
"tracks": {"play_count": ..., "position": ...},
|
||||
}
|
||||
)
|
||||
.get(name="Miami")
|
||||
)
|
||||
assert album.is_best_seller is None
|
||||
assert len(album.tracks) == 3
|
||||
for track in album.tracks:
|
||||
assert track.play_count is None
|
||||
assert track.position is None
|
||||
|
||||
album = (
|
||||
await Album.objects.select_related("tracks")
|
||||
.exclude_fields(
|
||||
{"is_best_seller": ..., "tracks": {"play_count", "position"}}
|
||||
)
|
||||
.get(name="Miami")
|
||||
)
|
||||
assert album.is_best_seller is None
|
||||
assert len(album.tracks) == 3
|
||||
for track in album.tracks:
|
||||
assert track.play_count is None
|
||||
assert track.position is None
|
||||
@ -0,0 +1,180 @@
|
||||
from typing import Optional
|
||||
|
||||
import databases
|
||||
import pydantic
|
||||
import pytest
|
||||
import sqlalchemy
|
||||
|
||||
import ormar
|
||||
from tests.settings import DATABASE_URL
|
||||
|
||||
database = databases.Database(DATABASE_URL, force_rollback=True)
|
||||
metadata = sqlalchemy.MetaData()
|
||||
|
||||
|
||||
class Company(ormar.Model):
|
||||
class Meta:
|
||||
tablename = "companies"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
name: str = ormar.String(max_length=100, nullable=False)
|
||||
founded: int = ormar.Integer(nullable=True)
|
||||
|
||||
|
||||
class Car(ormar.Model):
|
||||
class Meta:
|
||||
tablename = "cars"
|
||||
metadata = metadata
|
||||
database = database
|
||||
|
||||
id: int = ormar.Integer(primary_key=True)
|
||||
manufacturer: Optional[Company] = ormar.ForeignKey(Company)
|
||||
name: str = ormar.String(max_length=100)
|
||||
year: int = ormar.Integer(nullable=True)
|
||||
gearbox_type: str = ormar.String(max_length=20, nullable=True)
|
||||
gears: int = ormar.Integer(nullable=True, name="gears_number")
|
||||
aircon_type: str = ormar.String(max_length=20, nullable=True)
|
||||
|
||||
|
||||
@pytest.fixture(autouse=True, scope="module")
|
||||
def create_test_database():
|
||||
engine = sqlalchemy.create_engine(DATABASE_URL)
|
||||
metadata.drop_all(engine)
|
||||
metadata.create_all(engine)
|
||||
yield
|
||||
metadata.drop_all(engine)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_selecting_subset():
|
||||
async with database:
|
||||
async with database.transaction(force_rollback=True):
|
||||
toyota = await Company.objects.create(name="Toyota", founded=1937)
|
||||
await Car.objects.create(
|
||||
manufacturer=toyota,
|
||||
name="Corolla",
|
||||
year=2020,
|
||||
gearbox_type="Manual",
|
||||
gears=5,
|
||||
aircon_type="Manual",
|
||||
)
|
||||
await Car.objects.create(
|
||||
manufacturer=toyota,
|
||||
name="Yaris",
|
||||
year=2019,
|
||||
gearbox_type="Manual",
|
||||
gears=5,
|
||||
aircon_type="Manual",
|
||||
)
|
||||
await Car.objects.create(
|
||||
manufacturer=toyota,
|
||||
name="Supreme",
|
||||
year=2020,
|
||||
gearbox_type="Auto",
|
||||
gears=6,
|
||||
aircon_type="Auto",
|
||||
)
|
||||
|
||||
all_cars = (
|
||||
await Car.objects.select_related("manufacturer")
|
||||
.exclude_fields(
|
||||
[
|
||||
"gearbox_type",
|
||||
"gears",
|
||||
"aircon_type",
|
||||
"year",
|
||||
"manufacturer__founded",
|
||||
]
|
||||
)
|
||||
.all()
|
||||
)
|
||||
for car in all_cars:
|
||||
assert all(
|
||||
getattr(car, x) is None
|
||||
for x in ["year", "gearbox_type", "gears", "aircon_type"]
|
||||
)
|
||||
assert car.manufacturer.name == "Toyota"
|
||||
assert car.manufacturer.founded is None
|
||||
|
||||
all_cars = (
|
||||
await Car.objects.select_related("manufacturer")
|
||||
.exclude_fields(
|
||||
{
|
||||
"gearbox_type": ...,
|
||||
"gears": ...,
|
||||
"aircon_type": ...,
|
||||
"year": ...,
|
||||
"manufacturer": {"founded": ...},
|
||||
}
|
||||
)
|
||||
.all()
|
||||
)
|
||||
all_cars2 = (
|
||||
await Car.objects.select_related("manufacturer")
|
||||
.exclude_fields(
|
||||
{
|
||||
"gearbox_type": ...,
|
||||
"gears": ...,
|
||||
"aircon_type": ...,
|
||||
"year": ...,
|
||||
"manufacturer": {"founded"},
|
||||
}
|
||||
)
|
||||
.all()
|
||||
)
|
||||
|
||||
assert all_cars == all_cars2
|
||||
|
||||
for car in all_cars:
|
||||
assert all(
|
||||
getattr(car, x) is None
|
||||
for x in ["year", "gearbox_type", "gears", "aircon_type"]
|
||||
)
|
||||
assert car.manufacturer.name == "Toyota"
|
||||
assert car.manufacturer.founded is None
|
||||
|
||||
all_cars = (
|
||||
await Car.objects.select_related("manufacturer")
|
||||
.exclude_fields("year")
|
||||
.exclude_fields(["gearbox_type", "gears"])
|
||||
.exclude_fields("aircon_type")
|
||||
.all()
|
||||
)
|
||||
for car in all_cars:
|
||||
assert all(
|
||||
getattr(car, x) is None
|
||||
for x in ["year", "gearbox_type", "gears", "aircon_type"]
|
||||
)
|
||||
assert car.manufacturer.name == "Toyota"
|
||||
assert car.manufacturer.founded == 1937
|
||||
|
||||
all_cars_check = await Car.objects.select_related("manufacturer").all()
|
||||
for car in all_cars_check:
|
||||
assert all(
|
||||
getattr(car, x) is not None
|
||||
for x in ["year", "gearbox_type", "gears", "aircon_type"]
|
||||
)
|
||||
assert car.manufacturer.name == "Toyota"
|
||||
assert car.manufacturer.founded == 1937
|
||||
|
||||
all_cars_check2 = (
|
||||
await Car.objects.select_related("manufacturer")
|
||||
.fields(["id", "name", "manufacturer"])
|
||||
.exclude_fields("manufacturer__founded")
|
||||
.all()
|
||||
)
|
||||
for car in all_cars_check2:
|
||||
assert all(
|
||||
getattr(car, x) is None
|
||||
for x in ["year", "gearbox_type", "gears", "aircon_type"]
|
||||
)
|
||||
assert car.manufacturer.name == "Toyota"
|
||||
assert car.manufacturer.founded is None
|
||||
|
||||
with pytest.raises(pydantic.error_wrappers.ValidationError):
|
||||
# cannot exclude mandatory model columns - company__name in this example
|
||||
await Car.objects.select_related("manufacturer").exclude_fields(
|
||||
["manufacturer__name"]
|
||||
).all()
|
||||
Reference in New Issue
Block a user