diff options
-rw-r--r-- | .gitignore | 6 | ||||
-rw-r--r-- | chimere/admin.py | 56 | ||||
-rw-r--r-- | chimere/migrations/0015_auto__add_subcategoryuserlimit.py | 337 | ||||
-rw-r--r-- | chimere/models.py | 17 | ||||
-rw-r--r-- | chimere/tests.py | 444 |
5 files changed, 646 insertions, 214 deletions
@@ -12,3 +12,9 @@ example_project/local_settings.py chimere_env/ docs/en/build/ docs/fr/build/ +chimere_example_project +chimere/static/leaflet/ +chimere/migrations/v2.0/ +chimere/migrations_saclay/ +chimere_saclay +chimere_nef diff --git a/chimere/admin.py b/chimere/admin.py index 60d1141..fb3b15c 100644 --- a/chimere/admin.py +++ b/chimere/admin.py @@ -20,12 +20,11 @@ """ Settings for administration pages """ -import datetime - -from django import forms from django.conf import settings from django.contrib import admin, messages from django.contrib.admin import SimpleListFilter +from django.contrib.auth.admin import UserAdmin as VanillaUserAdmin +from django.contrib.auth.models import User from django.core.exceptions import ObjectDoesNotExist from django.db.models import Q from django.http import HttpResponse, HttpResponseRedirect @@ -45,7 +44,8 @@ from chimere.models import Category, Icon, SubCategory, Marker, \ PropertyModel, News, Route, Area, ColorTheme, Color, \ MultimediaFile, PictureFile, Importer, Layer, AreaLayers,\ PropertyModelChoice, MultimediaExtension, Page,\ - get_areas_for_user, get_users_by_area, ImporterKeyCategories + get_areas_for_user, get_users_by_area, ImporterKeyCategories,\ + SubCategoryUserLimit from chimere.utils import unicode_normalize, ShapefileManager, KMLManager,\ CSVManager @@ -164,6 +164,20 @@ def managed_modified(modeladmin, request, queryset): context_instance=RequestContext(request)) managed_modified.short_description = _(u"Managed modified items") + +class CatLimitInline(admin.TabularInline): + model = SubCategoryUserLimit + extra = 5 + + +class UserAdmin(VanillaUserAdmin): + list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff') + inlines = (CatLimitInline,) + +admin.site.unregister(User) +admin.site.register(User, UserAdmin) + + class PictureInline(admin.TabularInline): model = PictureFile extra = 1 @@ -217,6 +231,25 @@ class HasCategoriesListFilter(SimpleListFilter): return queryset.exclude(categories__isnull=True) return queryset + +def moderator_right(user, qs, geo_type='marker'): + if user.is_superuser: + return qs + areas = get_areas_for_user(user) + if areas: + contained = Q() + for area in areas: + if geo_type == 'marker': + contained = contained | area.getIncludeMarker() + elif geo_type == 'route': + contained = contained | area.getIncludeRoute() + qs = qs.filter(contained) + if user.subcategory_limit_to.count(): + qs = qs.filter(categories__in=SubCategory.objects.filter( + limited_for_user__user=user).all()) + return qs + + class MarkerAdmin(admin.ModelAdmin): """ Specialized the Point field. @@ -269,12 +302,7 @@ class MarkerAdmin(admin.ModelAdmin): def queryset(self, request): qs = self.model._default_manager.get_query_set() - if not request.user.is_superuser: - areas = get_areas_for_user(request.user) - contained = Q() - for area in areas: - contained = contained | area.getIncludeMarker() - qs = qs.filter(contained) + qs = moderator_right(request.user, qs, geo_type='marker') ordering = self.ordering or () if ordering: qs = qs.order_by(*ordering) @@ -297,6 +325,7 @@ class MarkerAdmin(admin.ModelAdmin): ) return my_urls + urls + class RouteAdmin(MarkerAdmin): """ Specialized the Route field. @@ -334,12 +363,7 @@ class RouteAdmin(MarkerAdmin): def queryset(self, request): qs = self.model._default_manager.get_query_set() - if not request.user.is_superuser: - areas = get_areas_for_user(request.user) - contained = Q() - for area in areas: - contained = contained | area.getIncludeRoute() - qs = qs.filter(contained) + qs = moderator_right(request.user, qs, geo_type='route') ordering = self.ordering or () if ordering: qs = qs.order_by(*ordering) diff --git a/chimere/migrations/0015_auto__add_subcategoryuserlimit.py b/chimere/migrations/0015_auto__add_subcategoryuserlimit.py new file mode 100644 index 0000000..e24663a --- /dev/null +++ b/chimere/migrations/0015_auto__add_subcategoryuserlimit.py @@ -0,0 +1,337 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'SubCategoryUserLimit' + db.create_table('chimere_subcategoryuserlimit', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('subcategory', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['chimere.SubCategory'])), + ('user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])), + )) + db.send_create_signal('chimere', ['SubCategoryUserLimit']) + + + def backwards(self, orm): + # Deleting model 'SubCategoryUserLimit' + db.delete_table('chimere_subcategoryuserlimit') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'chimere.aggregatedroute': { + 'Meta': {'object_name': 'AggregatedRoute', 'db_table': "'chimere_aggregated_routes'", 'managed': 'False'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'route': ('django.contrib.gis.db.models.fields.MultiLineStringField', [], {}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'subcategory': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.SubCategory']"}) + }, + 'chimere.area': { + 'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}), + 'dynamic_categories': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}), + 'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'unique': 'True'}), + 'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}), + 'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), + 'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}), + 'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.arealayers': { + 'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'}, + 'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}), + 'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.category': { + 'Meta': {'ordering': "['order']", 'object_name': 'Category'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.color': { + 'Meta': {'ordering': "['order']", 'object_name': 'Color'}, + 'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}), + 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.colortheme': { + 'Meta': {'object_name': 'ColorTheme'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.icon': { + 'Meta': {'object_name': 'Icon'}, + 'height': ('django.db.models.fields.IntegerField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'width': ('django.db.models.fields.IntegerField', [], {}) + }, + 'chimere.importer': { + 'Meta': {'object_name': 'Importer'}, + 'associate_marker_to_way': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'automatic_update': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'to': "orm['chimere.SubCategory']", 'null': 'True', 'blank': 'True'}), + 'default_description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'default_localisation': ('chimere.widgets.PointField', [], {'null': 'True', 'blank': 'True'}), + 'default_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'default_status': ('django.db.models.fields.CharField', [], {'default': "'I'", 'max_length': '1'}), + 'filtr': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'get_description': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}), + 'license': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'origin': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'overwrite': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'source_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'source_file_alt': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'state': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'chimere.importerkeycategories': { + 'Meta': {'object_name': 'ImporterKeyCategories'}, + 'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.SubCategory']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'importer': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'key_categories'", 'to': "orm['chimere.Importer']"}), + 'key': ('django.db.models.fields.CharField', [], {'max_length': '200'}) + }, + 'chimere.layer': { + 'Meta': {'object_name': 'Layer'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.marker': { + 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'}, + 'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'keywords': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'license': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'origin': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'point': ('chimere.widgets.PointField', [], {}), + 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}), + 'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.multimediaextension': { + 'Meta': {'object_name': 'MultimediaExtension'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'extensions'", 'to': "orm['chimere.MultimediaType']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '6'}) + }, + 'chimere.multimediafile': { + 'Meta': {'object_name': 'MultimediaFile'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}), + 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']", 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) + }, + 'chimere.multimediatype': { + 'Meta': {'object_name': 'MultimediaType'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.news': { + 'Meta': {'object_name': 'News'}, + 'areas': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'to': "orm['chimere.Area']", 'null': 'True', 'blank': 'True'}), + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'content': ('django.db.models.fields.TextField', [], {}), + 'date': ('django.db.models.fields.DateField', [], {}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.page': { + 'Meta': {'object_name': 'Page'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mnemonic': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '10', 'null': 'True', 'blank': 'True'}), + 'template_path': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}), + 'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.picturefile': { + 'Meta': {'object_name': 'PictureFile'}, + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}), + 'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), + 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), + 'thumbnailfile': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'thumbnailfile_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'thumbnailfile_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.property': { + 'Meta': {'object_name': 'Property'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}), + 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}), + 'value': ('django.db.models.fields.TextField', [], {}) + }, + 'chimere.propertymodel': { + 'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mandatory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {}), + 'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'properties'", 'blank': 'True', 'to': "orm['chimere.SubCategory']"}), + 'type': ('django.db.models.fields.CharField', [], {'max_length': '1'}) + }, + 'chimere.propertymodelchoice': { + 'Meta': {'object_name': 'PropertyModelChoice'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'choices'", 'to': "orm['chimere.PropertyModel']"}), + 'value': ('django.db.models.fields.CharField', [], {'max_length': '150'}) + }, + 'chimere.route': { + 'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'}, + 'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}), + 'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), + 'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'has_associated_marker': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), + 'keywords': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'license': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'origin': ('django.db.models.fields.CharField', [], {'max_length': '1000', 'null': 'True', 'blank': 'True'}), + 'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), + 'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}), + 'route': ('chimere.widgets.RouteField', [], {}), + 'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), + 'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), + 'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), + 'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) + }, + 'chimere.routefile': { + 'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'}, + 'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}) + }, + 'chimere.subcategory': { + 'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'}, + 'as_layer': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'category': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'subcategories'", 'to': "orm['chimere.Category']"}), + 'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}), + 'dated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'hover_icon': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subcat_hovered'", 'null': 'True', 'to': "orm['chimere.Icon']"}), + 'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), + 'keywords': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '1000'}), + 'routing_warn': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'submission': ('django.db.models.fields.BooleanField', [], {'default': 'True'}) + }, + 'chimere.subcategoryuserlimit': { + 'Meta': {'object_name': 'SubCategoryUserLimit'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'subcategory': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.SubCategory']"}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}) + }, + 'chimere.tinyurl': { + 'Meta': {'object_name': 'TinyUrl'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + } + } + + complete_apps = ['chimere']
\ No newline at end of file diff --git a/chimere/models.py b/chimere/models.py index 98dbd22..a37a548 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -323,6 +323,23 @@ class SubCategory(models.Model): def item_nb(self): return Marker.objects.filter(categories=self).count() + +class SubCategoryUserLimit(models.Model): + """ + Moderation limit for user by category + """ + subcategory = models.ForeignKey( + SubCategory, related_name='limited_for_user') + user = models.ForeignKey(User, related_name='subcategory_limit_to') + + def __unicode__(self): + return u"{} / {}".format(self.user, self.subcategory) + + class Meta: + verbose_name = _(u"Sub-category limit for user") + verbose_name_plural = _(u"Sub-category limits for users") + + STATUS = (('S', _(u'Submited')), ('A', _(u'Available')), ('M', _(u'Modified')), diff --git a/chimere/tests.py b/chimere/tests.py index 6c39cba..1c950fc 100644 --- a/chimere/tests.py +++ b/chimere/tests.py @@ -8,86 +8,68 @@ import simplejson as json test_path = os.path.abspath(__file__) test_dir_path = os.path.dirname(test_path) + os.sep -from django.conf import settings -from django.contrib.auth.models import User +from django.contrib.auth.models import User, Group from django.contrib.gis.geos import GEOSGeometry -from django.contrib.messages.storage.fallback import FallbackStorage from django.core.files import File from django.core.urlresolvers import reverse from django.template import Context from django.test import TestCase -from django.test.client import Client -from chimere.admin import managed_modified, MarkerAdmin -from chimere.models import Area, Icon, Importer, Category, SubCategory, Marker,\ - Route, News +from chimere.models import Area, Icon, Importer, Category, SubCategory, \ + Marker, Route, News, SubCategoryUserLimit from chimere.forms import MarkerForm, AreaAdminForm from chimere.templatetags.chimere_tags import display_news from chimere.utils import ShapefileManager + def areas_setup(): - area_1 = Area.objects.create(name='area 1', urn='area-1', order=1, - available=True, - upper_left_corner='SRID=4326;POINT(-4.907753 48.507656)', - lower_right_corner='SRID=4326;POINT(-4.049447 48.279688)') - area_2 = Area.objects.create(name='area 2', urn='area-2', order=2, - available=True, - upper_left_corner='SRID=4326;POINT(-3 47.5)', - lower_right_corner='SRID=4326;POINT(-2.5 47)') - area_3 = Area.objects.create(name='area 3', urn='area-3', order=3, - available=True, - upper_left_corner='SRID=4326;POINT(-1.5 1.5)', - lower_right_corner='SRID=4326;POINT(1.5 -1.5)') + area_1 = Area.objects.create( + name='area 1', urn='area-1', order=1, available=True, + upper_left_corner='SRID=4326;POINT(-4.907753 48.507656)', + lower_right_corner='SRID=4326;POINT(-4.049447 48.279688)') + area_2 = Area.objects.create( + name='area 2', urn='area-2', order=2, available=True, + upper_left_corner='SRID=4326;POINT(-3 47.5)', + lower_right_corner='SRID=4326;POINT(-2.5 47)') + area_3 = Area.objects.create( + name='area 3', urn='area-3', order=3, available=True, + upper_left_corner='SRID=4326;POINT(-1.5 1.5)', + lower_right_corner='SRID=4326;POINT(1.5 -1.5)') return [area_1, area_2, area_3] + def subcategory_setup(): - category = Category.objects.create(name='Main category', - available=True, - order=1, - description='') + category = Category.objects.create( + name='Main category', available=True, order=1, description='') icon = Icon.objects.create(name='Default icon', image='icons/marker.png', height=25, width=21) - subcategory_1 = SubCategory.objects.create(category=category, - name='Subcategory 1', - available=True, - icon=icon, - order=1, - item_type='M',) - - subcategory_2 = SubCategory.objects.create(category=category, - name='Subcategory 2', - available=True, - icon=icon, - order=1, - item_type='M',) - - subcategory_3 = SubCategory.objects.create(category=category, - name='Subcategory 3', - available=True, - icon=icon, - order=1, - item_type='M',) - - subcategory_4 = SubCategory.objects.create(category=category, - name='Subcategory 4', - available=True, - icon=icon, - order=1, - item_type='M',) - - subcategory_5 = SubCategory.objects.create(category=category, - name='Subcategory 5', - available=True, - icon=icon, - order=1, - item_type='M',) + subcategory_1 = SubCategory.objects.create( + category=category, name='Subcategory 1', available=True, icon=icon, + order=1, item_type='M',) + + subcategory_2 = SubCategory.objects.create( + category=category, name='Subcategory 2', available=True, icon=icon, + order=1, item_type='M',) + + subcategory_3 = SubCategory.objects.create( + category=category, name='Subcategory 3', available=True, icon=icon, + order=1, item_type='M',) + + subcategory_4 = SubCategory.objects.create( + category=category, name='Subcategory 4', available=True, icon=icon, + order=1, item_type='M',) + + subcategory_5 = SubCategory.objects.create( + category=category, name='Subcategory 5', available=True, icon=icon, + order=1, item_type='M',) return [subcategory_1, subcategory_2, subcategory_3, subcategory_4, subcategory_5] + def marker_setup(sub_categories=[]): if not sub_categories: sub_categories = subcategory_setup() @@ -105,41 +87,46 @@ def marker_setup(sub_categories=[]): start_date=current_date) marker_2.categories.add(sub_categories[1]) markers.append(marker_2) - marker_3 = Marker.objects.create(name="Marker 3", status='A', - point='SRID=4326;POINT(-4.5 48.45)', - is_front_page=True, - available_date=current_date - datetime.timedelta(days=60), - start_date=current_date - datetime.timedelta(days=60), - end_date=current_date - datetime.timedelta(days=30)) + marker_3 = Marker.objects.create( + name="Marker 3", status='A', point='SRID=4326;POINT(-4.5 48.45)', + is_front_page=True, + available_date=current_date - datetime.timedelta(days=60), + start_date=current_date - datetime.timedelta(days=60), + end_date=current_date - datetime.timedelta(days=30)) marker_3.categories.add(sub_categories[1]) markers.append(marker_3) return markers + def route_setup(sub_categories=[]): if not sub_categories: sub_categories = subcategory_setup() - current_date = datetime.datetime.now() + # current_date = datetime.datetime.now() routes = [] - route_1 = Route.objects.create(name="Route 1", status='A', - has_associated_marker=True, route='SRID=4326;LINESTRING(-1 1, 1 -1)') + route_1 = Route.objects.create( + name="Route 1", status='A', has_associated_marker=True, + route='SRID=4326;LINESTRING(-1 1, 1 -1)') route_1.categories.add(sub_categories[0]) routes.append(route_1) - route_2 = Route.objects.create(name="Route 2", status='A', - has_associated_marker=False, route='SRID=4326;LINESTRING(0 0, 2 2)') + route_2 = Route.objects.create( + name="Route 2", status='A', has_associated_marker=False, + route='SRID=4326;LINESTRING(0 0, 2 2)') route_2.categories.add(sub_categories[1]) routes.append(route_2) return routes + class ImporterTest: def test_get(self): nb_by_cat = {} for importer, awaited_nb in self.marker_importers: nb, nb_updated, res = importer.manager.get() - if awaited_nb == None: + if awaited_nb is None: continue - self.assertEqual(nb, awaited_nb, - msg=u"%s: get test failed - got %d when %d was awaited" % - (unicode(self.__class__), nb, awaited_nb)) + self.assertEqual( + nb, awaited_nb, + msg=u"%s: get test failed - got %d when %d was awaited" % + (unicode(self.__class__), nb, awaited_nb)) self.assertEqual(nb_updated, 0) for cat in importer.categories.all(): if cat not in nb_by_cat: @@ -154,7 +141,7 @@ class ImporterTest: importer.overwrite = True importer.save() nb, nb_updated, res = importer.manager.get() - if awaited_nb == None: + if awaited_nb is None: continue self.assertEqual(nb, 0) # manage overwrite @@ -164,11 +151,11 @@ class ImporterTest: # mimic the modification of one item for cls in (Marker, Route): items = cls.objects.filter( - categories=importer.categories.all()[0] - ).order_by('-pk').all() + categories=importer.categories.all()[0]).order_by( + '-pk').all() if items.count(): item = items.all()[0] - item.import_version = 99999 # fake version number + item.import_version = 99999 # fake version number item.save() # as when the import_version it is considered as an import # modification force the modification flag @@ -177,41 +164,49 @@ class ImporterTest: importer.overwrite = False importer.save() nb, nb_updated, res = importer.manager.get() - if awaited_nb == None: + if awaited_nb is None: continue - self.assertEqual(nb, 1, msg=u"%s: overwrite test failed" % - unicode(self.__class__)) + self.assertEqual( + nb, 1, msg=u"%s: overwrite test failed" % + unicode(self.__class__)) + class KMLImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() - importer1 = Importer.objects.create(importer_type='KML', - source=test_dir_path+'tests/sample.kml', + importer1 = Importer.objects.create( + importer_type='KML', + source=test_dir_path + 'tests/sample.kml', filtr="Category 1") importer1.categories.add(subcategories[0]) - importer2 = Importer.objects.create(importer_type='KML', - source=test_dir_path+'tests/sample.kml', - filtr="Subcategory 1", associate_marker_to_way=True) + importer2 = Importer.objects.create( + importer_type='KML', + source=test_dir_path + 'tests/sample.kml', + filtr="Subcategory 1", associate_marker_to_way=True) importer2.categories.add(subcategories[1]) - importer3 = Importer.objects.create(importer_type='KML', - source=test_path+'tests/sample.kml', - filtr="Subcategory 3") + importer3 = Importer.objects.create( + importer_type='KML', + source=test_path + 'tests/sample.kml', + filtr="Subcategory 3") importer3.categories.add(subcategories[2]) - importer4 = Importer.objects.create(importer_type='KML', - source=test_dir_path+'tests/sample.kml.zip', zipped=True, - default_description="Default description") + importer4 = Importer.objects.create( + importer_type='KML', + source=test_dir_path + 'tests/sample.kml.zip', zipped=True, + default_description="Default description") importer4.categories.add(subcategories[3]) - importer5 = Importer.objects.create(importer_type='KML', - source=test_dir_path+'tests/sample-no-folder.kml', zipped=False, - default_description="Default description") + importer5 = Importer.objects.create( + importer_type='KML', + source=test_dir_path + 'tests/sample-no-folder.kml', zipped=False, + default_description="Default description") importer5.categories.add(subcategories[4]) - self.marker_importers = [(importer1, 1), (importer2, 3), (importer3, 0), - (importer4, 4), (importer5, 3)] + self.marker_importers = [ + (importer1, 1), (importer2, 3), (importer3, 0), (importer4, 4), + (importer5, 3)] def test_defaultdescription(self): Marker.objects.all().delete() @@ -231,19 +226,22 @@ class KMLImporterTest(TestCase, ImporterTest): self.assertEqual(last_marker.description, new_desc) + class ShapefileImporterTest(TestCase, ImporterTest): def setUp(self): self.subcategories = subcategory_setup() - importer = Importer.objects.create(importer_type='SHP', - source=test_dir_path+'tests/sample_nodes.shp.zip', zipped=True) + importer = Importer.objects.create( + importer_type='SHP', + source=test_dir_path + 'tests/sample_nodes.shp.zip', zipped=True) importer.categories.add(self.subcategories[0]) - importer2 = Importer.objects.create(importer_type='SHP', - source=test_dir_path+'tests/sample_ways.shp.zip', + importer2 = Importer.objects.create( + importer_type='SHP', + source=test_dir_path + 'tests/sample_ways.shp.zip', zipped=True) importer2.categories.add(self.subcategories[1]) self.marker_importers = [(importer, 29), - (importer2, 5),] + (importer2, 5)] self.markers = marker_setup() def test_export(self): @@ -268,60 +266,71 @@ class ShapefileImporterTest(TestCase, ImporterTest): ).count() self.assertEqual(nb, 0) + class OSMImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() - markers = marker_setup() - importer1 = Importer.objects.create(importer_type='OSM', - source=test_dir_path+'tests/sample_nodes.osm') + marker_setup() + importer1 = Importer.objects.create( + importer_type='OSM', + source=test_dir_path + 'tests/sample_nodes.osm') importer1.categories.add(subcategories[0]) - importer2 = Importer.objects.create(importer_type='OSM', - source=test_dir_path+'tests/sample_ways.osm') + importer2 = Importer.objects.create( + importer_type='OSM', + source=test_dir_path + 'tests/sample_ways.osm') importer2.categories.add(subcategories[1]) - importer3 = Importer.objects.create(importer_type='OSM', - source='http://open.mapquestapi.com/xapi/api/0.6/way'\ - '[highway=motorway]'\ - '[bbox=2.0393839939136975,48.68908639634696,'\ + importer3 = Importer.objects.create( + importer_type='OSM', + source='http://open.mapquestapi.com/xapi/api/0.6/way' + '[highway=motorway]' + '[bbox=2.0393839939136975,48.68908639634696,' '2.3140421970277316,48.790972349390415]') self.marker_importers = [(importer1, 19), (importer2, 8), (importer3, None)] + class GeoRSSImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() - importer1 = Importer.objects.create(importer_type='RSS', - source=test_dir_path+'tests/georss_simple.xml') + importer1 = Importer.objects.create( + importer_type='RSS', + source=test_dir_path + 'tests/georss_simple.xml') importer1.categories.add(subcategories[0]) - importer2 = Importer.objects.create(importer_type='RSS', - source=test_dir_path+'tests/eqs7day-M5.xml') + importer2 = Importer.objects.create( + importer_type='RSS', source=test_dir_path + 'tests/eqs7day-M5.xml') importer2.categories.add(subcategories[1]) self.marker_importers = [(importer1, 1), (importer2, 32)] + class HtmlXsltImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() xslt1 = File(open(test_dir_path + 'tests/villiers-le-bacle.xslt')) - xslt2 = File(open(test_dir_path + 'tests/villiers-le-bacle-detail.xslt')) - importer1 = Importer.objects.create(importer_type='XSLT', - source='http://www.chymeres.net/test/ville-villierslebacle.fr/', - source_file=xslt1, source_file_alt=xslt2, - default_localisation='SRID=4326;POINT(-4.5 48.4)',) + xslt2 = File(open(test_dir_path + + 'tests/villiers-le-bacle-detail.xslt')) + importer1 = Importer.objects.create( + importer_type='XSLT', + source='http://www.chymeres.net/test/ville-villierslebacle.fr/', + source_file=xslt1, source_file_alt=xslt2, + default_localisation='SRID=4326;POINT(-4.5 48.4)',) importer1.categories.add(subcategories[0]) - self.marker_importers = [(importer1, 7),] + self.marker_importers = [(importer1, 7)] + class XmlXsltImporterTest(TestCase, ImporterTest): def setUp(self): subcategories = subcategory_setup() xslt1 = File(open(test_dir_path + 'tests/magny-xml.xslt')) - importer1 = Importer.objects.create(importer_type='XXLT', - source='http://www.chymeres.net/test/magny.xml', - source_file=xslt1, - default_localisation='SRID=4326;POINT(-4.5 48.4)',) + importer1 = Importer.objects.create( + importer_type='XXLT', + source='http://www.chymeres.net/test/magny.xml', + source_file=xslt1, + default_localisation='SRID=4326;POINT(-4.5 48.4)',) importer1.categories.add(subcategories[0]) - self.marker_importers = [(importer1, 10),] + self.marker_importers = [(importer1, 10)] class JsonImporterTest(TestCase, ImporterTest): @@ -357,34 +366,66 @@ class FeedsTest(TestCase): doc = lxml.etree.fromstring(response.content) self.assertEqual(int(doc.xpath('count(//item)')), 2) + class AdminTest(TestCase): def setUp(self): self.areas = areas_setup() - self.markers = marker_setup() - self.adminuser = User.objects.create_superuser('admin', - 'admin@test.com', - 'pass') - self.client.login(username='admin', password='pass') + self.subcategories = subcategory_setup() + self.markers = marker_setup(self.subcategories) + self.adminuser = User.objects.create_superuser( + 'admin', 'admin@test.com', 'pass') + self.moderation_user = User.objects.create_user( + 'mod_1', 'mod1@test.com', 'pass') + self.moderation_user.is_staff = True + self.moderation_user.save() + self.moderation_user2 = User.objects.create_user( + 'mod_2', 'mod2@test.com', 'pass') + self.moderation_user2.is_staff = True + self.moderation_user2.save() + SubCategoryUserLimit.objects.create( + subcategory=self.subcategories[0], + user=self.moderation_user2) + for g in Group.objects.all(): + g.user_set.add(self.moderation_user) + g.user_set.add(self.moderation_user2) def test_actions(self): + self.client.login(username='admin', password='pass') q_markers = Marker.objects.filter(pk__in=[m.pk for m in self.markers]) # disable - response = self.client.post('/admin/chimere/marker/', - data={'action':['disable'], - '_selected_action':[unicode(m.pk) - for m in self.markers], - }) + self.client.post( + '/admin/chimere/marker/', + data={'action': ['disable'], + '_selected_action': [unicode(m.pk) for m in self.markers], + }) self.assertEqual(q_markers.count(), q_markers.filter(status='D').count()) # validate - response = self.client.post('/admin/chimere/marker/', - data={'action':['validate'], - '_selected_action':[unicode(m.pk) - for m in self.markers] - }) + self.client.post('/admin/chimere/marker/', + data={'action': ['validate'], + '_selected_action': [unicode(m.pk) + for m in self.markers] + }) self.assertEqual(q_markers.count(), q_markers.filter(status='A').count()) + def test_moderation_action_filter(self): + m_ok = self.markers[0] + m_nok = self.markers[2] + self.client.login(username='mod_1', password='pass') + response = self.client.get('/admin/chimere/marker/{}/'.format(m_ok.pk)) + self.assertEqual(200, response.status_code) + response = self.client.get( + '/admin/chimere/marker/{}/'.format(m_nok.pk)) + self.assertEqual(200, response.status_code) + self.client.logout() + self.client.login(username='mod_2', password='pass') + response = self.client.get('/admin/chimere/marker/{}/'.format(m_ok.pk)) + self.assertEqual(200, response.status_code) + response = self.client.get( + '/admin/chimere/marker/{}/'.format(m_nok.pk)) + self.assertEqual(404, response.status_code) + class MarkerFormTest(TestCase): def setUp(self): @@ -393,13 +434,16 @@ class MarkerFormTest(TestCase): def test_marker_creation(self): current_date = datetime.datetime.now() # end_date before start_date - data = {'name':"Marker 1", 'status':'A', 'available_date':current_date, - 'point':'SRID=4326;POINT(-4.5 48.4)', 'start_date':current_date, - 'end_date':current_date - datetime.timedelta(1), - 'categories':[self.subcategories[0].pk]} + data = {'name': "Marker 1", 'status': 'A', + 'available_date': current_date, + 'point': 'SRID=4326;POINT(-4.5 48.4)', + 'start_date': current_date, + 'end_date': current_date - datetime.timedelta(1), + 'categories': [self.subcategories[0].pk]} form = MarkerForm(data) self.assertEqual(form.is_valid(), False) + class AreaTest(TestCase): def setUp(self): self.areas = areas_setup() @@ -411,6 +455,7 @@ class AreaTest(TestCase): response = self.client.get('/%s/' % area_1.urn) self.assertRedirects(response, '/') + class AreaAdminFormTest(TestCase): def setUp(self): self.areas = areas_setup() @@ -425,14 +470,15 @@ class AreaAdminFormTest(TestCase): self.assertEqual(area_1.default, False) def test_area_creation(self): - base_data = {'name':u'New test', 'order':3, 'available':True, - 'urn':'area-new', - 'upper_left_lat':48.5, - 'upper_left_lon':-5, - 'lower_right_lat':48, - 'lower_right_lon':-4, - 'upper_left_corner':'SRID=4326;POINT(0 0)', - 'lower_right_corner':'SRID=4326;POINT(0 0)'} + base_data = { + 'name': u'New test', 'order': 3, 'available': True, + 'urn': 'area-new', + 'upper_left_lat': 48.5, + 'upper_left_lon': -5, + 'lower_right_lat': 48, + 'lower_right_lon': -4, + 'upper_left_corner': 'SRID=4326;POINT(0 0)', + 'lower_right_corner': 'SRID=4326;POINT(0 0)'} # order already given data = base_data.copy() data['order'] = self.areas[0].order @@ -452,6 +498,7 @@ class AreaAdminFormTest(TestCase): form = AreaAdminForm(data) self.assertEqual(form.is_valid(), False) + class DynamicCategoryTest(TestCase): def setUp(self): self.areas = areas_setup() @@ -472,55 +519,55 @@ class DynamicCategoryTest(TestCase): cats = json.loads(response.content)['categories'] self.assertEqual(len(cats), 5) + class NewsTest(TestCase): def setUp(self): self.areas = areas_setup() self.markers = marker_setup() current_date = datetime.datetime.now() - marker = Marker.objects.create(name="Marker 4", status='A', - point='SRID=4326;POINT(-4.5 48.45)', - available_date=current_date - datetime.timedelta(days=90), - start_date=current_date - datetime.timedelta(days=90), - end_date=None) + Marker.objects.create( + name="Marker 4", status='A', point='SRID=4326;POINT(-4.5 48.45)', + available_date=current_date - datetime.timedelta(days=90), + start_date=current_date - datetime.timedelta(days=90), + end_date=None) self.news = [] self.news.append(News.objects.create(is_front_page=True, - title=u"Test news 1", available=True, - date=datetime.date.today())) + title=u"Test news 1", available=True, + date=datetime.date.today())) self.news.append(News.objects.create(is_front_page=True, - title=u"Test news 2", available=False, - date=datetime.date.today())) + title=u"Test news 2", available=False, + date=datetime.date.today())) def test_news_display(self): context = display_news(Context({})) self.assertEqual(len(context['news_lst']), 2) - context = display_news(Context({'area_name':'area-2'})) + context = display_news(Context({'area_name': 'area-2'})) self.assertEqual(len(context['news_lst']), 1) + class RapprochementTest(TestCase): def setUp(self): self.areas = areas_setup() self.subcategories = subcategory_setup() self.markers = marker_setup(self.subcategories) self.routes = route_setup(self.subcategories) - self.adminuser = User.objects.create_superuser('admin', - 'admin@test.com', - 'pass') + self.adminuser = User.objects.create_superuser( + 'admin', 'admin@test.com', 'pass') self.client.login(username='admin', password='pass') def test_managed_modified_markers(self): ref_marker = self.markers[0] - new_vals = {'name':"Marker 1 - modified", - 'point':GEOSGeometry('SRID=4326;POINT(-4 48)')} - values = {'status':'M', 'ref_item':ref_marker} + new_vals = {'name': "Marker 1 - modified", + 'point': GEOSGeometry('SRID=4326;POINT(-4 48)')} + values = {'status': 'M', 'ref_item': ref_marker} values.update(new_vals) modified_marker = Marker.objects.create(**values) modified_marker.categories.add(ref_marker.categories.all()[0]) - response = self.client.post('/admin/chimere/marker/', - data={'action':['managed_modified'], - 'index':0, 'rapprochement':1, - 'name':1, 'point':1, - '_selected_action':[unicode(ref_marker.pk)] - }) + self.client.post( + '/admin/chimere/marker/', + data={'action': ['managed_modified'], + 'index': 0, 'rapprochement': 1, 'name': 1, 'point': 1, + '_selected_action': [unicode(ref_marker.pk)]}) ref_marker = Marker.objects.get(pk=ref_marker.pk) self.assertEqual(Marker.objects.filter(ref_item=ref_marker, status='M').count(), 0) @@ -529,20 +576,20 @@ class RapprochementTest(TestCase): def test_managed_modified_imported_markers(self): ref_marker = self.markers[0] - new_vals = {'name':"Marker 1 - modified", - 'point':GEOSGeometry('SRID=4326;POINT(-4 48)')} - values = {'status':'I', 'ref_item':ref_marker, 'import_version':42} + new_vals = {'name': "Marker 1 - modified", + 'point': GEOSGeometry('SRID=4326;POINT(-4 48)')} + values = {'status': 'I', 'ref_item': ref_marker, 'import_version': 42} values.update(new_vals) modified_marker = Marker.objects.create(**values) self.assertNotEqual(ref_marker.import_version, modified_marker.import_version) modified_marker.categories.add(ref_marker.categories.all()[0]) - response = self.client.post('/admin/chimere/marker/', - data={'action':['managed_modified'], - 'index':0, 'rapprochement':1, - 'name':1, 'point':1, - '_selected_action':[unicode(ref_marker.pk)] - }) + self.client.post('/admin/chimere/marker/', + data={'action': ['managed_modified'], + 'index': 0, 'rapprochement': 1, + 'name': 1, 'point': 1, + '_selected_action': [unicode(ref_marker.pk)] + }) ref_marker = Marker.objects.get(pk=ref_marker.pk) self.assertEqual(Marker.objects.filter(ref_item=ref_marker, status='I').count(), 0) @@ -551,37 +598,38 @@ class RapprochementTest(TestCase): def test_managed_modified_routes(self): ref_route = self.routes[0] - new_vals = {'name':"Route 1 - modified", - 'route':GEOSGeometry('SRID=4326;LINESTRING(1 1,2 2)')} - values = {'status':'M', 'ref_item':ref_route, - 'has_associated_marker':True} + new_vals = {'name': "Route 1 - modified", + 'route': GEOSGeometry('SRID=4326;LINESTRING(1 1,2 2)')} + values = {'status': 'M', 'ref_item': ref_route, + 'has_associated_marker': True} values.update(new_vals) modified_route = Route.objects.create(**values) modified_route.categories.add(self.subcategories[1]) - response = self.client.post('/admin/chimere/route/', - data={'action':['managed_modified'], - 'index':0, 'rapprochement':1, - 'name':1, 'route':1, 'categories':1, - '_selected_action':[unicode(ref_route.pk)] - }) + self.client.post('/admin/chimere/route/', + data={'action': ['managed_modified'], + 'index': 0, 'rapprochement': 1, + 'name': 1, 'route': 1, 'categories': 1, + '_selected_action': [unicode(ref_route.pk)] + }) ref_route = Route.objects.get(pk=ref_route.pk) self.assertEqual(Route.objects.filter(ref_item=ref_route, - status='M').count(), 0) + status='M').count(), 0) self.assertEqual(ref_route.name, new_vals['name']) self.assertEqual(ref_route.route.wkt, new_vals['route'].wkt) self.assertEqual(ref_route.categories.all()[0], self.subcategories[1]) self.assertEqual(ref_route.associated_marker.all()[0].name, ref_route.name) + class RouteTest(TestCase): def setUp(self): self.subcategories = subcategory_setup() def test_route_creation(self): - route_1 = Route.objects.create(name='Route 1', - route='SRID=4326;LINESTRING (30 10, 10 30, 40 40)') + route_1 = Route.objects.create( + name='Route 1', route='SRID=4326;LINESTRING (30 10, 10 30, 40 40)') self.assertEqual(Marker.objects.filter(route=route_1).count(), 1) - route_2 = Route.objects.create(name='Route 1', - route='SRID=4326;LINESTRING (30 10, 10 30, 40 40)', - has_associated_marker=False) + route_2 = Route.objects.create( + name='Route 1', route='SRID=4326;LINESTRING (30 10, 10 30, 40 40)', + has_associated_marker=False) self.assertEqual(Marker.objects.filter(route=route_2).count(), 0) |