#encoding:UTF-8

""" Run these tests with 'python manage.py test text'  """

from django.conf import settings
from django.contrib.auth.models import *
from django.db import transaction
from django.test import TestCase
from ldt.core.models import Owner
from ldt.test.testcases import *
from ldt.text import VERSION_STR
from ldt.text.models import *
from ldt.text.views import *
import datetime
import lxml.etree
import time
import unittest
import urllib
import uuid
from oauth_provider.models import Resource, Consumer


CONSUMER_KEY = 'dpf43f3p2l4k3l03'
CONSUMER_SECRET = 'kd94hf93k423kf44'


# This test creates an annotation and checks that:
# 1. the annotation was created in the database (by trying to access it through a Django object)
# 2. the returned xml contains correct data
class CreateTest(OAuthTestCase):
    
    fixtures = ['base_data','oauth_data']
     
    def setUp(self):
        
        self.id = 'f2c1d1fa-629d-4520-a3d2-955b4f2582c0'
        self.text = "texte selectionne lors de la creation de l\'annotation"
        self.content = str('<iri><text-annotation><id>'+self.id+'</id><uri>http://www.leezam.com/pub/epub/123456!/OPS/chapter2.xhtml#pos=56,168</uri><tags><tag>tag1</tag><tag>tag2</tag></tags><content><color>#AAAAAA</color><description><![CDATA[texte de description]]></description><title><![CDATA[titre de l\'annotation]]></title><text>'+self.text+'</text></content><meta><contributor>oaubert</contributor><contributor-id>79cd0532-1dda-4130-b351-6a181130a7c9</contributor-id><created>2010-09-06 12:33:53.417550</created><creator>oaubert</creator><creator-id>79cd0532-1dda-4130-b351-6a181130a7c9</creator-id><modified>2010-09-06 12:33:53.420459</modified></meta></text-annotation></iri>')
        self.error_content = '<iri><text-annotation><id>z2c1d1fa-629d-4520-a3d2-955b4f2582c0</id><uri>http://www.leezam.com/pub/epub/123456!/OPS/chapter2.xhtml#pos=56,168</uri><tags><tag>tag1</tag><tag>tag2</tag></tags><content><color>#AAAAAA</color><description><![CDATA[texte de description]]></description><title><![CDATA[titre de l\'annotation]]></title><text><![CDATA[texte selectionne lors de la creation de l\'annotation]]></text></content><meta><contributor>oaubert</contributor><contributor-id>79cd0532-1dda-4130-b351-6a181130a7c9</contributor-id><created>2010-09-06 12:33:53.417550</created><creator>oaubert</creator><creator-id>79cd0532-1dda-4130-b351-6a181130a7c9</creator-id><modified>2010-09-06 12:33:53.420459</modified></meta></text-annotation></iri>' 
        
        self.set_consumer(CONSUMER_KEY, CONSUMER_SECRET)
        self.client.login(username='jane', password='toto')
        
    def test_create_annotation(self):
        
        response = self.client.post('/api/'+ VERSION_STR +'/text/create/', {'content':self.content})
        self.assertEqual(response.status_code,200)
        annot1 = lxml.etree.fromstring(response.content)
        self.assertEqual(annot1.xpath("/iri/text-annotation/id/text()")[0],self.id)
        self.assertEqual(annot1.xpath("/iri/text-annotation/content/text/text()")[0],self.text)
        self.assertEqual(len(annot1.xpath("/iri/text-annotation/tags/tag")),2)
        self.assertEqual(annot1.xpath("/iri/text-annotation/meta/created/text()")[0][:11], str(datetime.datetime.now())[:11])
        
        annot2 = Annotation.objects.get(external_id=self.id)
        self.assertEqual(annot2.text,self.text)
        self.assertEqual(len(annot2.tags.split(",")),2)
        self.assertEqual(str(annot2.creation_date)[:11], str(datetime.datetime.now())[:11])
        
    def test_error_create(self):
        
        response = self.client.post('/api/'+ VERSION_STR +'/text/create/', {'content':self.error_content})
        self.assertEqual(response.status_code, 409)


# This test creates an annotation, then gets it, and checks that the returned xml contains correct data
class GetTest(TestCase):
    
    fixtures = ['base_data']
    
    def setUp(self):
        
        self.id = 'z2c1d1fa-629d-4520-a3d2-955b4f2582c0'
        self.color = '#DDDDDD'
        self.creation_date = '2010-11-16 17:01:41'
        self.title = "titre de l'annotation"
   
    def test_get_annotation(self):
        
        response = self.client.get('http://127.0.0.1:8000/api/'+ VERSION_STR +'/text/get/'+self.id+'')
        self.assertEqual(response.status_code,200)
        annot1 = lxml.etree.fromstring(response.content)
        self.assertEqual(annot1.xpath("/iri/text-annotation/id/text()")[0],self.id)
        self.assertTrue('tag3','tag1' in annot1.xpath("/iri/text-annotation/tags/tag/text()"))
        self.assertTrue('mytag','tag2new' in annot1.xpath("/iri/text-annotation/tags/tag/text()"))
        self.assertEqual(annot1.xpath("/iri/text-annotation/content/color/text()")[0],self.color)
        self.assertEqual(annot1.xpath("/iri/text-annotation/content/title/text()")[0],self.title)
        self.assertEqual(annot1.xpath("/iri/text-annotation/meta/created/text()")[0], self.creation_date)

    def test_error_get(self):
        
        response = self.client.get('http://127.0.0.1:8000/api/'+ VERSION_STR +'/text/get/2')
        self.assertEqual(response.status_code,404)
        
        
class FilterTest(TestCase):
    
    fixtures = ['filter_data']
    
    def setUp(self):
        
        self.user = 'wakimd'
        self.uri = "http://www.leezam.com/pub/epub/123456!/OPS/chapter2.xhtml#pos=56,168"
        self.limit = "2,1"
        self.filter = 'lors'
        
    def test_filter_all(self):
        
        response = self.client.get('/api/'+ VERSION_STR +'/text/filter/', {'uri':self.uri,'creator':self.user,'limit':"1,1", 'filter':self.filter})
        self.assertEqual(response.status_code,200)
        doc = lxml.etree.fromstring(response.content)
        self.assertEqual(len(doc.xpath("/iri/text-annotation")),1)
        for elem in doc.xpath("/iri/text-annotation/meta/creator/text()"):
            self.assertEqual(elem,self.user)
        for elem in doc.xpath("/iri/text-annotation/uri/text()"):
            self.assertEqual(elem,self.uri)
        for elem in doc.xpath("/iri/text-annotation/content/text/text()"):
            self.assertTrue(self.filter in elem) 
          
    def test_filter_creator_limit(self):
        
        response = self.client.get('/api/'+ VERSION_STR +'/text/filter/', {'creator':self.user,'limit':self.limit})
        self.assertEqual(response.status_code,200)
        doc = lxml.etree.fromstring(response.content)
        if self.limit is not None:
            self.assertEqual(str(len(doc.xpath("/iri/text-annotation"))),self.limit[0])
        for elem in doc.xpath("/iri/text-annotation/meta/creator/text()"):
            self.assertEqual(elem,self.user)
        
    def test_filter_uri(self):
        
        response = self.client.get('/api/'+ VERSION_STR +'/text/filter/', {'uri':self.uri})
        self.assertEqual(response.status_code,200)
        doc = lxml.etree.fromstring(response.content)
        for elem in doc.xpath("/iri/text-annotation/uri/text()"):
            self.assertEqual(elem,self.uri)
            
    def test_filter_annotation_filter(self):
        
        response = self.client.get('/api/'+ VERSION_STR +'/text/filter/', {'uri':self.uri,'filter':self.filter})
        self.assertEqual(response.status_code,200)
        doc = lxml.etree.fromstring(response.content)
        for elem in doc.xpath("/iri/text-annotation/content/text/text()"):
            self.assertTrue(self.filter in elem)  
        for elem in doc.xpath("/iri/text-annotation/uri/text()"):
            self.assertEqual(elem,self.uri)

    def test_filter_none(self):
        
        response = self.client.get('/api/'+ VERSION_STR +'/text/filter/', {'uri':'uri','creator':'creator','filter':'filter'})
        self.assertEqual(response.status_code,200)
        self.assertEqual(response.content, '<iri/>\n')
        

        
# This test deletes an annotation, and checks that:
# 1. the annotation doesn't exist anymore in the database (by trying to access it through Django objects)
# 2. the returned xml contains an empty string
class DeleteTest(OAuthTestCase):
    
    fixtures = ['base_data','oauth_data']
    
    def setUp(self):
               
        self.id = 'z2c1d1fa-629d-4520-a3d2-955b4f2582c0'
        
        self.set_consumer(CONSUMER_KEY, CONSUMER_SECRET)
        self.client.login(username='jane', password='toto')
        
    def test_delete_annotation(self):
        
        response = self.client.delete('/api/'+ VERSION_STR +'/text/delete/'+self.id+'')
        self.assertEqual(response.content, "")
        self.assertEqual(response.status_code,200)
        
        self.assertRaises(Annotation.DoesNotExist, Annotation.objects.get, external_id=self.id)
        
    def test_error_delete(self):
        
        response = self.client.delete('/api/'+ VERSION_STR +'/text/ldt/delete/1')
        self.assertEqual(response.status_code,404)
        

# This test creates an annotation, then updates it with new content, and checks that the returned xml contains the updated data
class UpdateTest(OAuthTestCase):
    
    fixtures = ['oauth_data','base_data']
    
    def setUp(self):
        
        self.id = 'z2c1d1fa-629d-4520-a3d2-955b4f2582c0'
        self.color = '#DDDDDD'
        self.description = "texte de description update"
        self.text = "texte selectionne a nouveau lors de la creation de l\'annotation"
        self.contributor = "oaubert"
        self.content = '<iri><text-annotation><id></id><uri></uri><tags><tag>tag2new</tag><tag>mytag</tag></tags><content><color>'+self.color+'</color><description>'+self.description+'</description><title></title><text>'+self.text+'</text></content><meta><contributor>'+self.contributor+'</contributor><contributor-id>80cd0532-1dda-4130-b351-6a181130a7c9</contributor-id><created></created><creator></creator><creator-id></creator-id><modified>2010-11-06 12:33:53.420459</modified></meta></text-annotation></iri>'
        
        self.set_consumer(CONSUMER_KEY, CONSUMER_SECRET)
        self.client.login(username='jane', password='toto')
        
    def test_update_annotation(self):
        
        response = self.client.put('/api/'+ VERSION_STR +'/text/update/'+self.id+'', {'content':self.content})        
        self.assertEqual(response.status_code,200)     
        annot = Annotation.objects.get(external_id=self.id)
        self.assertEqual(str(annot.update_date)[:11],str(datetime.datetime.now())[:11])
        self.assertEqual(annot.external_id,self.id)
        self.assertTrue('tag3','tag1' not in annot.tags)
        self.assertTrue('mytag','tag2new' in annot.tags)
        self.assertEqual(annot.color,self.color)
        self.assertEqual(annot.description,self.description)
        self.assertEqual(annot.text,self.text)
        self.assertEqual(annot.contributor,self.contributor)
        
    def test_error_update(self):
        
        response = self.client.put('/api/'+ VERSION_STR +'/text/update/1', {'content':self.content})
        self.assertEqual(response.status_code,404)
