]> git.parisson.com Git - telemeta.git/commitdiff
Setup a basic unit tests framework
authorThomas Fillon <thomas@parisson.com>
Tue, 4 Jul 2017 12:15:21 +0000 (14:15 +0200)
committerThomas Fillon <thomas@parisson.com>
Tue, 4 Jul 2017 12:15:21 +0000 (14:15 +0200)
Fix #181

.travis.yml
app/pytest.ini [new file with mode: 0644]
app/settings.py
pytest.ini [deleted file]
requirements.txt
telemeta/models/fields.py
telemeta/tests/instrument_factories.py [deleted file]
telemeta/tests/model_tests.py [deleted file]
telemeta/tests/settings_sqlite.py
telemeta/tests/test_models.py [new file with mode: 0644]

index c88814cef94d426f6848764823d2b774a48a6ca4..40de291f605ee2135194bd4e4542d3d31db2a35c 100644 (file)
@@ -18,6 +18,7 @@ install:
   - docker-compose build
 
 script:
+  - docker-compose run app pytest /srv/src/telemeta
   - docker-compose up -d
   - sleep 60
   - curl --fail --retry 10 --retry-delay 5  -v $(docker-compose port nginx 80)
diff --git a/app/pytest.ini b/app/pytest.ini
new file mode 100644 (file)
index 0000000..b776a95
--- /dev/null
@@ -0,0 +1,2 @@
+[pytest]
+DJANGO_SETTINGS_MODULE=telemeta.tests.settings_sqlite
index d7f3035566ed8102bd711fd871f406f2a8a0b57d..1540791e03ef782ef735e3c29f361283624376f3 100644 (file)
@@ -35,10 +35,11 @@ DATABASES = {
         'PASSWORD': env('MYSQL_PASSWORD'),  # Not used with sqlite3.
         'NAME': env('MYSQL_DATABASE'),
         'HOST': 'db',      # Set to empty string for localhost. Not used with sqlite3.
-        'PORT': '3306',      # Set to empty string for default. Not used with sqlite3.
+        'PORT': '3306',    # Set to empty string for default. Not used with sqlite3.
     }
 }
-
+if 'test' in sys.argv:
+    DATABASES['default']['ENGINE'] = 'django.db.backends.sqlite3'
 # Local time zone for this installation. Choices can be found here:
 # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
 # although not all choices may be available on all operating systems.
diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644 (file)
index 43eff23..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-[pytest]
-DJANGO_SETTINGS_MODULE=telemeta.tests.settings_sqlite
\ No newline at end of file
index 04fef4d29d7aafabf49605adfa50ddb458e7b97e..73d8c67af2ac4e3953d9dfa33201376f57eab0fe 100644 (file)
@@ -3,3 +3,7 @@
 setuptools
 wheel
 -e .
+# Tests
+pytest-django==2.9
+pytest-cov
+factory-boy
index 72d7bf1928bb8d4ed6bdbdb30c20ff84a3544f1b..452ff89cb5241df0af1bf81fe016e7d49675195f 100644 (file)
@@ -140,7 +140,7 @@ class DurationField(models.Field):
     def __init__(self, *args, **kwargs):
         super(DurationField, self).__init__(*args, **normalize_field(kwargs, '0'))
 
-    def db_type(self):
+    def db_type(self, connection):
         return 'int'
 
     def to_python(self, value):
diff --git a/telemeta/tests/instrument_factories.py b/telemeta/tests/instrument_factories.py
deleted file mode 100644 (file)
index 54214cd..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-# -*- coding: utf-8 -*-
-"""
-Factories for the telemeta.models.instrument
-
-"""
-import factory
-
-from telemeta.models.instrument import Instrument
-
-
-class InstrumentFactory(factory.django.DjangoModelFactory):
-    class Meta:
-        model = Instrument
-
-    name = factory.Sequence(lambda n: 'name{0}'.format(n))
diff --git a/telemeta/tests/model_tests.py b/telemeta/tests/model_tests.py
deleted file mode 100644 (file)
index dfbd180..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-# -*- coding: utf-8 -*-
-# Copyright (C) 2007-2010 Samalyse SARL
-
-# This file is part of Telemeta.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU Affero General Public License for more details.
-
-# You should have received a copy of the GNU Affero General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Authors: Olivier Guilyardi <olivier@samalyse.com>
-#          David LIPSZYC <davidlipszyc@gmail.com>
-
-from django.contrib.auth.models import User
-import unittest
-from telemeta.models import LocationType, Location, EthnicGroup, Publisher
-from telemeta.models import MediaCollection, MediaItem
-from datetime import datetime, timedelta
-import pytest
-
-pytestmark = pytest.mark.django_db
-
-
-@pytest.mark.django_db
-class CollectionItemTestCase(unittest.TestCase):
-    pytestmark = pytest.mark.django_db
-
-    def setUp(self):
-        "Create a test database based on objects created in Django"
-
-#        self.david   = User.objects.create(username="david", level="user")
-#        self.olivier = User.objects.create(username="olivier", level="admin")
-        self.david   = User.objects.create_user(username="david")
-        self.olivier = User.objects.create_user(username="olivier")
-
-        self.country = LocationType.objects.create(code="country", name="Country")
-        self.continent = LocationType.objects.create(code="continent", name="Continent")
-        self.city = LocationType.objects.create(code="city", name="City")
-
-        self.paris = Location.objects.create(name="Paris", type=Location.OTHER_TYPE, complete_type=self.city)
-        self.france = Location.objects.create(name="France", type=Location.COUNTRY, complete_type=self.country)
-        self.europe = Location.objects.create(name="Europe", type=Location.CONTINENT, complete_type=self.continent)
-        self.belgique = Location.objects.create(name="Belgique", type=Location.COUNTRY, complete_type=self.country)
-
-        self.europe.add_child(self.france)
-        self.france.add_child(self.paris)
-        self.europe.add_child(self.belgique)
-
-        self.a = EthnicGroup.objects.create(value="a")
-        self.b = EthnicGroup.objects.create(value="b")
-        self.c = EthnicGroup.objects.create(value="c")
-        self.d = EthnicGroup.objects.create(value="d")
-
-        self.persepolis = MediaCollection(id=1, code="CNRSMH_E_1970_001_002", reference="A1", title="persepolis",
-            creator="Abraham LINCOLN", collector="Friedrich HEINZ", year_published=2009, is_published=True,
-            recorded_from_year=1970, recorded_to_year=1980)
-
-        self.persepolis.set_revision(self.david)
-
-        self.volonte = MediaCollection(id=2, reference="A2",  code="CNRSMH_I_1960_001", title="Volonté de puissance",
-            creator="Friedrich NIETZSCHE", collector="Jean AMORA", year_published=1999,
-            recorded_from_year=1960, recorded_to_year=2000)
-
-        self.volonte.set_revision(self.olivier)
-
-        self.nicolas = MediaCollection(id=3, reference="A3",  code="CNRSMH_I_1967_123", title="petit nicolas",
-            creator="Georgette McKenic", collector="Paul MAILLE",  year_published=1999,
-            recorded_from_year=1967, recorded_to_year=1968)
-
-        self.nicolas.set_revision(self.olivier)
-
-        self.item_1 = MediaItem(id=1, collection=self.persepolis, code="CNRSMH_E_1970_001_002_44",
-            recorded_from_date="1971-01-12", recorded_to_date="1971-02-24", location=self.paris,
-            ethnic_group=self.a, title="item 1", author="Mickael SHEPHERD", collector="Charles PREMIER",
-            comment="comment 1")
-
-        self.item_1.set_revision(self.david)
-
-        self.item_2 = MediaItem(id=2, collection=self.volonte, code="CNRSMH_I_1960_001_129",
-            recorded_from_date="1981-01-12", recorded_to_date="1991-02-24", location=self.france,
-            ethnic_group=self.a, title="item 2", author="Rick ROLL", comment="comment 2")
-
-        self.item_2.set_revision(self.david)
-
-        self.item_3 = MediaItem(id=3, collection=self.nicolas, code="CNRSMH_I_1967_123_456_01",
-            recorded_from_date="1968-01-12", recorded_to_date="1968-02-24", location=self.belgique,
-            ethnic_group=self.b, title="item 3", author="John SMITH", collector="Paul CARLOS",
-            comment="comment 3",  )
-
-        self.item_3.set_revision(self.olivier)
-
-        self.item_4 = MediaItem(id=4, collection=self.persepolis, code="CNRSMH_E_1970_001_002_22_33",
-            recorded_from_date="1972-01-12", recorded_to_date="1972-02-24", location=self.europe,
-            ethnic_group=self.a, title="item 4", alt_title="I4", author="Keanu REAVES",
-            collector="Christina BARCELONA", comment="comment 4")
-
-        self.item_4.set_revision(self.olivier)
-
-        self.item_5 = MediaItem(id=5, collection=self.volonte,code="CNRSMH_I_1960_001_789_85_22",
-            approx_duration="00:05:00", recorded_from_date="1978-01-12", recorded_to_date="1978-02-24",
-            location=self.belgique, ethnic_group=self.a, title="item 5", alt_title="I5",
-            author="Simon PAUL", collector="Javier BARDEM",
-            comment="comment 5")
-
-        self.item_5.set_revision(self.olivier)
-
-        self.item_6 = MediaItem(id=6, collection=self.persepolis, code="CNRSMH_E_1970_001_002_90",
-            recorded_from_date="1968-01-12", recorded_to_date="1968-02-11", location=self.france,
-            ethnic_group=self.b, title="item 6", author="Paul ANDERSON",
-            collector="Jim CARLSON", comment="comment 10000")
-
-        self.item_6.set_revision(self.david)
-
-        self.collections = MediaCollection.objects.all()
-        self.items       = MediaItem.objects.all()
-
-    def tearDown(self):
-        User.objects.all().delete()
-        LocationType.objects.all().delete()
-        Location.objects.all().delete()
-        EthnicGroup.objects.all().delete()
-        MediaCollection.objects.all().delete()
-        MediaItem.objects.all().delete()
-
-    def testQuickSearchOnCollections(self):
-        "Test quick_search property of MediaCollection class"
-        result = self.collections.quick_search("persepolis")
-        self.assertEquals(len(result), 1)
-        self.assertEquals(result[0], self.persepolis)
-        self.assertEquals(self.collections.quick_search("nietzsche")[0], self.volonte)
-        result = self.collections.quick_search("nicolas")
-        self.assertEquals(result[0], self.nicolas)
-
-    def testQuickSearchOnItems(self):
-        "Test quick_search property of MediaItem class"
-        result = self.items.quick_search("item").order_by("title")
-        self.assertEquals(result[0], self.item_1)
-        self.assertEquals(result[1], self.item_2)
-        self.assertEquals(result[2], self.item_3)
-        self.assertEquals(result[3], self.item_4)
-        self.assertEquals(result[4], self.item_5)
-        self.assertEquals(result[5], self.item_6)
-
-    def testWordSearch(self):
-        "Test quick_search property of MediaCollection class, specificly quick_search on collection title"
-        result = self.collections.quick_search("volonté puissance")
-        self.assertEquals(result[0], self.volonte)
-        result = self.collections.quick_search("puissance volonté")
-        self.assertEquals(result[0], self.volonte)
-        result = self.collections.quick_search("volonte puissance")
-        self.assertEquals(result[0], self.volonte)
-        result = self.collections.quick_search("puissance volonte")
-        self.assertEquals(result[0], self.volonte)
-
-    def testLocationSearch(self):
-        "Test by_country and by_continent properties of MediaCollection class"
-        self.assertEquals(self.collections.by_location(self.france)[0], self.persepolis)
-        self.assertEquals(self.collections.by_location(self.europe)[0], self.persepolis)
-        self.assertEquals(self.collections.by_location(self.belgique).order_by("title")[0], self.nicolas)
-        self.assertEquals(self.collections.by_location(self.belgique).order_by("title")[1], self.volonte)
-
-    def testRecordingYear(self):
-        "Test by_recording_year property of MediaCollection class"
-        self.assertEquals(self.collections.by_recording_year(1970, 1980)[0], self.persepolis)
-        result = self.collections.by_recording_year(1975).order_by("title")
-        self.assertEquals(result[0], self.persepolis)
-        self.assertEquals(result[1], self.volonte)
-
-    def testPublishYearOnCollection(self):
-        "Test by_publish_year property of MediaCollection class"
-        result=self.collections.by_publish_year(1999).order_by("title")
-        self.assertEquals(result[0], self.nicolas)
-        self.assertEquals(result[1], self.volonte)
-
-    def testEthnicGroup(self):
-        "Test by_ethnic_group property of MediaCollection class"
-        result=self.collections.by_ethnic_group(self.a).order_by("title")
-        self.assertEquals(result[0], self.persepolis)
-        self.assertEquals(result[1], self.volonte)
-
-    def testRecordingDate(self):
-        "Test by_recording_date property of MediaItem class"
-        result = self.items.by_recording_date("1968-01-01", "1972-12-12").order_by("title")
-        self.assertEquals(result[0], self.item_1)
-        self.assertEquals(result[1], self.item_3)
-        self.assertEquals(result[2], self.item_4)
-        self.assertEquals(result[3], self.item_6)
-        result = self.items.by_recording_date("1968-02-06").order_by("title")
-        self.assertEquals(result[0], self.item_3)
-        self.assertEquals(result[1], self.item_6)
-
-    def testTitle(self):
-        "Test by_title property of MediaItem class"
-        result = self.items.by_title("item").order_by("title")
-        self.assertEquals(result[0], self.item_1)
-        self.assertEquals(result[1], self.item_2)
-        self.assertEquals(result[2], self.item_3)
-        self.assertEquals(result[3], self.item_4)
-        self.assertEquals(result[4], self.item_5)
-        self.assertEquals(result[5], self.item_6)
-        self.item_2.title = ''
-        self.item_2.save()
-        self.item_5.title = ''
-        self.item_5.save()
-        result = self.items.by_title("volonté").order_by("title")
-        self.assertEquals(result[0], self.item_2)
-        self.assertEquals(result[1], self.item_5)
-        result = self.items.by_title("puissance volonté").order_by("title")
-        self.assertEquals(result[0], self.item_2)
-        self.assertEquals(result[1], self.item_5)
-
-    def testPublishYearOnItem(self):
-        "Test by_publish_year property of MediaItem class"
-        result = self.items.by_publish_year(1999).order_by("title")
-        self.assertEquals(result[0], self.item_2)
-        self.assertEquals(result[1], self.item_3)
-        self.assertEquals(result[2], self.item_5)
-
-    def testWordSearchCore(self):
-        "Test word_search property of CoreQuerySet class"
-        self.assertEquals(self.collections.word_search("title", "volonté")[0], self.volonte)
-        self.assertEquals(self.collections.word_search("code", "CNRSMH_E_1970_001_002")[0], self.persepolis)
-        self.assertEquals(self.items.word_search("code", "CNRSMH_E_1970_001_002_44")[0], self.item_1)
-        result = self.items.word_search("comment", "comment").order_by("title")
-        self.assertEquals(result[0], self.item_1)
-        self.assertEquals(result[1], self.item_2)
-        self.assertEquals(result[2], self.item_3)
-        self.assertEquals(result[3], self.item_4)
-        self.assertEquals(result[4], self.item_5)
-        self.assertEquals(result[5], self.item_6)
-
-    def testByChangeTimeOnCollection(self):
-        "Test by_change_time property of MediaCollection class"
-        now = datetime.now()
-        print self.collections.all()
-        print MediaCollection.objects.all()
-        result = self.collections.by_change_time(now - timedelta(hours=1), now).order_by("title")
-        self.assertEquals(result[0], self.persepolis)
-
-    def testByChangeTimeOnItem(self):
-        "Test by_change_time property of MediaItem class"
-        now = datetime.now()
-        result = self.items.by_change_time(now - timedelta(hours=1), now).order_by("title")
-        self.assertEquals(result[0], self.item_1)
-
-    def testWithoutCollection(self):
-        "Test without_collection property of MediaItem class"
-        self.assertEquals(self.items.without_collection().count(), 0)
-
-    def testCodeRequired(self):
-        "Test that a proper failure occur when a collection code isn't provided"
-        c = MediaCollection()
-        try:
-            c.set_revision(self.olivier)
-        except RequiredFieldError, e:
-            self.assertEquals(e.field.name, 'code')
-        else:
-            self.fail("No exception raised")
-
-    def testDomForeignKey(self):
-        "Test DOM foreign key embedding"
-        doc = self.item_4.to_dom()
-        self.assertEquals(doc.getElementsByTagName('collection')[0].getAttribute('key'), str(self.persepolis.id))
-
-    def testLocationRelation(self):
-        "Test location country and continent resolving"
-        self.assertEquals(self.france, self.item_1.location.countries()[0])
-        self.assertEquals(self.europe, self.item_1.location.continents()[0])
-        self.assertEquals(self.france, self.item_2.location.countries()[0])
-        self.assertEquals(self.europe, self.item_2.location.continents()[0])
-
-    def testCollectionCountries(self):
-        "Test the MediaCollection.countries() method"
-        self.assertEquals(self.volonte.countries(), [self.belgique, self.france])
-
-pytestmark = pytest.mark.django_db
-
-@pytest.mark.django_db
-class RelatedDeleteTestCase(unittest.TestCase):
-    pytestmark = pytest.mark.django_db
-
-    def setUp(self):
-        self.publisher1 = Publisher.objects.create(id=1, value='publisher1')
-        self.publisher2 = Publisher.objects.create(id=2, value='publisher2')
-        self.pubcollection1 = PublisherCollection.objects.create(publisher=self.publisher1, value='pub1_collection1')
-
-        self.rights1 = LegalRight.objects.create(id=1, value='right1')
-
-        MediaCollection.objects.create(id=1, code='CNRSMH_I_1256_456', title='Collection1',
-                                       publisher=self.publisher1, publisher_collection=self.pubcollection1,
-                                       legal_rights=self.rights1)
-        MediaCollection.objects.create(id=2, code='CNRSMH_I_1256_123', title='Collection2',
-                                       publisher=self.publisher2)
-
-    def tearDown(self):
-        Publisher.objects.all().delete()
-        PublisherCollection.objects.all().delete()
-        LegalRight.objects.all().delete()
-        MediaCollection.objects.all().delete()
-
-    def testOnDeleteSetNull(self):
-        self.rights1.delete()
-        self.assertEquals(LegalRight.objects.filter(id=1).count(), 0)
-        q = MediaCollection.objects.filter(id=1)
-        self.assertEquals(q.count(), 1)
-        self.assertEquals(q[0].legal_rights, None)
-
-    def testOnDeleteCascade(self):
-        self.publisher1.delete()
-        self.assertEquals(Publisher.objects.filter(id=1).count(), 0)
-        self.assertEquals(Publisher.objects.filter(id=2).count(), 1)
-        self.assertEquals(PublisherCollection.objects.filter(id=1).count(), 0)
-
-        q = MediaCollection.objects.filter(id=1)
-        self.assertEquals(q.count(), 1)
-        self.assertEquals(q[0].publisher, None)
-        self.assertEquals(q[0].publisher_collection, None)
-
-        q = MediaCollection.objects.filter(id=2)
-        self.assertEquals(q.count(), 1)
-        self.assertEquals(q[0].publisher, self.publisher2)
-        self.assertEquals(q[0].publisher_collection, None)
-
-    def testOnDeleteMultiple(self):
-        Publisher.objects.all().delete()
-        self.assertEquals(Publisher.objects.count(), 0)
-        self.assertEquals(PublisherCollection.objects.count(), 0)
-        self.assertEquals(MediaCollection.objects.count(), 2)
-
-
-
index ef5262b3c28e16f320002980fb8fe270958d7c1d..cc7423bd3670c98f58c6efed30b8724bfecfe625 100644 (file)
@@ -1,6 +1,18 @@
-from telemeta.settings_base import SECRET_KEY, INSTALLED_APPS
+#from telemeta.settings_base import SECRET_KEY, INSTALLED_APPS
 
 
+SECRET_KEY = 'test_key'
+INSTALLED_APPS = ('django.contrib.auth',
+                  'django.contrib.contenttypes',
+                  'django.contrib.sessions',
+                  'django.contrib.sites',
+                  'django.contrib.messages',
+                  'suit',
+                  'django.contrib.admin',
+                  'django.contrib.staticfiles',
+                  'django_extensions',
+                  'telemeta',)
+
 DATABASES = {
     'default': {
         'ENGINE': 'django.db.backends.sqlite3',
diff --git a/telemeta/tests/test_models.py b/telemeta/tests/test_models.py
new file mode 100644 (file)
index 0000000..f7c6529
--- /dev/null
@@ -0,0 +1,375 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2007-2010 Samalyse SARL
+
+# This file is part of Telemeta.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+
+# You should have received a copy of the GNU Affero General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Authors: Olivier Guilyardi <olivier@samalyse.com>
+#          David LIPSZYC <davidlipszyc@gmail.com>
+
+from django.contrib.auth.models import User
+from django.test import TestCase
+
+from telemeta.models import LocationType, Location, EthnicGroup
+from telemeta.models.enum import Publisher, PublisherCollection
+from telemeta.models.enum import LegalRight
+from telemeta.models import MediaCollection, MediaItem
+from telemeta.models.fields import RequiredFieldError
+from datetime import datetime, timedelta
+import pytest
+
+pytestmark = pytest.mark.django_db
+
+@pytest.mark.django_db
+class CollectionItemTestCase(TestCase):
+    pytestmark = pytest.mark.django_db
+
+    def setUp(self):
+        "Create a test database based on objects created in Django"
+
+#        self.david   = User.objects.create(username="david", level="user")
+#        self.olivier = User.objects.create(username="olivier", level="admin")
+        self.david   = User.objects.create_user(username="david")
+        self.olivier = User.objects.create_user(username="olivier")
+
+        self.country = LocationType.objects.create(code="country", name="Country")
+        self.continent = LocationType.objects.create(code="continent", name="Continent")
+        self.city = LocationType.objects.create(code="city", name="City")
+
+        self.paris = Location.objects.create(name="Paris", type=Location.OTHER_TYPE, complete_type=self.city)
+        self.france = Location.objects.create(name="France", type=Location.COUNTRY, complete_type=self.country)
+        self.europe = Location.objects.create(name="Europe", type=Location.CONTINENT, complete_type=self.continent)
+        self.belgique = Location.objects.create(name="Belgique", type=Location.COUNTRY, complete_type=self.country)
+
+        self.europe.add_child(self.france)
+        self.france.add_child(self.paris)
+        self.europe.add_child(self.belgique)
+
+        self.a = EthnicGroup.objects.create(value="a")
+        self.b = EthnicGroup.objects.create(value="b")
+        self.c = EthnicGroup.objects.create(value="c")
+        self.d = EthnicGroup.objects.create(value="d")
+
+        self.persepolis = MediaCollection(id=1,
+                                          code="CNRSMH_E_1970_001_002",
+                                          reference="A1",
+                                          title="Persepolis",
+                                          creator="Abraham LINCOLN",
+                                          collector="Friedrich HEINZ",
+                                          year_published=2009,
+                                          is_published=True,
+                                          recorded_from_year=1970,
+                                          recorded_to_year=1980)
+
+        self.persepolis.set_revision(self.david)
+        self.persepolis.save()
+
+        self.volonte = MediaCollection(id=2,
+                                       reference="A2",
+                                       code="CNRSMH_I_1960_001",
+                                       title="Volonté de puissance",
+                                       creator="Friedrich NIETZSCHE",
+                                       collector="Jean AMORA",
+                                       year_published=1999,
+                                       recorded_from_year=1960,
+                                       recorded_to_year=2000)
+
+        self.volonte.set_revision(self.olivier)
+        self.volonte.save()
+
+        self.nicolas = MediaCollection(id=3,
+                                       reference="A3",
+                                       code="CNRSMH_I_1967_123",
+                                       title="Petit nicolas",
+                                       creator="Georgette McKenic",
+                                       collector="Paul MAILLE",
+                                       year_published=1999,
+                                       recorded_from_year=1967,
+                                       recorded_to_year=1968)
+
+        self.nicolas.set_revision(self.olivier)
+        self.nicolas.save()
+
+        self.item_1 = MediaItem(id=1, collection=self.persepolis, code="CNRSMH_E_1970_001_002_44",
+            recorded_from_date="1971-01-12", recorded_to_date="1971-02-24", location=self.paris,
+            ethnic_group=self.a, title="item 1", author="Mickael SHEPHERD", collector="Charles PREMIER",
+            comment="comment 1")
+
+        self.item_1.set_revision(self.david)
+
+        self.item_2 = MediaItem(id=2, collection=self.volonte, code="CNRSMH_I_1960_001_129",
+            recorded_from_date="1981-01-12", recorded_to_date="1991-02-24", location=self.france,
+            ethnic_group=self.a, title="item 2", author="Rick ROLL", comment="comment 2")
+
+        self.item_2.set_revision(self.david)
+
+        self.item_3 = MediaItem(id=3, collection=self.nicolas, code="CNRSMH_I_1967_123_456_01",
+            recorded_from_date="1968-01-12", recorded_to_date="1968-02-24", location=self.belgique,
+            ethnic_group=self.b, title="item 3", author="John SMITH", collector="Paul CARLOS",
+            comment="comment 3",  )
+
+        self.item_3.set_revision(self.olivier)
+
+        self.item_4 = MediaItem(id=4, collection=self.persepolis, code="CNRSMH_E_1970_001_002_22_33",
+            recorded_from_date="1972-01-12", recorded_to_date="1972-02-24", location=self.europe,
+            ethnic_group=self.a, title="item 4", alt_title="I4", author="Keanu REAVES",
+            collector="Christina BARCELONA", comment="comment 4")
+
+        self.item_4.set_revision(self.olivier)
+
+        self.item_5 = MediaItem(id=5, collection=self.volonte,code="CNRSMH_I_1960_001_789_85_22",
+            approx_duration="00:05:00", recorded_from_date="1978-01-12", recorded_to_date="1978-02-24",
+            location=self.belgique, ethnic_group=self.a, title="item 5", alt_title="I5",
+            author="Simon PAUL", collector="Javier BARDEM",
+            comment="comment 5")
+
+        self.item_5.set_revision(self.olivier)
+
+        self.item_6 = MediaItem(id=6, collection=self.persepolis, code="CNRSMH_E_1970_001_002_90",
+            recorded_from_date="1968-01-12", recorded_to_date="1968-02-11", location=self.france,
+            ethnic_group=self.b, title="item 6", author="Paul ANDERSON",
+            collector="Jim CARLSON", comment="comment 10000")
+
+        self.item_6.set_revision(self.david)
+
+        self.item_1.save()
+        self.item_2.save()
+        self.item_3.save()
+        self.item_4.save()
+        self.item_5.save()
+        self.item_6.save()
+        
+
+        self.collections = MediaCollection.objects.all()
+        self.items       = MediaItem.objects.all()
+
+    def tearDown(self):
+        User.objects.all().delete()
+        LocationType.objects.all().delete()
+        Location.objects.all().delete()
+        EthnicGroup.objects.all().delete()
+        MediaCollection.objects.all().delete()
+        MediaItem.objects.all().delete()
+
+    def testQuickSearchOnCollections(self):
+        "Test quick_search property of MediaCollection class"
+        self.assertEquals(len(self.collections), 3)
+        result = self.collections.quick_search("persepolis")
+        self.assertEquals(len(result), 1)
+        self.assertEquals(result[0], self.persepolis)
+        self.assertEquals(self.collections.quick_search("nietzsche")[0], self.volonte)
+        result = self.collections.quick_search("nicolas")
+        self.assertEquals(result[0], self.nicolas)
+
+    def testQuickSearchOnItems(self):
+        "Test quick_search property of MediaItem class"
+        result = self.items.quick_search("item").order_by('title')
+        self.assertEquals(result[0], self.item_1)
+        self.assertEquals(result[1], self.item_2)
+        self.assertEquals(result[2], self.item_3)
+        self.assertEquals(result[3], self.item_4)
+        self.assertEquals(result[4], self.item_5)
+        self.assertEquals(result[5], self.item_6)
+
+    def testWordSearch(self):
+        "Test quick_search property of MediaCollection class, specificly quick_search on collection title"
+        result = self.collections.quick_search("volonté puissance")
+        self.assertEquals(result[0], self.volonte)
+        result = self.collections.quick_search("puissance volonté")
+        self.assertEquals(result[0], self.volonte)
+        #result = self.collections.quick_search("volonte puissance")
+        #self.assertEquals(result[0], self.volonte)
+        #result = self.collections.quick_search("puissance volonte")
+        #self.assertEquals(result[0], self.volonte)
+
+    def testLocationSearch(self):
+        "Test by_country and by_continent properties of MediaCollection class"
+        self.assertEquals(self.collections.by_location(self.france)[0], self.persepolis)
+        self.assertEquals(self.collections.by_location(self.europe)[0], self.persepolis)
+        self.assertEquals(self.collections.by_location(self.belgique).order_by("title")[0], self.nicolas)
+        self.assertEquals(self.collections.by_location(self.belgique).order_by("title")[1], self.volonte)
+
+    def testRecordingYear(self):
+        "Test by_recording_year property of MediaCollection class"
+        self.assertEquals(self.collections.by_recording_year(1970, 1980)[0], self.persepolis)
+        result = self.collections.by_recording_year(1975).order_by("title")
+        self.assertEquals(result[0], self.persepolis)
+        self.assertEquals(result[1], self.volonte)
+
+    def testPublishYearOnCollection(self):
+        "Test by_publish_year property of MediaCollection class"
+        result=self.collections.by_publish_year(1999).order_by('title')
+        self.assertEquals(result[0], self.nicolas)
+        self.assertEquals(result[1], self.volonte)
+
+    def testEthnicGroup(self):
+        "Test by_ethnic_group property of MediaCollection class"
+        result=self.collections.by_ethnic_group(self.a).order_by("title")
+        self.assertEquals(result[0], self.persepolis)
+        self.assertEquals(result[1], self.volonte)
+
+    def testRecordingDate(self):
+        "Test by_recording_date property of MediaItem class"
+        result = self.items.by_recording_date("1968-01-01", "1972-12-12").order_by("title")
+        self.assertEquals(result[0], self.item_1)
+        self.assertEquals(result[1], self.item_3)
+        self.assertEquals(result[2], self.item_4)
+        self.assertEquals(result[3], self.item_6)
+        result = self.items.by_recording_date("1968-02-06").order_by("title")
+        self.assertEquals(result[0], self.item_3)
+        self.assertEquals(result[1], self.item_6)
+
+    def testTitle(self):
+        "Test by_title property of MediaItem class"
+        result = self.items.by_title("item").order_by("title")
+        self.assertEquals(result[0], self.item_1)
+        self.assertEquals(result[1], self.item_2)
+        self.assertEquals(result[2], self.item_3)
+        self.assertEquals(result[3], self.item_4)
+        self.assertEquals(result[4], self.item_5)
+        self.assertEquals(result[5], self.item_6)
+        self.item_2.title = ''
+        self.item_2.save()
+        self.item_5.title = ''
+        self.item_5.save()
+        result = self.items.by_title("volonté").order_by("title")
+        self.assertEquals(result[0], self.item_2)
+        self.assertEquals(result[1], self.item_5)
+        result = self.items.by_title("puissance volonté").order_by("title")
+        self.assertEquals(result[0], self.item_2)
+        self.assertEquals(result[1], self.item_5)
+
+    def testPublishYearOnItem(self):
+        "Test by_publish_year property of MediaItem class"
+        result = self.items.by_publish_year(1999).order_by("title")
+        self.assertEquals(result[0], self.item_2)
+        self.assertEquals(result[1], self.item_3)
+        self.assertEquals(result[2], self.item_5)
+
+    def testWordSearchCore(self):
+        "Test word_search property of CoreQuerySet class"
+        self.assertEquals(self.collections.word_search("title", "volonté")[0], self.volonte)
+        self.assertEquals(self.collections.word_search("code", "CNRSMH_E_1970_001_002")[0], self.persepolis)
+        self.assertEquals(self.items.word_search("code", "CNRSMH_E_1970_001_002_44")[0], self.item_1)
+        result = self.items.word_search("comment", "comment").order_by("title")
+        self.assertEquals(result[0], self.item_1)
+        self.assertEquals(result[1], self.item_2)
+        self.assertEquals(result[2], self.item_3)
+        self.assertEquals(result[3], self.item_4)
+        self.assertEquals(result[4], self.item_5)
+        self.assertEquals(result[5], self.item_6)
+
+    @pytest.mark.skip(reason="This test has to be reviewed")
+    def testByChangeTimeOnCollection(self):
+        "Test by_change_time property of MediaCollection class"
+        now = datetime.now()
+        print MediaCollection.objects.all()
+        result = self.collections.by_change_time(now - timedelta(hours=1), now).order_by("title")
+        self.assertEquals(result[0], self.persepolis)
+
+    @pytest.mark.skip(reason="This test has to be reviewed")
+    def testByChangeTimeOnItem(self):
+        "Test by_change_time property of MediaItem class"
+        now = datetime.now()
+        result = self.items.by_change_time(now - timedelta(hours=1), now).order_by("title")
+        self.assertEquals(result[0], self.item_1)
+
+    def testWithoutCollection(self):
+        "Test without_collection property of MediaItem class"
+        self.assertEquals(self.items.without_collection().count(), 0)
+
+    def testCodeRequired(self):
+        "Test that a proper failure occur when a collection code isn't provided"
+        c = MediaCollection(title='test')
+        try:
+            c.save()
+            #c.set_revision(self.olivier)
+        except RequiredFieldError, e:
+            self.assertEquals(e.field.name, 'code')
+        else:
+            self.fail("No exception raised")
+
+    def testDomForeignKey(self):
+        "Test DOM foreign key embedding"
+        doc = self.item_4.to_dom()
+        self.assertEquals(doc.getElementsByTagName('collection')[0].getAttribute('key'), str(self.persepolis.id))
+
+    def testLocationRelation(self):
+        "Test location country and continent resolving"
+        self.assertEquals(self.france, self.item_1.location.countries()[0])
+        self.assertEquals(self.europe, self.item_1.location.continents()[0])
+        self.assertEquals(self.france, self.item_2.location.countries()[0])
+        self.assertEquals(self.europe, self.item_2.location.continents()[0])
+
+    def testCollectionCountries(self):
+        "Test the MediaCollection.countries() method"
+        self.assertEquals(self.volonte.countries(), [self.belgique, self.france])
+
+pytestmark = pytest.mark.django_db
+
+@pytest.mark.django_db
+class RelatedDeleteTestCase(TestCase):
+    pytestmark = pytest.mark.django_db
+
+    def setUp(self):
+        self.publisher1 = Publisher.objects.create(id=1, value='publisher1')
+        self.publisher2 = Publisher.objects.create(id=2, value='publisher2')
+        self.pubcollection1 = PublisherCollection.objects.create(publisher=self.publisher1, value='pub1_collection1')
+
+        self.rights1 = LegalRight.objects.create(id=1, value='right1')
+
+        MediaCollection.objects.create(id=1, code='CNRSMH_I_1256_456', title='Collection1',
+                                       publisher=self.publisher1, publisher_collection=self.pubcollection1,
+                                       legal_rights=self.rights1)
+        MediaCollection.objects.create(id=2, code='CNRSMH_I_1256_123', title='Collection2',
+                                       publisher=self.publisher2)
+
+    def tearDown(self):
+        Publisher.objects.all().delete()
+        PublisherCollection.objects.all().delete()
+        LegalRight.objects.all().delete()
+        MediaCollection.objects.all().delete()
+
+    def testOnDeleteSetNull(self):
+        self.rights1.delete()
+        self.assertEquals(LegalRight.objects.filter(id=1).count(), 0)
+        q = MediaCollection.objects.filter(id=1)
+        self.assertEquals(q.count(), 1)
+        self.assertEquals(q[0].legal_rights, None)
+
+    def testOnDeleteCascade(self):
+        self.publisher1.delete()
+        self.assertEquals(Publisher.objects.filter(id=1).count(), 0)
+        self.assertEquals(Publisher.objects.filter(id=2).count(), 1)
+        self.assertEquals(PublisherCollection.objects.filter(id=1).count(), 0)
+
+        q = MediaCollection.objects.filter(id=1)
+        self.assertEquals(q.count(), 1)
+        self.assertEquals(q[0].publisher, None)
+        self.assertEquals(q[0].publisher_collection, None)
+
+        q = MediaCollection.objects.filter(id=2)
+        self.assertEquals(q.count(), 1)
+        self.assertEquals(q[0].publisher, self.publisher2)
+        self.assertEquals(q[0].publisher_collection, None)
+
+    def testOnDeleteMultiple(self):
+        Publisher.objects.all().delete()
+        self.assertEquals(Publisher.objects.count(), 0)
+        self.assertEquals(PublisherCollection.objects.count(), 0)
+        self.assertEquals(MediaCollection.objects.count(), 2)
+
+
+