Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
    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))))
Пример #4
0
    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))
Пример #5
0
    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"))
Пример #6
0
    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")
        )
Пример #7
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()
        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))
Пример #8
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]))
                   )
        )
Пример #9
0
    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()))))
Пример #10
0
    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))
Пример #11
0
    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())))))
Пример #12
0
    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))))
Пример #13
0
    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())
Пример #14
0
    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))
Пример #15
0
    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),
            )
        ))
Пример #16
0
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))

            )
        ))
Пример #18
0
    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)))
Пример #20
0
    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))))
Пример #21
0
    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())))))
Пример #22
0
    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])