Skip to content

Commit

Permalink
Merge pull request #11 from uclouvain/api
Browse files Browse the repository at this point in the history
Api
  • Loading branch information
SebCorbin committed May 5, 2021
2 parents 8ffc8e7 + 32a4a74 commit 523135f
Show file tree
Hide file tree
Showing 21 changed files with 178 additions and 20 deletions.
2 changes: 1 addition & 1 deletion __init__.py
@@ -1 +1 @@
default_app_config = "history.apps.HistoryConfig"
default_app_config = "osis_history.apps.HistoryConfig"
2 changes: 1 addition & 1 deletion admin.py
@@ -1,5 +1,5 @@
from django.contrib import admin
from history.models import HistoryEntry
from osis_history.models import HistoryEntry


class HistoryEntryAdmin(admin.ModelAdmin):
Expand Down
4 changes: 2 additions & 2 deletions apps.py
Expand Up @@ -2,7 +2,7 @@


class HistoryConfig(AppConfig):
name = "history"
name = "osis_history"

def ready(self):
import history.signals.receivers
import osis_history.signals.receivers
Empty file added contrib/__init__.py
Empty file.
18 changes: 18 additions & 0 deletions contrib/mixins.py
@@ -0,0 +1,18 @@
from rest_framework.authentication import SessionAuthentication
from rest_framework.generics import ListAPIView

from .serializers import HistoryEntryListSerializer
from osis_history.models import HistoryEntry

__all__ = [
"HistoryEntryListAPIMixin",
]


class HistoryEntryListAPIMixin(ListAPIView):
serializer_class = HistoryEntryListSerializer
authentication_classes = [SessionAuthentication]

def get_queryset(self):
"""Filter the queryset with the object's uuid passed in url"""
return HistoryEntry.objects.filter(object_uuid=self.kwargs["uuid"])
16 changes: 16 additions & 0 deletions contrib/serializers.py
@@ -0,0 +1,16 @@
from rest_framework import serializers

from osis_history.models import HistoryEntry

__all__ = [
"HistoryEntryListSerializer",
]


class HistoryEntryListSerializer(serializers.ModelSerializer):
class Meta:
model = HistoryEntry
fields = [
"message",
"created",
]
3 changes: 2 additions & 1 deletion migrations/0001_initial.py
@@ -1,4 +1,4 @@
# Generated by Django 2.2.13 on 2021-04-16 11:57
# Generated by Django 2.2.13 on 2021-04-16 15:34

from django.db import migrations, models

Expand All @@ -22,6 +22,7 @@ class Migration(migrations.Migration):
options={
'verbose_name': 'History entry',
'verbose_name_plural': 'History entries',
'ordering': ('-created',),
},
),
]
12 changes: 10 additions & 2 deletions models/__init__.py
@@ -1,5 +1,13 @@
from .history_entry import HistoryEntry
from .mixins import HistoryDeleteMixin
try:
from .history_entry import HistoryEntry
from .mixins import HistoryDeleteMixin
except RuntimeError as e: # pragma: no cover
# There's a weird bug when running tests, the test runner seeing a models
# package tries to import it directly, failing to do so
import sys

if 'test' not in sys.argv:
raise e

__all__ = [
"HistoryDeleteMixin",
Expand Down
1 change: 1 addition & 0 deletions models/history_entry.py
Expand Up @@ -12,3 +12,4 @@ class HistoryEntry(models.Model):
class Meta:
verbose_name = _("History entry")
verbose_name_plural = _("History entries")
ordering = ("-created", )
2 changes: 1 addition & 1 deletion signals/receivers.py
@@ -1,7 +1,7 @@
from django.db.models.signals import post_delete
from django.dispatch import receiver

from history.models import HistoryDeleteMixin, HistoryEntry
from osis_history.models import HistoryDeleteMixin, HistoryEntry


@receiver(post_delete)
Expand Down
2 changes: 1 addition & 1 deletion tests/history_test/README.md
@@ -1,3 +1,3 @@
This app is for testing purpose only.

With it, the base test suite from the history app can create `DummyModel` instances, that inherit from HistoryDeleteMixin.
With it, the base test suite from the osis_history app can create `DummyModel` instances, that inherit from HistoryDeleteMixin.
2 changes: 1 addition & 1 deletion tests/history_test/__init__.py
@@ -1 +1 @@
default_app_config = "history.tests.history_test.apps.HistoryTestConfig"
default_app_config = "osis_history.tests.history_test.apps.HistoryTestConfig"
2 changes: 1 addition & 1 deletion tests/history_test/apps.py
Expand Up @@ -2,4 +2,4 @@


class HistoryTestConfig(AppConfig):
name = "history.tests.history_test"
name = "osis_history.tests.history_test"
4 changes: 2 additions & 2 deletions tests/history_test/migrations/0001_initial.py
@@ -1,7 +1,7 @@
# Generated by Django 2.2.13 on 2021-04-15 16:46

from django.db import migrations, models
import history.models.mixins
import osis_history.models.mixins


class Migration(migrations.Migration):
Expand All @@ -18,6 +18,6 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('uuid', models.UUIDField()),
],
bases=(history.models.mixins.HistoryDeleteMixin, models.Model),
bases=(osis_history.models.mixins.HistoryDeleteMixin, models.Model),
),
]
2 changes: 1 addition & 1 deletion tests/history_test/models.py
@@ -1,6 +1,6 @@
from django.db import models

from history.models import HistoryDeleteMixin
from osis_history.models import HistoryDeleteMixin


class DummyModel(HistoryDeleteMixin, models.Model):
Expand Down
32 changes: 32 additions & 0 deletions tests/history_test/urls.py
@@ -0,0 +1,32 @@
# ##############################################################################
#
# OSIS stands for Open Student Information System. It's an application
# designed to manage the core business of higher education institutions,
# such as universities, faculties, institutes and professional schools.
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2021 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of this license - GNU General Public License - is available
# at the root of the source code of this program. If not,
# see http://www.gnu.org/licenses/.
#
# ##############################################################################
from django.urls import path

from .views import HistoryTestEntryListView

urlpatterns = [
path("<uuid:uuid>/", HistoryTestEntryListView.as_view(), name="history-test"),
]
5 changes: 5 additions & 0 deletions tests/history_test/views.py
@@ -0,0 +1,5 @@
from osis_history.contrib.mixins import HistoryEntryListAPIMixin


class HistoryTestEntryListView(HistoryEntryListAPIMixin):
pass
4 changes: 2 additions & 2 deletions tests/signals/test_receivers.py
Expand Up @@ -2,8 +2,8 @@

from django.test import TestCase

from history.models import HistoryEntry
from history.tests.history_test.models import DummyModel
from osis_history.models import HistoryEntry
from osis_history.tests.history_test.models import DummyModel


class HistorySignalTest(TestCase):
Expand Down
6 changes: 3 additions & 3 deletions tests/test_utilities.py
Expand Up @@ -2,9 +2,9 @@

from django.test import TestCase

from history.models import HistoryEntry
from history.tests.history_test.models import DummyModel
from history.utilities import add_history_entry, get_history_entries
from osis_history.models import HistoryEntry
from osis_history.tests.history_test.models import DummyModel
from osis_history.utilities import add_history_entry, get_history_entries


class UtilitiesTest(TestCase):
Expand Down
77 changes: 77 additions & 0 deletions tests/test_views.py
@@ -0,0 +1,77 @@
# ##############################################################################
#
# OSIS stands for Open Student Information System. It's an application
# designed to manage the core business of higher education institutions,
# such as universities, faculties, institutes and professional schools.
# The core business involves the administration of students, teachers,
# courses, programs and so on.
#
# Copyright (C) 2015-2021 Université catholique de Louvain (http://www.uclouvain.be)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# A copy of this license - GNU General Public License - is available
# at the root of the source code of this program. If not,
# see http://www.gnu.org/licenses/.
#
# ##############################################################################

import uuid

from django.test import TestCase, override_settings
from django.urls import reverse
from rest_framework.test import APIClient

from base.tests.factories.user import UserFactory
from osis_history.models import HistoryEntry
from osis_history.tests.history_test.models import DummyModel


@override_settings(ROOT_URLCONF='osis_history.tests.history_test.urls')
class HistoryApiTestCase(TestCase):
client_class = APIClient

@classmethod
def setUpTestData(cls):
cls.user = UserFactory()
cls.dumb_instance = DummyModel.objects.create(uuid=uuid.uuid4())
cls.dumb_instance_without_history_entries = DummyModel.objects.create(
uuid=uuid.uuid4()
)
cls.history_entry_data = {
"object_uuid": cls.dumb_instance.uuid,
"message": "a test message",
}
# Create 3 history entries related to the same instance
HistoryEntry.objects.create(**cls.history_entry_data)
HistoryEntry.objects.create(**cls.history_entry_data)
HistoryEntry.objects.create(**cls.history_entry_data)
cls.list_url = reverse("history-test", args=[cls.dumb_instance.uuid])

def test_list_api_view_returns_related_history_entries(self):
self.client.force_login(self.user)
response = self.client.get(self.list_url)
self.assertEqual(response.status_code, 200)
# We must get back the 3 history entries created in the setup
self.assertEqual(response.data["count"], 3)
self.assertEqual(
response.data["results"][0]["message"], self.history_entry_data["message"]
)

def test_list_api_view_returns_no_results_if_given_uuid_is_not_found(self):
self.client.force_login(self.user)
list_url = reverse(
"history-test",
args=[self.dumb_instance_without_history_entries.uuid],
)
response = self.client.get(list_url)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["count"], 0)
2 changes: 1 addition & 1 deletion utilities.py
Expand Up @@ -2,7 +2,7 @@
from datetime import datetime
from typing import List, Tuple, Union

from history.models import HistoryEntry
from osis_history.models import HistoryEntry

__all__ = [
"add_history_entry",
Expand Down

0 comments on commit 523135f

Please sign in to comment.