Add API endpoints for the message of the day app.

This commit is contained in:
Roberto Rosario
2017-02-10 18:16:46 -04:00
parent 7a1b3e2ee2
commit c218819728
11 changed files with 346 additions and 13 deletions

80
docs/releases/2.1.8.rst Normal file
View File

@@ -0,0 +1,80 @@
===============================
Mayan EDMS v2.1.8 release notes
===============================
Released: February XX, 2017
What's new
==========
This is a bug-fix release and all users are encouraged to upgrade. The focus
of this micro release was REST API improvement.
Changes
-------------
- Fixes in the trashed document API endpoints.
- Improved tags API PUT and PATCH endpoints.
- Bulk document adding when creating and editing tags.
- The version of django-mptt is preserved in case mayan-cabinets is installed.
- Add Django GPG API endpoints for singing keys.
- Add API endpoints for the document states app.
- Add API endpoints for the messsage of the day (MOTD) app.
Removals
--------
* None
Upgrading from a previous version
---------------------------------
Using PIP
~~~~~~~~~
Type in the console::
$ pip install -U mayan-edms
the requirements will also be updated automatically.
Using Git
~~~~~~~~~
If you installed Mayan EDMS by cloning the Git repository issue the commands::
$ git reset --hard HEAD
$ git pull
otherwise download the compressed archived and uncompress it overriding the
existing installation.
Next upgrade/add the new requirements::
$ pip install --upgrade -r requirements.txt
Common steps
~~~~~~~~~~~~
Migrate existing database schema with::
$ mayan-edms.py performupgrade
Add new static media::
$ mayan-edms.py collectstatic --noinput
The upgrade procedure is now complete.
Backward incompatible changes
=============================
* None
Bugs fixed or issues closed
===========================
* None
.. _PyPI: https://pypi.python.org/pypi/mayan-edms/

View File

@@ -22,6 +22,7 @@ versions of the documentation contain the release notes for any later releases.
.. toctree::
:maxdepth: 1
2.1.8
2.1.7
2.1.6
2.1.5

View File

@@ -0,0 +1,76 @@
from __future__ import absolute_import, unicode_literals
from rest_framework import generics
from rest_api.filters import MayanObjectPermissionsFilter
from rest_api.permissions import MayanPermission
from .models import Message
from .permissions import (
permission_message_create, permission_message_delete,
permission_message_edit, permission_message_view
)
from .serializers import MessageSerializer
class APIMessageListView(generics.ListCreateAPIView):
filter_backends = (MayanObjectPermissionsFilter,)
mayan_object_permissions = {'GET': (permission_message_view,)}
mayan_view_permissions = {'POST': (permission_message_create,)}
permission_classes = (MayanPermission,)
queryset = Message.objects.all()
serializer_class = MessageSerializer
def get(self, *args, **kwargs):
"""
Returns a list of all the messages.
"""
return super(APIMessageListView, self).get(*args, **kwargs)
def post(self, *args, **kwargs):
"""
Create a new message.
"""
return super(APIMessageListView, self).post(*args, **kwargs)
class APIMessageView(generics.RetrieveUpdateDestroyAPIView):
filter_backends = (MayanObjectPermissionsFilter,)
mayan_object_permissions = {
'DELETE': (permission_message_delete,),
'GET': (permission_message_view,),
'PATCH': (permission_message_edit,),
'PUT': (permission_message_edit,)
}
queryset = Message.objects.all()
serializer_class = MessageSerializer
def delete(self, *args, **kwargs):
"""
Delete the selected message.
"""
return super(APIMessageView, self).delete(*args, **kwargs)
def get(self, *args, **kwargs):
"""
Return the details of the selected message.
"""
return super(APIMessageView, self).get(*args, **kwargs)
def patch(self, *args, **kwargs):
"""
Edit the selected message.
"""
return super(APIMessageView, self).patch(*args, **kwargs)
def put(self, *args, **kwargs):
"""
Edit the selected message.
"""
return super(APIMessageView, self).put(*args, **kwargs)

View File

@@ -6,6 +6,7 @@ from django.utils.translation import ugettext_lazy as _
from common import MayanAppConfig, menu_object, menu_secondary, menu_setup
from navigation import SourceColumn
from rest_api.classes import APIEndPoint
from .links import (
link_message_create, link_message_delete, link_message_edit,
@@ -23,6 +24,8 @@ class MOTDApp(MayanAppConfig):
def ready(self):
super(MOTDApp, self).ready()
APIEndPoint(app=self, version_string='1')
Message = self.get_model('Message')
SourceColumn(

View File

@@ -13,12 +13,37 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name='MessageOfTheDay',
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('label', models.CharField(max_length=32, verbose_name='Label')),
('message', models.TextField(verbose_name='Message', blank=True)),
('enabled', models.BooleanField(default=True, verbose_name='Enabled')),
('start_datetime', models.DateTimeField(verbose_name='Start date time', blank=True)),
('end_datetime', models.DateTimeField(verbose_name='End date time', blank=True)),
(
'id', models.AutoField(
verbose_name='ID', serialize=False,
auto_created=True, primary_key=True
)
),
(
'label', models.CharField(
max_length=32, verbose_name='Label'
)
),
(
'message', models.TextField(
verbose_name='Message', blank=True
)
),
(
'enabled', models.BooleanField(
default=True, verbose_name='Enabled'
)
),
(
'start_datetime', models.DateTimeField(
verbose_name='Start date time', blank=True
)
),
(
'end_datetime', models.DateTimeField(
verbose_name='End date time', blank=True
)
),
],
options={
'verbose_name': 'Message of the day',

View File

@@ -14,21 +14,33 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='message',
name='end_datetime',
field=models.DateTimeField(help_text='Date and time until when this message is to be displayed.', null=True, verbose_name='End date time', blank=True),
field=models.DateTimeField(
help_text='Date and time until when this message is to be displayed.',
null=True, verbose_name='End date time', blank=True
),
),
migrations.AlterField(
model_name='message',
name='label',
field=models.CharField(help_text='Short description of this message.', max_length=32, verbose_name='Label'),
field=models.CharField(
help_text='Short description of this message.', max_length=32,
verbose_name='Label'
),
),
migrations.AlterField(
model_name='message',
name='message',
field=models.TextField(help_text='The actual message to be displayed.', verbose_name='Message'),
field=models.TextField(
help_text='The actual message to be displayed.',
verbose_name='Message'
),
),
migrations.AlterField(
model_name='message',
name='start_datetime',
field=models.DateTimeField(help_text='Date and time after which this message will be displayed.', null=True, verbose_name='Start date time', blank=True),
field=models.DateTimeField(
help_text='Date and time after which this message will be displayed.',
null=True, verbose_name='Start date time', blank=True
),
),
]

View File

@@ -0,0 +1,17 @@
from __future__ import absolute_import, unicode_literals
from rest_framework import serializers
from .models import Message
class MessageSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
extra_kwargs = {
'url': {'view_name': 'rest_api:message-detail'},
}
fields = (
'end_datetime', 'enabled', 'label', 'message', 'start_datetime',
'id', 'url'
)
model = Message

View File

@@ -0,0 +1,6 @@
from __future__ import unicode_literals
TEST_LABEL = 'test label'
TEST_LABEL_EDITED = 'test label edited'
TEST_MESSAGE = 'test message'
TEST_MESSAGE_EDITED = 'test message edited'

View File

@@ -0,0 +1,103 @@
from __future__ import unicode_literals
from django.contrib.auth import get_user_model
from django.core.urlresolvers import reverse
from django.test import override_settings
from rest_framework.test import APITestCase
from user_management.tests.literals import (
TEST_ADMIN_EMAIL, TEST_ADMIN_PASSWORD, TEST_ADMIN_USERNAME
)
from ..models import Message
from .literals import (
TEST_LABEL, TEST_LABEL_EDITED, TEST_MESSAGE, TEST_MESSAGE_EDITED
)
@override_settings(OCR_AUTO_OCR=False)
class MOTDAPITestCase(APITestCase):
def setUp(self):
self.admin_user = get_user_model().objects.create_superuser(
username=TEST_ADMIN_USERNAME, email=TEST_ADMIN_EMAIL,
password=TEST_ADMIN_PASSWORD
)
self.client.login(
username=TEST_ADMIN_USERNAME, password=TEST_ADMIN_PASSWORD
)
def _create_message(self):
return Message.objects.create(
label=TEST_LABEL, message=TEST_MESSAGE
)
def test_message_create_view(self):
response = self.client.post(
reverse('rest_api:message-list'), {
'label': TEST_LABEL, 'message': TEST_MESSAGE
}
)
message = Message.objects.first()
self.assertEqual(response.data['id'], message.pk)
self.assertEqual(response.data['label'], TEST_LABEL)
self.assertEqual(response.data['message'], TEST_MESSAGE)
self.assertEqual(Message.objects.count(), 1)
self.assertEqual(message.label, TEST_LABEL)
self.assertEqual(message.message, TEST_MESSAGE)
def test_message_delete_view(self):
message = self._create_message()
self.client.delete(
reverse('rest_api:message-detail', args=(message.pk,))
)
self.assertEqual(Message.objects.count(), 0)
def test_message_detail_view(self):
message = self._create_message()
response = self.client.get(
reverse('rest_api:message-detail', args=(message.pk,))
)
self.assertEqual(
response.data['label'], TEST_LABEL
)
def test_message_path_view(self):
message = self._create_message()
self.client.patch(
reverse('rest_api:message-detail', args=(message.pk,)),
{
'label': TEST_LABEL_EDITED,
'message': TEST_MESSAGE_EDITED
}
)
message.refresh_from_db()
self.assertEqual(message.label, TEST_LABEL_EDITED)
self.assertEqual(message.message, TEST_MESSAGE_EDITED)
def test_message_put_view(self):
message = self._create_message()
self.client.put(
reverse('rest_api:message-detail', args=(message.pk,)),
{
'label': TEST_LABEL_EDITED,
'message': TEST_MESSAGE_EDITED
}
)
message.refresh_from_db()
self.assertEqual(message.label, TEST_LABEL_EDITED)
self.assertEqual(message.message, TEST_MESSAGE_EDITED)

View File

@@ -7,8 +7,7 @@ from django.utils import timezone
from ..models import Message
TEST_LABEL = 'test label'
TEST_MESSAGE = 'test message'
from .literals import TEST_LABEL, TEST_MESSAGE
class MOTDTestCase(TestCase):

View File

@@ -2,6 +2,7 @@ from __future__ import unicode_literals
from django.conf.urls import patterns, url
from .api_views import APIMessageListView, APIMessageView
from .views import (
MessageCreateView, MessageDeleteView, MessageEditView, MessageListView
)
@@ -10,9 +11,19 @@ urlpatterns = patterns(
'',
url(r'^list/$', MessageListView.as_view(), name='message_list'),
url(r'^create/$', MessageCreateView.as_view(), name='message_create'),
url(r'^(?P<pk>\d+)/edit/$', MessageEditView.as_view(), name='message_edit'),
url(
r'^(?P<pk>\d+)/edit/$', MessageEditView.as_view(), name='message_edit'
),
url(
r'^(?P<pk>\d+)/delete/$', MessageDeleteView.as_view(),
name='message_delete'
),
)
api_urls = [
url(r'^messages/$', APIMessageListView.as_view(), name='message-list'),
url(
r'^messages/(?P<pk>[0-9]+)/$', APIMessageView.as_view(),
name='message-detail'
),
]