Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date filter for Hacknight (fixes #493) #494

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions backend/resources/hacknight.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,31 @@
from marshmallow import fields, Schema, ValidationError

from backend.extensions import db
from backend.models import Hacknight, Participant
from backend.serializers.hacknight_serializer import HacknightSchema
from backend.models import Hacknight, Participant, participant_hacknight
from backend.serializers.hacknight_serializer import DateFilterSchema, HacknightSchema


class HacknightList(Resource):
@jwt_required
def get(self):
hacknight_schema = HacknightSchema(many=True)
hacknight_schema = HacknightSchema(
many=True, only=("id", "date", "participants.id")
)
date_filter_schema = DateFilterSchema(partial=True)
date_filter = date_filter_schema.load(request.args)
query = db.session.query(Hacknight)

# Apply date filter if provided
if start_date := date_filter.get("start_date"):
query = query.filter(Hacknight.date >= start_date)
if end_date := date_filter.get("end_date"):
query = query.filter(Hacknight.date <= end_date)

return (
hacknight_schema.dump(
Hacknight.query.order_by(Hacknight.date.desc()).all()
query.join(participant_hacknight, isouter=True)
.order_by(Hacknight.date.desc())
.all()
),
HTTPStatus.OK,
)
Expand Down
12 changes: 11 additions & 1 deletion backend/serializers/hacknight_serializer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from marshmallow import Schema, fields
from marshmallow import Schema, fields, pre_load


class HacknightSchema(Schema):
Expand All @@ -12,3 +12,13 @@ class Meta:
"ParticipantSchema", exclude=("hacknights",), many=True
)
date = fields.Date()


class DateFilterSchema(Schema):
start_date = fields.Date(data_key="startDate")
end_date = fields.Date(data_key="endDate")

@pre_load
def remove_empty_value(self, data, many, **kwargs):
"""Remove field whenever value is empty string."""
return {key: value for key, value in data.items() if value}
37 changes: 36 additions & 1 deletion backend/tests/test_hacknight.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,50 @@
from http import HTTPStatus
import json

import pytest
from datetime import date, timedelta

from backend.factories import HacknightFactory
from backend.models import Hacknight, Participant


def test_get_hacknights_when_logged_in(auth_client, add_hacknights):
def test_get_all_hacknights_when_logged_in(
auth_client, add_hacknights, add_participants_to_hacknight
):
"""Test get list of hacknights for logged in user."""
rv = auth_client.get("/api/hacknights/")
response = rv.get_json()
assert rv.status_code == HTTPStatus.OK
assert len(response) == len(Hacknight.query.all())
for hacknigt in response:
assert len(hacknigt["participants"]) == len(
Hacknight.query.get(hacknigt["id"]).participants
)


@pytest.mark.parametrize(
"start_date,end_date",
[("2022-01-12", "2022-10-12"), ("2022-01-12", ""), ("", "2022-10-12")],
)
def test_get_hacknights_date_filter(auth_client, start_date, end_date):
"""Test get list of hacknights with date filter applied."""
expected_count = 0
if start_date:
start_date_formatted = date.fromisoformat(start_date)
out_of_range = start_date_formatted - timedelta(days=1)
HacknightFactory.create(date=start_date_formatted)
HacknightFactory.create(date=out_of_range)
expected_count += 1
if end_date:
end_date_formatted = date.fromisoformat(end_date)
out_of_range = end_date_formatted + timedelta(days=1)
HacknightFactory.create(date=end_date_formatted)
HacknightFactory.create(date=out_of_range)
expected_count += 1
rv = auth_client.get(f"/api/hacknights/?startDate={start_date}&endDate={end_date}")
response = rv.get_json()
assert rv.status_code == HTTPStatus.OK
assert len(response) == expected_count


def test_get_hacknights_with_empty_db(auth_client):
Expand Down