add personal group, default_group to users and add group info to session on backend
--- a/src/irinotes/settings.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/irinotes/settings.py Mon Jul 31 23:18:38 2017 +0200
@@ -197,11 +197,11 @@
'level': LOG_LEVEL,
'propagate': True,
},
- 'django.db.backends': {
- 'handlers': ['file'],
- 'level': LOG_LEVEL,
- 'propagate': True,
- },
+ # 'django.db.backends': {
+ # 'handlers': ['file'],
+ # 'level': LOG_LEVEL,
+ # 'propagate': True,
+ # },
'irinotes': {
'handlers': ['file'],
'level': LOG_LEVEL,
--- a/src/notes/api/serializers/auth.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/api/serializers/auth.py Mon Jul 31 23:18:38 2017 +0200
@@ -10,11 +10,12 @@
class GroupSerializer(serializers.ModelSerializer):
owner = serializers.CharField(source='profile.owner.username', read_only=True)
+ is_personal = serializers.BooleanField(source='profile.is_personal', read_only=True)
description = serializers.CharField(source='profile.description')
class Meta:
model = Group
- fields = ['name', 'owner', 'description']
+ fields = ['name', 'owner', 'is_personal', 'description']
class DetailGroupSerializer(GroupSerializer):
@@ -27,7 +28,8 @@
class Meta:
model = Group
- fields = ['name', 'owner', 'description', 'users']
+ fields = ['name', 'owner', 'description', 'users', 'is_personal']
+
class WriteGroupSerializer(serializers.ModelSerializer):
'''
--- a/src/notes/api/serializers/core.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/api/serializers/core.py Mon Jul 31 23:18:38 2017 +0200
@@ -3,8 +3,10 @@
"""
import logging
+from django.contrib.auth.models import Group
+from rest_framework import serializers
+
from notes.models import Note, Session
-from rest_framework import serializers
logger = logging.getLogger(__name__)
@@ -87,40 +89,63 @@
owner = serializers.SlugRelatedField(
read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
+ group = serializers.SlugRelatedField(read_only=True, slug_field='name')
class Meta:
model = Session
fields = (
'ext_id', 'version', 'date', 'created', 'updated',
- 'owner', 'title', 'description', 'protocol'
+ 'owner', 'title', 'description', 'protocol', 'group'
)
- read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner')
+ read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group')
class DetailSessionSerializer(serializers.ModelSerializer):
owner = serializers.SlugRelatedField(read_only=True, slug_field='username')
notes = DetailNoteSerializer(many=True, read_only=True)
+ group = serializers.SlugRelatedField(slug_field='name', read_only=True)
+
+ class Meta:
+ model = Session
+ fields = (
+ 'ext_id', 'version', 'date', 'created', 'updated',
+ 'owner', 'title', 'description', 'protocol', 'group',
+ 'notes'
+ )
+ read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner', 'group')
+
+class CreateSessionSerializer(serializers.ModelSerializer):
+
+ owner = serializers.SlugRelatedField(
+ read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
+ group = serializers.SlugRelatedField(slug_field='name', queryset=Group.objects.all(), required=False)
class Meta:
model = Session
fields = (
'ext_id', 'version', 'date', 'created', 'updated',
- 'owner', 'title', 'description', 'protocol',
- 'notes'
- )
- read_only_fields = ('ext_id', 'version', 'created', 'updated', 'owner')
-
-class CreateSessionSerializer(serializers.ModelSerializer):
-
- owner = serializers.SlugRelatedField(
- read_only=True, slug_field='username', default=serializers.CurrentUserDefault())
-
-
- class Meta:
- model = Session
- fields = (
- 'ext_id', 'version', 'date', 'created', 'updated',
- 'owner', 'title', 'description', 'protocol'
+ 'owner', 'title', 'description', 'protocol', 'group'
)
read_only_fields = ('version', 'created', 'updated', 'owner')
+
+ def validate(self, data):
+ data = super().validate(data)
+
+ group = data.get('group')
+ owner = data.get('owner')
+
+ if group is None:
+ if owner and owner.profile and owner.profile.default_group:
+ group = owner.profile.default_group
+ if group is None and owner:
+ group = Group.objects.filter(profile__owner_personal=owner).first()
+
+ if group is None:
+ raise serializers.ValidationError("group field is required or default group or personal group could not be found for owner")
+ elif not owner in group.user_set.all():
+ raise serializers.ValidationError("Owner must be in group")
+
+ data['group'] = group
+ return data
+
--- a/src/notes/locale/en/LC_MESSAGES/django.po Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/locale/en/LC_MESSAGES/django.po Mon Jul 31 23:18:38 2017 +0200
@@ -7,7 +7,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-06-21 10:51+0000\n"
+"POT-Creation-Date: 2017-07-31 10:40+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -16,27 +16,31 @@
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-#: models/auth.py:11
+#: models/auth.py:12
msgid "User"
msgstr "User"
-#: models/auth.py:12
+#: models/auth.py:13
msgid "Users"
msgstr "Users"
-#: models/auth.py:17
+#: models/auth.py:23
+msgid "UserProfile|default_group"
+msgstr "default group"
+
+#: models/auth.py:26
msgid "UserProfile"
msgstr "User profile"
-#: models/auth.py:18
+#: models/auth.py:27
msgid "UserProfiles"
msgstr "User profiles"
-#: models/auth.py:25
+#: models/auth.py:48
msgid "GroupProfile"
msgstr "Group profile"
-#: models/auth.py:26
+#: models/auth.py:49
msgid "GroupProfiles"
msgstr "Group profiles"
@@ -96,66 +100,70 @@
msgid "Categories"
msgstr "Categories"
-#: models/core.py:17
+#: models/core.py:19
msgid "Session"
msgstr "Session"
-#: models/core.py:18
+#: models/core.py:20
msgid "Sessions"
msgstr "Sessions"
-#: models/core.py:20
+#: models/core.py:22
msgid "Session|date"
msgstr "date"
-#: models/core.py:29
+#: models/core.py:31
msgid "Session|title"
msgstr "title"
-#: models/core.py:34
+#: models/core.py:36
msgid "Session|description"
msgstr "description"
-#: models/core.py:39
+#: models/core.py:41
+msgid "Session|group"
+msgstr "group"
+
+#: models/core.py:46
msgid "Session|protocol"
msgstr "protocol"
-#: models/core.py:48
+#: models/core.py:61
msgid "Note"
msgstr "Note"
-#: models/core.py:49
+#: models/core.py:62
msgid "Notes"
msgstr "Notes"
-#: models/core.py:52
+#: models/core.py:68
msgid "Note|tc_start"
msgstr "start timecode"
-#: models/core.py:53
+#: models/core.py:69
msgid "Note|tc_end"
msgstr "end timeocde"
-#: models/core.py:58
+#: models/core.py:74
msgid "Note|session"
msgstr "session"
-#: models/core.py:63
+#: models/core.py:79
msgid "Note|plain"
msgstr "text plain"
-#: models/core.py:68
+#: models/core.py:84
msgid "Note|html"
msgstr "text html"
-#: models/core.py:73
+#: models/core.py:89
msgid "Note|raw"
msgstr "text raw"
-#: models/core.py:78
+#: models/core.py:94
msgid "Note|margin_note"
msgstr "margin note"
-#: models/core.py:83
+#: models/core.py:99
msgid "Note|categorization"
msgstr "categorization"
--- a/src/notes/locale/fr/LC_MESSAGES/django.po Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/locale/fr/LC_MESSAGES/django.po Mon Jul 31 23:18:38 2017 +0200
@@ -7,7 +7,7 @@
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2017-06-21 10:51+0000\n"
+"POT-Creation-Date: 2017-07-31 10:40+0000\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,27 +17,31 @@
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-#: models/auth.py:11
+#: models/auth.py:12
msgid "User"
msgstr "Utilisateur"
-#: models/auth.py:12
+#: models/auth.py:13
msgid "Users"
msgstr "Utilisateurs"
-#: models/auth.py:17
+#: models/auth.py:23
+msgid "UserProfile|default_group"
+msgstr "Groupe par défaut"
+
+#: models/auth.py:26
msgid "UserProfile"
msgstr "Profil utilisateur"
-#: models/auth.py:18
+#: models/auth.py:27
msgid "UserProfiles"
msgstr "Profils utilisateur"
-#: models/auth.py:25
+#: models/auth.py:48
msgid "GroupProfile"
msgstr "Profile groupe"
-#: models/auth.py:26
+#: models/auth.py:49
msgid "GroupProfiles"
msgstr "Profiles groupe"
@@ -97,66 +101,70 @@
msgid "Categories"
msgstr "Categories"
-#: models/core.py:17
+#: models/core.py:19
msgid "Session"
msgstr "Session"
-#: models/core.py:18
+#: models/core.py:20
msgid "Sessions"
msgstr "Sessions"
-#: models/core.py:20
+#: models/core.py:22
msgid "Session|date"
msgstr "date"
-#: models/core.py:29
+#: models/core.py:31
msgid "Session|title"
msgstr "titre"
-#: models/core.py:34
+#: models/core.py:36
msgid "Session|description"
msgstr "description"
-#: models/core.py:39
+#: models/core.py:41
+msgid "Session|group"
+msgstr "groupe"
+
+#: models/core.py:46
msgid "Session|protocol"
msgstr "protocole"
-#: models/core.py:48
+#: models/core.py:61
msgid "Note"
msgstr "Note"
-#: models/core.py:49
+#: models/core.py:62
msgid "Notes"
msgstr "Notes"
-#: models/core.py:52
+#: models/core.py:68
msgid "Note|tc_start"
msgstr "timecode début"
-#: models/core.py:53
+#: models/core.py:69
msgid "Note|tc_end"
msgstr "timecode fin"
-#: models/core.py:58
+#: models/core.py:74
msgid "Note|session"
msgstr "session"
-#: models/core.py:63
+#: models/core.py:79
msgid "Note|plain"
msgstr "texte seul"
-#: models/core.py:68
+#: models/core.py:84
msgid "Note|html"
msgstr "texte html"
-#: models/core.py:73
+#: models/core.py:89
msgid "Note|raw"
msgstr "texte brut"
-#: models/core.py:78
+#: models/core.py:94
msgid "Note|margin_note"
msgstr "note de marge"
-#: models/core.py:83
+#: models/core.py:99
msgid "Note|categorization"
msgstr "catégorisation"
--- a/src/notes/migrations/0001_initial.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/migrations/0001_initial.py Mon Jul 31 23:18:38 2017 +0200
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Generated by Django 1.11.2 on 2017-07-19 13:26
+# Generated by Django 1.11.2 on 2017-07-31 13:32
from __future__ import unicode_literals
import colorful.fields
@@ -68,6 +68,7 @@
('description', models.TextField(blank=True, null=True)),
('group', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to='auth.Group')),
('owner', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
+ ('owner_personal', models.OneToOneField(null=True, on_delete=django.db.models.deletion.CASCADE, related_name='personal_group', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'GroupProfile',
@@ -124,6 +125,7 @@
('title', models.TextField(blank=True, null=True, verbose_name='Session|title')),
('description', models.TextField(blank=True, null=True, verbose_name='Session|description')),
('protocol', models.TextField(blank=True, null=True, verbose_name='Session|protocol')),
+ ('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group', verbose_name='Session|group')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
@@ -135,7 +137,8 @@
name='UserProfile',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ('default_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group', verbose_name='UserProfile|default_group')),
+ ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name': 'UserProfile',
--- a/src/notes/models/auth.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/models/auth.py Mon Jul 31 23:18:38 2017 +0200
@@ -7,13 +7,20 @@
class User(AbstractUser):
+
class Meta:
verbose_name = _('User')
verbose_name_plural = _('Users')
class UserProfile(models.Model):
- user = models.OneToOneField(User, on_delete=models.CASCADE)
+ user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
+
+ # TODO:
+ default_group = models.ForeignKey(
+ Group,
+ null=False,
+ verbose_name=_("UserProfile|default_group"))
class Meta:
verbose_name = _('UserProfile')
@@ -26,6 +33,17 @@
description = models.TextField(null=True, blank=True)
# TODO: manage when user is deleted: put first user as owner. delete group if empty
owner = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
+ # TODO: can not delete group when user is not deleted.
+ # TODO: other users cannot set as owner
+ # TODO: delete personal group when user is deleted
+ # TODO: change group name when user change name
+ # indicate that this group is a personal group.
+ # used this instead of a boolean because it allows to easily enforce that a user has only one personal group
+ owner_personal = models.OneToOneField(User, on_delete=models.CASCADE, null=True, related_name='personal_group')
+
+ @property
+ def is_personal(self):
+ return self.owner == self.owner_personal
class Meta:
verbose_name = _('GroupProfile')
--- a/src/notes/models/core.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/models/core.py Mon Jul 31 23:18:38 2017 +0200
@@ -3,6 +3,7 @@
"""
from auditlog.registry import auditlog
from django.conf import settings
+from django.contrib.auth.models import Group
from django.db import models
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
@@ -34,6 +35,11 @@
blank=True,
verbose_name=_('Session|description')
)
+ group = models.ForeignKey(
+ Group,
+ null=False,
+ verbose_name=_('Session|group')
+ )
protocol = models.TextField(
null=True,
blank=True,
--- a/src/notes/signals.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/signals.py Mon Jul 31 23:18:38 2017 +0200
@@ -1,10 +1,17 @@
"""
Signals for notes app
"""
+import logging
+
+from django.contrib.auth import get_user_model
+from django.contrib.auth.models import Group
from django.db.models.signals import post_save
from django.dispatch import receiver
-from django.contrib.auth.models import Group
-from notes.models import GroupProfile
+
+from notes.models import GroupProfile, UserProfile
+
+User = get_user_model()
+logger = logging.getLogger(__name__)
@receiver(post_save, sender=Group, dispatch_uid="group_created_signal")
def group_saved_callback(sender, instance, **kwargs):
@@ -13,3 +20,33 @@
profile = GroupProfile(group=instance)
profile.save()
+@receiver(post_save, sender=User, dispatch_uid="user_created_signal")
+def user_saved_callback(sender, instance, **kwargs):
+ created = kwargs.pop('created')
+ if not instance:
+ return
+ base_group_name = instance.username + " group"
+ group_name = base_group_name
+ if created:
+ # create personal group
+ personal_group = None
+ personal_group_profile = GroupProfile.objects.filter(owner=instance, owner_personal=instance).first()
+ if personal_group_profile is None:
+ # find a new name
+ i = 1
+ while Group.objects.filter(name=group_name).exists(): # should always ends...
+ group_name = "%s %s" % (base_group_name, i)
+ i += 1
+ personal_group = Group.objects.create(name=group_name)
+ personal_group.user_set.add(instance)
+ personal_group_profile = personal_group.profile
+ personal_group_profile.description = "%s personal group" % instance.username
+ personal_group_profile.owner = instance
+ personal_group_profile.owner_personal = instance
+ personal_group_profile.save()
+ else:
+ personal_group = personal_group_profile.group
+
+ UserProfile.objects.create(user=instance, default_group=personal_group)
+ # else we do nothing, because we do not know if the group's name was changed or not
+ # and we do not know the user older name
--- a/src/notes/tests/api/auth.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/tests/api/auth.py Mon Jul 31 23:18:38 2017 +0200
@@ -20,12 +20,12 @@
User = get_user_model()
self.user1 = User.objects.create_user(
username='test_user1',
- email='test_user@emial.com',
+ email='test_user@email.com',
password='top_secret'
)
self.user2 = User.objects.create_user(
username='test_user2',
- email='test_user@emial.com',
+ email='test_user@email.com',
password='top_secret'
)
@@ -58,14 +58,24 @@
self.assertEqual(response.status_code, status.HTTP_200_OK)
- self.assertEqual(2, len(response.data), "Must have 2 groups")
- for group_def in response.data:
- self.assertIn('name', group_def.keys())
- self.assertIn('owner', group_def.keys())
- self.assertIn('description', group_def.keys())
+ resp_json = response.json()
+ self.assertIn('count', resp_json)
+ self.assertIn('results', resp_json)
+ self.assertEqual(4, resp_json['count'], "Must have 4 groups")
+ self.assertEqual(4, len(resp_json['results']), "Must have 4 groups")
+
+ for group_def in resp_json['results']:
+ self.assertIn('name', group_def)
+ self.assertIn('owner', group_def)
+ self.assertIn('is_personal', group_def)
+ self.assertIn('description', group_def)
self.assertIn(group_def.get('owner'), ['test_user1', 'test_user2'])
- self.assertIn(group_def.get('description'), ['This is the group 1', 'This is the group 2'])
- self.assertIn(group_def.get('name'), ['group1', 'group2'])
+ self.assertIn(group_def.get('description'), [
+ 'This is the group 1',
+ 'This is the group 2',
+ 'test_user1 personal group',
+ 'test_user2 personal group'])
+ self.assertIn(group_def.get('name'), ['group1', 'group2', 'test_user1 group', 'test_user2 group'])
def test_create_group(self):
url = reverse('auth_group-list')
--- a/src/notes/tests/api/note.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/tests/api/note.py Mon Jul 31 23:18:38 2017 +0200
@@ -43,6 +43,7 @@
title="a new session 1",
description="Description 1",
protocol="[]",
+ group=user1.profile.default_group,
owner=user1
)
@@ -50,6 +51,7 @@
title="a new session 2",
description="Description 2",
protocol="[]",
+ group=user2.profile.default_group,
owner=user2
)
@@ -57,6 +59,7 @@
title="a new session 3",
description="Description 3",
protocol="[]",
+ group=user3.profile.default_group,
owner=user3
)
--- a/src/notes/tests/api/session.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/tests/api/session.py Mon Jul 31 23:18:38 2017 +0200
@@ -6,12 +6,13 @@
from uuid import uuid4
from django.contrib.auth import get_user_model
+from django.contrib.auth.models import Group
from django.urls import reverse
from django.utils import timezone
from rest_framework import status
from rest_framework.test import APITransactionTestCase
-from notes.models import Session, Note
+from notes.models import Session, Note, GroupProfile
logger = logging.getLogger(__name__)
@@ -19,12 +20,12 @@
def setUp(self):
User = get_user_model()
- user1 = User.objects.create_user(
+ self.user1 = User.objects.create_user(
username='test_user1',
email='test_user@emial.com',
password='top_secret'
)
- user2 = User.objects.create_user(
+ self.user2 = User.objects.create_user(
username='test_user2',
email='test_user@emial.com',
password='top_secret'
@@ -35,24 +36,38 @@
password='top_secret'
)
+ self.group1 = Group(name='group1')
+ self.group1.save()
+ self.group1.user_set.add(self.user1)
+ self.group1.user_set.add(self.user2)
+ self.group1.profile.owner = self.user1
+ self.group1.profile.description = "This is the group 1"
+ self.group1.profile.save()
+
+ self.user2.profile.default_group = self.group1
+ self.user2.profile.save()
+
self.session1 = Session.objects.create(
title="a new session 1",
description="Description 1",
protocol="[]",
- owner=user1
+ group=self.user1.profile.default_group,
+ owner=self.user1
)
self.session2 = Session.objects.create(
title="a new session 2",
description="Description 2",
protocol="[]",
- owner=user2
+ group=self.user2.profile.default_group,
+ owner=self.user2
)
self.session3 = Session.objects.create(
title="a new session 3",
description="Description 3",
protocol="[]",
+ group=user3.profile.default_group,
owner=user3
)
@@ -60,6 +75,7 @@
title="a new session 4",
description="Description 4",
protocol="[]",
+ group=user3.profile.default_group,
owner=user3
)
@@ -150,14 +166,89 @@
response = self.client.post(url, {
'title': "a new session",
'description': "description of the session",
- 'protocol': "[]"
+ 'protocol': "[]",
+ 'group': 'group1'
}, format='json')
-
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
json = response.json()
self.assertIn('ext_id', json)
+ session = Session.objects.get(ext_id=json['ext_id'])
+ self.assertIsNotNone(session)
+ self.assertEqual(self.group1, session.group)
+
+
+ def test_create_session_no_group(self):
+ url = reverse('notes:session-list')
+ self.client.login(username='test_user1', password='top_secret')
+ response = self.client.post(url, {
+ 'title': "a new session",
+ 'description': "description of the session",
+ 'protocol': "[]",
+ }, format='json')
+
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Error when creating session %r" % response.json())
+ json = response.json()
+ self.assertIn('ext_id', json)
+
+ session = Session.objects.get(ext_id=json['ext_id'])
+ self.assertIsNotNone(session)
+ user1_personal_group = Group.objects.get(profile__owner_personal=self.user1)
+ self.assertEqual(user1_personal_group, session.group)
+
+ def test_create_session_no_group_default(self):
+ url = reverse('notes:session-list')
+ self.client.login(username='test_user2', password='top_secret')
+ response = self.client.post(url, {
+ 'title': "a new session",
+ 'description': "description of the session",
+ 'protocol': "[]",
+ }, format='json')
+
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Error when creating session %r" % response.json())
+ json = response.json()
+ self.assertIn('ext_id', json)
+
+ session = Session.objects.get(ext_id=json['ext_id'])
+ self.assertIsNotNone(session)
+ self.assertEqual(self.group1, session.group)
+
+
+ def test_create_session_no_group_default(self):
+ url = reverse('notes:session-list')
+ self.client.login(username='test_user2', password='top_secret')
+ response = self.client.post(url, {
+ 'title': "a new session",
+ 'description': "description of the session",
+ 'protocol': "[]",
+ }, format='json')
+
+ self.assertEqual(response.status_code, status.HTTP_201_CREATED, "Error when creating session %r" % response.json())
+ json = response.json()
+ self.assertIn('ext_id', json)
+
+ session = Session.objects.get(ext_id=json['ext_id'])
+ self.assertIsNotNone(session)
+ self.assertEqual(self.group1, session.group)
+
+
+ def test_create_session_bad_group(self):
+ url = reverse('notes:session-list')
+ self.client.login(username='test_user3', password='top_secret')
+ response = self.client.post(url, {
+ 'title': "a new session",
+ 'description': "description of the session",
+ 'protocol': "[]",
+ 'group': "group1"
+ }, format='json')
+
+ self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
+ json = response.json()
+ self.assertIn('non_field_errors', json)
+ self.assertIn('Owner must be in group', json['non_field_errors'])
+
+
def test_create_session_with_ext_id(self):
url = reverse('notes:session-list')
self.client.login(username='test_user1', password='top_secret')
@@ -166,6 +257,7 @@
'ext_id': ext_id,
'title': "a new session",
'description': "description of the session",
+ 'group': 'group1',
'protocol': "[]"
}, format='json')
--- a/src/notes/tests/models/auth.py Sun Jul 30 01:02:09 2017 +0200
+++ b/src/notes/tests/models/auth.py Mon Jul 31 23:18:38 2017 +0200
@@ -20,6 +20,10 @@
email='test_user@emial.com',
password='top_secret'
)
+
+ group = Group(name='test_user2 group')
+ group.save()
+
self.user2 = User.objects.create_user(
username='test_user2',
email='test_user@emial.com',
@@ -32,3 +36,23 @@
self.assertIsNotNone(self.group)
self.assertIsNotNone(self.group.profile)
+ def test_create_personal_group(self):
+ self.assertIsNotNone(self.user1.profile)
+ self.assertIsNotNone(self.user2.profile)
+ default_group1 = self.user1.profile.default_group
+ self.assertIsNotNone(default_group1)
+ self.assertIsNotNone(default_group1.profile)
+ self.assertTrue(default_group1.profile.is_personal)
+ self.assertEqual(default_group1.profile.owner, self.user1)
+ self.assertEqual(default_group1.profile.owner_personal, self.user1)
+
+ def test_create_personal_group_new_name(self):
+ default_group2 = self.user2.profile.default_group
+ self.assertIsNotNone(default_group2)
+ self.assertEqual(default_group2.name, "test_user2 group 1")
+
+ def test_create_personal_group(self):
+ personal_group = Group.objects.get(profile__owner_personal=self.user1)
+ self.assertIsNotNone(personal_group)
+ self.assertIn(self.user1, personal_group.user_set.all())
+
--- a/src/requirements/dev.txt Sun Jul 30 01:02:09 2017 +0200
+++ b/src/requirements/dev.txt Mon Jul 31 23:18:38 2017 +0200
@@ -1,1 +1,3 @@
-r base.txt
+pylint-django
+pylint