diff options
| author | Étienne Loks <etienne.loks@proxience.com> | 2015-01-24 18:46:27 +0100 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@proxience.com> | 2015-01-24 18:46:27 +0100 | 
| commit | e874b48bc99c2081ca918bf3e6ef6602f8148307 (patch) | |
| tree | 240a04d141dbbce702de39f17b6859fb888a342e | |
| parent | 73d21de642443d03a76285a9038389a5acbdd92d (diff) | |
| download | Ishtar-e874b48bc99c2081ca918bf3e6ef6602f8148307.tar.bz2 Ishtar-e874b48bc99c2081ca918bf3e6ef6602f8148307.zip | |
Prevent incoherent RelationType
* check that no relation type with symmetrical=True and an inverse relation are
  set
* after saving check that theinverse_relation of the inverse_relation
  point to the saved object
* test update
| -rw-r--r-- | archaeological_context_records/models.py | 19 | ||||
| -rw-r--r-- | archaeological_context_records/tests.py | 90 | ||||
| -rw-r--r-- | archaeological_operations/tests.py | 73 | 
3 files changed, 177 insertions, 5 deletions
| diff --git a/archaeological_context_records/models.py b/archaeological_context_records/models.py index a8c6a1dcc..9a4fa7880 100644 --- a/archaeological_context_records/models.py +++ b/archaeological_context_records/models.py @@ -19,6 +19,7 @@  from django.conf import settings  from django.contrib.gis.db import models +from django.core.exceptions import ValidationError  from django.core.urlresolvers import reverse  from django.utils.translation import ugettext_lazy as _, ugettext, pgettext @@ -252,6 +253,24 @@ class RelationType(GeneralType):          verbose_name_plural = _(u"Relation types")          ordering = ('order',) +    def clean(self): +        # cannot have symmetrical and an inverse_relation +        if self.symmetrical and self.inverse_relation: +            raise ValidationError( +                        _(u"Cannot have symmetrical and an inverse_relation")) + +    def save(self, *args, **kwargs): +        obj = super(RelationType, self).save(*args, **kwargs) +        # after saving check that the inverse_relation of the inverse_relation +        # point to the saved object +        if self.inverse_relation \ +           and (not self.inverse_relation.inverse_relation +                or self.inverse_relation.inverse_relation != self): +            self.inverse_relation.inverse_relation = self +            self.inverse_relation.symmetrical = False +            self.inverse_relation.save() +        return obj +  class RecordRelations(models.Model):      left_record = models.ForeignKey(ContextRecord,                                      related_name='left_relations') diff --git a/archaeological_context_records/tests.py b/archaeological_context_records/tests.py new file mode 100644 index 000000000..2d144de3a --- /dev/null +++ b/archaeological_context_records/tests.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright (C) 2015 Étienne Loks  <etienne.loks_AT_peacefrogsDOTnet> + +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU Affero General Public License for more details. + +# You should have received a copy of the GNU Affero General Public License +# along with this program.  If not, see <http://www.gnu.org/licenses/>. + +# See the file COPYING for details. + +""" +Unit tests +""" +import json + +from django.conf import settings +from django.core.exceptions import ValidationError +from django.test import TestCase + +from archaeological_operations.tests import OperationInitTest +from archaeological_operations.models import Parcel +from archaeological_context_records import models + + +class ContextRecordInit(OperationInitTest): + +    def create_context_record(self, user=None, data={}): +        if not getattr(self, 'context_records', None): +            self.context_records = [] + +        default = {'label':"Context record"} +        if not data.get('operation'): +            data['operation'] = self.get_default_operation() +        if not data.get('parcel'): +            data['parcel'] = self.get_default_parcel() +        if not data.get('user'): +            data['user'] = self.get_default_user() + +        default.update(data) +        context_records.append(models.ContextRecord.create(**default)) +        return context_records + +    def get_default_context_record(self): +        return self.create_context_record()[0] + +class RecordRelationsTest(TestCase, ContextRecordInit): +    fixtures = [settings.ROOT_PATH + +                '../fixtures/initial_data.json', +                settings.ROOT_PATH + +                '../ishtar_common/fixtures/initial_data.json', +                settings.ROOT_PATH + +                '../archaeological_files/fixtures/initial_data.json', +                settings.ROOT_PATH + +                '../archaeological_operations/fixtures/initial_data-fr.json'] +    model = models.ContextRecord + +    def setUp(self): +        # two different context record +        print(1333) +        self.create_context_record({"label":u"CR 1"}) +        print(1444) +        self.create_context_record({"label":u"CR 2"}) +        print(15555) + +    def testRelations(self): +        print(1) +        sym_rel = models.RelationType.objects.create(symmetrical=True) +        print(12) +        rel_1 = models.RelationType.objects.create(symmetrical=False) +        print(13) +        rel_2 = models.RelationType.objects.create(symmetrical=False, +                                    inverse_relation=rel_1) +        print(14) +        # cannot have symmetrical and an inverse_relation +        with self.assertRaises(ValidationError): +            rel_3 = models.RelationType.objects.create(symmetrical=True, +                                    inverse_relation=rel_1) +        print(15) +        # auto fill inverse relations +        self.assertEqual(rel_1.inverse_relation, rel_2) + diff --git a/archaeological_operations/tests.py b/archaeological_operations/tests.py index 808d999af..1e2cadc27 100644 --- a/archaeological_operations/tests.py +++ b/archaeological_operations/tests.py @@ -43,7 +43,7 @@ class ImportOperationTest(TestCase):                  '../archaeological_operations/fixtures/initial_data-fr.json']      def setUp(self): -        user = User.objects.create_superuser('username') +        self.username, self.password, self.user = create_superuser()      def testImportDbfOperation(self):          """ @@ -324,7 +324,7 @@ def create_orga(user):      orga, created = Organization.objects.get_or_create(name='Operator',                                              organization_type=orga_type,                                              history_modifier=user) -    return [orga] +    return orga  def create_operation(user, orga=None):      dct = {'year':2010, 'operation_type_id':1, @@ -334,8 +334,71 @@ def create_operation(user, orga=None):      operations = [models.Operation.objects.create(**dct)]      return operations -class OperationTest(TestCase): +class OperationInitTest(object): +    def create_user(self): +        username, password, self.user = create_user() + +    def get_default_user(self): +        if not hasattr(self, 'user') or not self.user: +            self.create_user() +        return self.user + +    def create_orgas(self, user=None): +        if not user: +            user = self.get_default_user() +        self.orgas = [create_orga(user)] +        return self.orgas + +    def get_default_orga(self, user=None): +        if not hasattr(self, 'orgas') or not self.orgas: +            self.create_orgas(user) +        return self.orgas[0] + +    def create_towns(self, datas={}): +        default = {'numero_insee':'12345', 'name':'default_town'} +        default.update(datas) +        town = models.Town.objects.create(**default) +        if not hasattr(self, 'towns') or not self.towns: +            self.towns = [] +        self.towns.append(town) +        return self.towns + +    def get_default_town(self): +        town = getattr(self, 'towns', None) +        if not town: +            self.create_towns() +            town = self.towns[0] +        return town + +    def create_parcel(self, data={}): +        default = {'town':self.get_default_town(), +                   'section':'A', 'parcel_number':'1'} +        default.update(data) +        if not getattr(self, 'parcels', None): +            self.parcels = [] +        self.parcels.update(models.Parcel.objects.create(**default)) +        return self.parcels + +    def get_default_parcel(self): +        return self.create_parcel()[0] + +    def create_operation(self, user=None, orga=None): +        if not orga: +            self.get_default_orga(user) +        if not user: +            self.get_default_user() +        if not getattr(self, 'operations', None): +            self.operations = [] +        self.operations.append(create_operation(user, orga)) +        return self.operations + +    def get_default_operation(self): +        return self.create_operation()[0] + +class OperationTest(TestCase, OperationInitTest):      fixtures = [settings.ROOT_PATH + +                '../fixtures/initial_data.json', +                settings.ROOT_PATH +                  '../ishtar_common/fixtures/initial_data.json',                  settings.ROOT_PATH +                  '../archaeological_files/fixtures/initial_data.json', @@ -347,8 +410,8 @@ class OperationTest(TestCase):          self.alt_username, self.alt_password, self.alt_user = create_user()          self.alt_user.user_permissions.add(Permission.objects.get(                                              codename='view_own_operation')) -        self.orgas = create_orga(self.user) -        self.operations = create_operation(self.user, self.orgas[0]) +        self.orgas = self.create_orgas(self.user) +        self.operations = self.create_operation(self.user, self.orgas[0])          self.operations += create_operation(self.alt_user, self.orgas[0])          self.item = self.operations[0] | 
