src/notes/tests/api/sync.py
author ymh <ymh.work@gmail.com>
Fri, 30 Nov 2018 10:53:15 +0100
changeset 183 f8f3af9e5c83
parent 129 d48946d164c6
permissions -rw-r--r--
Change the settings to avoid using Session authentication for rest framework as it raise exceptions in case client and backend are on the same domain On the filter, adapt to take into account new version of django_filters

"""
Tests the sync api
"""
import datetime
import logging
import uuid

from django.contrib.auth import get_user_model
from django.contrib.contenttypes.models import ContentType
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 auditlog.models import LogEntry

logger = logging.getLogger(__name__)


class SyncApiTests(APITransactionTestCase):
    '''
    Test Sync api
    '''

    def setUp(self):
        User = get_user_model()
        user1 = User.objects.create_user(
            username='test_user1',
            email='test_user@emial.com',
            password='top_secret'
        )
        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.clientId = str(uuid.uuid4())

        url = reverse('notes:session-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.post(url, {
            'title': "a new session 1",
            'description': "Description 1",
            'protocol': "[]"
        }, format='json', HTTP_AUDITLOG_CLIENT=self.clientId)


        self.session1 = Session.objects.get(ext_id=response.json()['ext_id'])
        self.client.logout()

        self.client.login(username='test_user2', password='top_secret')
        response = self.client.post(url, {
            'title': "a new session 2",
            'description': "Description 2",
            'protocol': "[]"
        }, format='json')

        self.session2 = Session.objects.get(ext_id=response.json()['ext_id'])
        self.client.logout()

        self.client.login(username='test_user3', password='top_secret')
        response = self.client.post(url, {
            'title': "a new session 3",
            'description': "Description 3",
            'protocol': "[]"
        }, format='json')

        self.session3 = Session.objects.get(ext_id=response.json()['ext_id'])
        self.client.logout()

        self.client.login(username='test_user1', password='top_secret')

        url = reverse('notes:notes-session-list',
                      kwargs={'session_ext_id': self.session1.ext_id})

        response = self.client.post(url, {
            'tc_start': timezone.now(),
            'tc_end': timezone.now(),
            'plain': "example note 1",
            'html': "<i>example note 1</i>",
            'raw': "<i>example note 1</i>",
            'margin_note': "margin note 1",
            'categorization': "[]"
        }, format='json')

        self.note1 = Note.objects.get(ext_id=response.json()['ext_id'])

        response = self.client.post(url, {
            'tc_start': timezone.now(),
            'tc_end': timezone.now(),
            'plain': "example note 2",
            'html': "<i>example note 2</i>",
            'raw': "<i>example note 2</i>",
            'margin_note': "margin note 2",
            'categorization': "[]"
        }, format='json')

        self.note2 = Note.objects.get(ext_id=response.json()['ext_id'])
        self.client.logout()

        self.client.login(username='test_user2', password='top_secret')
        url = reverse('notes:notes-session-list',
                      kwargs={'session_ext_id': self.session2.ext_id})

        response = self.client.post(url, {
            'tc_start': timezone.now(),
            'tc_end': timezone.now(),
            'plain': "example note 3",
            'html': "<i>example note 3</i>",
            'raw': "<i>example note 3</i>",
            'margin_note': "margin note 3",
            'categorization': "[]"
        }, format='json')

        self.note3 = Note.objects.get(ext_id=response.json()['ext_id'])
        self.client.logout()

    def test_not_authenticated(self):
        url = reverse('notes:sync-list')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

    def test_simple(self):
        url = reverse('notes:sync-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

    def test_bad_method(self):
        url = reverse('notes:sync-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.post(url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_simple_output(self):
        url = reverse('notes:sync-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_resp = response.json()
        self.assertIn('sessions', json_resp)
        self.assertEqual(1, len(json_resp['sessions']))
        self.assertEqual('session', json_resp['sessions'][0]['type'])
        self.assertEqual(0, json_resp['sessions'][0]['action'])
        self.assertEqual(str(self.session1.ext_id), json_resp['sessions'][0]['ext_id'])

        self.assertIn('notes', json_resp)
        self.assertEqual(2, len(json_resp['notes']))
        for sync_def in json_resp['notes']:
            self.assertEqual('note', sync_def['type'])
            self.assertEqual(0, sync_def['action'])
            self.assertIn(sync_def['ext_id'], [str(self.note1.ext_id), str(self.note2.ext_id)])

    def test_simple_output_client_id(self):
        url = reverse('notes:sync-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, HTTP_AUDITLOG_CLIENT=self.clientId)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json_resp = response.json()
        self.assertIn('sessions', json_resp)
        self.assertEqual(0, len(json_resp['sessions']))

    def test_modified_since_empty(self):
        url = reverse('notes:sync-list')
        self.client.login(username='test_user1', password='top_secret')

        nexthour = \
            datetime.datetime.utcnow().replace(tzinfo=timezone.utc) +\
            datetime.timedelta(hours=1)

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

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json_resp = response.json()
        self.assertIn('sessions', json_resp)
        self.assertEqual(0, len(json_resp['sessions']))
        self.assertIn('notes', json_resp)
        self.assertEqual(0, len(json_resp['notes']))

    def test_modified_since_notes(self):
        url = reverse('notes:sync-list')
        self.client.login(username='test_user1', password='top_secret')

        nexthour = \
            datetime.datetime.utcnow().replace(tzinfo=timezone.utc) +\
            datetime.timedelta(hours=1)

        LogEntry.objects.filter(content_type=ContentType.objects.get_for_model(Note)).update(timestamp=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_resp = response.json()
        self.assertIn('sessions', json_resp)
        self.assertEqual(0, len(json_resp['sessions']))
        self.assertIn('notes', json_resp)
        self.assertEqual(2, len(json_resp['notes']))
        for sync_def in json_resp['notes']:
            self.assertEqual('note', sync_def['type'])
            self.assertEqual(0, sync_def['action'])
            self.assertIn(sync_def['ext_id'],[str(self.note1.ext_id), str(self.note2.ext_id)])


    def test_modified_since_single_update(self):
        self.client.login(username='test_user1', password='top_secret')
        url = reverse('notes:notes-session-detail',
                      kwargs={'session_ext_id': self.session1.ext_id, 'ext_id': self.note2.ext_id})

        self.client.put(url, {
            'plain': "example note 2 modified",
            'html': "<i>example note 2 modified</i>",
            'raw': "<i>example note 2 modified</i>",
            'margin_note': "margin note 2 modified",
            'categorization': "[]"
        }, format='json')

        url = reverse('notes:sync-list')

        nexthour = \
            datetime.datetime.utcnow().replace(tzinfo=timezone.utc) +\
            datetime.timedelta(hours=1)

        LogEntry.objects.filter(
            content_type=ContentType.objects.get_for_model(Note),
            object_pk=self.note2.id,
            action=LogEntry.Action.UPDATE
        ).update(timestamp=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_resp = response.json()
        self.assertIn('sessions', json_resp)
        self.assertEqual(0, len(json_resp['sessions']))
        self.assertIn('notes', json_resp)
        self.assertEqual(1, len(json_resp['notes']))
        sync_def = json_resp['notes'][0]
        self.assertEqual(LogEntry.Action.UPDATE, sync_def['action'])

    def test_note_delete(self):

        self.client.login(username='test_user1', password='top_secret')
        url = reverse('notes:notes-session-detail',
                      kwargs={'session_ext_id': self.session1.ext_id, 'ext_id': self.note2.ext_id})

        self.client.delete(url)
        self.client.logout()


        url = reverse('notes:sync-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_resp = response.json()
        self.assertIn('sessions', json_resp)
        self.assertEqual(1, len(json_resp['sessions']))
        self.assertEqual('session', json_resp['sessions'][0]['type'])
        self.assertEqual(0, json_resp['sessions'][0]['action'])
        self.assertEqual(str(self.session1.ext_id), json_resp['sessions'][0]['ext_id'])

        self.assertIn('notes', json_resp)
        self.assertEqual(1, len(json_resp['notes']))
        sync_def = json_resp['notes'][0]
        self.assertEqual('note', sync_def['type'])
        self.assertEqual(0, sync_def['action'])
        self.assertEqual(sync_def['ext_id'],str(self.note1.ext_id))

    def test_note_delete_modified(self):

        self.client.login(username='test_user1', password='top_secret')
        url = reverse('notes:notes-session-detail',
                      kwargs={'session_ext_id': self.session1.ext_id, 'ext_id': self.note2.ext_id})

        self.client.delete(url)
        self.client.logout()


        nexthour = \
            datetime.datetime.utcnow().replace(tzinfo=timezone.utc) +\
            datetime.timedelta(hours=1)

        LogEntry.objects.filter(
            content_type=ContentType.objects.get_for_model(Note),
            object_pk=self.note2.id,
            action=LogEntry.Action.DELETE
        ).update(timestamp=nexthour)

        url = reverse('notes:sync-list')
        self.client.login(username='test_user1', password='top_secret')
        response = self.client.get(url, {'modified_since': (nexthour-datetime.timedelta(minutes=30)).timestamp()})
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        json_resp = response.json()
        self.assertIn('sessions', json_resp)
        self.assertEqual(0, len(json_resp['sessions']))

        self.assertIn('notes', json_resp)
        self.assertEqual(1, len(json_resp['notes']))
        sync_def = json_resp['notes'][0]
        self.assertEqual('note', sync_def['type'])
        self.assertEqual(2, sync_def['action'])
        self.assertEqual(sync_def['ext_id'],str(self.note2.ext_id))