def initialize_circular_scenario(self): from river.models.factories import \ TransitionObjectFactory, \ UserObjectFactory, \ PermissionObjectFactory, \ ProceedingMetaObjectFactory, \ StateObjectFactory TransitionObjectFactory.reset_sequence(0) ProceedingMetaObjectFactory.reset_sequence(0) StateObjectFactory.reset_sequence(0) TestModel.objects.all().delete() self.content_type = ContentType.objects.get_for_model(TestModel) self.permissions = PermissionObjectFactory.create_batch(4) self.user1 = UserObjectFactory(user_permissions=[self.permissions[0]]) self.user2 = UserObjectFactory(user_permissions=[self.permissions[1]]) self.user3 = UserObjectFactory(user_permissions=[self.permissions[2]]) self.user4 = UserObjectFactory(user_permissions=[self.permissions[3]]) self.open_state = StateObjectFactory( label='open' ) self.in_progress_state = StateObjectFactory( label='in-progress' ) self.resolved_state = StateObjectFactory( label='resolved' ) self.re_opened_state = StateObjectFactory( label='re-opened' ) self.closed_state = StateObjectFactory( label='closed' ) self.transitions = [ TransitionObjectFactory(source_state=self.open_state, destination_state=self.in_progress_state), TransitionObjectFactory(source_state=self.in_progress_state, destination_state=self.resolved_state), TransitionObjectFactory(source_state=self.resolved_state, destination_state=self.re_opened_state), TransitionObjectFactory(source_state=self.resolved_state, destination_state=self.closed_state), TransitionObjectFactory(source_state=self.re_opened_state, destination_state=self.in_progress_state)] self.proceeding_metas = ProceedingMetaObjectFactory.create_batch( 5, content_type=self.content_type, transition=factory.Sequence(lambda n: self.transitions[n]), order=0 ) for n, proceeding_meta in enumerate(self.proceeding_metas): proceeding_meta.permissions.add(self.permissions[n] if n < len(self.permissions) else self.permissions[0]) self.objects = TestModelObjectFactory.create_batch(2)
def initialize_normal_scenario(self): from river.models.factories import \ TransitionObjectFactory, \ UserObjectFactory, \ PermissionObjectFactory, \ ProceedingMetaObjectFactory, \ StateObjectFactory TransitionObjectFactory.reset_sequence(0) ProceedingMetaObjectFactory.reset_sequence(0) StateObjectFactory.reset_sequence(0) TestModel.objects.all().delete() self.content_type = ContentType.objects.get_for_model(TestModel) self.permissions = PermissionObjectFactory.create_batch(4) self.user1 = UserObjectFactory(user_permissions=[self.permissions[0]]) self.user2 = UserObjectFactory(user_permissions=[self.permissions[1]]) self.user3 = UserObjectFactory(user_permissions=[self.permissions[2]]) self.user4 = UserObjectFactory(user_permissions=[self.permissions[3]]) self.states = StateObjectFactory.create_batch( 9, label=factory.Sequence( lambda n: "s%s" % str(n + 1) if n <= 4 else ("s4.%s" % str(n - 4) if n <= 6 else "s5.%s" % str(n - 6))) ) self.transitions = TransitionObjectFactory.create_batch(8, source_state=factory.Sequence( lambda n: self.states[n] if n <= 2 else ( self.states[n - 1]) if n <= 4 else ( self.states[n - 2] if n <= 6 else self.states[ 4])), destination_state=factory.Sequence( lambda n: self.states[n + 1])) self.proceeding_metas = ProceedingMetaObjectFactory.create_batch( 9, content_type=self.content_type, transition=factory.Sequence(lambda n: self.transitions[n] if n <= 1 else self.transitions[n - 1]), order=factory.Sequence(lambda n: 1 if n == 2 else 0) ) for n, proceeding_meta in enumerate(self.proceeding_metas): proceeding_meta.permissions.add(self.permissions[n] if n <= 3 else self.permissions[3]) self.objects = TestModelObjectFactory.create_batch(2)
def test_shouldCancelAllOtherStateTransition(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) state1 = RawState("state1") state2 = RawState("state2") state3 = RawState("state3") state4 = RawState("state4") authorization_policies = [ AuthorizationPolicyBuilder().with_permission( authorized_permission).build(), ] flow = FlowBuilder("my_field", self.content_type) \ .with_transition(state1, state2, authorization_policies) \ .with_transition(state1, state3, authorization_policies) \ .with_transition(state1, state4, authorization_policies) \ .build() workflow_object = flow.objects[0] assert_that(workflow_object.my_field, equal_to(flow.get_state(state1))) workflow_object.river.my_field.approve( as_user=authorized_user, next_state=flow.get_state(state3)) assert_that(workflow_object.my_field, equal_to(flow.get_state(state3))) assert_that( flow.transitions_approval_metas[0].transition_approvals.all(), all_of(has_length(1), has_item(has_property("status", CANCELLED)))), assert_that( flow.transitions_approval_metas[1].transition_approvals.all(), all_of(has_length(1), has_item(has_property("status", APPROVED)))), assert_that( flow.transitions_approval_metas[2].transition_approvals.all(), all_of(has_length(1), has_item(has_property("status", CANCELLED))))
def test_shouldAllowAuthorizedUserToProceedToNextState(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") TransitionApprovalMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, priority=0, permissions=[authorized_permission] ) workflow_object = BasicTestModelObjectFactory() 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))
def test_shouldNotAllowUnauthorizedUserToProceedToNextState(self): unauthorized_user = UserObjectFactory() authorized_permission = PermissionObjectFactory() state1 = RawState("state1") state2 = RawState("state2") authorization_policies = [ AuthorizationPolicyBuilder().with_permission( authorized_permission).build() ] flow = FlowBuilder("my_field", self.content_type) \ .with_transition(state1, state2, authorization_policies) \ .build() workflow_object = flow.objects[0] assert_that( calling(workflow_object.river.my_field.approve).with_args( as_user=unauthorized_user), raises(RiverException, "There is no available approval for the user"))
def test_shouldNotAllowUnauthorizedUserToProceedToNextState(self): unauthorized_user = UserObjectFactory() state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") authorized_permission = PermissionObjectFactory() workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") TransitionApprovalMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, priority=0, permissions=[authorized_permission] ) workflow_object = BasicTestModelObjectFactory() assert_that( calling(workflow_object.model.river.my_field.approve).with_args(as_user=unauthorized_user), raises(RiverException, "There is no available approval for the user") )
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() TransitionApprovalMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, priority=0, permissions=[authorized_permission]) BasicTestModelObjectFactory() available_approvals = BasicTestModel.river.my_field.get_available_approvals( as_user=unauthorized_user) assert_that(available_approvals, has_length(0))
def test_shouldNotAcceptANextStateWhichIsNotAmongPossibleNextStates(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory(user_permissions=[authorized_permission]) state1 = StateObjectFactory(label="state1") state2 = StateObjectFactory(label="state2") state3 = StateObjectFactory(label="state3") invalid_state = StateObjectFactory(label="state4") workflow = WorkflowFactory(initial_state=state1, content_type=self.content_type, field_name="my_field") TransitionApprovalMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, priority=0, permissions=[authorized_permission] ) TransitionApprovalMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state3, priority=0, permissions=[authorized_permission] ) workflow_object = BasicTestModelObjectFactory() assert_that( calling(workflow_object.model.river.my_field.approve).with_args(as_user=authorized_user, next_state=invalid_state), raises(RiverException, "Invalid state is given\(%s\). Valid states is\(are\) (%s|%s)" % ( invalid_state.label, ",".join([state2.label, state3.label]), ",".join([state3.label, state2.label])) ) )
def test_shouldReturnAnApprovalWhenUserIsAuthorizedWithAPermission(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]) 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__shouldReturnApprovalsOnTimeWhenTooManyWorkflowObject(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) state1 = RawState("state1") state2 = RawState("state2") authorization_policies = [ AuthorizationPolicyBuilder().with_permission( authorized_permission).build() ] FlowBuilder("my_field", self.content_type) \ .with_transition(state1, state2, authorization_policies) \ .with_objects(250) \ .build() before = datetime.now() approvals = BasicTestModel.river.my_field.get_on_approval_objects( as_user=authorized_user) after = datetime.now() assert_that(after - before, less_than(timedelta(milliseconds=200))) assert_that(approvals, has_length(250)) print("Time taken %s" % str(after - before))
def test_shouldInvokeCallbackThatIsRegisteredWithoutInstanceWhenAnApprovingHappens( self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) content_type = ContentType.objects.get_for_model(BasicTestModel) state1 = RawState("state1") state2 = RawState("state2") authorization_policies = [ AuthorizationPolicyBuilder().with_priority(0).with_permission( authorized_permission).build(), AuthorizationPolicyBuilder().with_priority(1).with_permission( authorized_permission).build(), ] flow = FlowBuilder("my_field", content_type) \ .with_transition(state1, state2, authorization_policies) \ .build() workflow_object = flow.objects[0] self.hook_pre_approve(flow.workflow, flow.transitions_approval_metas[0]) assert_that(self.get_output(), none()) assert_that(workflow_object.my_field, equal_to(flow.get_state(state1))) workflow_object.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.my_field, equal_to(flow.get_state(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)), has_entry( equal_to("transition_approval"), equal_to(flow.transitions_approval_metas[0]. transition_approvals.all().first()))))) workflow_object.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.my_field, equal_to(flow.get_state(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)), has_entry( equal_to("transition_approval"), equal_to(flow.transitions_approval_metas[0]. transition_approvals.all().first())))))
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_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_shouldNotCancelDescendantsIfItIsPartOfPossibleFuture(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) first_state = RawState("first") diamond_left_state_1 = RawState("diamond-left-1") diamond_left_state_2 = RawState("diamond-left-2") diamond_right_state_1 = RawState("diamond-right-1") diamond_right_state_2 = RawState("diamond-right-2") diamond_join_state = RawState("diamond-join") final_state = RawState("final") authorization_policies = [ AuthorizationPolicyBuilder().with_permission( authorized_permission).build(), ] flow = FlowBuilder("my_field", self.content_type) \ .with_transition(first_state, diamond_left_state_1, authorization_policies) \ .with_transition(first_state, diamond_right_state_1, authorization_policies) \ .with_transition(diamond_left_state_1, diamond_left_state_2, authorization_policies) \ .with_transition(diamond_right_state_1, diamond_right_state_2, authorization_policies) \ .with_transition(diamond_left_state_2, diamond_join_state, authorization_policies) \ .with_transition(diamond_right_state_2, diamond_join_state, authorization_policies) \ .with_transition(diamond_join_state, final_state, authorization_policies) \ .build() workflow_object = flow.objects[0] assert_that(workflow_object.my_field, equal_to(flow.get_state(first_state))) workflow_object.river.my_field.approve( as_user=authorized_user, next_state=flow.get_state(diamond_left_state_1)) assert_that(workflow_object.my_field, equal_to(flow.get_state(diamond_left_state_1))) approvals = TransitionApproval.objects.filter( workflow=flow.workflow, workflow_object=workflow_object) assert_that(approvals, has_approval(first_state, diamond_left_state_1, APPROVED)) assert_that( approvals, has_approval(diamond_left_state_1, diamond_left_state_2, PENDING)) assert_that( approvals, has_approval(diamond_left_state_2, diamond_join_state, PENDING)) assert_that( approvals, has_approval(first_state, diamond_right_state_1, CANCELLED)) assert_that( approvals, has_approval(diamond_right_state_1, diamond_right_state_2, CANCELLED)) assert_that( approvals, has_approval(diamond_right_state_2, diamond_join_state, CANCELLED)) assert_that(approvals, has_approval(diamond_join_state, final_state, PENDING))
def test_shouldAllowCyclicTransitions(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory(user_permissions=[authorized_permission]) 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=self.content_type, field_name="my_field") meta_1 = TransitionApprovalMetaFactory.create( workflow=workflow, source_state=cycle_state_1, destination_state=cycle_state_2, priority=0, permissions=[authorized_permission] ) meta_2 = TransitionApprovalMetaFactory.create( workflow=workflow, source_state=cycle_state_2, destination_state=cycle_state_3, priority=0, permissions=[authorized_permission] ) meta_3 = TransitionApprovalMetaFactory.create( workflow=workflow, source_state=cycle_state_3, destination_state=cycle_state_1, priority=0, permissions=[authorized_permission] ) TransitionApprovalMetaFactory.create( workflow=workflow, source_state=cycle_state_3, destination_state=off_the_cycle_state, priority=0, permissions=[authorized_permission] ) 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_3)) approvals = TransitionApproval.objects.filter(workflow=workflow, workflow_object=workflow_object.model) assert_that(approvals, has_length(4)) assert_that(approvals, has_item( is_not( all_of( has_property("source_state", meta_1.source_state), has_property("destination_state", meta_1.destination_state), has_permission("permissions", has_length(1)), has_permission("permissions", has_item(authorized_permission)), has_property("status", PENDING), ) ) )) assert_that(approvals, has_item( is_not( all_of( has_property("source_state", meta_2.source_state), has_property("destination_state", meta_2.destination_state), has_permission("permissions", has_length(1)), has_permission("permissions", has_item(authorized_permission)), has_property("status", PENDING), ) ) )) assert_that(approvals, has_item( is_not( all_of( has_property("source_state", meta_3.source_state), has_property("destination_state", meta_3.destination_state), has_permission("permissions", has_length(1)), has_permission("permissions", has_item(authorized_permission)), has_property("status", PENDING), ) ) )) 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)) approvals = TransitionApproval.objects.filter(workflow=workflow, workflow_object=workflow_object.model) assert_that(approvals, has_length(7)) assert_that(approvals, has_item( all_of( has_property("source_state", meta_1.source_state), has_property("destination_state", meta_1.destination_state), has_permission("permissions", has_length(1)), has_permission("permissions", has_item(authorized_permission)), has_property("status", PENDING), ) )) assert_that(approvals, has_item( all_of( has_property("source_state", meta_2.source_state), has_property("destination_state", meta_2.destination_state), has_permission("permissions", has_length(1)), has_permission("permissions", has_item(authorized_permission)), has_property("status", PENDING), ) )) assert_that(approvals, has_item( all_of( has_property("source_state", meta_3.source_state), has_property("destination_state", meta_3.destination_state), has_permission("permissions", has_length(1)), has_permission("permissions", has_item(authorized_permission)), has_property("status", PENDING), ) ))
def permission(context, name): from river.models.factories import PermissionObjectFactory PermissionObjectFactory(name=name)
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_shouldAssessIterationsCorrectlyWhenCycled(self): authorized_permission = PermissionObjectFactory() authorized_user = UserObjectFactory( user_permissions=[authorized_permission]) cycle_state_1 = RawState("cycle_state_1") cycle_state_2 = RawState("cycle_state_2") cycle_state_3 = RawState("cycle_state_3") off_the_cycle_state = RawState("off_the_cycle_state") final_state = RawState("final_state") authorization_policies = [ AuthorizationPolicyBuilder().with_permission( authorized_permission).build(), ] flow = FlowBuilder("my_field", self.content_type) \ .with_transition(cycle_state_1, cycle_state_2, authorization_policies) \ .with_transition(cycle_state_2, cycle_state_3, authorization_policies) \ .with_transition(cycle_state_3, cycle_state_1, authorization_policies) \ .with_transition(cycle_state_3, off_the_cycle_state, authorization_policies) \ .with_transition(off_the_cycle_state, final_state, authorization_policies) \ .build() workflow_object = flow.objects[0] assert_that(workflow_object.my_field, equal_to(flow.get_state(cycle_state_1))) workflow_object.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.my_field, equal_to(flow.get_state(cycle_state_2))) workflow_object.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.my_field, equal_to(flow.get_state(cycle_state_3))) approvals = TransitionApproval.objects.filter( workflow=flow.workflow, workflow_object=workflow_object) assert_that(approvals, has_length(5)) workflow_object.river.my_field.approve( as_user=authorized_user, next_state=flow.get_state(cycle_state_1)) assert_that(workflow_object.my_field, equal_to(flow.get_state(cycle_state_1))) approvals = TransitionApproval.objects.filter( workflow=flow.workflow, workflow_object=workflow_object) assert_that(approvals, has_length(10)) assert_that( approvals, has_approval(cycle_state_1, cycle_state_2, APPROVED, iteration=0)) assert_that( approvals, has_approval(cycle_state_2, cycle_state_3, APPROVED, iteration=1)) assert_that( approvals, has_approval(cycle_state_3, cycle_state_1, APPROVED, iteration=2)) assert_that( approvals, has_approval(cycle_state_3, off_the_cycle_state, CANCELLED, iteration=2)) assert_that( approvals, has_approval(off_the_cycle_state, final_state, CANCELLED, iteration=3)) assert_that( approvals, has_approval(cycle_state_1, cycle_state_2, PENDING, iteration=3)) assert_that( approvals, has_approval(cycle_state_2, cycle_state_3, PENDING, iteration=4)) assert_that( approvals, has_approval(cycle_state_3, cycle_state_1, PENDING, iteration=5)) assert_that( approvals, has_approval(cycle_state_3, off_the_cycle_state, PENDING, iteration=5)) assert_that( approvals, has_approval(off_the_cycle_state, final_state, PENDING, iteration=6))
def test_shouldInvokeTheRegisteredViaClassApiCallBackWhenASpecificTransitionHappens( self): self.test_args = None self.test_kwargs = None def test_callback(*args, **kwargs): self.test_args = args self.test_kwargs = kwargs 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") TransitionApprovalMetaFactory.create( workflow=workflow, source_state=state1, destination_state=state2, priority=0, permissions=[authorized_permission]) TransitionApprovalMetaFactory.create( workflow=workflow, source_state=state2, destination_state=state3, priority=0, permissions=[authorized_permission]) workflow_object = BasicTestModelObjectFactory() BasicTestModel.river.my_field.hook_post_transition( test_callback, source_state=state2, destination_state=state3) assert_that(self.test_args, 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.test_args, none()) workflow_object.model.river.my_field.approve(as_user=authorized_user) assert_that(workflow_object.model.my_field, equal_to(state3)) assert_that(self.test_args, equal_to((workflow_object.model, "my_field"))) last_approval = TransitionApproval.objects.get( object_id=workflow_object.model.pk, source_state=state2, destination_state=state3) assert_that( self.test_kwargs, has_entry(equal_to("transition_approval"), equal_to(last_approval)))
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_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 initialize_standard_scenario(self): TransitionApprovalMetaFactory.reset_sequence(0) StateObjectFactory.reset_sequence(0) content_type = ContentType.objects.get_for_model(TestModel) permissions = PermissionObjectFactory.create_batch(4) self.user1 = UserObjectFactory(user_permissions=[permissions[0]]) self.user2 = UserObjectFactory(user_permissions=[permissions[1]]) self.user3 = UserObjectFactory(user_permissions=[permissions[2]]) self.user4 = UserObjectFactory(user_permissions=[permissions[3]]) self.state1 = StateObjectFactory(label="state1") self.state2 = StateObjectFactory(label="state2") self.state3 = StateObjectFactory(label="state3") self.state4 = StateObjectFactory(label="state4") self.state5 = StateObjectFactory(label="state5") self.state41 = StateObjectFactory(label="state4.1") self.state42 = StateObjectFactory(label="state4.2") self.state51 = StateObjectFactory(label="state5.1") self.state52 = StateObjectFactory(label="state5.2") t1 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state1, destination_state=self.state2, priority=0) t1.permissions.add(permissions[0]) t2 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state2, destination_state=self.state3, priority=0) t2.permissions.add(permissions[1]) t3 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state2, destination_state=self.state3, priority=1) t3.permissions.add(permissions[2]) t4 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state3, destination_state=self.state4, priority=0) t4.permissions.add(permissions[3]) t5 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state3, destination_state=self.state5, priority=0) t5.permissions.add(permissions[3]) t6 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state4, destination_state=self.state41, priority=0) t6.permissions.add(permissions[3]) t7 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state4, destination_state=self.state42, priority=0) t7.permissions.add(permissions[3]) t8 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state5, destination_state=self.state51, priority=0) t8.permissions.add(permissions[3]) t9 = TransitionApprovalMetaFactory.create( field_name="my_field", content_type=content_type, source_state=self.state5, destination_state=self.state52, priority=0) t9.permissions.add(permissions[3])