def test__shouldMigrationForIterationMustFinishInShortAmountOfTimeWithTooManyObject(self): out = StringIO() sys.stout = out state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") state3 = StateObjectFactory(label="state3") state4 = StateObjectFactory(label="state4") workflow = WorkflowFactory(initial_state=state1, content_type=ContentType.objects.get_for_model(BasicTestModel), field_name="my_field") transition_meta_1 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state1, ) transition_meta_2 = TransitionMetaFactory.create( workflow=workflow, source_state=state2, destination_state=state3, ) transition_meta_3 = TransitionMetaFactory.create( workflow=workflow, source_state=state2, destination_state=state4, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_1, priority=0 ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=0 ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=1 ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_3, priority=0 ) BasicTestModelObjectFactory.create_batch(250) call_command('migrate', 'river', '0006', stdout=out) before = datetime.now() call_command('migrate', 'river', '0007', stdout=out) after = datetime.now() assert_that(after - before, less_than(timedelta(minutes=5)))
def test_shouldAssesFinalStateProperlyWhenThereAreMultiple(self): state1 = StateObjectFactory(label="state1") state21 = StateObjectFactory(label="state21") state22 = StateObjectFactory(label="state22") state31 = StateObjectFactory(label="state31") state32 = StateObjectFactory(label="state32") workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") transition_meta1 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state21, ) transition_meta2 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state22, ) transition_meta3 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state31, ) transition_meta4 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state32, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta1, priority=0 ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta2, priority=0 ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta3, priority=0 ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta4, priority=0 ) assert_that(BasicTestModel.river.my_field.final_states, has_length(4)) assert_that(list(BasicTestModel.river.my_field.final_states), has_items(state21, state22, state31, state32))
def test_shouldNotAllowWorkflowToBeDeletedWhenThereIsATransitionApproval( self): content_type = ContentType.objects.get_for_model(BasicTestModel) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) TransitionApprovalMetaFactory.create(workflow=workflow, transition_meta=transition_meta, priority=0) BasicTestModelObjectFactory(workflow=workflow) TransitionApproval.objects.filter(workflow=workflow).update( status=APPROVED) approvals = TransitionApproval.objects.filter(workflow=workflow) assert_that(approvals, has_length(1)) assert_that( calling(workflow.delete), raises( ProtectedError, "Cannot delete some instances of model 'Workflow' because they are referenced through a protected foreign key" ))
def test_shouldNotDeletePendingTransitionWhenDeleted(self): content_type = ContentType.objects.get_for_model(BasicTestModel) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) meta1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0) BasicTestModelObjectFactory(workflow=workflow) TransitionApproval.objects.filter(workflow=workflow).update( status=PENDING) assert_that(TransitionApproval.objects.filter(workflow=workflow), has_length(1)) meta1.delete() assert_that(TransitionApproval.objects.filter(workflow=workflow), has_length(0))
def test_shouldReturnNoApprovalWhenUserIsUnAuthorized(self): unauthorized_user = UserObjectFactory() state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") authorized_permission = PermissionObjectFactory() transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0, permissions=[authorized_permission]) BasicTestModelObjectFactory(workflow=workflow) available_approvals = BasicTestModel.river.my_field.get_available_approvals( as_user=unauthorized_user) assert_that(available_approvals, has_length(0))
def test__shouldReturnApprovalsOnTimeWhenTooManyWorkflowObject(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0, permissions=[authorized_permission]) self.objects = BasicTestModelObjectFactory.create_batch( 250, workflow=workflow) before = datetime.now() BasicTestModel.river.my_field.get_on_approval_objects( as_user=authorized_user) after = datetime.now() assert_that(after - before, less_than(timedelta(milliseconds=200))) print("Time taken %s" % str(after - before))
def test_shouldReturnAnApprovalWhenUserIsAuthorizedWithAUserGroup(self): authorized_user_group = GroupObjectFactory() authorized_user = UserObjectFactory(groups=[authorized_user_group]) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) approval_meta = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0) approval_meta.groups.add(authorized_user_group) workflow_object = BasicTestModelObjectFactory(workflow=workflow) available_approvals = BasicTestModel.river.my_field.get_available_approvals( as_user=authorized_user) assert_that(available_approvals, has_length(1)) assert_that( list(available_approvals), has_item( all_of( has_property("workflow_object", workflow_object.model), has_property("workflow", workflow), has_property("transition", transition_meta.transitions.first()))))
def test_shouldInjectTheField(self): # pylint: disable=no-self-use assert_that(BasicTestModel, has_property('river', is_(instance_of(RiverObject)))) assert_that(BasicTestModel.river, has_property('my_field', is_(instance_of(ClassWorkflowObject)))) content_type = ContentType.objects.get_for_model(BasicTestModel) state1 = StateObjectFactory.create(label="state1") state2 = StateObjectFactory.create(label="state2") workflow = WorkflowFactory(content_type=content_type, field_name="my_field", initial_state=state1) transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0 ) test_model = BasicTestModel.objects.create(workflow=workflow) assert_that(test_model, has_property('river', is_(instance_of(RiverObject)))) assert_that(test_model.river, has_property('my_field', is_(instance_of(InstanceWorkflowObject)))) assert_that(BasicTestModel.river.my_field, has_property('initial_state', is_(instance_of(State)))) assert_that(BasicTestModel.river.my_field, has_property('final_states', is_(instance_of(QuerySet)))) assert_that(test_model.river.my_field, has_property('approve', has_property("__call__"))) assert_that(test_model.river.my_field, has_property('on_initial_state', is_(instance_of(bool)))) assert_that(test_model.river.my_field, has_property('on_final_state', is_(instance_of(bool))))
def test_shouldNotDeleteApprovedTransitionWhenDeleted(self): content_type = ContentType.objects.get_for_model(BasicTestModel) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) meta1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0) BasicTestModelObjectFactory(workflow=workflow) TransitionApproval.objects.filter(workflow=workflow).update( status=APPROVED) approvals = TransitionApproval.objects.filter(workflow=workflow) assert_that(approvals, has_length(1)) assert_that(approvals, has_item(has_property("meta", meta1))) meta1.delete() approvals = TransitionApproval.objects.filter(workflow=workflow) assert_that(approvals, has_length(1)) assert_that(approvals, has_item(has_property("meta", none())))
def transition(context, source_state_label, destination_state_label, workflow_identifier): from river.models import State from django.contrib.contenttypes.models import ContentType from river.models.factories import TransitionMetaFactory from river.tests.models import BasicTestModel from river.models.factories import WorkflowFactory source_state, _ = State.objects.get_or_create(label=source_state_label) workflow = getattr(context, "workflows", {}).get(workflow_identifier, None) if not workflow: content_type = ContentType.objects.get_for_model(BasicTestModel) workflow = WorkflowFactory(initial_state=source_state, content_type=content_type, field_name="my_field") if "workflows" not in context: context.workflows = {} context.workflows[workflow_identifier] = workflow destination_state, _ = State.objects.get_or_create(label=destination_state_label) transition = TransitionMetaFactory.create( workflow=workflow, source_state=source_state, destination_state=destination_state, ) identifier = source_state_label + destination_state_label transitions = getattr(context, "transitions", {}) transitions[identifier] = transition context.transitions = transitions
def test__shouldMigrateTransitionApprovalStatusToStringInDB(self): out = StringIO() sys.stout = out state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory( initial_state=state1, content_type=ContentType.objects.get_for_model(BasicTestModel), field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) TransitionApprovalMetaFactory.create(workflow=workflow, transition_meta=transition_meta, priority=0) workflow_object = BasicTestModelObjectFactory() with connection.cursor() as cur: result = cur.execute( "select status from river_transitionapproval where object_id=%s;" % workflow_object.model.pk).fetchall() assert_that(result[0][0], equal_to("pending")) call_command('migrate', 'river', '0004', stdout=out) with connection.cursor() as cur: schema = cur.execute( "PRAGMA table_info('river_transitionapproval');").fetchall() status_col_type = list( filter(lambda column: column[1] == 'status', schema))[0][2] assert_that(status_col_type, equal_to("integer")) result = cur.execute( "select status from river_transitionapproval where object_id=%s;" % workflow_object.model.pk).fetchall() assert_that(result[0][0], equal_to(0)) call_command('migrate', 'river', '0005', stdout=out) with connection.cursor() as cur: schema = cur.execute( "PRAGMA table_info('river_transitionapproval');").fetchall() status_col_type = list( filter(lambda column: column[1] == 'status', schema))[0][2] assert_that(status_col_type, equal_to("varchar(100)")) result = cur.execute( "select status from river_transitionapproval where object_id=%s;" % workflow_object.model.pk).fetchall() assert_that(result[0][0], equal_to("pending"))
def transition(context, source_state_label, destination_state_label, workflow_identifier): from river.models import State from river.models.factories import TransitionMetaFactory workflow = getattr(context, "workflows", {})[workflow_identifier] source_state = State.objects.get(label=source_state_label) destination_state = State.objects.get(label=destination_state_label) transition = TransitionMetaFactory.create( workflow=workflow, source_state=source_state, destination_state=destination_state, ) identifier = source_state_label + destination_state_label transitions = getattr(context, "transitions", {}) transitions[identifier] = transition context.transitions = transitions
def test_shouldAssesInitialStateProperly(self): state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0 ) assert_that(BasicTestModel.river.my_field.initial_state, equal_to(state1))
def test_shouldAssesFinalStateProperlyWhenThereIsOnlyOne(self): state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0 ) assert_that(BasicTestModel.river.my_field.final_states, has_length(1)) assert_that(list(BasicTestModel.river.my_field.final_states), has_item(state2))
def build(self): workflow = None states = {} transition_metas = [] transitions_approval_metas = [] workflow_objects = [] for additional_raw_state in self.additional_raw_states: state, _ = State.objects.get_or_create(label=additional_raw_state.label) states[state.label] = state for raw_transition in self.raw_transitions: source_state, _ = State.objects.get_or_create(label=raw_transition.source_state.label) if not workflow: workflow = Workflow.objects.create(field_name=self.field_name, content_type=self.content_type, initial_state=source_state) destination_state, _ = State.objects.get_or_create(label=raw_transition.destination_state.label) states[source_state.label] = source_state states[destination_state.label] = destination_state transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=source_state, destination_state=destination_state, ) transition_metas.append(transition_meta) if raw_transition.authorization_policies: for authorization_policy in raw_transition.authorization_policies: transition_approval_meta = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=authorization_policy.priority, permissions=authorization_policy.permissions, ) transition_approval_meta.groups.set(authorization_policy.groups) transitions_approval_metas.append(transition_approval_meta) for i in range(self.objects_count): workflow_objects.append(self.object_factory()) return Flow(workflow, states, transition_metas, transitions_approval_metas, workflow_objects)
def test_shouldInvokeCallbackThatIsRegisteredWithoutInstanceWhenAnApprovingHappens( self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") content_type = ContentType.objects.get_for_model(BasicTestModel) workflow = WorkflowFactory(initial_state=state1, content_type=content_type, field_name="my_field") transition_meta = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) meta1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=0, permissions=[authorized_permission]) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta, priority=1, permissions=[authorized_permission]) workflow_object = BasicTestModelObjectFactory(workflow=workflow) self.hook_pre_approve(workflow, meta1) assert_that(self.get_output(), none()) assert_that(workflow_object.model.my_field, equal_to(state1)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(state1)) output = self.get_output() assert_that(output, has_length(1)) assert_that(output[0], has_key("hook")) assert_that(output[0]["hook"], has_entry("type", "on-approved")) assert_that(output[0]["hook"], has_entry("when", BEFORE)) assert_that( output[0]["hook"], has_entry( "payload", all_of( has_entry(equal_to("workflow_object"), equal_to(workflow_object.model)), has_entry( equal_to("transition_approval"), equal_to( meta1.transition_approvals.filter( priority=0).first()))))) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(state2)) output = self.get_output() assert_that(output, has_length(1)) assert_that(output[0], has_key("hook")) assert_that(output[0]["hook"], has_entry("type", "on-approved")) assert_that(output[0]["hook"], has_entry("when", BEFORE)) assert_that( output[0]["hook"], has_entry( "payload", all_of( has_entry(equal_to("workflow_object"), equal_to(workflow_object.model)), has_entry( equal_to("transition_approval"), equal_to( meta1.transition_approvals.filter( priority=0).first())))))
def test_shouldInvokeCallbackForTheOnlyGivenApproval(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") state3 = StateObjectFactory(label="state3") content_type = ContentType.objects.get_for_model(BasicTestModel) workflow = WorkflowFactory(initial_state=state1, content_type=content_type, field_name="my_field") transition_meta_1 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) transition_meta_2 = TransitionMetaFactory.create( workflow=workflow, source_state=state2, destination_state=state3, ) transition_meta_3 = TransitionMetaFactory.create( workflow=workflow, source_state=state3, destination_state=state1, ) meta1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_1, priority=0, permissions=[authorized_permission]) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=0, permissions=[authorized_permission]) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_3, priority=0, permissions=[authorized_permission]) workflow_object = BasicTestModelObjectFactory(workflow=workflow) workflow_object.model.river.my_field.approve(as_user=authorized_user) workflow_object.model.river.my_field.approve(as_user=authorized_user) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(TransitionApproval.objects.filter(meta=meta1), has_length(2)) first_approval = TransitionApproval.objects.filter( meta=meta1, transition__iteration=0).first() assert_that(first_approval, is_not(none())) self.hook_pre_approve(workflow, meta1, transition_approval=first_approval) output = self.get_output() assert_that(output, none()) workflow_object.model.river.my_field.approve(as_user=authorized_user) output = self.get_output() assert_that(output, none())
def test__shouldMigrateObjectIdInHooksByCastingItToString(self): out = StringIO() sys.stout = out state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") workflow = WorkflowFactory( initial_state=state1, content_type=ContentType.objects.get_for_model(BasicTestModel), field_name="my_field") transition_1 = TransitionMetaFactory.create(workflow=workflow, source_state=state1, destination_state=state2) transition_approval_meta_1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_1, priority=0) workflow_object = BasicTestModelObjectFactory() callback_method = """ from river.tests.hooking.base_hooking_test import callback_output def handle(context): print(context) key = '%s' callback_output[key] = callback_output.get(key,[]) + [context] """ callback_function = Function.objects.create(name=uuid4(), body=callback_method % str(uuid4())) OnApprovedHook.objects.create( workflow=workflow, callback_function=callback_function, transition_approval_meta=transition_approval_meta_1, hook_type=BEFORE, workflow_object=workflow_object.model) OnCompleteHook.objects.create(workflow=workflow, callback_function=callback_function, hook_type=BEFORE, workflow_object=workflow_object.model) OnTransitHook.objects.create(workflow=workflow, callback_function=callback_function, transition_meta=transition_1, hook_type=BEFORE, workflow_object=workflow_object.model) call_command('migrate', 'river', '0013', stdout=out) with connection.cursor() as cur: schema = cur.execute( "PRAGMA table_info('river_onapprovedhook');").fetchall() column_type = next( iter([ column[2] for column in schema if column[1] == 'object_id' ]), None) assert_that(column_type, equal_to("integer unsigned")) schema = cur.execute( "PRAGMA table_info('river_ontransithook');").fetchall() column_type = next( iter([ column[2] for column in schema if column[1] == 'object_id' ]), None) assert_that(column_type, equal_to("integer unsigned")) schema = cur.execute( "PRAGMA table_info('river_oncompletehook');").fetchall() column_type = next( iter([ column[2] for column in schema if column[1] == 'object_id' ]), None) assert_that(column_type, equal_to("integer unsigned")) result = cur.execute( "select object_id from river_onapprovedhook where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(1)) assert_that(result[0][0], equal_to(workflow_object.model.pk)) result = cur.execute( "select object_id from river_ontransithook where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(1)) assert_that(result[0][0], equal_to(workflow_object.model.pk)) result = cur.execute( "select object_id from river_oncompletehook where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(1)) assert_that(result[0][0], equal_to(workflow_object.model.pk)) call_command('migrate', 'river', '0014', stdout=out) with connection.cursor() as cur: schema = cur.execute( "PRAGMA table_info('river_onapprovedhook');").fetchall() column_type = next( iter([ column[2] for column in schema if column[1] == 'object_id' ]), None) assert_that(column_type, equal_to("varchar(200)")) schema = cur.execute( "PRAGMA table_info('river_ontransithook');").fetchall() column_type = next( iter([ column[2] for column in schema if column[1] == 'object_id' ]), None) assert_that(column_type, equal_to("varchar(200)")) schema = cur.execute( "PRAGMA table_info('river_oncompletehook');").fetchall() column_type = next( iter([ column[2] for column in schema if column[1] == 'object_id' ]), None) assert_that(column_type, equal_to("varchar(200)")) result = cur.execute( "select object_id from river_onapprovedhook where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(1)) assert_that(result[0][0], equal_to(str(workflow_object.model.pk))) result = cur.execute( "select object_id from river_ontransithook where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(1)) assert_that(result[0][0], equal_to(str(workflow_object.model.pk))) result = cur.execute( "select object_id from river_oncompletehook where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(1)) assert_that(result[0][0], equal_to(str(workflow_object.model.pk)))
def test__shouldAssessIterationsForExistingApprovals(self): out = StringIO() sys.stout = out state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") state3 = StateObjectFactory(label="state3") state4 = StateObjectFactory(label="state4") workflow = WorkflowFactory(initial_state=state1, content_type=ContentType.objects.get_for_model(BasicTestModel), field_name="my_field") transition_meta_1 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) transition_meta_2 = TransitionMetaFactory.create( workflow=workflow, source_state=state2, destination_state=state3, ) transition_meta_3 = TransitionMetaFactory.create( workflow=workflow, source_state=state2, destination_state=state4, ) meta_1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_1, priority=0 ) meta_2 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=0 ) meta_3 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=1 ) meta_4 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_3, priority=0 ) workflow_object = BasicTestModelObjectFactory() with connection.cursor() as cur: result = cur.execute(""" select river_transitionapproval.meta_id, iteration from river_transitionapproval inner join river_transition rt on river_transitionapproval.transition_id = rt.id where river_transitionapproval.object_id=%s; """ % workflow_object.model.pk).fetchall() assert_that(result, has_length(4)) assert_that(result, has_item(equal_to((meta_1.pk, 0)))) assert_that(result, has_item(equal_to((meta_2.pk, 1)))) assert_that(result, has_item(equal_to((meta_3.pk, 1)))) assert_that(result, has_item(equal_to((meta_4.pk, 1)))) call_command('migrate', 'river', '0006', stdout=out) with connection.cursor() as cur: schema = cur.execute("PRAGMA table_info('river_transitionapproval');").fetchall() columns = six.moves.map(lambda column: column[1], schema) assert_that(columns, is_not(has_item("iteration"))) call_command('migrate', 'river', '0007', stdout=out) with connection.cursor() as cur: result = cur.execute("select meta_id, iteration from river_transitionapproval where object_id=%s;" % workflow_object.model.pk).fetchall() assert_that(result, has_length(4)) assert_that(result, has_item(equal_to((meta_1.pk, 0)))) assert_that(result, has_item(equal_to((meta_2.pk, 1)))) assert_that(result, has_item(equal_to((meta_3.pk, 1)))) assert_that(result, has_item(equal_to((meta_4.pk, 1))))
def test__shouldAssessIterationsForExistingApprovalsWhenThereIsCycle(self): out = StringIO() sys.stout = out authorized_permission1 = PermissionObjectFactory() authorized_permission2 = PermissionObjectFactory() authorized_user = UserObjectFactory(user_permissions=[authorized_permission1, authorized_permission2]) cycle_state_1 = StateObjectFactory(label="cycle_state_1") cycle_state_2 = StateObjectFactory(label="cycle_state_2") cycle_state_3 = StateObjectFactory(label="cycle_state_3") off_the_cycle_state = StateObjectFactory(label="off_the_cycle_state") workflow = WorkflowFactory(initial_state=cycle_state_1, content_type=ContentType.objects.get_for_model(BasicTestModel), field_name="my_field") transition_meta_1 = TransitionMetaFactory.create( workflow=workflow, source_state=cycle_state_1, destination_state=cycle_state_2, ) transition_meta_2 = TransitionMetaFactory.create( workflow=workflow, source_state=cycle_state_2, destination_state=cycle_state_3, ) transition_meta_3 = TransitionMetaFactory.create( workflow=workflow, source_state=cycle_state_3, destination_state=cycle_state_1, ) transition_meta_4 = TransitionMetaFactory.create( workflow=workflow, source_state=cycle_state_3, destination_state=off_the_cycle_state, ) meta_1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_1, priority=0, permissions=[authorized_permission1] ) meta_21 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=0, permissions=[authorized_permission1] ) meta_22 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=1, permissions=[authorized_permission2] ) meta_3 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_3, priority=0, permissions=[authorized_permission1] ) final_meta = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_4, priority=0, permissions=[authorized_permission1] ) workflow_object = BasicTestModelObjectFactory() assert_that(workflow_object.model.my_field, equal_to(cycle_state_1)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(cycle_state_2)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(cycle_state_2)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(cycle_state_3)) approvals = TransitionApproval.objects.filter(workflow=workflow, workflow_object=workflow_object.model) assert_that(approvals, has_length(5)) workflow_object.model.river.my_field.approve(as_user=authorized_user, next_state=cycle_state_1) assert_that(workflow_object.model.my_field, equal_to(cycle_state_1)) with connection.cursor() as cur: result = cur.execute(""" select river_transitionapproval.meta_id, iteration from river_transitionapproval inner join river_transition rt on river_transitionapproval.transition_id = rt.id where river_transitionapproval.object_id=%s; """ % workflow_object.model.pk).fetchall() assert_that(result, has_length(10)) assert_that(result, has_item(equal_to((meta_1.pk, 0)))) assert_that(result, has_item(equal_to((meta_21.pk, 1)))) assert_that(result, has_item(equal_to((meta_22.pk, 1)))) assert_that(result, has_item(equal_to((meta_3.pk, 2)))) assert_that(result, has_item(equal_to((final_meta.pk, 2)))) assert_that(result, has_item(equal_to((meta_1.pk, 3)))) assert_that(result, has_item(equal_to((meta_21.pk, 4)))) assert_that(result, has_item(equal_to((meta_22.pk, 4)))) assert_that(result, has_item(equal_to((meta_3.pk, 5)))) assert_that(result, has_item(equal_to((final_meta.pk, 5)))) call_command('migrate', 'river', '0006', stdout=out) with connection.cursor() as cur: schema = cur.execute("PRAGMA table_info('river_transitionapproval');").fetchall() columns = six.moves.map(lambda column: column[1], schema) assert_that(columns, is_not(has_item("iteration"))) call_command('migrate', 'river', '0007', stdout=out) with connection.cursor() as cur: result = cur.execute("select meta_id, iteration from river_transitionapproval where object_id=%s;" % workflow_object.model.pk).fetchall() assert_that(result, has_length(10)) assert_that(result, has_item(equal_to((meta_1.pk, 0)))) assert_that(result, has_item(equal_to((meta_21.pk, 1)))) assert_that(result, has_item(equal_to((meta_22.pk, 1)))) assert_that(result, has_item(equal_to((meta_3.pk, 2)))) assert_that(result, has_item(equal_to((final_meta.pk, 2)))) assert_that(result, has_item(equal_to((meta_1.pk, 3)))) assert_that(result, has_item(equal_to((meta_21.pk, 4)))) assert_that(result, has_item(equal_to((meta_22.pk, 4)))) assert_that(result, has_item(equal_to((meta_3.pk, 5)))) assert_that(result, has_item(equal_to((final_meta.pk, 5))))
def test_shouldInvokeCallbackThatIsRegisteredWithoutInstanceWhenTransitionHappens(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory(user_permissions=[authorized_permission]) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") state3 = StateObjectFactory(label="state3") content_type = ContentType.objects.get_for_model(BasicTestModel) workflow = WorkflowFactory(initial_state=state1, content_type=content_type, field_name="my_field") transition_meta_1 = TransitionMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, ) transition_meta_2 = TransitionMetaFactory.create( workflow=workflow, source_state=state2, destination_state=state3, ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_1, priority=0, permissions=[authorized_permission] ) TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_meta_2, priority=0, permissions=[authorized_permission] ) workflow_object = BasicTestModelObjectFactory() self.hook_post_transition(workflow, transition_meta_2) assert_that(self.get_output(), none()) assert_that(workflow_object.model.my_field, equal_to(state1)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(state2)) assert_that(self.get_output(), none()) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(state3)) last_approval = TransitionApproval.objects.get(object_id=workflow_object.model.pk, transition__source_state=state2, transition__destination_state=state3) output = self.get_output() assert_that(output, has_length(1)) assert_that(output[0], has_key("hook")) assert_that(output[0]["hook"], has_entry("type", "on-transit")) assert_that(output[0]["hook"], has_entry("when", AFTER)) assert_that(output[0]["hook"], has_entry( "payload", all_of( has_entry(equal_to("workflow_object"), equal_to(workflow_object.model)), has_entry(equal_to("transition_approval"), equal_to(last_approval)) ) ))
def test__shouldAssessIterationsForExistingApprovalsWhenThereIsMoreAdvanceCycle(self): out = StringIO() sys.stout = out authorized_permission1 = PermissionObjectFactory() authorized_permission2 = PermissionObjectFactory() authorized_user = UserObjectFactory(user_permissions=[authorized_permission1, authorized_permission2]) opn = StateObjectFactory(label="open") in_progress = StateObjectFactory(label="in_progress") resolved = StateObjectFactory(label="resolved") re_opened = StateObjectFactory(label="re_opened") closed = StateObjectFactory(label="closed") final = StateObjectFactory(label="final") workflow = WorkflowFactory(initial_state=opn, content_type=ContentType.objects.get_for_model(BasicTestModel), field_name="my_field") open_to_in_progress_transition = TransitionMetaFactory.create( workflow=workflow, source_state=opn, destination_state=in_progress, ) in_progress_to_resolved_transition = TransitionMetaFactory.create( workflow=workflow, source_state=in_progress, destination_state=resolved ) resolved_to_re_opened_transition = TransitionMetaFactory.create( workflow=workflow, source_state=resolved, destination_state=re_opened ) re_opened_to_in_progress_transition = TransitionMetaFactory.create( workflow=workflow, source_state=re_opened, destination_state=in_progress ) resolved_to_closed_transition = TransitionMetaFactory.create( workflow=workflow, source_state=resolved, destination_state=closed ) closed_to_final_transition = TransitionMetaFactory.create( workflow=workflow, source_state=closed, destination_state=final ) open_to_in_progress = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=open_to_in_progress_transition, priority=0, permissions=[authorized_permission1] ) in_progress_to_resolved = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=in_progress_to_resolved_transition, priority=0, permissions=[authorized_permission1] ) resolved_to_re_opened = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=resolved_to_re_opened_transition, priority=0, permissions=[authorized_permission2] ) re_opened_to_in_progress = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=re_opened_to_in_progress_transition, priority=0, permissions=[authorized_permission1] ) resolved_to_closed = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=resolved_to_closed_transition, priority=0, permissions=[authorized_permission1] ) closed_to_final = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=closed_to_final_transition, priority=0, permissions=[authorized_permission1] ) workflow_object = BasicTestModelObjectFactory() assert_that(workflow_object.model.my_field, equal_to(opn)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(in_progress)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(resolved)) workflow_object.model.river.my_field.approve(as_user=authorized_user, next_state=re_opened) assert_that(workflow_object.model.my_field, equal_to(re_opened)) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(in_progress)) with connection.cursor() as cur: result = cur.execute(""" select river_transitionapproval.meta_id, iteration from river_transitionapproval inner join river_transition rt on river_transitionapproval.transition_id = rt.id where river_transitionapproval.object_id=%s; """ % workflow_object.model.pk).fetchall() assert_that(result, has_length(11)) assert_that(result, has_item(equal_to((open_to_in_progress.pk, 0)))) assert_that(result, has_item(equal_to((in_progress_to_resolved.pk, 1)))) assert_that(result, has_item(equal_to((resolved_to_closed.pk, 2)))) assert_that(result, has_item(equal_to((resolved_to_re_opened.pk, 2)))) assert_that(result, has_item(equal_to((re_opened_to_in_progress.pk, 3)))) assert_that(result, has_item(equal_to((closed_to_final.pk, 3)))) assert_that(result, has_item(equal_to((in_progress_to_resolved.pk, 4)))) assert_that(result, has_item(equal_to((resolved_to_closed.pk, 5)))) assert_that(result, has_item(equal_to((resolved_to_re_opened.pk, 5)))) assert_that(result, has_item(equal_to((re_opened_to_in_progress.pk, 6)))) assert_that(result, has_item(equal_to((closed_to_final.pk, 6)))) call_command('migrate', 'river', '0006', stdout=out) with connection.cursor() as cur: schema = cur.execute("PRAGMA table_info('river_transitionapproval');").fetchall() columns = six.moves.map(lambda column: column[1], schema) assert_that(columns, is_not(has_item("iteration"))) call_command('migrate', 'river', '0007', stdout=out) with connection.cursor() as cur: result = cur.execute("select meta_id, iteration from river_transitionapproval where object_id=%s;" % workflow_object.model.pk).fetchall() assert_that(result, has_length(11)) assert_that(result, has_item(equal_to((open_to_in_progress.pk, 0)))) assert_that(result, has_item(equal_to((in_progress_to_resolved.pk, 1)))) assert_that(result, has_item(equal_to((resolved_to_closed.pk, 2)))) assert_that(result, has_item(equal_to((resolved_to_re_opened.pk, 2)))) assert_that(result, has_item(equal_to((re_opened_to_in_progress.pk, 3)))) assert_that(result, has_item(equal_to((closed_to_final.pk, 3)))) assert_that(result, has_item(equal_to((in_progress_to_resolved.pk, 4)))) assert_that(result, has_item(equal_to((resolved_to_closed.pk, 5)))) assert_that(result, has_item(equal_to((resolved_to_re_opened.pk, 5)))) assert_that(result, has_item(equal_to((re_opened_to_in_progress.pk, 6)))) assert_that(result, has_item(equal_to((closed_to_final.pk, 6))))
def test__shouldCreateTransitionsAndTransitionMetasOutOfApprovalMetaAndApprovals(self): out = StringIO() sys.stout = out state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") state3 = StateObjectFactory(label="state3") state4 = StateObjectFactory(label="state4") workflow = WorkflowFactory(initial_state=state1, content_type=ContentType.objects.get_for_model(BasicTestModel), field_name="my_field") transition_1 = TransitionMetaFactory.create(workflow=workflow, source_state=state1, destination_state=state2) transition_2 = TransitionMetaFactory.create(workflow=workflow, source_state=state2, destination_state=state3) transition_3 = TransitionMetaFactory.create(workflow=workflow, source_state=state2, destination_state=state4) meta_1 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_1, priority=0 ) meta_2 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_2, priority=0 ) meta_3 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_2, priority=1 ) meta_4 = TransitionApprovalMetaFactory.create( workflow=workflow, transition_meta=transition_3, priority=0 ) workflow_object = BasicTestModelObjectFactory() with connection.cursor() as cur: result = cur.execute("select id, transition_meta_id from river_transitionapprovalmeta;").fetchall() assert_that(result, has_length(4)) assert_that(result, has_item(equal_to((meta_1.pk, transition_1.pk)))) assert_that(result, has_item(equal_to((meta_2.pk, transition_2.pk)))) assert_that(result, has_item(equal_to((meta_3.pk, transition_2.pk)))) assert_that(result, has_item(equal_to((meta_4.pk, transition_3.pk)))) result = cur.execute("select id, transition_id from river_transitionapproval where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(4)) assert_that(result, has_item(equal_to((meta_1.transition_approvals.first().pk, transition_1.transitions.first().pk)))) assert_that(result, has_item(equal_to((meta_2.transition_approvals.first().pk, transition_2.transitions.first().pk)))) assert_that(result, has_item(equal_to((meta_3.transition_approvals.first().pk, transition_2.transitions.first().pk)))) assert_that(result, has_item(equal_to((meta_4.transition_approvals.first().pk, transition_3.transitions.first().pk)))) call_command('migrate', 'river', '0009', stdout=out) with connection.cursor() as cur: schema = cur.execute("PRAGMA table_info('river_transitionapprovalmeta');").fetchall() columns = [column[1] for column in schema] assert_that(columns, is_not(has_item("transition_meta_id"))) assert_that(columns, has_item("source_state_id")) assert_that(columns, has_item("destination_state_id")) schema = cur.execute("PRAGMA table_info('river_transitionapproval');").fetchall() columns = [column[1] for column in schema] assert_that(columns, is_not(has_item("transition_id"))) assert_that(columns, has_item("source_state_id")) assert_that(columns, has_item("destination_state_id")) call_command('migrate', 'river', '0010', stdout=out) with connection.cursor() as cur: schema = cur.execute("PRAGMA table_info('river_transitionapprovalmeta');").fetchall() columns = six.moves.map(lambda column: column[1], schema) assert_that(columns, has_item("transition_meta_id")) assert_that(columns, is_not(has_item("source_state_id"))) assert_that(columns, is_not(has_item("destination_state_id"))) schema = cur.execute("PRAGMA table_info('river_transitionapproval');").fetchall() columns = [column[1] for column in schema] assert_that(columns, has_item("transition_id")) assert_that(columns, is_not(has_item("source_state_id"))) assert_that(columns, is_not(has_item("destination_state_id"))) with connection.cursor() as cur: result = cur.execute("select id, transition_meta_id from river_transitionapprovalmeta;").fetchall() assert_that(result, has_length(4)) assert_that(result, has_item(equal_to((meta_1.pk, transition_1.pk)))) assert_that(result, has_item(equal_to((meta_2.pk, transition_2.pk)))) assert_that(result, has_item(equal_to((meta_3.pk, transition_2.pk)))) assert_that(result, has_item(equal_to((meta_4.pk, transition_3.pk)))) result = cur.execute("select id, transition_id from river_transitionapproval where object_id='%s';" % workflow_object.model.pk).fetchall() assert_that(result, has_length(4)) assert_that(result, has_item(equal_to((meta_1.transition_approvals.first().pk, transition_1.transitions.first().pk)))) assert_that(result, has_item(equal_to((meta_2.transition_approvals.first().pk, transition_2.transitions.first().pk)))) assert_that(result, has_item(equal_to((meta_3.transition_approvals.first().pk, transition_2.transitions.first().pk)))) assert_that(result, has_item(equal_to((meta_4.transition_approvals.first().pk, transition_3.transitions.first().pk))))