Skip to content

Commit

Permalink
Add more demo objects to the demo suite
Browse files Browse the repository at this point in the history
  • Loading branch information
uittenbroekrobbert committed Jun 28, 2024
1 parent d454169 commit a6d3a98
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 24 deletions.
7 changes: 7 additions & 0 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ When poetry is done installing all dependencies you can start using the tool.
poetry run python -m uvicorn tad.main:app --log-level warning
```

### Suggested development ENVIRONMENT settings
To use a demo environment during local development, you can use the following environment options. You can leave out the TRUNCATE_TABLES option if you wish to keep the state between runs.
```shell
export ENVIRONMENT=demo AUTO_CREATE_SCHEMA=true TRUNCATE_TABLES=true
```


## Database

We support most SQL database types. You can use the variable `APP_DATABASE_SCHEME` to change the database. The default scheme is sqlite.
Expand Down
1 change: 1 addition & 0 deletions tad/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Settings(BaseSettings):

DEBUG: bool = False
AUTO_CREATE_SCHEMA: bool = False
TRUNCATE_TABLES: bool = False

# todo(berry): create submodel for database settings
APP_DATABASE_SCHEME: DatabaseSchemaType = "sqlite"
Expand Down
57 changes: 43 additions & 14 deletions tad/core/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from sqlalchemy.engine import Engine
from sqlalchemy.pool import QueuePool, StaticPool
from sqlmodel import Session, SQLModel, create_engine, select
from sqlmodel import Session, SQLModel, create_engine, delete, select

from tad.core.config import get_settings
from tad.models import Status, Task, User
Expand Down Expand Up @@ -43,21 +43,50 @@ def init_db():

with Session(get_engine()) as session:
if get_settings().ENVIRONMENT == "demo":
if get_settings().TRUNCATE_TABLES:
truncate_tables(session)

logger.info("Creating demo data")
add_demo_users(session)
add_demo_statuses(session)
todo_status = session.exec(select(Status).where(Status.name == "todo")).first()
if todo_status is not None:
add_demo_tasks(session, todo_status)
session.commit()
logger.info("Finished initializing database")


def truncate_tables(session: Session) -> None:
logger.info("Truncating tables")
session.exec(delete(Task)) # type: ignore
session.exec(delete(User)) # type: ignore
session.exec(delete(Status)) # type: ignore

user = session.exec(select(User).where(User.name == "Robbert")).first()
if not user:
user = User(name="Robbert", avatar=None)
session.add(user)

status = session.exec(select(Status).where(Status.name == "Todo")).first()
if not status:
status = Status(name="Todo", sort_order=1)
session.add(status)
def add_demo_users(session: Session) -> None:
user = session.exec(select(User).where(User.name == "Robbert")).first()
if not user:
user = User(name="Robbert", avatar=None)
session.add(user)

task = session.exec(select(Task).where(Task.title == "First task")).first()
if not task:
task = Task(title="First task", description="This is the first task", sort_order=1, status_id=status.id)
session.add(task)

def add_demo_tasks(session: Session, status: Status) -> None:
for index in range(1, 4):
task = session.exec(select(Task).where(Task.title == "Example task " + str(index))).first()
if not task:
task = Task(
title="Example task " + str(index),
description="Example description " + str(index),
sort_order=index,
status_id=status.id,
)
session.add(task)


def add_demo_statuses(session: Session) -> None:
for index, status_name in enumerate(["todo", "review", "in_progress", "done"]):
status = session.exec(select(Status).where(Status.name == status_name)).first()
if not status:
status = Status(name=status_name, sort_order=index + 1)
session.add(status)
session.commit()
logger.info("Finished initializing database")
63 changes: 53 additions & 10 deletions tests/core/test_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,25 @@
from unittest.mock import MagicMock

import pytest
from sqlmodel import Session, select
from sqlmodel import Session, delete, select
from tad.core.config import Settings
from tad.core.db import check_db, init_db
from tad.models import Status, Task, User

logger = logging.getLogger(__name__)

expected_selects = [
(select(User).where(User.name == "Robbert"),),
(select(Status).where(Status.name == "todo"),),
(select(Status).where(Status.name == "in_progress"),),
(select(Status).where(Status.name == "review"),),
(select(Status).where(Status.name == "done"),),
(select(Status).where(Status.name == "done"),),
(select(Task).where(Task.title == "Test task 1"),),
(select(Task).where(Task.title == "Test task 2"),),
(select(Task).where(Task.title == "Test task 3"),),
]


def test_check_database():
org_exec = Session.exec
Expand All @@ -32,14 +44,27 @@ def test_init_database_none(patch_settings: Settings):

init_db()

expected = [
(select(User).where(User.name == "Robbert"),),
(select(Status).where(Status.name == "Todo"),),
(select(Task).where(Task.title == "First task"),),
]
for i, call_args in enumerate(Session.exec.call_args_list):
assert str(expected_selects[i][0]) == str(call_args.args[0])

Session.exec = org_exec


@pytest.mark.parametrize(
"patch_settings",
[{"ENVIRONMENT": "demo", "AUTO_CREATE_SCHEMA": True}],
indirect=True,
)
def test_init_database_none_with_todo_status(patch_settings: Settings):
org_exec = Session.exec
Session.exec = MagicMock()
todo_status = Status(id=1, name="todo", sort_order=1)
Session.exec.return_value.first.side_effect = [None, None, None, None, None, todo_status, None, None, None]

init_db()

for i, call_args in enumerate(Session.exec.call_args_list):
assert str(expected[i][0]) == str(call_args.args[0])
assert str(expected_selects[i][0]) == str(call_args.args[0])

Session.exec = org_exec

Expand All @@ -55,10 +80,28 @@ def test_init_database(patch_settings: Settings):

init_db()

for i, call_args in enumerate(Session.exec.call_args_list):
assert str(expected_selects[i][0]) == str(call_args.args[0])

Session.exec = org_exec


@pytest.mark.parametrize(
"patch_settings",
[{"ENVIRONMENT": "demo", "AUTO_CREATE_SCHEMA": True, "TRUNCATE_TABLES": True}],
indirect=True,
)
def test_truncate_database(patch_settings: Settings):
org_exec = Session.exec
Session.exec = MagicMock()

init_db()

expected = [
(select(User).where(User.name == "Robbert"),),
(select(Status).where(Status.name == "Todo"),),
(select(Task).where(Task.title == "First task"),),
(delete(Task),),
(delete(User),),
(delete(Status),),
*expected_selects,
]

for i, call_args in enumerate(Session.exec.call_args_list):
Expand Down

0 comments on commit a6d3a98

Please sign in to comment.