Skip to content

Commit

Permalink
fix consume void services
Browse files Browse the repository at this point in the history
  • Loading branch information
jefer94 committed Jul 26, 2024
1 parent e25c13a commit 82570ef
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 47 deletions.
57 changes: 39 additions & 18 deletions breathecode/payments/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1278,8 +1278,9 @@ def list(
user: User | str | int,
lang: str = "en",
service: Optional[Service | str | int] = None,
service_type: Optional[str] = None,
permission: Optional[Permission | str | int] = None,
extra: dict = None,
extra: Optional[dict] = None,
) -> QuerySet[Consumable]:

if extra is None:
Expand Down Expand Up @@ -1324,6 +1325,9 @@ def list(
elif isinstance(service, Service):
param["service_item__service"] = service

if service_type and isinstance(service_type, str):
param["service_item__service__type"] = service_type.upper()

# Permission
if permission and isinstance(permission, str) and not permission.isdigit():
param["service_item__service__groups__permissions__codename"] = permission
Expand Down Expand Up @@ -1351,11 +1355,14 @@ def alist(
user: User | str | int,
lang: str = "en",
service: Optional[Service | str | int] = None,
service_type: Optional[str] = None,
permission: Optional[Permission | str | int] = None,
extra: dict = None,
) -> QuerySet[Consumable]:

return cls.list(user=user, lang=lang, service=service, permission=permission, extra=extra)
return cls.list(
user=user, lang=lang, service=service, service_type=service_type, permission=permission, extra=extra
)

@classmethod
def get(
Expand All @@ -1364,14 +1371,17 @@ def get(
user: User | str | int,
lang: str = "en",
service: Optional[Service | str | int] = None,
service_type: Optional[str] = None,
permission: Optional[Permission | str | int] = None,
extra: Optional[dict] = None,
) -> Consumable | None:

if extra is None:
extra = {}

return cls.list(user=user, lang=lang, service=service, permission=permission, extra=extra).first()
return cls.list(
user=user, lang=lang, service=service, service_type=service_type, permission=permission, extra=extra
).first()

@classmethod
@sync_to_async
Expand All @@ -1381,10 +1391,13 @@ def aget(
user: User | str | int,
lang: str = "en",
service: Optional[Service | str | int] = None,
service_type: Optional[str] = None,
permission: Optional[Permission | str | int] = None,
extra: Optional[dict] = None,
) -> Consumable | None:
return cls.get(user=user, lang=lang, service=service, permission=permission, extra=extra)
return cls.get(
user=user, lang=lang, service=service, service_type=service_type, permission=permission, extra=extra
)

def clean(self) -> None:
resources = [self.event_type_set, self.mentorship_service_set, self.cohort_set]
Expand Down Expand Up @@ -1494,6 +1507,7 @@ def build_session(
delta: timedelta,
user: Optional[User] = None,
operation_code: Optional[str] = None,
force_create: bool = False,
) -> "ConsumptionSession":
assert request, "You must provide a request"
assert consumable, "You must provide a consumable"
Expand All @@ -1504,7 +1518,12 @@ def build_session(

utc_now = timezone.now()

resource = consumable.mentorship_service_set or consumable.event_type_set or consumable.cohort_set
resource = (
consumable.mentorship_service_set
or consumable.event_type_set
or consumable.cohort_set
or consumable.service_item.service
)
id = resource.id if resource else 0
slug = resource.slug if resource else ""

Expand All @@ -1528,20 +1547,22 @@ def build_session(
# assert path, 'You must provide a path'
assert delta, "You must provide a delta"

session = (
cls.objects.filter(
eta__gte=utc_now,
request=data,
path=path,
duration=delta,
related_id=id,
related_slug=slug,
operation_code=operation_code,
user=user,
session = None
if force_create is False:
session = (
cls.objects.filter(
eta__gte=utc_now,
request=data,
path=path,
duration=delta,
related_id=id,
related_slug=slug,
operation_code=operation_code,
user=user,
)
.exclude(eta__lte=utc_now)
.first()
)
.exclude(eta__lte=utc_now)
.first()
)

if session:
return session
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
import random
from datetime import datetime, timedelta, timezone

import pytest
from django.urls import reverse_lazy
from rest_framework import status

from breathecode.tests.mixins.breathecode_mixin.breathecode import Breathecode
from capyc.rest_framework.pytest import fixtures as rfx


@pytest.fixture(autouse=True)
def setup(db, monkeypatch: pytest.MonkeyPatch):
monkeypatch.setattr(
"breathecode.payments.tasks.end_the_consumption_session.apply_async", lambda *args, **kwargs: None
)
yield


def db_item(service, data={}):
return {
"consumable_id": 1,
"duration": ...,
"eta": ...,
"how_many": 1.0,
"id": 1,
"operation_code": "unsafe-consume-service-set",
"path": "",
"related_id": 0,
"related_slug": "",
"request": {
"args": [],
"headers": {
"academy": None,
},
"kwargs": {
"service_slug": service.slug,
},
"user": 1,
},
"status": "PENDING",
"user_id": 1,
"was_discounted": False,
**data,
}


def random_duration():
hours = random.randint(0, 23)
minutes = random.randint(0, 59)
seconds = random.randint(0, 59)
return timedelta(hours=hours, minutes=minutes, seconds=seconds)


def test_no_auth(bc: Breathecode, client: rfx.Client):
url = reverse_lazy("payments:me_service_slug_consumptionsession", kwargs={"service_slug": "my-service"})

response = client.put(url)

json = response.json()
expected = {"detail": "Authentication credentials were not provided.", "status_code": 401}

assert json == expected
assert response.status_code == status.HTTP_401_UNAUTHORIZED
assert bc.database.list_of("payments.ConsumptionSession") == []


def test_no_consumables(bc: Breathecode, client: rfx.Client):
url = reverse_lazy("payments:me_service_slug_consumptionsession", kwargs={"service_slug": "my-service"})

model = bc.database.create(user=1)
client.force_authenticate(user=model.user)

response = client.put(url)

json = response.json()
expected = {"detail": "insufficient-credits", "status_code": 402}

assert json == expected
assert response.status_code == status.HTTP_402_PAYMENT_REQUIRED
assert bc.database.list_of("payments.ConsumptionSession") == []


def test_created(bc: Breathecode, client: rfx.Client, utc_now):
duration = random_duration()
model = bc.database.create(user=1, consumable=1, service={"session_duration": duration, "type": "VOID"})
url = reverse_lazy("payments:me_service_slug_consumptionsession", kwargs={"service_slug": model.service.slug})

client.force_authenticate(user=model.user)

response = client.put(url)

json = response.json()
expected = {"id": 1, "status": "ok"}

assert json == expected
assert response.status_code == status.HTTP_201_CREATED
assert bc.database.list_of("payments.ConsumptionSession") == [
db_item(
model.service,
data={
"related_id": 1,
"related_slug": model.service.slug,
"path": "payments.Service",
"duration": duration,
"eta": utc_now + duration,
},
)
]


def test_cached(bc: Breathecode, client: rfx.Client, utc_now, fake):
slug = fake.slug()
duration = random_duration()
model = bc.database.create(
user=1,
consumable=1,
service={
"session_duration": duration,
"slug": slug,
"type": "VOID",
},
consumption_session={
"how_many": 1,
"eta": utc_now + duration,
"duration": duration,
"was_discounted": False,
"operation_code": "unsafe-consume-service-set",
"related_id": 1,
"related_slug": slug,
"status": "PENDING",
"path": "payments.Service",
"request": {
"args": [],
"headers": {
"academy": None,
},
"kwargs": {
"service_slug": slug,
},
"user": 1,
},
},
)
url = reverse_lazy("payments:me_service_slug_consumptionsession", kwargs={"service_slug": model.service.slug})

client.force_authenticate(user=model.user)

response = client.put(url)

json = response.json()
expected = {"id": 2, "status": "ok"}

assert json == expected
assert response.status_code == status.HTTP_201_CREATED
assert bc.database.list_of("payments.ConsumptionSession") == [
db_item(
model.service,
data={
"id": 1,
"related_id": 1,
"related_slug": model.service.slug,
"path": "payments.Service",
"duration": duration,
"eta": utc_now + duration,
},
),
db_item(
model.service,
data={
"id": 2,
"related_id": 1,
"related_slug": model.service.slug,
"path": "payments.Service",
"duration": duration,
"eta": utc_now + duration,
},
),
]
Loading

0 comments on commit 82570ef

Please sign in to comment.