conftest.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import asyncio
  2. from collections.abc import AsyncGenerator
  3. from datetime import datetime
  4. import pytest
  5. import pytest_asyncio
  6. from httpx import AsyncClient
  7. from sqlalchemy import delete, select
  8. from sqlalchemy.orm import Session
  9. from app.core import config, security
  10. from app.core.session import engine
  11. from app.core.session import session as session_maker
  12. from app.main import app
  13. from app.models import Base, Project, Slot, SlotTag, SlotTemplate, Sms, User, Volunteer
  14. default_user_id = "b75365d9-7bf9-4f54-add5-aeab333a087b"
  15. default_user_email = "geralt@wiedzmin.pl"
  16. default_user_password = "geralt"
  17. default_user_password_hash = security.get_password_hash(default_user_password)
  18. default_user_access_token = security.create_jwt_token(
  19. str(default_user_id), 60 * 60 * 24, refresh=False
  20. )[0]
  21. default_project_id = "e233ac66-3a29-4ae5-991e-30ec7334c566"
  22. default_project_name = "Default project"
  23. default_volunteer_id = "5514f4ef-75ee-40b2-ad99-420927c5c9e5"
  24. default_slot_id = "def04027-0048-48e2-8f47-f955fe080b31"
  25. default_sms_id = "b05c2b38-edb1-4e7a-9689-a0cba904ef29"
  26. default_tag_id = "47709be8-7edb-4fb1-9de0-8a529a91856d"
  27. default_template_id = "dcfcf2e9-8b1d-4bbf-b44b-aa511a7fe274"
  28. @pytest.fixture(scope="session")
  29. def event_loop():
  30. loop = asyncio.new_event_loop()
  31. asyncio.set_event_loop(loop)
  32. yield loop
  33. loop.close()
  34. @pytest_asyncio.fixture(scope="session")
  35. async def test_db_setup_sessionmaker():
  36. # assert if we use TEST_DB URL for 100%
  37. assert config.settings.ENVIRONMENT == "PYTEST"
  38. # always drop and create test db tables between tests session
  39. Base.metadata.drop_all(engine)
  40. Base.metadata.create_all(engine)
  41. @pytest_asyncio.fixture(autouse=True)
  42. async def session(test_db_setup_sessionmaker) -> AsyncGenerator[Session, None]:
  43. with session_maker() as db:
  44. yield db
  45. # delete all data from all tables after test
  46. for name, table in Base.metadata.tables.items():
  47. db.execute(delete(table))
  48. db.commit()
  49. @pytest_asyncio.fixture(scope="session")
  50. async def client() -> AsyncGenerator[AsyncClient, None]:
  51. async with AsyncClient(app=app, base_url="http://test") as client:
  52. client.headers.update({"Host": "localhost"})
  53. yield client
  54. @pytest.fixture
  55. def default_user(test_db_setup_sessionmaker) -> User:
  56. with session_maker() as db:
  57. result = db.execute(select(User).where(User.email == default_user_email))
  58. user = result.scalars().first()
  59. if user is None:
  60. new_user = User(
  61. email=default_user_email,
  62. hashed_password=default_user_password_hash,
  63. )
  64. new_user.id = default_user_id
  65. db.add(new_user)
  66. db.commit()
  67. db.refresh(new_user)
  68. return new_user
  69. return user
  70. @pytest.fixture
  71. def default_project(test_db_setup_sessionmaker) -> Project:
  72. """An empty private project"""
  73. with session_maker() as db:
  74. result = db.execute(select(Project).where(Project.id == default_project_id))
  75. project = result.scalars().first()
  76. if project is None:
  77. new_project = Project(name=default_project_name, is_public=False)
  78. new_project.id = default_project_id
  79. db.add(new_project)
  80. db.commit()
  81. db.refresh(new_project)
  82. return new_project
  83. return project
  84. @pytest.fixture
  85. def default_public_project(test_db_setup_sessionmaker) -> Project:
  86. """A public project with 1 volunteer, 1 slot & 1 sms associated to."""
  87. with session_maker() as db:
  88. result = db.execute(select(Project).where(Project.id == default_project_id))
  89. project = result.scalars().first()
  90. if project is None:
  91. new_project = Project(name=default_project_name, is_public=True)
  92. new_project.id = default_project_id
  93. db.add(new_project)
  94. # Create a volunteer
  95. volunteer = Volunteer(
  96. project_id=default_project_id,
  97. name="Arthur",
  98. surname="Pandragon",
  99. email="arthur.pandragon@kamelot.fr",
  100. phone_number="02 66 66 66 66 66",
  101. automatic_sms=True,
  102. )
  103. volunteer.id = default_volunteer_id
  104. db.add(volunteer)
  105. # Create a slot
  106. slot = Slot(
  107. project_id=default_project_id,
  108. title="être roi",
  109. starting_time=datetime(1600, 1, 1),
  110. ending_time=datetime(1900, 1, 1),
  111. )
  112. slot.id = default_slot_id
  113. slot.volunteers.append(volunteer)
  114. db.add(slot)
  115. tag = SlotTag(project_id=default_project_id, title="Royal")
  116. tag.id = default_tag_id
  117. db.add(tag)
  118. # Create a sms
  119. sms = Sms(
  120. project_id=default_project_id,
  121. content="Bonjour sir",
  122. phone_number="66 66 66 66 66",
  123. )
  124. sms.id = default_sms_id
  125. db.add(sms)
  126. tmp = SlotTemplate(project_id=default_project_id, title="basic template")
  127. tmp.id = default_template_id
  128. db.add(tmp)
  129. db.commit()
  130. db.commit()
  131. db.refresh(sms)
  132. db.refresh(slot)
  133. db.refresh(volunteer)
  134. db.refresh(new_project)
  135. return new_project
  136. return project
  137. @pytest.fixture
  138. def default_user_headers(default_user: User):
  139. return {"Authorization": f"Bearer {default_user_access_token}"}