Ver código fonte

expose required_volunteers throught api

clovis 1 ano atrás
pai
commit
1a57f2b0f2
3 arquivos alterados com 63 adições e 13 exclusões
  1. 5 1
      app/schemas/requests.py
  2. 1 0
      app/schemas/responses.py
  3. 57 12
      app/tests/test_slot.py

+ 5 - 1
app/schemas/requests.py

@@ -62,7 +62,9 @@ class ProjectSMSBatchRequest(BaseRequest):
      - {respo} slot.responsible_contact
      - {prenom} volunteer.name
      - {nom} volunteer.surname""",
-        examples=["Bonjour {prenom},\nTon créneau {titre} commence à {debut}.\nla com bénévole"],
+        examples=[
+            "Bonjour {prenom},\nTon créneau {titre} commence à {debut}.\nla com bénévole"
+        ],
     )
     delta_t: int = Field(
         default=10,
@@ -92,6 +94,7 @@ class SlotCreateRequest(BaseRequest):
     title: str
     starting_time: datetime.datetime
     ending_time: datetime.datetime
+    required_volunteers: Optional[int] = 0
     volunteers: Optional[list[UUID4]] = None
     template_id: Optional[UUID4] = None
 
@@ -100,6 +103,7 @@ class SlotUpdateRequest(BaseRequest):
     title: Optional[str] = None
     starting_time: Optional[datetime.datetime] = None
     ending_time: Optional[datetime.datetime] = None
+    required_volunteers: Optional[int] = None
     volunteers: Optional[list[UUID4]] = None
     template_id: Optional[UUID4] = None
 

+ 1 - 0
app/schemas/responses.py

@@ -42,6 +42,7 @@ class SlotResponse(BaseObjectResponse):
     title: str
     starting_time: datetime
     ending_time: datetime
+    required_volunteers: int
     volunteers_id: list[str] = []
     template_id: Optional[str]
 

+ 57 - 12
app/tests/test_slot.py

@@ -51,7 +51,9 @@ async def test_create_slot(
     session: Session,
 ):
     # Test without autentication
-    response = await client.post(app.url_path_for("create_slot", project_id=default_project_id))
+    response = await client.post(
+        app.url_path_for("create_slot", project_id=default_project_id)
+    )
     assert response.status_code == 401
     starting_time = datetime(1900, 1, 1)
     payload = {
@@ -59,7 +61,7 @@ async def test_create_slot(
         "starting_time": starting_time.isoformat(),
         "ending_time": (starting_time + timedelta(minutes=60)).isoformat(),
     }
-    # test invalid project_id
+    # Test invalid project_id
     response = await client.post(
         app.url_path_for("create_slot", project_id=uuid.uuid4()),
         json=payload,
@@ -76,16 +78,18 @@ async def test_create_slot(
     assert response.status_code == 200
     assert response.json()["id"] != default_slot_id
     assert response.json()["title"] == "être mort"
+    assert response.json()["required_volunteers"] == 0
     result = session.execute(select(Slot).where(Slot.project_id == default_project_id))
     slots = result.scalars().all()
     assert len(slots) > 1
     slot = [s for s in slots if s.id != default_slot_id][0]
     assert slot.title == "être mort"
-    assert abs(slot.starting_time - starting_time.replace(tzinfo=timezone.utc)) < timedelta(
-        minutes=30
-    )
+    assert slot.required_volunteers == 0
+    assert abs(
+        slot.starting_time - starting_time.replace(tzinfo=timezone.utc)
+    ) < timedelta(minutes=30)
 
-    # test invalid payload
+    # Test invalid payload
     del payload["title"]
     response = await client.post(
         app.url_path_for("create_slot", project_id=default_project_id),
@@ -95,6 +99,34 @@ async def test_create_slot(
     assert response.status_code == 422
 
 
+async def test_create_slot_min_volunteer(
+    client: AsyncClient,
+    default_public_project: Project,
+    default_user_headers: dict,
+    session: Session,
+):
+    starting_time = datetime(1900, 1, 1)
+    payload = {
+        "title": "être mort",
+        "starting_time": starting_time.isoformat(),
+        "ending_time": (starting_time + timedelta(minutes=60)).isoformat(),
+        "required_volunteers": 2,
+    }
+    # Test normal payload
+    response = await client.post(
+        app.url_path_for("create_slot", project_id=default_project_id),
+        json=payload,
+        headers=default_user_headers,
+    )
+    assert response.status_code == 200
+
+    result = session.execute(select(Slot).where(Slot.project_id == default_project_id))
+    slots = result.scalars().all()
+    assert len(slots) > 1
+    slot = [s for s in slots if s.id != default_slot_id][0]
+    assert slot.required_volunteers == 2
+
+
 async def test_update_slot(
     client: AsyncClient,
     default_public_project: Project,
@@ -116,6 +148,7 @@ async def test_update_slot(
         "title": "être mort 2 fois",
         "starting_time": starting_time.isoformat(),
         "ending_time": (starting_time + timedelta(minutes=60)).isoformat(),
+        "required_volunteers": 2,
     }
 
     # test invalid project_id
@@ -157,7 +190,9 @@ async def test_update_slot(
         assert response.status_code == 200
         assert response.json()["id"] == default_slot_id
         if "time" in k:
-            assert datetime.fromisoformat(response.json()[k]) == datetime.fromisoformat(v)
+            assert datetime.fromisoformat(response.json()[k]) == datetime.fromisoformat(
+                v
+            )
         else:
             assert response.json()[k] == v
 
@@ -239,7 +274,9 @@ async def test_update_slot_volunteers(
     )
 
     assert response.status_code == 200
-    result = session.execute(select(Volunteer).where(Volunteer.id == default_volunteer_id))
+    result = session.execute(
+        select(Volunteer).where(Volunteer.id == default_volunteer_id)
+    )
     volunteer = result.scalars().first()
     assert volunteer is not None
     assert volunteer.slots_id == []
@@ -307,7 +344,9 @@ async def test_delete_slot_fail(
 
     # Cannot delete non uuid string
     response = await client.delete(
-        app.url_path_for("delete_slot", project_id=default_project_id, slot_id="not uidstr"),
+        app.url_path_for(
+            "delete_slot", project_id=default_project_id, slot_id="not uidstr"
+        ),
         headers=default_user_headers,
     )
     assert response.status_code == 422
@@ -334,14 +373,18 @@ async def test_delete_slot(
     assert slot is None
 
     # check deletion is cascaded to volunteers
-    result = session.execute(select(Volunteer).where(Volunteer.id == default_volunteer_id))
+    result = session.execute(
+        select(Volunteer).where(Volunteer.id == default_volunteer_id)
+    )
     volunteer: Volunteer | None = result.scalars().first()
     assert volunteer is not None
     assert default_slot_id not in volunteer.slots_id
 
     # can delete random uuid
     response = await client.delete(
-        app.url_path_for("delete_slot", project_id=default_project_id, slot_id=uuid.uuid4()),
+        app.url_path_for(
+            "delete_slot", project_id=default_project_id, slot_id=uuid.uuid4()
+        ),
         headers=default_user_headers,
     )
     assert response.status_code == 200
@@ -354,7 +397,9 @@ async def test_delete_slot_idempotent(
     default_public_project: Project,
 ):
     # Idempotence test
-    url = app.url_path_for("delete_slot", project_id=default_project_id, slot_id=default_slot_id)
+    url = app.url_path_for(
+        "delete_slot", project_id=default_project_id, slot_id=default_slot_id
+    )
     response = await client.delete(url, headers=default_user_headers)
     response = await client.delete(url, headers=default_user_headers)
     assert response.status_code == 200