From: olivier <> Date: Mon, 18 Jan 2010 20:54:19 +0000 (+0000) Subject: fix various issues in CREM models, move unit tests into tests.py X-Git-Tag: 1.1~604 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=0870f4fe090d3f72f0eab88ed0771315adfcf0d9;p=telemeta.git fix various issues in CREM models, move unit tests into tests.py --- diff --git a/telemeta/models/crem.py b/telemeta/models/crem.py index a41a3c59..58c4ccb2 100755 --- a/telemeta/models/crem.py +++ b/telemeta/models/crem.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright (C) 2007 Samalyse SARL +# Copyright (C) 2007-2010 Samalyse SARL # This software is a computer program whose purpose is to backup, analyse, # transcode and stream any audio content with its metadata over a web frontend. @@ -34,7 +34,57 @@ # David LIPSZYC from django.db import models -import query +import cremquery as query + +class MediaCore(object): + "Base class of all media objects" + + def to_dict(self): + "Return model fields as a dict of name/value pairs" + fields_dict = {} + for field in self._meta.fields: + fields_dict[field.name] = getattr(self, field.name) + return fields_dict + + def to_list(self): + "Return model fields as a list" + fields_list = [] + for field in self._meta.fields: + fields_list.append({'name': field.name, 'value': getattr(self, field.name)}) + return fields_list + + def get_dom_element_name(cls): + "Convert the class name to a DOM element name" + clsname = cls.__name__ + return clsname[0].lower() + clsname[1:] + get_dom_element_name = classmethod(get_dom_element_name) + + def to_dom(self): + "Return the DOM representation of this media object" + impl = getDOMImplementation() + root = self.get_dom_element_name() + doc = impl.createDocument(None, root, None) + top = doc.documentElement + top.setAttribute("id", self.id) + fields = self.to_dict() + for name, value in fields.iteritems(): + element = doc.createElement(name) + value = unicode(value) + element.appendChild(doc.createTextNode(value)) + top.appendChild(element) + return doc + + def is_well_formed_id(cls, value): + "Check if the media id is well formed" + regex = re.compile(r"^" + media_id_regex + r"$") + if regex.match(value): + return True + else: + return False + is_well_formed_id = classmethod(is_well_formed_id) + +class MetaCore: + app_label = 'telemeta' class MediaCollection(models.Model): "Describe a collection of items" @@ -86,7 +136,7 @@ class MediaCollection(models.Model): a_informer_07_03 = models.CharField(max_length=250, default="") ad_conversion = models.ForeignKey('AdConversion', related_name='collections', null=True) - public_access = models.CharField(choices=PUBLIC_ACCESS_CHOICES, max_length=250, default="metadata") + public_access = models.CharField(choices=PUBLIC_ACCESS_CHOICES, max_length=16, default="metadata") objects = query.MediaCollectionManager() @@ -101,7 +151,7 @@ class MediaCollection(models.Model): super(MediaCollection, self).save(force_insert, force_update) Revision(element_type='collection', element_id=self.id, user=user).touch() - class Meta: + class Meta(MetaCore): db_table = 'media_collections' class MediaItem(models.Model): @@ -139,11 +189,11 @@ class MediaItem(models.Model): comment = models.TextField(default="") filename = models.CharField(max_length=250, default="") public_access = models.CharField(choices=PUBLIC_ACCESS_CHOICES, - max_length=250, default="metadata") + max_length=16, default="metadata") objects = query.MediaItemManager() - class Meta: + class Meta(MetaCore): db_table = 'media_items' def __unicode__(self): @@ -166,7 +216,7 @@ class MediaPart(models.Model): start = models.FloatField() end = models.FloatField() - class Meta: + class Meta(MetaCore): db_table = 'media_parts' def __unicode__(self): @@ -174,86 +224,86 @@ class MediaPart(models.Model): class PhysicalFormat(models.Model): "Collection physical format" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'physical_formats' class PublishingStatus(models.Model): "Collection publishing status" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'publishing_status' class AcquisitionMode(models.Model): "Mode of acquisition of the collection" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'acquisition_modes' class MetadataAuthor(models.Model): "Collection metadata author" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'metadata_authors' class MetadataWriter(models.Model): "Collection metadata writer" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'metadata_writers' class LegalRight(models.Model): "Collection legal rights" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'legal_rights' class RecordingContext(models.Model): "Collection recording context" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'recording_contexts' class AdConversion(models.Model): "Collection digital to analog conversion status" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'ad_conversions' class VernacularStyle(models.Model): "Item vernacular style" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'vernacular_styles' class GenericStyle(models.Model): "Item generic style" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'generic_styles' class Instrument(models.Model): "Instrument used in the item" name = models.CharField(max_length=250) - class Meta: + class Meta(MetaCore): db_table = 'instruments' class InstrumentAlias(models.Model): "Instrument other name" name = models.CharField(max_length=250) - class Meta: + class Meta(MetaCore): db_table = 'instrument_aliases' class InstrumentRelation(models.Model): @@ -261,16 +311,18 @@ class InstrumentRelation(models.Model): instrument = models.ForeignKey('Instrument', related_name="parent_relation") parent_instrument = models.ForeignKey('Instrument', related_name="child_relation") - class Meta: + class Meta(MetaCore): db_table = 'instrument_relations' + unique_together = (('instrument', 'parent_instrument'),) class InstrumentAliasRelation(models.Model): "Instrument family other name" alias = models.ForeignKey('InstrumentAlias', related_name="other_name") instrument = models.ForeignKey('InstrumentAlias', related_name="relation") - class Meta: + class Meta(MetaCore): db_table = 'instrument_alias_relations' + unique_together = (('alias', 'instrument'),) class MediaItemPerformance(models.Model): "Item performance" @@ -282,29 +334,29 @@ class MediaItemPerformance(models.Model): instruments_num = models.CharField(max_length=250, default="") musicians = models.CharField(max_length=250, default="") - class Meta: + class Meta(MetaCore): db_table = 'media_item_performances' class User(models.Model): "Telemeta user" LEVEL_CHOICES = (('user', 'user'), ('maintainer', 'maintainer'), ('admin', 'admin')) - username = models.CharField(primary_key=True, max_length=250) + username = models.CharField(primary_key=True, max_length=64) level = models.CharField(choices=LEVEL_CHOICES, max_length=250) first_name = models.CharField(max_length=250, default="") last_name = models.CharField(max_length=250, default="") phone = models.CharField(max_length=250, default="") email = models.CharField(max_length=250, default="") - class Meta: + class Meta(MetaCore): db_table = 'users' class Playlist(models.Model): "Item or collection playlist" - owner_username = models.ForeignKey('User', related_name="playlists") + owner_username = models.ForeignKey('User', related_name="playlists", db_column="owner_username") name = models.CharField(max_length=250) - class Meta: + class Meta(MetaCore): db_table = 'playlists' class PlaylistResource(models.Model): @@ -315,21 +367,21 @@ class PlaylistResource(models.Model): resource_type = models.CharField(choices=RESOURCE_TYPE_CHOICES, max_length=250) resource = models.IntegerField() - class Meta: + class Meta(MetaCore): db_table = 'playlist_resources' class Location(models.Model): "Item location" TYPE_CHOICES = (('country', 'country'), ('continent', 'continent'), ('other', 'other')) - name = models.CharField(primary_key=True, max_length=250) - type = models.CharField(choices=TYPE_CHOICES, max_length=250) + name = models.CharField(primary_key=True, max_length=150) + type = models.CharField(choices=TYPE_CHOICES, max_length=16) complete_type = models.ForeignKey('LocationType', related_name="types") current_name = models.ForeignKey('self', related_name="past_names", db_column="current_name", null=True) is_authoritative = models.BooleanField(default=0) - class Meta: + class Meta(MetaCore): db_table = 'locations' def __unicode__(self): @@ -337,38 +389,39 @@ class Location(models.Model): class LocationType(models.Model): "Location type of an item location" - id = models.CharField(max_length=250, primary_key=True) - name = models.CharField(max_length=250) + id = models.CharField(max_length=64, primary_key=True) + name = models.CharField(max_length=150) - class Meta: + class Meta(MetaCore): db_table = 'location_types' class LocationAlias(models.Model): "Location other name" location_name = models.ForeignKey('Location', related_name="aliases", - db_column="location_name") - alias = models.CharField(max_length=250) + db_column="location_name", max_length=150) + alias = models.CharField(max_length=150) is_authoritative = models.BooleanField(default=0) - class Meta: + class Meta(MetaCore): db_table = 'location_aliases' + unique_together = (('location_name', 'alias'),) class LocationRelation(models.Model): "Location family" location_name = models.ForeignKey('Location', related_name="parent_relations", - db_column="location_name") + db_column="location_name", max_length=150) parent_location_name = models.ForeignKey('Location', related_name="child_relations", - db_column="parent_location_name", null=True) + db_column="parent_location_name", null=True, max_length=150) is_authoritative = models.BooleanField() - class Meta: + class Meta(MetaCore): db_table = 'location_relations' class ContextKeyword(models.Model): "Keyword" value = models.CharField(max_length=250) - class Meta: + class Meta(MetaCore): db_table = 'context_keywords' class MediaItemKeyword(models.Model): @@ -376,14 +429,15 @@ class MediaItemKeyword(models.Model): item = models.ForeignKey('MediaItem') keyword = models.ForeignKey('ContextKeyword') - class Meta: + class Meta(MetaCore): db_table = 'media_item_keywords' + unique_together = (('item', 'keyword'),) class Publisher(models.Model): "Collection publisher" - value = models.CharField(max_length=250) + value = models.CharField(max_length=250, unique=True) - class Meta: + class Meta(MetaCore): db_table = 'publishers' class PublisherCollection(models.Model): @@ -391,7 +445,7 @@ class PublisherCollection(models.Model): publisher = models.ForeignKey('Publisher', related_name="publisher_collections") value = models.CharField(max_length=250) - class Meta: + class Meta(MetaCore): db_table = 'publisher_collections' class Revision(models.Model): @@ -399,9 +453,9 @@ class Revision(models.Model): ELEMENT_TYPE_CHOICES = (('collection', 'collection'), ('item', 'item'), ('part', 'part')) CHANGE_TYPE_CHOICES = (('import', 'import'), ('create', 'create'), ('update', 'update'), ('delete','delete')) - element_type = models.CharField(choices=ELEMENT_TYPE_CHOICES, max_length=250) + element_type = models.CharField(choices=ELEMENT_TYPE_CHOICES, max_length=16) element_id = models.IntegerField() - change_type = models.CharField(choices=CHANGE_TYPE_CHOICES, max_length=250) + change_type = models.CharField(choices=CHANGE_TYPE_CHOICES, max_length=16) time = models.DateTimeField(auto_now_add=True) user = models.ForeignKey('User', db_column='username', related_name="revisions") @@ -414,14 +468,14 @@ class Revision(models.Model): self.change_type = 'create' self.save() - class Meta: + class Meta(MetaCore): db_table = 'revisions' class EthnicGroup(models.Model): "Item ethnic group" name = models.CharField(max_length=250) - class Meta: + class Meta(MetaCore): db_table = 'ethnic_groups' def __unicode__(self): @@ -432,7 +486,7 @@ class EthnicGroupAlias(models.Model): ethnic_group = models.ForeignKey('EthnicGroup', related_name="aliases") name = models.CharField(max_length=250) - class Meta: + class Meta(MetaCore): db_table = 'ethnic_group_aliases' diff --git a/telemeta/models/cremtests.py b/telemeta/models/cremtests.py deleted file mode 100644 index ce1ff1be..00000000 --- a/telemeta/models/cremtests.py +++ /dev/null @@ -1,311 +0,0 @@ -# -*- coding: utf-8 -*- -# Copyright (C) 2007 Samalyse SARL - -# This software is a computer program whose purpose is to backup, analyse, -# transcode and stream any audio content with its metadata over a web frontend. - -# This software is governed by the CeCILL license under French law and -# abiding by the rules of distribution of free software. You can use, -# modify and/ or redistribute the software under the terms of the CeCILL -# license as circulated by CEA, CNRS and INRIA at the following URL -# "http://www.cecill.info". - -# As a counterpart to the access to the source code and rights to copy, -# modify and redistribute granted by the license, users are provided only -# with a limited warranty and the software's author, the holder of the -# economic rights, and the successive licensors have only limited -# liability. - -# In this respect, the user's attention is drawn to the risks associated -# with loading, using, modifying and/or developing or reproducing the -# software by the user in light of its specific status of free software, -# that may mean that it is complicated to manipulate, and that also -# therefore means that it is reserved for developers and experienced -# professionals having in-depth computer knowledge. Users are therefore -# encouraged to load and test the software's suitability as regards their -# requirements in conditions enabling the security of their systems and/or -# data to be ensured and, more generally, to use and operate it in the -# same conditions as regards security. - -# The fact that you are presently reading this means that you have had -# knowledge of the CeCILL license and that you accept its terms. -# -# Authors: Olivier Guilyardi -# David LIPSZYC - -import unittest -from models import MediaCollection, MediaItem, Location, EthnicGroup, LocationType, User, Revision -from datetime import datetime, timedelta - -class CollectionItemTestCase(unittest.TestCase): - def setUp(self): - "Create a test database based on objects created in Django" - - User.objects.all().delete() - self.david = User.objects.create(username="david", level="user", first_name="david", last_name="aaa", phone="0156565656", - email="david@a.com") - self.olivier = User.objects.create(username="olivier", level="admin", first_name="olivier", last_name="bbb", - phone="0155555555", email="olivier@a.com") - - LocationType.objects.all().delete() - self.country = LocationType.objects.create(id="country", name="country") - self.continent = LocationType.objects.create(id="continent", name="continent") - self.city = LocationType.objects.create(id="city", name="city") - - Location.objects.all().delete() - self.paris = Location.objects.create(name="Paris", type="other", complete_type=self.city, is_authoritative=0) - self.france = Location.objects.create(name="France", type="country", complete_type=self.country, is_authoritative=0) - self.europe = Location.objects.create(name="Europe", type="continent", complete_type=self.continent, is_authoritative=0) - self.belgique = Location.objects.create(name="Belgique", type="country", complete_type=self.country, is_authoritative=0) - - EthnicGroup.objects.all().delete() - self.a = EthnicGroup.objects.create(name="a") - self.b = EthnicGroup.objects.create(name="b") - self.c = EthnicGroup.objects.create(name="c") - self.d = EthnicGroup.objects.create(name="d") - - MediaCollection.objects.all().delete() - self.persepolis = MediaCollection(id=1, reference="A1", physical_format_id=1111, old_code="10", code="100", title="persepolis", alt_title="bjr", creator="Abraham LINCOLN", - booklet_author="Maria BALTHAZAR", - booklet_description="compilation de mots français", - collector="Friedrich HEINZ", collector_is_creator=0, publisher_id=1442, - year_published=2009, publisher_collection_id=1234, - publisher_serial="123456", external_references="Larousse", - acquisition_mode_id=1, comment="chants", metadata_author_id=1, - metadata_writer_id=1, legal_rights_id=1, alt_ids="89", - recorded_from_year=1970, recorded_to_year=1980, recording_context_id=1, - approx_duration="5:00:00", doctype_code=1357, travail="travail", - state="etat", cnrs_contributor="Jean PETIT", items_done="fiches", - a_informer_07_03="a informer", ad_conversion_id=9, public_access="full") - - self.persepolis.save_by_user(self.david) - - self.volonte = MediaCollection(id=2, reference="A2", physical_format_id=222, old_code="20", code="200", - title="Volonté de puissance", alt_title="ar", creator="Friedrich NIETZSCHE", - booklet_author="George POMPIDOU", booklet_description="notice numero 2", - collector="Jean AMORA", collector_is_creator=0, publisher_id=2884, - year_published=1999, publisher_collection_id=2345, - publisher_serial="234567", external_references="dico", - acquisition_mode_id=2, comment="commentaire 2", metadata_author_id=2, - metadata_writer_id=2, legal_rights_id=2, alt_ids="78", - recorded_from_year=1960, recorded_to_year=2000, recording_context_id=2, - approx_duration="1:00:00", doctype_code=2468, travail="travail 2", - state="etat 2", cnrs_contributor="Richard LIONHEART", items_done="fiches 2", - a_informer_07_03="a informer 2", ad_conversion_id=8, - public_access="metadata") - - self.volonte.save_by_user(self.olivier) - - self.nicolas = MediaCollection(id=3, reference="A3", physical_format_id=333, old_code="30", code="300", - title="petit nicolas", alt_title="slt", creator="Georgette McKenic", - booklet_author="Francesca DICORTO", booklet_description="notice 3", - collector="Paul MAILLE", collector_is_creator=0, publisher_id=3773, - year_published=1999, publisher_collection_id=7890, publisher_serial="8764", - external_references="ref externes", acquisition_mode_id=3, - comment="commentaire 3", metadata_author_id=3, metadata_writer_id=3, - legal_rights_id=3, alt_ids="56", recorded_from_year=1967, - recorded_to_year=1968, recording_context_id=3, approx_duration="0:00:00", - doctype_code=5790, travail="travail 3", state="etat 3", - cnrs_contributor="Gerard MICKAEL", items_done="fiches 3", - a_informer_07_03="a informer 3", ad_conversion_id=8, public_access="none") - - self.nicolas.save_by_user(self.olivier) - - MediaItem.objects.all().delete() - self.item_1 = MediaItem(id=1, collection=self.persepolis, track="1111", old_code="101", code="1010", - approx_duration="00:01:00", recorded_from_date="1971-01-12", - recorded_to_date="1971-02-24", location_name=self.paris, - location_comment="capital de la France", ethnic_group=self.a, - title="item 1", alt_title="I1", author="Mickael SHEPHERD", - context_comment="contexte ethno 1", external_references="ext ref 1", - moda_execut="moda exec 1",copied_from_item_id=99, - collector="Charles PREMIER", cultural_area="Ile de France", generic_style_id=1, - collector_selection="collec sel 1", creator_reference="ref du deposant 1", - comment="comment 1", filename="item 1.item", public_access="full") - - self.item_1.save_by_user(self.david) - - self.item_2 = MediaItem(id=2, collection=self.volonte, track="2222", old_code="202", code="2020", - approx_duration="00:02:00", recorded_from_date="1981-01-12", - recorded_to_date="1991-02-24", location_name=self.france, - location_comment="loc comment 2", ethnic_group=self.a, title="item 2", - alt_title="I2", author="Rick ROLL", context_comment="contexte ethno 2", - external_references="ext ref 2", moda_execut="moda exec 2", - copied_from_item_id=98, collector="Gerard LENORMAND", - cultural_area="Nord de la France", generic_style_id=1, - collector_selection="collec sel 2", creator_reference="ref du deposant 2", - comment="comment 2", filename="item 2.item", public_access="metadata") - - self.item_2.save_by_user(self.david) - - self.item_3 = MediaItem(id=3, collection=self.nicolas, track="3333", old_code="303", code="3030", - approx_duration="00:03:00", recorded_from_date="1968-01-12", - recorded_to_date="1968-02-24", location_name=self.belgique, - location_comment="en Europe", ethnic_group=self.b, title="item 3", - alt_title="I3", author="John SMITH", context_comment="contexte ethno 3", - external_references="ext ref 3", moda_execut="moda exec 3", copied_from_item_id=97, - collector="Paul CARLOS", cultural_area="Europe occidentale", generic_style_id=1, - collector_selection="collec sel 3", creator_reference="ref du deposant 3", - comment="comment 3", filename="item 3.item", public_access="none") - - self.item_3.save_by_user(self.olivier) - - self.item_4 = MediaItem(id=4, collection=self.persepolis, track="4444", old_code="404", code="4040", - approx_duration="00:04:00", recorded_from_date="1972-01-12", - recorded_to_date="1972-02-24", location_name=self.europe, - location_comment="loc comm 4", ethnic_group=self.a, title="item 4", - alt_title="I4", author="Keanu REAVES", context_comment="contexte ethno 4", - external_references="ext ref 4", moda_execut="moda exec 4", copied_from_item_id=96, - collector="Christina BARCELONA", cultural_area="aire culturelle 4", - generic_style_id=1, collector_selection="collec sel 4", - creator_reference="ref du deposant 4", comment="comment 4", filename="item 4.item", - public_access="none") - - self.item_4.save_by_user(self.olivier) - - self.item_5 = MediaItem(id=5, collection=self.volonte, track="5555", old_code="505", code="5050", - approx_duration="00:05:00", recorded_from_date="1978-01-12", - recorded_to_date="1978-02-24", location_name=self.belgique, - location_comment="loc comm 5", ethnic_group=self.a, title="item 5", - alt_title="I5", author="Simon PAUL", context_comment="contexte ethno 5", - external_references="ext ref 5", moda_execut="moda exec 5", copied_from_item_id=95, - collector="Javier BARDEM", cultural_area="aire culturelle 5", generic_style_id=1, - collector_selection="collec sel 5", creator_reference="ref du deposant 5", - comment="comment 5", filename="item 5.item", public_access="metadata") - - self.item_5.save_by_user(self.olivier) - - self.item_6 = MediaItem(id=6, collection=self.persepolis, track="10000", old_code="1111111", - code="6060", approx_duration="10:03:00", recorded_from_date="1968-01-12", - recorded_to_date="1968-02-11", location_name=self.france, - location_comment="loc comment 10000", ethnic_group=self.b, - title="item 6", alt_title="I10000", author="Paul ANDERSON", - context_comment="contexte ethno 10000", external_references="ext ref 10000", - moda_execut="moda exec 10000", copied_from_item_id=11111, collector="Jim CARLSON", - cultural_area="cul area 10000", generic_style_id=1, - collector_selection="collec sel 10000", creator_reference="ref du deposant 10000", - comment="comment 10000", filename="item 10000.item", public_access="none") - - self.item_6.save_by_user(self.david) - - self.collections = MediaCollection.objects.all() - self.items = MediaItem.objects.all() - - 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_country("France")[0], self.persepolis) - self.assertEquals(self.collections.by_continent("Europe")[0], self.persepolis) - self.assertEquals(self.collections.by_country("Belgique").order_by("title")[0], self.nicolas) - self.assertEquals(self.collections.by_country("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("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) - 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", "100")[0], self.persepolis) - self.assertEquals(self.items.word_search("code", "1010")[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() - 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) diff --git a/telemeta/tests.py b/telemeta/tests.py new file mode 100644 index 00000000..ce1ff1be --- /dev/null +++ b/telemeta/tests.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +# Copyright (C) 2007 Samalyse SARL + +# This software is a computer program whose purpose is to backup, analyse, +# transcode and stream any audio content with its metadata over a web frontend. + +# This software is governed by the CeCILL license under French law and +# abiding by the rules of distribution of free software. You can use, +# modify and/ or redistribute the software under the terms of the CeCILL +# license as circulated by CEA, CNRS and INRIA at the following URL +# "http://www.cecill.info". + +# As a counterpart to the access to the source code and rights to copy, +# modify and redistribute granted by the license, users are provided only +# with a limited warranty and the software's author, the holder of the +# economic rights, and the successive licensors have only limited +# liability. + +# In this respect, the user's attention is drawn to the risks associated +# with loading, using, modifying and/or developing or reproducing the +# software by the user in light of its specific status of free software, +# that may mean that it is complicated to manipulate, and that also +# therefore means that it is reserved for developers and experienced +# professionals having in-depth computer knowledge. Users are therefore +# encouraged to load and test the software's suitability as regards their +# requirements in conditions enabling the security of their systems and/or +# data to be ensured and, more generally, to use and operate it in the +# same conditions as regards security. + +# The fact that you are presently reading this means that you have had +# knowledge of the CeCILL license and that you accept its terms. +# +# Authors: Olivier Guilyardi +# David LIPSZYC + +import unittest +from models import MediaCollection, MediaItem, Location, EthnicGroup, LocationType, User, Revision +from datetime import datetime, timedelta + +class CollectionItemTestCase(unittest.TestCase): + def setUp(self): + "Create a test database based on objects created in Django" + + User.objects.all().delete() + self.david = User.objects.create(username="david", level="user", first_name="david", last_name="aaa", phone="0156565656", + email="david@a.com") + self.olivier = User.objects.create(username="olivier", level="admin", first_name="olivier", last_name="bbb", + phone="0155555555", email="olivier@a.com") + + LocationType.objects.all().delete() + self.country = LocationType.objects.create(id="country", name="country") + self.continent = LocationType.objects.create(id="continent", name="continent") + self.city = LocationType.objects.create(id="city", name="city") + + Location.objects.all().delete() + self.paris = Location.objects.create(name="Paris", type="other", complete_type=self.city, is_authoritative=0) + self.france = Location.objects.create(name="France", type="country", complete_type=self.country, is_authoritative=0) + self.europe = Location.objects.create(name="Europe", type="continent", complete_type=self.continent, is_authoritative=0) + self.belgique = Location.objects.create(name="Belgique", type="country", complete_type=self.country, is_authoritative=0) + + EthnicGroup.objects.all().delete() + self.a = EthnicGroup.objects.create(name="a") + self.b = EthnicGroup.objects.create(name="b") + self.c = EthnicGroup.objects.create(name="c") + self.d = EthnicGroup.objects.create(name="d") + + MediaCollection.objects.all().delete() + self.persepolis = MediaCollection(id=1, reference="A1", physical_format_id=1111, old_code="10", code="100", title="persepolis", alt_title="bjr", creator="Abraham LINCOLN", + booklet_author="Maria BALTHAZAR", + booklet_description="compilation de mots français", + collector="Friedrich HEINZ", collector_is_creator=0, publisher_id=1442, + year_published=2009, publisher_collection_id=1234, + publisher_serial="123456", external_references="Larousse", + acquisition_mode_id=1, comment="chants", metadata_author_id=1, + metadata_writer_id=1, legal_rights_id=1, alt_ids="89", + recorded_from_year=1970, recorded_to_year=1980, recording_context_id=1, + approx_duration="5:00:00", doctype_code=1357, travail="travail", + state="etat", cnrs_contributor="Jean PETIT", items_done="fiches", + a_informer_07_03="a informer", ad_conversion_id=9, public_access="full") + + self.persepolis.save_by_user(self.david) + + self.volonte = MediaCollection(id=2, reference="A2", physical_format_id=222, old_code="20", code="200", + title="Volonté de puissance", alt_title="ar", creator="Friedrich NIETZSCHE", + booklet_author="George POMPIDOU", booklet_description="notice numero 2", + collector="Jean AMORA", collector_is_creator=0, publisher_id=2884, + year_published=1999, publisher_collection_id=2345, + publisher_serial="234567", external_references="dico", + acquisition_mode_id=2, comment="commentaire 2", metadata_author_id=2, + metadata_writer_id=2, legal_rights_id=2, alt_ids="78", + recorded_from_year=1960, recorded_to_year=2000, recording_context_id=2, + approx_duration="1:00:00", doctype_code=2468, travail="travail 2", + state="etat 2", cnrs_contributor="Richard LIONHEART", items_done="fiches 2", + a_informer_07_03="a informer 2", ad_conversion_id=8, + public_access="metadata") + + self.volonte.save_by_user(self.olivier) + + self.nicolas = MediaCollection(id=3, reference="A3", physical_format_id=333, old_code="30", code="300", + title="petit nicolas", alt_title="slt", creator="Georgette McKenic", + booklet_author="Francesca DICORTO", booklet_description="notice 3", + collector="Paul MAILLE", collector_is_creator=0, publisher_id=3773, + year_published=1999, publisher_collection_id=7890, publisher_serial="8764", + external_references="ref externes", acquisition_mode_id=3, + comment="commentaire 3", metadata_author_id=3, metadata_writer_id=3, + legal_rights_id=3, alt_ids="56", recorded_from_year=1967, + recorded_to_year=1968, recording_context_id=3, approx_duration="0:00:00", + doctype_code=5790, travail="travail 3", state="etat 3", + cnrs_contributor="Gerard MICKAEL", items_done="fiches 3", + a_informer_07_03="a informer 3", ad_conversion_id=8, public_access="none") + + self.nicolas.save_by_user(self.olivier) + + MediaItem.objects.all().delete() + self.item_1 = MediaItem(id=1, collection=self.persepolis, track="1111", old_code="101", code="1010", + approx_duration="00:01:00", recorded_from_date="1971-01-12", + recorded_to_date="1971-02-24", location_name=self.paris, + location_comment="capital de la France", ethnic_group=self.a, + title="item 1", alt_title="I1", author="Mickael SHEPHERD", + context_comment="contexte ethno 1", external_references="ext ref 1", + moda_execut="moda exec 1",copied_from_item_id=99, + collector="Charles PREMIER", cultural_area="Ile de France", generic_style_id=1, + collector_selection="collec sel 1", creator_reference="ref du deposant 1", + comment="comment 1", filename="item 1.item", public_access="full") + + self.item_1.save_by_user(self.david) + + self.item_2 = MediaItem(id=2, collection=self.volonte, track="2222", old_code="202", code="2020", + approx_duration="00:02:00", recorded_from_date="1981-01-12", + recorded_to_date="1991-02-24", location_name=self.france, + location_comment="loc comment 2", ethnic_group=self.a, title="item 2", + alt_title="I2", author="Rick ROLL", context_comment="contexte ethno 2", + external_references="ext ref 2", moda_execut="moda exec 2", + copied_from_item_id=98, collector="Gerard LENORMAND", + cultural_area="Nord de la France", generic_style_id=1, + collector_selection="collec sel 2", creator_reference="ref du deposant 2", + comment="comment 2", filename="item 2.item", public_access="metadata") + + self.item_2.save_by_user(self.david) + + self.item_3 = MediaItem(id=3, collection=self.nicolas, track="3333", old_code="303", code="3030", + approx_duration="00:03:00", recorded_from_date="1968-01-12", + recorded_to_date="1968-02-24", location_name=self.belgique, + location_comment="en Europe", ethnic_group=self.b, title="item 3", + alt_title="I3", author="John SMITH", context_comment="contexte ethno 3", + external_references="ext ref 3", moda_execut="moda exec 3", copied_from_item_id=97, + collector="Paul CARLOS", cultural_area="Europe occidentale", generic_style_id=1, + collector_selection="collec sel 3", creator_reference="ref du deposant 3", + comment="comment 3", filename="item 3.item", public_access="none") + + self.item_3.save_by_user(self.olivier) + + self.item_4 = MediaItem(id=4, collection=self.persepolis, track="4444", old_code="404", code="4040", + approx_duration="00:04:00", recorded_from_date="1972-01-12", + recorded_to_date="1972-02-24", location_name=self.europe, + location_comment="loc comm 4", ethnic_group=self.a, title="item 4", + alt_title="I4", author="Keanu REAVES", context_comment="contexte ethno 4", + external_references="ext ref 4", moda_execut="moda exec 4", copied_from_item_id=96, + collector="Christina BARCELONA", cultural_area="aire culturelle 4", + generic_style_id=1, collector_selection="collec sel 4", + creator_reference="ref du deposant 4", comment="comment 4", filename="item 4.item", + public_access="none") + + self.item_4.save_by_user(self.olivier) + + self.item_5 = MediaItem(id=5, collection=self.volonte, track="5555", old_code="505", code="5050", + approx_duration="00:05:00", recorded_from_date="1978-01-12", + recorded_to_date="1978-02-24", location_name=self.belgique, + location_comment="loc comm 5", ethnic_group=self.a, title="item 5", + alt_title="I5", author="Simon PAUL", context_comment="contexte ethno 5", + external_references="ext ref 5", moda_execut="moda exec 5", copied_from_item_id=95, + collector="Javier BARDEM", cultural_area="aire culturelle 5", generic_style_id=1, + collector_selection="collec sel 5", creator_reference="ref du deposant 5", + comment="comment 5", filename="item 5.item", public_access="metadata") + + self.item_5.save_by_user(self.olivier) + + self.item_6 = MediaItem(id=6, collection=self.persepolis, track="10000", old_code="1111111", + code="6060", approx_duration="10:03:00", recorded_from_date="1968-01-12", + recorded_to_date="1968-02-11", location_name=self.france, + location_comment="loc comment 10000", ethnic_group=self.b, + title="item 6", alt_title="I10000", author="Paul ANDERSON", + context_comment="contexte ethno 10000", external_references="ext ref 10000", + moda_execut="moda exec 10000", copied_from_item_id=11111, collector="Jim CARLSON", + cultural_area="cul area 10000", generic_style_id=1, + collector_selection="collec sel 10000", creator_reference="ref du deposant 10000", + comment="comment 10000", filename="item 10000.item", public_access="none") + + self.item_6.save_by_user(self.david) + + self.collections = MediaCollection.objects.all() + self.items = MediaItem.objects.all() + + 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_country("France")[0], self.persepolis) + self.assertEquals(self.collections.by_continent("Europe")[0], self.persepolis) + self.assertEquals(self.collections.by_country("Belgique").order_by("title")[0], self.nicolas) + self.assertEquals(self.collections.by_country("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("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) + 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", "100")[0], self.persepolis) + self.assertEquals(self.items.word_search("code", "1010")[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() + 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)