From 683fdd73c91141eb8ce908b2d2fc0926b060ba34 Mon Sep 17 00:00:00 2001 From: lemoer Date: Sat, 21 Dec 2024 02:39:27 +0100 Subject: [PATCH] Task: create_additional_requests() --- models.py | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) diff --git a/models.py b/models.py index 5f1e211..72746c6 100644 --- a/models.py +++ b/models.py @@ -4,7 +4,7 @@ import os import enum from typing import List from pydantic import BaseModel -from result import Result, Ok, Err, is_ok +from result import Result, Ok, Err, is_err, is_ok from sqlmodel import Field, Session, SQLModel, create_engine, Relationship, select import datetime @@ -104,6 +104,29 @@ class Task(SQLModel, table=True): if maybe_timeout is not None: expired_requests.append(r) + def create_additional_requests(self, now: datetime.datetime, session: Session) -> Result[List["ParticipationRequest"], List["ParticipationRequest"]]: + additional_requests = [] + + for _ in range(self.additional_requests_to_be_sent()): + user = next_user_to_send_request(session, self) + if user is None: + break + + request = ParticipationRequest( + user=user, + task=self, + requested_at=now + ) + session.add(request) + additional_requests.append(request) + + if user is None: + # Incomplete requests + return Err(additional_requests) + else: + return Ok(additional_requests) + + class ParticipationState(enum.Enum): REQUESTED = "requested" ACCEPTED = "accepted" @@ -528,3 +551,67 @@ def test_active(session): users = all_users_sorted(session) assert users == [u1, u2, u3] + +def test_create_additional_requests(session): + now = datetime.datetime(2024, 12, 10, 0, 0) + dt = datetime.timedelta(days=1) + + u1 = User(name="u1") + u2 = User(name="u2") + u3 = User(name="u3") + + session.add(u1) + session.add(u2) + session.add(u3) + + session.commit() + + t1 = Task(name="t1", required_number_of_participants=2, + due=now + 10*dt, timeout=dt.total_seconds()) + + session.add(t1) + + requests = t1.create_additional_requests(now + 0.5*dt, session) + assert(is_ok(requests)) + requests = requests.unwrap() + assert(len(requests) == 2) + + requested_users = [req.user for req in requests] + assert(requested_users == [u1, u2]) + + assert(isinstance(requests[0].try_reject(now + 0.75*dt).unwrap(), RejectInTime)) + assert(isinstance(requests[1].try_reject(now + 0.75*dt).unwrap(), RejectInTime)) + + requests = t1.create_additional_requests(now + 0.5*dt, session) + + # could not create all requests, so we have Err now + assert(is_err(requests)) + requests = requests.unwrap_err() + assert(len(requests) == 1) + + requested_users = [req.user for req in requests] + assert(requested_users == [u3]) + + # No user left to ask... + requests = t1.create_additional_requests(now + 0.5*dt, session) + + assert(is_err(requests)) + requests = requests.unwrap_err() + assert(len(requests) == 0) + + u4 = User(name="u4") + session.add(u4) + + # Now, we have a user again, so we can ask. Since u3 did not + # reject (so far), we only need one additional request. So, + # the result is Ok(...). + requests = t1.create_additional_requests(now + 0.5*dt, session) + + assert(is_ok(requests)) + requests = requests.unwrap() + assert(len(requests) == 1) + + requested_users = [req.user for req in requests] + assert(requested_users == [u4]) + + session.commit()