summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/app/tests/test_workflow.py53
-rw-r--r--src/mailman/app/workflow.py8
2 files changed, 59 insertions, 2 deletions
diff --git a/src/mailman/app/tests/test_workflow.py b/src/mailman/app/tests/test_workflow.py
index a5bbd0792..d13dce552 100644
--- a/src/mailman/app/tests/test_workflow.py
+++ b/src/mailman/app/tests/test_workflow.py
@@ -17,10 +17,13 @@
"""App-level workflow tests."""
+import json
import unittest
from mailman.app.workflow import Workflow
+from mailman.interfaces.workflow import IWorkflowStateManager
from mailman.testing.layers import ConfigLayer
+from zope.component import getUtility
class MyWorkflow(Workflow):
@@ -111,6 +114,56 @@ class TestWorkflow(unittest.TestCase):
self.assertEqual(new_workflow.cat, 7)
self.assertEqual(new_workflow.dog, 4)
+ def test_save_and_restore_dependant_attributes(self):
+ # Attributes must be restored in the order they are declared in
+ # SAVE_ATTRIBUTES.
+
+ class DependantWorkflow(MyWorkflow):
+ SAVE_ATTRIBUTES = ('ant', 'bee', 'cat', 'elf')
+
+ def __init__(self):
+ super().__init__()
+ self._elf = 5
+
+ @property
+ def elf(self):
+ return self._elf
+
+ @elf.setter
+ def elf(self, value):
+ # This attribute depends on other attributes.
+ assert self.ant is not None
+ assert self.bee is not None
+ assert self.cat is not None
+ self._elf = value
+
+ workflow = iter(DependantWorkflow())
+ workflow.elf = 6
+ workflow.save()
+ new_workflow = DependantWorkflow()
+ # The elf attribute must be restored last, set triggering values for
+ # attributes it depends on.
+ new_workflow.ant = new_workflow.bee = new_workflow.cat = None
+ new_workflow.restore()
+ self.assertEqual(new_workflow.elf, 6)
+
+ def test_save_and_restore_obsolete_attributes(self):
+ # Obsolete saved attributes are ignored.
+ state_manager = getUtility(IWorkflowStateManager)
+ # Save the state of an old version of the workflow that would not have
+ # the cat attribute.
+ state_manager.save(
+ 'MyWorkflow', self._workflow.token, 'first',
+ json.dumps({'ant': 1, 'bee': 2}))
+ # Restore in the current version that needs the cat attribute.
+ new_workflow = MyWorkflow()
+ try:
+ new_workflow.restore()
+ except KeyError:
+ self.fail("Restore does not handle obsolete attributes")
+ # Restoring must not raise an exception, the default value is kept.
+ self.assertEqual(new_workflow.cat, 3)
+
def test_run_thru(self):
# Run all steps through the given one.
results = self._workflow.run_thru('second')
diff --git a/src/mailman/app/workflow.py b/src/mailman/app/workflow.py
index 36fd7d611..cd9124993 100644
--- a/src/mailman/app/workflow.py
+++ b/src/mailman/app/workflow.py
@@ -143,5 +143,9 @@ class Workflow:
self._next.clear()
if state.step:
self._next.append(state.step)
- for attr, value in json.loads(state.data).items():
- setattr(self, attr, value)
+ data = json.loads(state.data)
+ for attr in self.SAVE_ATTRIBUTES:
+ try:
+ setattr(self, attr, data[attr])
+ except KeyError:
+ pass