Exemple #1
0
    def test_replace(self):
        """replace method adds function to patch object"""
        patch = ApiPatch()

        def mock_function():
            pass

        patch.replace('test-replace', mock_function)

        self.assertEqual(len(patch._actions), 1)
        self.assertEqual(patch._actions[0]['op'], 'replace')
        self.assertEqual(patch._actions[0]['path'], 'test-replace')
        self.assertEqual(patch._actions[0]['handler'], mock_function)
Exemple #2
0
    def test_dispatch_action(self):
        """dispatch_action calls specified actions"""
        patch = ApiPatch()

        mock_target = MockObject(13)

        def action_a(request, target, value):
            self.assertEqual(request, 'request')
            self.assertEqual(target, mock_target)
            return {'a': value * 2, 'b': 111}

        patch.replace('abc', action_a)

        def action_b(request, target, value):
            self.assertEqual(request, 'request')
            self.assertEqual(target, mock_target)
            return {'b': value * 10}

        patch.replace('abc', action_b)

        def action_fail(request, target, value):
            self.fail("unrequired action was called")

        patch.add('c', action_fail)
        patch.remove('c', action_fail)
        patch.replace('c', action_fail)

        patch_dict = {'id': 123}

        patch.dispatch_action(
            patch_dict, 'request', mock_target, {
                'op': 'replace',
                'path': 'abc',
                'value': 5,
            }
        )

        self.assertEqual(len(patch_dict), 3)
        self.assertEqual(patch_dict['id'], 123)
        self.assertEqual(patch_dict['a'], 10)
        self.assertEqual(patch_dict['b'], 50)
Exemple #3
0
def patch_title(request, thread, value):
    try:
        value_cleaned = six.text_type(value).strip()
    except (TypeError, ValueError):
        raise ValidationError(_("Invalid thread title."))

    validate_title(value_cleaned)

    allow_edit_thread(request.user, thread)

    moderation.change_thread_title(request, thread, value_cleaned)
    return {'title': thread.title}


thread_patch_dispatcher.replace('title', patch_title)


def patch_weight(request, thread, value):
    allow_pin_thread(request.user, thread)

    if not thread.acl.get('can_pin_globally') and thread.weight == 2:
        raise PermissionDenied(
            _("You can't change globally pinned threads weights in this category."
              ))

    if value == 2:
        if thread.acl.get('can_pin_globally'):
            moderation.pin_thread_globally(request, thread)
        else:
            raise PermissionDenied(
Exemple #4
0
    for like in post.postlike_set.all()[:4]:
        post.last_likes.append({
            'id': like.liker_id,
            'username': like.liker_name,
        })

    post.save(update_fields=['likes', 'last_likes'])

    return {
        'likes': post.likes,
        'last_likes': post.last_likes or [],
        'is_liked': value,
    }


post_patch_dispatcher.replace('is-liked', patch_is_liked)


def patch_is_protected(request, post, value):
    allow_protect_post(request.user, post)
    if value:
        moderation.protect_post(request.user, post)
    else:
        moderation.unprotect_post(request.user, post)
    return {'is_protected': post.is_protected}


post_patch_dispatcher.replace('is-protected', patch_is_protected)


def patch_is_unapproved(request, post, value):
Exemple #5
0
    def test_dispatch_bulk(self):
        """dispatch_bulk calls actions and returns response"""
        patch = ApiPatch()

        def action_error(request, target, value):
            if value == '404':
                raise Http404()
            if value == '404_reason':
                raise Http404("something was removed")
            if value == 'perm':
                raise PermissionDenied("yo ain't doing that!")
            if value == 'invalid':
                raise ValidationError("invalid data here!")
            if value == 'api_invalid':
                raise ApiValidationError("invalid api data here!")

        patch.replace('error', action_error)

        def action_mutate(request, target, value):
            return {'value': value * 2}

        patch.replace('mutate', action_mutate)

        # valid bulk dispatch
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '200',
                'patch': {
                    'value': 14
                }
            },
            {
                'id': '7',
                'status': '200',
                'patch': {
                    'value': 14
                }
            },
        ])

        # invalid action in bulk dispatch
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data, {
            'detail': '"replace" op has to specify path.',
        })

        # op raised validation error
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'invalid',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '400',
                'detail': ["invalid data here!"]
            },
            {
                'id': '7',
                'status': '400',
                'detail': ["invalid data here!"]
            },
        ])

        # op raised api validation error
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'api_invalid',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '400',
                'detail': ["invalid api data here!"]
            },
            {
                'id': '7',
                'status': '400',
                'detail': ["invalid api data here!"]
            },
        ])

        # action in bulk dispatch raised perm denied
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 9,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'perm',
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '403',
                'detail': "yo ain't doing that!"
            },
            {
                'id': '7',
                'status': '403',
                'detail': "yo ain't doing that!"
            },
        ])

        # action in bulk dispatch raised 404
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': '404',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '404',
                'detail': "NOT FOUND"
            },
            {
                'id': '7',
                'status': '404',
                'detail': "NOT FOUND"
            },
        ])

        # action in bulk dispatch raised 404 with message
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': '404_reason',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '404',
                'detail': "something was removed"
            },
            {
                'id': '7',
                'status': '404',
                'detail': "something was removed"
            },
        ])
    def test_dispatch(self):
        """dispatch calls actions and returns response"""
        patch = ApiPatch()

        def action_error(request, target, value):
            if value == '404':
                raise Http404()
            if value == '404_reason':
                raise Http404("something was removed")
            if value == 'perm':
                raise PermissionDenied("yo ain't doing that!")
            if value == 'invalid':
                raise ValidationError("invalid data here!")
            if value == 'api_invalid':
                raise ApiValidationError("invalid api data here!")

        patch.replace('error', action_error)

        def action_mutate(request, target, value):
            return {'value': value * 2}

        patch.replace('mutate', action_mutate)

        # dispatch requires list as an argument
        response = patch.dispatch(MockRequest({}), {})
        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data['detail'],
                         "PATCH request should be a list of operations.")

        # valid dispatch
        response = patch.dispatch(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]), MockObject(13))

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, {'value': 14, 'id': 13})

        # invalid action in dispatch
        response = patch.dispatch(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]), MockObject(13))

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data['detail'],
                         '"replace" op has to specify path.')

        # op raised validation error
        response = patch.dispatch(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'invalid',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]), MockObject(13))

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data['detail'], ["invalid data here!"])

        # op raised api validation error
        response = patch.dispatch(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'api_invalid',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]), MockObject(13))

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data['detail'], ["invalid api data here!"])

        # action in dispatch raised perm denied
        response = patch.dispatch(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 9,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'perm',
                },
            ]), MockObject(13))

        self.assertEqual(response.status_code, 403)
        self.assertEqual(response.data['detail'], "yo ain't doing that!")

        # action in dispatch raised 404
        response = patch.dispatch(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': '404',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]), MockObject(13))

        self.assertEqual(response.status_code, 404)
        self.assertEqual(response.data['detail'], "NOT FOUND")

        # action in dispatch raised 404 with message
        response = patch.dispatch(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': '404_reason',
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 7,
                },
            ]), MockObject(13))

        self.assertEqual(response.status_code, 404)
        self.assertEqual(response.data['detail'], "something was removed")
Exemple #7
0
event_patch_dispatcher.add('acl', patch_acl)


def patch_is_hidden(request, event, value):
    if value:
        allow_hide_event(request.user, event)
        moderation.hide_post(request.user, event)
    else:
        allow_unhide_event(request.user, event)
        moderation.unhide_post(request.user, event)

    return {'is_hidden': event.is_hidden}


event_patch_dispatcher.replace('is-hidden', patch_is_hidden)


def event_patch_endpoint(request, event):
    old_is_hidden = event.is_hidden

    response = event_patch_dispatcher.dispatch(request, event)

    if old_is_hidden != event.is_hidden:
        event.thread.synchronize()
        event.thread.save()

        event.category.synchronize()
        event.category.save()
    return response
    def test_dispatch_bulk(self):
        """dispatch_bulk calls actions and returns response"""
        patch = ApiPatch()

        def action_error(request, target, value):
            if value == '404':
                raise Http404()
            if value == '404_reason':
                raise Http404("something was removed")
            if value == 'perm':
                raise PermissionDenied("yo ain't doing that!")
            if value == 'invalid':
                raise ValidationError("invalid data here!")
            if value == 'api_invalid':
                raise ApiValidationError("invalid api data here!")

        patch.replace('error', action_error)

        def action_mutate(request, target, value):
            return {'value': value * 2}

        patch.replace('mutate', action_mutate)

        # valid bulk dispatch
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '200',
                'patch': {
                    'value': 12
                }
            },
            {
                'id': '7',
                'status': '200',
                'patch': {
                    'value': 12
                }
            },
        ])

        # dispatch requires list as an argument
        response = patch.dispatch_bulk(MockRequest(
            {}), [MockObject(5), MockObject(7)])
        self.assertEqual(response.status_code, 400)
        self.assertEqual(
            response.data, {
                'non_field_errors':
                ["PATCH request should be a list of operations."],
            })

        # invalid action in bulk dispatch
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data, {
            'non_field_errors': ['"replace" op has to specify path.'],
        })

        # repeated action in dispatch
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 12,
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 400)
        self.assertEqual(response.data, {
            'non_field_errors':
            ['"replace" op for "mutate" path is repeated.'],
        })

        # op raised validation error
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'invalid',
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '400',
                'value': ["invalid data here!"]
            },
            {
                'id': '7',
                'status': '400',
                'value': ["invalid data here!"]
            },
        ])

        # op raised api validation error
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'api_invalid',
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '400',
                'value': ["invalid api data here!"]
            },
            {
                'id': '7',
                'status': '400',
                'value': ["invalid api data here!"]
            },
        ])

        # action in bulk dispatch raised perm denied
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': 'perm',
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '403',
                'detail': "yo ain't doing that!"
            },
            {
                'id': '7',
                'status': '403',
                'detail': "yo ain't doing that!"
            },
        ])

        # action in bulk dispatch raised 404
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 6,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': '404',
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '404',
                'detail': 'NOT FOUND'
            },
            {
                'id': '7',
                'status': '404',
                'detail': 'NOT FOUND'
            },
        ])

        # action in dispatch raised 404 with message but didn't expose it
        response = patch.dispatch_bulk(
            MockRequest([
                {
                    'op': 'replace',
                    'path': 'mutate',
                    'value': 2,
                },
                {
                    'op': 'replace',
                    'path': 'error',
                    'value': '404_reason',
                },
            ]),
            [MockObject(5), MockObject(7)],
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.data, [
            {
                'id': '5',
                'status': '404',
                'detail': 'NOT FOUND'
            },
            {
                'id': '7',
                'status': '404',
                'detail': 'NOT FOUND'
            },
        ])