src/notes/tests/api/session.py
author ymh <ymh.work@gmail.com>
Mon, 08 Oct 2018 18:35:47 +0200
changeset 168 ea92f4fe783d
parent 142 56850f5c73f6
permissions -rw-r--r--
- move SlateEditor and dependencies to its own folder - remove Immutable - remove redux-persist-immutable - remobe redux-immutable - update libraries - added tests on store manipulations (accessor and reducers)

"""
Tests the core api for sessions
"""
import datetime
import logging
from unittest import skip
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 import constants
from notes.models import GroupProfile, Note, Session

logger = logging.getLogger(__name__)

class SessionApiTests(APITransactionTestCase):

    def setUp(self):
        User = get_user_model()
        self.user1 = User.objects.create_user(
            username='test_user1',
            email='test_user@emial.com',
            password='top_secret'
        )
        self.user2 = User.objects.create_user(
            username='test_user2',
            email='test_user@emial.com',
            password='top_secret'
        )
        user3 = User.objects.create_user(
            username='test_user3',
            email='test_user@emial.com',
            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",
            group=self.user1.profile.default_group,
            owner=self.user1
        )

        self.session2 = Session.objects.create(
            title="a new session 2",
            description="Description 2",
            group=self.user2.profile.default_group,
            owner=self.user2
        )

        self.session3 = Session.objects.create(
            title="a new session 3",
            description="Description 3",
            group=user3.profile.default_group,
            owner=user3
        )

        self.session4 = Session.objects.create(
            title="a new session 4",
            description="Description 4",
            group=user3.profile.default_group,
            owner=user3
        )

        Note.objects.create(
            tc_start=timezone.now(),
            tc_end=timezone.now(),
            session=self.session1,
            plain="example note 1",
            html="<i>example note 1</i>",
            raw="<i>example note 1</i>",
            margin_note="margin note 1",
            categorization="[]"
        )

        Note.objects.create(
            tc_start=timezone.now(),
            tc_end=timezone.now(),
            session=self.session2,
            plain="example note 2",
            html="<i>example note</i>",
            raw="<i>example note</i>",
            margin_note="margin note",
            categorization="[]"
        )


    def test_list_session_no_user(self):
        url = reverse('notes:session-list')
        response = self.client.post(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)


    def test_list_session(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json = response.json()
        self.assertIn('results', json, "must have results")
        self.assertIn('count', json, "must have count")
        self.assertEqual(json['count'], 1, "must have one session")
        self.assertEqual(len(json['results']), 1, "must have one session")

        for session in json['results']:
            self.assertEqual(session['owner'], 'test_user1')


    def test_list_session_filter(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, {"ext_id__in": ",".join([str(self.session1.ext_id)])})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json = response.json()
        self.assertIn('results', json, "must have results")
        self.assertIn('count', json, "must have count")
        self.assertEqual(json['count'], 1, "must have one session")
        self.assertEqual(len(json['results']), 1, "must have one session")

        for session in json['results']:
            self.assertEqual(session['owner'], 'test_user1')


    def test_list_session_filter_bad(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, {"ext_id__in": ",".join([str(uuid4())])})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json = response.json()
        self.assertIn('results', json, "must have results")
        self.assertIn('count', json, "must have count")
        self.assertEqual(json['count'], 0, "must have no session")
        self.assertEqual(len(json['results']), 0, "must have no session")

    def test_create_session_no_user(self):
        url = reverse('notes:session-list')
        response = self.client.post(url, {
            'title': "a new session",
            'description': "description of the session",
            'protocol': "[]"
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)


    def test_create_session(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",
            'group': 'group1'
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_201_CREATED, "error msg: %r" % response.content)
        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)
        self.assertEqual(self.group1.profile.protocol, session.protocol)


    def test_create_session_protocol(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",
            'group': 'group1',
            'protocol': {}
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_201_CREATED, 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)
        self.assertNotEqual(self.group1.profile.protocol, session.protocol)


    def test_create_session_protocol_as_str(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        group1 = Group.objects.get(id=self.group1.id)
        response = self.client.post(url, {
            'title': "a new session",
            'description': "description of the session",
            'group': 'group1',
            'protocol': group1.profile.protocol
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_201_CREATED, 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)
        self.assertEqual(self.group1.profile.protocol, session.protocol)


    def test_create_session_protocol_as_str_unknown(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        group1 = Group.objects.get(id=self.group1.id)
        response = self.client.post(url, {
            'title': "a new session",
            'description': "description of the session",
            'group': 'group1',
            'protocol': constants.PROTOCOL_URN_PREFIX + str(uuid4()) + ".1"
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.json())
        json = response.json()
        self.assertIn('protocol', json)
        self.assertIn('Incorrect protocol', json['protocol'][0])
        self.assertIn('does not exists', json['protocol'][0])


    def test_create_session_protocol_as_str_bad(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        group1 = Group.objects.get(id=self.group1.id)
        response = self.client.post(url, {
            'title': "a new session",
            'description': "description of the session",
            'group': 'group1',
            'protocol': constants.PROTOCOL_URN_PREFIX + "foo"
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.json())
        json = response.json()
        self.assertIn('protocol', json)
        self.assertEqual('Incorrect format. Expected `urn:protocol:<ext_id>.<version>`.', json['protocol'][0])


    def test_create_session_protocol_as_other_type_bad(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        group1 = Group.objects.get(id=self.group1.id)
        response = self.client.post(url, {
            'title': "a new session",
            'description': "description of the session",
            'group': 'group1',
            'protocol': True
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST, response.json())
        json = response.json()
        self.assertIn('protocol', json)
        self.assertEqual('Incorrect format. Expected `urn:protocol:<ext_id>.<version>` or dict.', json['protocol'][0])


    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"
        }, 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)
        self.assertEqual(user1_personal_group.profile.protocol, session.protocol)

    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"
        }, 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': { 'owner': 'group1' },
            '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')
        ext_id = str(uuid4())
        response = self.client.post(url, {
            'ext_id': ext_id,
            'title': "a new session",
            'description': "description of the session",
            'group': 'group1'
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_201_CREATED, "response content: %r" % response.content)
        json = response.json()
        self.assertIn('ext_id', json)
        self.assertEqual(json['ext_id'], ext_id)


    def test_detail_session(self):
        url = reverse('notes:session-detail', kwargs={'ext_id':str(self.session1.ext_id)})
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_list_notes(self):
        url = reverse('notes:notes-session-list', kwargs={'session_ext_id':str(self.session1.ext_id)})
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_detail_session_bad(self):
        url = reverse('notes:session-detail', kwargs={'ext_id':str(self.session2.ext_id)})
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

    def test_list_notes_bad(self):
        url = reverse('notes:notes-session-list', kwargs={'session_ext_id':str(self.session2.ext_id)})
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, format='json')
        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

    def test_filter_modified_since(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user3', password='top_secret')
        nexthour = \
            datetime.datetime.utcnow().replace(tzinfo=timezone.utc) +\
            datetime.timedelta(hours=1)
        Session.objects.filter(pk=self.session4.id).update(updated=nexthour)

        response = self.client.get(
            url,
            {'modified_since': (nexthour - datetime.timedelta(minutes=30)).timestamp()},
            format='json'
        )

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json = response.json()
        self.assertIn('results', json, "must have results")
        self.assertIn('count', json, "must have count")
        self.assertEqual(json['count'], 1, "must have one session")
        self.assertEqual(len(json['results']), 1, "must have one session")

        self.assertEqual(json['results'][0].get('title'), "a new session 4")


    def test_filter_modified_since_zero(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user3', password='top_secret')

        response = self.client.get(url, {'modified_since': 0}, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json = response.json()
        self.assertIn('results', json, "must have results")
        self.assertIn('count', json, "must have count")
        self.assertEqual(json['count'], 2, "must have two sessions")
        self.assertEqual(len(json['results']), 2, "must have two sessions")

        for session_json in json['results']:
            self.assertIn(session_json.get('title'), ['a new session 3', 'a new session 4'])


    def test_filter_modified_seconds(self):
        url = reverse('notes:session-list')
        self.client.login(username='test_user3', password='top_secret')

        prevmoment = \
            datetime.datetime.utcnow().replace(tzinfo=timezone.utc) -\
            datetime.timedelta(seconds=5)

        response = self.client.get(url, {'modified_since': prevmoment.timestamp()}, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json = response.json()
        self.assertIn('results', json, "must have results")
        self.assertIn('count', json, "must have count")
        self.assertEqual(json['count'], 2, "must have two sessions")
        self.assertEqual(len(json['results']), 2, "must have two sessions")
        for session_json in json['results']:
            self.assertIn(session_json.get('title'), ['a new session 3', 'a new session 4'])

    def test_update_session(self):
        url = reverse('notes:session-detail', kwargs={'ext_id': self.session1.ext_id})

        self.client.login(username='test_user1', password='top_secret')
        response = self.client.put(url, {
            'title': "a new session",
            'description': "description of the session",
            'group': 'group1'
        }, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK, "response content: %r" % response.content)
        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)
        self.assertEqual(self.group1.profile.protocol, session.protocol)

    @skip("Protocol update not yet implemented")
    def test_update_session_protocol(self):
        url = reverse('notes:session-detail', kwargs={'ext_id': self.session1.ext_id})

        self.client.login(username='test_user1', password='top_secret')
        response = self.client.put(url, {
            'title': "an updated session",
            'description': "description of the session",
            'group': 'group1',
            'protocol': "urn:protocol:845ac623-b85a-4ddd-91ee-a2deb1a9b54f.3"
        }, format='json')

        json = response.json()
        # self.assertIn('ext_id', json)
        session = Session.objects.get(ext_id=self.session1.ext_id)
        self.assertEqual(response.status_code, status.HTTP_200_OK, "response content: %r" % response.content)


        # session = Session.objects.get(ext_id=json['ext_id'])
        # self.assertIsNotNone(session)
        # self.assertEqual(self.group1, session.group)
        # self.assertEqual(self.group1.profile.protocol, session.protocol)