Skip to content
This repository has been archived by the owner on Feb 5, 2024. It is now read-only.

Commit

Permalink
Merge pull request #101 from SELab-2/visit_api
Browse files Browse the repository at this point in the history
Fixed visit API and added some tests for it
  • Loading branch information
BrentBlanckaert authored Mar 16, 2023
2 parents 8cb4840 + 85729d6 commit b2aa412
Show file tree
Hide file tree
Showing 13 changed files with 192 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 4.1.7 on 2023-03-16 18:05

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
('drtrottoir', '0012_alter_waste_building'),
]

operations = [
migrations.RemoveField(
model_name='visit',
name='building',
),
migrations.AddField(
model_name='visit',
name='building_in_tour',
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.CASCADE, to='drtrottoir.buildingintour', verbose_name='id of building in tour'),
preserve_default=False,
),
]
8 changes: 5 additions & 3 deletions backend/drtrottoir/models/visit.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from django.db import models

from .building import Building
from .building_in_tour import BuildingInTour
from .custom_user import CustomUser


class Visit(models.Model):
arrival = models.DateTimeField(verbose_name="time of arrival")
building = models.ForeignKey(Building, verbose_name="id of building", on_delete=models.CASCADE)
building_in_tour = models.ForeignKey(BuildingInTour,
verbose_name="id of building in tour",
on_delete=models.CASCADE)
user = models.ForeignKey(CustomUser, verbose_name="id of user", on_delete=models.CASCADE)
comment = models.TextField(verbose_name="Comment on the visit", blank=True)

def __str__(self):
return f"{self.user.first_name}, {self.building}: {self.arrival}"
return f"{self.user.first_name}, {self.building_in_tour.building.nickname}: {self.arrival}"
5 changes: 5 additions & 0 deletions backend/drtrottoir/serializers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
from .waste_serializer import WasteSerializer
from .waste_partial import WastePartialSerializer
from .register_serializer import RegisterSerializer
from .building_in_tour_partial import BuildingInTourPartialSerializer
from .tour_partial import TourPartialSerializer


__all__ = [
BuildingSerializer,
Expand All @@ -22,4 +25,6 @@
RegisterSerializer,
TourSerializer,
BuildingInTourSerializer,
BuildingInTourPartialSerializer,
TourPartialSerializer
]
28 changes: 28 additions & 0 deletions backend/drtrottoir/serializers/building_in_tour_partial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from drtrottoir.models import BuildingInTour
from rest_framework import serializers


class BuildingInTourPartialSerializer(serializers.HyperlinkedModelSerializer):
"""
A serializer for buildings in tours, not showing recursive relations
"""
building_data = serializers.SerializerMethodField()
tour_name = serializers.SerializerMethodField()

class Meta:
model = BuildingInTour
fields = [
'url',
'order_index',
'building',
'building_data',
'tour',
'tour_name'
]

def get_building_data(self, obj):
building = obj.building
return {"nickname": building.nickname, "description": building.description}

def get_tour_name(self, obj):
return obj.tour.name
20 changes: 20 additions & 0 deletions backend/drtrottoir/serializers/tour_partial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from drtrottoir.models import Tour
from rest_framework import serializers


class TourPartialSerializer(serializers.HyperlinkedModelSerializer):
"""
A serializer for buildings, not showing recursive relations
"""
region_name = serializers.CharField(
source='region.region_name',
read_only=True
)

class Meta:
model = Tour
fields = [
'url',
'name',
'region_name'
]
1 change: 1 addition & 0 deletions backend/drtrottoir/serializers/user_partial.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ class UserPartialSerializer(serializers.HyperlinkedModelSerializer):
"""
A serializer for CustomUser, not showing recursive relations
"""

class Meta:
model = User
fields = [
Expand Down
27 changes: 22 additions & 5 deletions backend/drtrottoir/serializers/visit_serializer.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,34 @@
from rest_framework import serializers
from drtrottoir.models import Visit
from .building_partial import BuildingPartialSerializer
from .user_partial import UserPartialSerializer
from drtrottoir.models import Visit, CustomUser, BuildingInTour


class VisitSerializer(serializers.HyperlinkedModelSerializer):
"""
A serializer for visits
"""

user = UserPartialSerializer()
building = BuildingPartialSerializer()
user = serializers.HyperlinkedRelatedField(queryset=CustomUser.objects.all(), view_name='customuser-detail')
user_data = serializers.SerializerMethodField()
building_in_tour = serializers.HyperlinkedRelatedField(queryset=BuildingInTour.objects.all(),
view_name='buildingintour-detail')
building_in_tour_data = serializers.SerializerMethodField()

class Meta:
model = Visit
fields = '__all__'

def get_user_data(self, obj):
user = obj.user
return {"email": user.email,
"first_name": user.first_name,
"last_name": user.last_name
}

def get_building_in_tour_data(self, obj):
building_in_tour = obj.building_in_tour
tour = building_in_tour.tour
building = building_in_tour.building
return {"nickname": building.nickname,
"description": building.description,
"tour_name": tour.name
}
2 changes: 2 additions & 0 deletions backend/drtrottoir/tests/factories/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from .waste_factory import WasteFactory
from .tour_factory import TourFactory
from .building_factory import BuildingFactory
from .building_in_tour_factory import BuildingInTourFactory

__all__ = [
RegionFactory,
Expand All @@ -12,4 +13,5 @@
VisitFactory,
WasteFactory,
TourFactory,
BuildingInTourFactory
]
14 changes: 14 additions & 0 deletions backend/drtrottoir/tests/factories/building_in_tour_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from factory.django import DjangoModelFactory
import factory
from drtrottoir.models import BuildingInTour
from .tour_factory import TourFactory
from .building_factory import BuildingFactory


class BuildingInTourFactory(DjangoModelFactory):
order_index = factory.Faker('pyint', min_value=0, max_value=100)
building = factory.SubFactory(BuildingFactory)
tour = factory.SubFactory(TourFactory)

class Meta:
model = BuildingInTour
4 changes: 2 additions & 2 deletions backend/drtrottoir/tests/factories/visit_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
import factory
from django.utils import timezone
from drtrottoir.models import Visit
from .building_factory import BuildingFactory
from .building_in_tour_factory import BuildingInTourFactory
from .user_factory import DeveloperUserFactory


class VisitFactory(DjangoModelFactory):
user = factory.SubFactory(DeveloperUserFactory)
building = factory.SubFactory(BuildingFactory)
building_in_tour = factory.SubFactory(BuildingInTourFactory)
arrival = factory.Faker("date_time", tzinfo=timezone.utc)
comment = factory.Faker("sentence")

Expand Down
4 changes: 2 additions & 2 deletions backend/drtrottoir/tests/views/test_tour.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def test_post(self):

response3 = self.client.post('/api/tour/', data={}, follow=True)
self.assertEqual(response3.status_code, status.HTTP_400_BAD_REQUEST)
response4 = self.client.post('/api/tour/', data={"region": 6548749, "name": "test"}, follow=True) # Region
response4 = self.client.post('/api/tour/', data={"region": -1, "name": "test"}, follow=True) # Region
# should not exist in this case
self.assertEqual(response4.status_code, status.HTTP_400_BAD_REQUEST)

Expand All @@ -50,7 +50,7 @@ def test_post_from_existing(self):
self.assertEqual(response_get.data["region"], response2.data["region"])
self.assertNotEqual(response_get.data["url"], response2.data["url"])

response_fault = self.client.post('/api/tour/', data={"id": 5648561}, follow=True) # tour should not exist
response_fault = self.client.post('/api/tour/', data={"id": -1}, follow=True) # tour should not exist
self.assertEqual(response_fault.status_code, status.HTTP_400_BAD_REQUEST)

def test_delete(self):
Expand Down
71 changes: 66 additions & 5 deletions backend/drtrottoir/tests/views/test_visit.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,81 @@
from rest_framework.test import APITestCase
from django.urls import reverse

from drtrottoir.serializers import VisitSerializer
from drtrottoir.tests.factories import VisitFactory, DeveloperUserFactory
from drtrottoir.serializers import VisitSerializer, UserSerializer, BuildingInTourSerializer
from drtrottoir.tests.factories import VisitFactory, DeveloperUserFactory, BuildingInTourFactory


class TestVisitView(APITestCase):
""" Test module for GET single Visit API """
""" Test module for Visit API """

def setUp(self):
self.visit = VisitFactory()
user = DeveloperUserFactory()
self.client.force_authenticate(user=user)
self.building_in_tour = BuildingInTourFactory()
self.user = DeveloperUserFactory()
self.client.force_authenticate(user=self.user)

def test_get(self):
response = self.client.get(reverse("visit-detail", kwargs={'pk': self.visit.pk}))
serializer = VisitSerializer(self.visit, context={'request': response.wsgi_request})
self.assertEqual(response.data, serializer.data)
self.assertEqual(response.status_code, status.HTTP_200_OK)

self.assertTrue("url" in response.data and
"user" in response.data and
"user_data" in response.data and
"building_in_tour" in response.data and
"building_in_tour_data" in response.data and
"arrival" in response.data and
"comment" in response.data)

user_data = response.data["user_data"]
self.assertTrue("email" in user_data and
"first_name" in user_data and
"last_name" in user_data)

building_in_tour_data = response.data["building_in_tour_data"]
self.assertTrue("nickname" in building_in_tour_data and
"description" in building_in_tour_data and
"tour_name" in building_in_tour_data)

response2 = self.client.get(reverse("visit-detail", kwargs={'pk': -1})) # Visit object shouldn't exist
self.assertEqual(response2.status_code, 404)

def test_delete(self):
self.client.delete(reverse("visit-detail", kwargs={'pk': self.visit.pk}), follow=True)
response = self.client.get(reverse("visit-detail", kwargs={'pk': self.visit.pk}), follow=True)
self.assertEqual(response.data["detail"].code, "not_found")

def test_patch(self):
response = self.client.get(reverse("visit-detail", kwargs={'pk': self.visit.pk}), follow=True)
original = response.data
response = self.client.patch(reverse("visit-detail", kwargs={'pk': self.visit.pk}),
data={"comment": "UPDATE TEST"}, follow=True)
new_data = response.data
print(new_data)
self.assertNotEqual(original["comment"], new_data["comment"])
self.assertEqual(new_data["comment"], "UPDATE TEST")

def test_post(self):
response = self.client.get("/api/building_in_tour/" + str(self.building_in_tour.pk) + "/", follow=True)
serializerBuildTour = BuildingInTourSerializer(self.building_in_tour,
context={'request': response.wsgi_request})
serializerUser = UserSerializer(self.user, context={'request': response.wsgi_request})
response = self.client.post("/api/visit/",
data={"comment": "TEST",
"arrival": "2023-03-15T17:10:46Z",
"building_in_tour": serializerBuildTour.data["url"],
"user": serializerUser.data["url"]
}, follow=True)
self.assertEqual(response.status_code, 201)
response = self.client.get(response.data["url"], follow=True)
self.assertEqual(response.status_code, status.HTTP_200_OK)

# Test incorrect POST body
response = self.client.post("/api/visit/",
data={"comment": "TEST",
"arrival": "2023-03-15T17:10:46Z",
"building_in_tour": 1,
"user": "user"
}, follow=True)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
2 changes: 1 addition & 1 deletion backend/fixtures/init_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@
"pk": 1,
"fields": {
"arrival": "2023-03-08T16:00:33Z",
"building": 1,
"building_in_tour": 1,
"user": 2,
"comment": "Vuilbakken zijn buitengezet"
}
Expand Down

0 comments on commit b2aa412

Please sign in to comment.