fix #1452413 : is_in_state selector does not match initial state of an entity stable
authorAlexandre Fayolle <alexandre.fayolle@logilab.fr>
Thu, 27 Jan 2011 14:10:44 +0100
branchstable
changeset 6908 f07dc0e8948d
parent 6907 449e5b46ed3d
child 6909 b8171392de16
fix #1452413 : is_in_state selector does not match initial state of an entity
selectors.py
test/data/schema.py
test/unittest_selectors.py
--- a/selectors.py	Thu Jan 27 13:43:49 2011 +0100
+++ b/selectors.py	Thu Jan 27 14:10:44 2011 +0100
@@ -1186,11 +1186,13 @@
     """
     def __init__(self, *states):
         def score(entity, states=set(states)):
-            trinfo = entity.cw_adapt_to('IWorkflowable').latest_trinfo()
-            try:
-                return trinfo.new_state.name in states
-            except AttributeError:
-                return None
+            adapted = entity.cw_adapt_to('IWorkflowable')
+            trinfo = adapted.latest_trinfo()
+            if trinfo is None: # entity is probably in it's initial state
+                statename = adapted.state
+            else:
+                statename = trinfo.new_state.name
+            return statename in states
         super(is_in_state, self).__init__(score)
 
 
--- a/test/data/schema.py	Thu Jan 27 13:43:49 2011 +0100
+++ b/test/data/schema.py	Thu Jan 27 14:10:44 2011 +0100
@@ -19,7 +19,9 @@
 
 """
 
-from yams.buildobjs import EntityType, String, SubjectRelation, RelationDefinition
+from yams.buildobjs import (EntityType, String, SubjectRelation,
+                            RelationDefinition)
+from cubicweb.schema import  WorkflowableEntityType
 
 class Personne(EntityType):
     nom = String(required=True)
@@ -48,3 +50,8 @@
 class evaluee(RelationDefinition):
     subject = 'CWUser'
     object = 'Note'
+
+class StateFull(WorkflowableEntityType):
+    name = String()
+
+
--- a/test/unittest_selectors.py	Thu Jan 27 13:43:49 2011 +0100
+++ b/test/unittest_selectors.py	Thu Jan 27 14:10:44 2011 +0100
@@ -24,9 +24,10 @@
 from cubicweb.devtools.testlib import CubicWebTC
 from cubicweb.appobject import Selector, AndSelector, OrSelector
 from cubicweb.selectors import (is_instance, adaptable, match_user_groups,
-                                multi_lines_rset, score_entity)
+                                multi_lines_rset, score_entity, is_in_state)
 from cubicweb.interfaces import IDownloadable
 from cubicweb.web import action
+from cubicweb.server.migractions import ServerMigrationHelper
 
 class _1_(Selector):
     def __call__(self, *args, **kwargs):
@@ -137,6 +138,37 @@
         selector |= _0_()
         self.assertEqual(selector(None), 0)
 
+class IsInStateSelectorTC(CubicWebTC):
+    def setup_database(self):
+        mh = ServerMigrationHelper(self.repo.config, None,
+                                   repo=self.repo, cnx=self.cnx,
+                                   interactive=False)
+        wf = mh.cmd_add_workflow('testwf', 'StateFull', default=True)
+        initial = wf.add_state(u'initial', initial=True)
+        final = wf.add_state(u'final')
+        wf.add_transition(u'forward', (initial,), final)
+
+    def test_initial_state(self):
+        req = self.request()
+        entity = req.create_entity('StateFull')
+        selector = is_in_state(u'initial')
+        self.commit()
+        score = selector(entity.__class__, None, entity=entity)
+        self.assertEqual(score, 1)
+
+    def test_final_state(self):
+        req = self.request()
+        entity = req.create_entity('StateFull')
+        selector = is_in_state(u'initial')
+        self.commit()
+        entity.cw_adapt_to('IWorkflowable').fire_transition(u'forward')
+        self.commit()
+        score = selector(entity.__class__, None, entity=entity)
+        self.assertEqual(score, 0)
+        selector = is_in_state(u'final')
+        score = selector(entity.__class__, None, entity=entity)
+        self.assertEqual(score, 1)
+
 
 class ImplementsSelectorTC(CubicWebTC):
     def test_etype_priority(self):