Browse Source

Doing todo

Added a dummy EmFieldType_icon
Added a test for EmType deletion with superiors
Yann Weber 9 years ago
parent
commit
e757a3fb90
3 changed files with 82 additions and 30 deletions
  1. 21
    0
      EditorialModel/fieldtypes.py
  2. 19
    0
      EditorialModel/test/test_types.py
  3. 42
    30
      EditorialModel/types.py

+ 21
- 0
EditorialModel/fieldtypes.py View File

@@ -191,3 +191,24 @@ class EmField_mlstring(EmFieldType):
191 191
 
192 192
     def sqlalchemy_args(self):
193 193
         return {'type_': VARCHAR(250), 'nullable': True, 'default': None}
194
+
195
+class EmField_icon(EmFieldType):
196
+    
197
+    def __init__(self):
198
+        super(EmField_icon, self).__init__('icon')
199
+        pass
200
+
201
+    def from_string(self,value):
202
+        self.value = value
203
+
204
+    def to_sql(self, value=None):
205
+        if value != None:
206
+            value = str(value)
207
+        return value
208
+
209
+    def sql_column(self):
210
+        pass
211
+
212
+    def sqlalchemy_args(self):
213
+        return {'type_': INTEGER, 'nullable': True, 'default': None}
214
+

+ 19
- 0
EditorialModel/test/test_types.py View File

@@ -221,4 +221,23 @@ class TestDeleteTypes(TypeTestCase):
221 221
         except EmComponentNotExistError:
222 222
             self.fail("The type was deleted but it has subordinates when deleted")
223 223
         pass
224
+    
225
+    def testDeleteTypesInHierarchy(self):
226
+        """ Testing if deletetion deletes properly links with superiors """
227
+        type_name = self.emtype.name
228
+        type_uid = self.emtype.uid
229
+        self.emtype.add_superior(self.emtype2, EmNature.PARENT)
230
+        self.emtype.delete()
231
+        try:
232
+            subs_dict = self.emtype2.subordinates()
233
+        except EmComponentNotExistError:
234
+            self.fail("The deleted type is style in the types hierarchu. Trying to retrieve it raises an EmComponentNotFoundError")
235
+
236
+        subsuid=[]
237
+        for _, subs in subs_dict.items():
238
+            subsuid += subs
239
+        self.assertNotIn(type_uid, subsuid)
240
+        pass
241
+
242
+
224 243
 

+ 42
- 30
EditorialModel/types.py View File

@@ -6,6 +6,7 @@ import sqlalchemy as sql
6 6
 import EditorialModel
7 7
 from EditorialModel.components import EmComponent, EmComponentNotExistError
8 8
 from EditorialModel.fieldgroups import EmFieldGroup
9
+from EditorialModel.fields import EmField
9 10
 from EditorialModel.classtypes import EmNature, EmClassType
10 11
 import EditorialModel.fieldtypes as ftypes
11 12
 import EditorialModel.classes
@@ -18,13 +19,14 @@ import EditorialModel.classes
18 19
 # @see EditorialModel::components::EmComponent
19 20
 class EmType(EmComponent):
20 21
     table = 'em_type'
22
+    table_hierarchy = 'em_type_hierarchy'
21 23
     ranked_in = 'class_id'
22 24
 
23 25
     ## @brief Specific EmClass fields
24 26
     # @see EditorialModel::components::EmComponent::_fields
25 27
     _fields = [
26 28
         ('class_id', ftypes.EmField_integer),
27
-        ('icon', ftypes.EmField_integer),
29
+        ('icon', ftypes.EmField_icon),
28 30
         ('sortcolumn', ftypes.EmField_char)
29 31
         ]
30 32
 
@@ -37,22 +39,37 @@ class EmType(EmComponent):
37 39
     # @throw EmComponentExistError if an EmType with this name but different attributes exists
38 40
     # @see EmComponent::__init__()
39 41
     # 
40
-    # @todo Remove hardcoded default value for icon
41
-    # @todo check that em_class is an EmClass object
42
+    # @todo check that em_class is an EmClass object (fieldtypes can handle it)
42 43
     def create(c, name, em_class, **em_component_args):
43
-        return super(EmType, c).create(name=name, class_id=em_class.uid, icon=0, **em_component_args)
44
-    
44
+        return super(EmType, c).create(name=name, class_id=em_class.uid, **em_component_args)
45
+
46
+    @property
47
+    ## Return an sqlalchemy table for type hierarchy
48
+    # @return sqlalchemy em_type_hierarchy table object
49
+    # @todo Don't hardcode table name
50
+    def _table_hierarchy(self):
51
+        return sql.Table(self.__class__.table_hierarchy, sqlutils.meta(self.db_engine()))
52
+
53
+    @property
54
+    ## Return the EmClassType of the type
55
+    # @return EditorialModel.classtypes.*
56
+    def classtype(self):
57
+        return getattr(EmClassType, EditorialModel.classes.EmClass(self.class_id).classtype)
58
+
45 59
     ## @brief Delete an EmType
46 60
     # The deletion is only possible if a type is not linked by any EmClass
47 61
     # and if it has no subordinates
48 62
     # @return True if delete False if not deleted
49 63
     # @todo Check if the type is not linked by any EmClass
50 64
     # @todo Check if there is no other ''non-deletion'' conditions
51
-    # @todo Delete it as subordinates for all its superiors
52 65
     def delete(self):
53 66
         subs = self.subordinates()
54 67
         if sum([len(subs[subnat]) for subnat in subs]) > 0:
55 68
             return False
69
+        #Delete all relation with superiors
70
+        for nature,sups in self.superiors().items():
71
+            for sup in sups:
72
+                self.del_superior(sup, nature)
56 73
         return super(EmType, self).delete()
57 74
         
58 75
 
@@ -103,8 +120,10 @@ class EmType(EmComponent):
103 120
     #
104 121
     # @param field EmField: The optional field to select
105 122
     # @return True if success False if failed
106
-    # @throw TypeError
107
-    # @todo change exception type and define return value and raise condition
123
+    #
124
+    # @throw TypeError if field is not an EmField instance
125
+    # @throw ValueError if field is not optional or is not associated with this type
126
+    # @see EmType::_opt_field_act()
108 127
     def select_field(self, field):
109 128
         return self._opt_field_act(field, True)
110 129
         
@@ -114,7 +133,10 @@ class EmType(EmComponent):
114 133
     #
115 134
     # @param field EmField: The optional field to unselect
116 135
     # @return True if success False if fails
117
-    # @throw TypeError
136
+    #
137
+    # @throw TypeError if field is not an EmField instance
138
+    # @throw ValueError if field is not optional or is not associated with this type
139
+    # @see EmType::_opt_field_act()
118 140
     def unselect_field(self, field):
119 141
         return self._opt_field_act(field, False)
120 142
 
@@ -123,9 +145,12 @@ class EmType(EmComponent):
123 145
     # @param field EmField: The EmField to select or unselect
124 146
     # @param select bool: If True select field, else unselect it
125 147
     # @return True if success False if fails
148
+    #
126 149
     # @throw TypeError if field is not an EmField instance
127 150
     # @throw ValueError if field is not optional or is not associated with this type
128 151
     def _opt_field_act(self, field, select=True):
152
+        if not isinstance(field, EmField):
153
+            raise TypeError("Excepted <class EmField> as field argument. But got "+str(type(field)))
129 154
         if not field in self.all_fields():
130 155
             raise ValueError("This field is not part of this type")
131 156
         if not field.optional:
@@ -149,7 +174,7 @@ class EmType(EmComponent):
149 174
     # @note Not conceptualized yet
150 175
     # @todo Conception
151 176
     def hooks(self):
152
-        pass
177
+        raise NotImplementedError()
153 178
 
154 179
     ## Add a new hook
155 180
     # @param hook EmHook: An EmHook instance
@@ -157,7 +182,7 @@ class EmType(EmComponent):
157 182
     # @note Not conceptualized yet
158 183
     # @todo Conception
159 184
     def add_hook(self, hook):
160
-        pass
185
+        raise NotImplementedError()
161 186
 
162 187
     ## Delete a hook
163 188
     # @param hook EmHook: An EmHook instance
@@ -166,22 +191,9 @@ class EmType(EmComponent):
166 191
     # @todo Conception
167 192
     # @todo Maybe we don't need a EmHook instance but just a hook identifier
168 193
     def del_hook(self,hook):
169
-        pass
170
-
171
-
172
-    @classmethod
173
-    ## Return an sqlalchemy table for type hierarchy
174
-    # @return sqlalchemy em_type_hierarchy table object
175
-    # @todo Don't hardcode table name
176
-    def _tableHierarchy(cl):
177
-        return sql.Table('em_type_hierarchy', sqlutils.meta(cl.db_engine()))
178
-
179
-    @property
180
-    ## Return the EmClassType of the type
181
-    # @return EditorialModel.classtypes.*
182
-    def classtype(self):
183
-        return getattr(EmClassType, EditorialModel.classes.EmClass(self.class_id).classtype)
194
+        raise NotImplementedError()
184 195
 
196
+    
185 197
     ## @brief Get the list of subordinates EmType
186 198
     # Get a list of EmType instance that have this EmType for superior
187 199
     # @return Return a dict with relation nature as keys and values as a list of subordinates
@@ -207,7 +219,7 @@ class EmType(EmComponent):
207 219
     # @see EmType::subordinates(), EmType::superiors()
208 220
     def _subOrSup(self, sup = True):
209 221
         conn = self.db_engine().connect()
210
-        htable = self.__class__._tableHierarchy()
222
+        htable = self._table_hierarchy
211 223
         req = htable.select()
212 224
         if sup:
213 225
             req = req.where(htable.c.subordinate_id == self.uid)
@@ -255,7 +267,7 @@ class EmType(EmComponent):
255 267
             raise ValueError("Not allowed to put a different em_type as superior in a relation of nature '"+relation_nature+"'")
256 268
 
257 269
         conn = self.db_engine().connect()
258
-        htable = self.__class__._tableHierarchy()
270
+        htable = self._table_hierarchy
259 271
         values = { 'subordinate_id': self.uid, 'superior_id': em_type.uid, 'nature': relation_nature }
260 272
         req = htable.insert(values=values)
261 273
 
@@ -280,7 +292,7 @@ class EmType(EmComponent):
280 292
             raise ValueError("Invalid nature for add_superior : '"+relation_nature+"'. Allowed relations for this type are "+str(EmClassType.natures(self.classtype['name'])))
281 293
 
282 294
         conn = self.db_engine().connect()
283
-        htable = self.__class__._tableHierarchy()
295
+        htable = self._table_hierarchy
284 296
         req = htable.delete(htable.c.superior_id == em_type.uid and htable.c.nature == relation_nature)
285 297
         conn.execute(req)
286 298
         conn.close()
@@ -296,7 +308,7 @@ class EmType(EmComponent):
296 308
     # @return A list of EmType objects
297 309
     def _linked_types_Db(self):
298 310
         conn = self.db_engine().connect()
299
-        htable = self.__class__._tableHierarchy()
311
+        htable = self._table_hierarchy
300 312
         req = htable.select(htable.c.superior_id, htable.c.subordinate_id)
301 313
         req = req.where(sql.or_(htable.c.subordinate_id == self.uid, htable.c.superior_id == self.uid))
302 314
 

Loading…
Cancel
Save