fastapi-svelte-template/backend/todo/utils/fakery.py

139 lines
3.7 KiB
Python
Raw Normal View History

"""This module contains utilities for creating fake database entries."""
from random import randint
from faker import Faker
from sqlalchemy.orm import Session
from todo.schemas.users import UserCreate, User
from todo.crud.users import hash_password
from todo.models.users import User as UserModel
from todo.schemas.todos import TodoItemCreate, TodoItem
from todo.models.todos import TodoItem as TodoItemModel
from todo.database.engine import get_db
def _get_faker() -> Faker:
"""Creates and returns a Faker object."""
return Faker()
def get_fake_user_details() -> UserCreate:
"""Returns a set of fake details for creating a new user."""
fk = _get_faker()
password = fk.password(length=randint(6, 16))
email = fk.profile(fields=['mail'])['mail']
first_name = fk.first_name()
last_name = fk.last_name()
return UserCreate(
email=email,
first_name=first_name,
last_name=last_name,
password=password,
password_confirmation=password,
)
def get_fake_todo_details() -> TodoItemCreate:
"""Returns a set of fake details for creating a new todo-item."""
fk = _get_faker()
title = fk.sentence(nb_words=randint(4, 6))
# Generate some sentences and concatenate them with a randomized delimiter
description_sentences = [fk.sentence(nb_words=randint(4, 6)) for i in range(randint(1, 5))]
if randint(0, 1):
delimiter = '\n- '
description_sentences[0] = "- " + description_sentences[0]
elif randint(0, 1):
delimiter = '\n'
else:
delimiter = ' '
description = delimiter.join(description_sentences)
return TodoItemCreate(
title=title,
description=description,
)
def create_fake_user(db: Session = next(get_db())) -> User:
"""Creates a fake user and saves them to the database."""
user = get_fake_user_details()
fk = _get_faker()
created = fk.date_time_between('-2y', 'now')
updated = fk.date_time_between(created, 'now')
db_user = UserModel(
email=user.email,
first_name=user.first_name,
last_name=user.last_name,
password=hash_password(user.password),
created=created,
updated=updated,
)
db.add(db_user)
db.commit()
db.refresh(db_user)
return User.from_orm(db_user)
def create_fake_todo(user_id: int, db: Session = next(get_db())) -> TodoItem:
"""Creates a fake todo-item for the specified user and saves it to the database."""
todo = get_fake_todo_details()
db_user = db.query(UserModel).filter(UserModel.id == user_id).first()
if not db_user:
raise RuntimeError('User not found.')
fk = _get_faker()
created = fk.date_time_between(db_user.created, 'now')
if randint(1, 4) == 1:
updated = fk.date_time_between(created, 'now')
else:
updated = created
if randint(1, 4) == 1:
finished = fk.date_time_between(created, 'now')
updated = finished
done = True
else:
finished = None
done = False
db_todo = TodoItemModel(
user_id=user_id,
title=todo.title,
description=todo.description,
done=done,
created=created,
updated=updated,
finished=finished
)
db.add(db_todo)
db.commit()
db.refresh(db_todo)
return TodoItem.from_orm(db_todo)
def populate_database(num_users: int = randint(50, 150), max_todos_per_user: int = randint(50, 150)) -> None:
"""Creates the specified number of users, each with between 0 and max_todos_per_user todo-items."""
db = next(get_db())
for i in range(num_users):
user = create_fake_user(db)
for j in range(randint(0, max_todos_per_user)):
create_fake_todo(user.id, db)