Skip to content

Commit

Permalink
Merge pull request #1500 from lumi-tip/development-lumi-7920
Browse files Browse the repository at this point in the history
add technologies filter into eventTypes
  • Loading branch information
jefer94 authored Nov 22, 2024
2 parents b396d51 + 6dab58e commit 60a2e0a
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 6 deletions.
24 changes: 24 additions & 0 deletions breathecode/events/migrations/0060_eventtype_technologies.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 5.1.2 on 2024-11-18 15:58

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("events", "0059_event_asset_slug"),
]

operations = [
migrations.AddField(
model_name="eventtype",
name="technologies",
field=models.CharField(
blank=True,
default=None,
help_text="Add comma-separated list of technologies",
max_length=200,
null=True,
),
),
]
4 changes: 4 additions & 0 deletions breathecode/events/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ class EventType(models.Model):
default=True, help_text="Other academies are allowed to create events of this type"
)

technologies = models.CharField(
max_length=200, null=True, default=None, blank=True, help_text="Add comma-separated list of technologies"
)

created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)

Expand Down
1 change: 1 addition & 0 deletions breathecode/events/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class EventTypeSmallSerializer(serpy.Serializer):
id = serpy.Field()
slug = serpy.Field()
name = serpy.Field()
technologies = serpy.Field()


class EventTypeSerializer(EventTypeSmallSerializer):
Expand Down
2 changes: 2 additions & 0 deletions breathecode/events/tests/urls/tests_academy_eventype.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def get_serializer(event_type, academy=None, city=None, data={}):
"slug": event_type.slug,
"lang": event_type.lang,
"description": event_type.description,
"technologies": event_type.technologies,
**data,
}

Expand Down Expand Up @@ -288,6 +289,7 @@ def test_post_event_type(self):
"description": "Potato",
"icon_url": "https://www.google.com",
"lang": "en",
"technologies": "",
}

url = reverse_lazy("events:academy_eventype")
Expand Down
10 changes: 7 additions & 3 deletions breathecode/events/tests/urls/tests_academy_eventype_slug.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from unittest.mock import MagicMock, call, patch
from breathecode.events.caches import EventCache

from django.urls.base import reverse_lazy
from django.utils import timezone

from breathecode.events.caches import EventCache
from breathecode.services import datetime_to_iso_format
from breathecode.utils.api_view_extensions.api_view_extension_handlers import APIViewExtensionHandlers

from ..mixins.new_events_tests_case import EventTestCase
from breathecode.services import datetime_to_iso_format
from django.utils import timezone


def get_serializer(event_type, academy=None, city=None, data={}):
Expand Down Expand Up @@ -35,6 +37,7 @@ def get_serializer(event_type, academy=None, city=None, data={}):
"allow_shared_creation": event_type.allow_shared_creation,
"description": event_type.description,
"visibility_settings": event_type.visibility_settings,
"technologies": event_type.technologies,
**data,
}

Expand All @@ -51,6 +54,7 @@ def put_serializer(event_type, data={}):
"allow_shared_creation": event_type.allow_shared_creation,
"free_for_bootcamps": event_type.free_for_bootcamps,
"description": event_type.description,
"technologies": event_type.technologies,
**data,
}

Expand Down
198 changes: 198 additions & 0 deletions breathecode/events/tests/urls/tests_all.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
from datetime import datetime, timedelta, timezone

import capyc.pytest as capy
from django.urls.base import reverse_lazy


def serialize_event(event):
return {
"id": event.id,
"title": event.title,
"starting_at": (
event.starting_at.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z"
if isinstance(event.starting_at, datetime)
else None
),
"ending_at": (
event.ending_at.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z"
if isinstance(event.ending_at, datetime)
else None
),
"event_type": {
"id": event.event_type.id,
"slug": event.event_type.slug,
"name": event.event_type.name,
"technologies": event.event_type.technologies,
},
"slug": event.slug,
"excerpt": event.excerpt,
"lang": event.lang,
"url": event.url,
"banner": event.banner,
"description": event.description,
"capacity": event.capacity,
"status": event.status,
"host": event.host,
"ended_at": (
event.ended_at.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f") + "Z" if event.ended_at else None
),
"online_event": event.online_event,
"venue": (
None
if not event.venue
else {
"id": event.venue.id,
"title": event.venue.title,
"street_address": event.venue.street_address,
"city": event.venue.city.name,
"zip_code": event.venue.zip_code,
"state": event.venue.state,
"updated_at": event.venue.updated_at.isoformat(),
}
),
"academy": (
None
if not event.academy
else {
"id": event.academy.id,
"slug": event.academy.slug,
"name": event.academy.name,
"city": {"name": event.academy.city.name} if event.academy.city else None,
}
),
"sync_with_eventbrite": event.sync_with_eventbrite,
"eventbrite_sync_status": event.eventbrite_sync_status,
"eventbrite_sync_description": event.eventbrite_sync_description,
"tags": event.tags,
"asset_slug": event.asset_slug,
"host_user": (
None
if not event.host_user
else {
"id": event.host_user.id,
"first_name": event.host_user.first_name,
"last_name": event.host_user.last_name,
}
),
"author": (
None
if not event.author
else {
"id": event.author.id,
"first_name": event.author.first_name,
"last_name": event.author.last_name,
}
),
"asset": None,
}


def test_filter_by_technologies(client: capy.Client, database: capy.Database, fake: capy.Fake):
url = reverse_lazy("events:all")

model = database.create(
city=1,
country=1,
academy={
"slug": fake.slug(),
"name": fake.name(),
"logo_url": "https://example.com/logo.jpg",
"street_address": "Address",
},
event_type=[
{
"slug": fake.slug(),
"name": fake.name(),
"description": "description1",
"technologies": "python, flask",
},
{
"slug": fake.slug(),
"name": fake.name(),
"description": "description2",
"technologies": "flask, pandas",
},
],
event=[
{
"title": "My First Event",
"capacity": 100,
"banner": "https://example.com/banner.jpg",
"starting_at": datetime.now(),
"ending_at": datetime.now() + timedelta(hours=2),
"status": "ACTIVE",
"event_type_id": n + 1,
}
for n in range(0, 2)
],
)

response = client.get(f"{url}?technologies=python")
json = response.json()

expected = [serialize_event(event) for event in model.event if "python" in event.event_type.technologies]

assert response.status_code == 200
assert len(json) == 1
assert expected == json


def test_filter_by_technologies_obtain_two(client: capy.Client, database: capy.Database, fake: capy.Fake):
url = reverse_lazy("events:all")

model = database.create(
city=1,
country=1,
academy={
"slug": fake.slug(),
"name": fake.name(),
"logo_url": "https://example.com/logo.jpg",
"street_address": "Address",
},
event_type=[
{
"slug": fake.slug(),
"name": fake.name(),
"description": "description1",
"technologies": "python, flask",
},
{
"slug": fake.slug(),
"name": fake.name(),
"description": "description2",
"technologies": "flask, pandas",
},
{
"slug": fake.slug(),
"name": fake.name(),
"description": "description3",
"technologies": "javascript, java",
},
],
event=[
{
"title": f"My Event {n + 1}",
"capacity": 100,
"banner": "https://example.com/banner.jpg",
"starting_at": datetime.now(),
"ending_at": datetime.now() + timedelta(hours=2),
"status": "ACTIVE",
"event_type_id": n + 1,
}
for n in range(3)
],
)

response = client.get(f"{url}?technologies=python,java")
json = response.json()

technologies_to_filter = {"python", "java"}
expected = [
serialize_event(event)
for event in model.event
if any(tech in event.event_type.technologies.split(", ") for tech in technologies_to_filter)
]

assert response.status_code == 200
assert len(json) == 2
assert expected == json
10 changes: 7 additions & 3 deletions breathecode/events/tests/urls/tests_eventype.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
from unittest.mock import MagicMock, call, patch
from breathecode.events.caches import EventCache

from django.urls.base import reverse_lazy
from django.utils import timezone

from breathecode.events.caches import EventCache
from breathecode.services import datetime_to_iso_format
from breathecode.utils.api_view_extensions.api_view_extension_handlers import APIViewExtensionHandlers

from ..mixins.new_events_tests_case import EventTestCase
from breathecode.services import datetime_to_iso_format
from django.utils import timezone


def get_serializer(event_type, academy=None, city=None, data={}):
Expand All @@ -32,6 +34,7 @@ def get_serializer(event_type, academy=None, city=None, data={}):
"slug": event_type.slug,
"lang": event_type.lang,
"description": event_type.description,
"technologies": event_type.technologies,
**data,
}

Expand Down Expand Up @@ -73,6 +76,7 @@ def test_academy_event_type_with_results(self):
"created_at": timezone.now(),
"updated_at": timezone.now(),
"icon_url": "https://www.google.com",
"technologies": None,
}
model = self.generate_models(
authenticate=True, event=True, event_type=True, event_type_kwargs=event_type_kwargs
Expand Down
1 change: 1 addition & 0 deletions breathecode/events/tests/urls/tests_me.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ def get_serializer(
"allow_shared_creation": event_type.allow_shared_creation,
"description": event_type.description,
"visibility_settings": visibility_settings_serializer(event_type.visibility_settings),
"technologies": event_type.technologies,
},
"eventbrite_id": event.eventbrite_id,
"eventbrite_organizer_id": event.eventbrite_organizer_id,
Expand Down
1 change: 1 addition & 0 deletions breathecode/events/tests/urls/tests_me_event_id.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ def get_serializer(
"allow_shared_creation": event_type.allow_shared_creation,
"description": event_type.description,
"visibility_settings": visibility_settings_serializer(event_type.visibility_settings),
"technologies": event_type.technologies,
},
"eventbrite_id": event.eventbrite_id,
"eventbrite_organizer_id": event.eventbrite_organizer_id,
Expand Down
7 changes: 7 additions & 0 deletions breathecode/events/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ def get_events(request):
elif online_event == "false":
lookup["online_event"] = False

if "technologies" in request.GET:
values = request.GET.get("technologies").split(",")
tech_query = Q()
for value in values:
tech_query |= Q(event_type__technologies__icontains=value.strip())
items = items.filter(tech_query)

lookup["ending_at__gte"] = timezone.now()
if "past" in request.GET:
if request.GET.get("past") == "true":
Expand Down

0 comments on commit 60a2e0a

Please sign in to comment.