add blocklist/block api (#13737)
* add blocklist/block api * refactor test_serializer.py
This commit is contained in:
Родитель
a2b2fcad7e
Коммит
d54dc781dc
|
@ -0,0 +1,31 @@
|
|||
=========
|
||||
Blocklist
|
||||
=========
|
||||
|
||||
.. note::
|
||||
|
||||
These APIs are not frozen and can change at any time without warning.
|
||||
See :ref:`the API versions available<api-versions-list>` for alternatives
|
||||
if you need stability.
|
||||
|
||||
|
||||
------
|
||||
Blocks
|
||||
------
|
||||
|
||||
.. _blocklist-block:
|
||||
|
||||
This endpoint returns an add-on Block from the blocklist, specified by guid or id.
|
||||
|
||||
|
||||
.. http:get:: /api/v4/blocklist/block/(int:block_id|string:guid)
|
||||
|
||||
:query string wrap_outgoing_links: If this parameter is present, wrap outgoing links through ``outgoing.prod.mozaws.net`` (See :ref:`Outgoing Links <api-overview-outgoing>`)
|
||||
:>json int id: The id for the block.
|
||||
:>json string created: The date the block was created.
|
||||
:>json string modified: The date the block was last updated.
|
||||
:>json string guid: The guid of the add-on being blocked.
|
||||
:>json string min_version: The minimum version of the add-on that will be blocked. "0" is the lowest version, meaning all versions up to max_version will be blocked. ("0" - "*" would be all versions).
|
||||
:>json string max_version: The maximum version of the add-on that will be blocked. "*" is the highest version, meaning all versions from min_version will be blocked. ("0" - "*" would be all versions).
|
||||
:>json string|null reason: Why the add-on needed to be blocked.
|
||||
:>json string|null url: A url to the report/request that detailed why the add-on should potentially be blocked. Typically a bug report on bugzilla.mozilla.org.
|
|
@ -36,6 +36,7 @@ using the API.
|
|||
accounts
|
||||
activity
|
||||
addons
|
||||
blocklist
|
||||
categories
|
||||
collections
|
||||
discovery
|
||||
|
|
|
@ -370,6 +370,7 @@ v4 API changelog
|
|||
* 2020-01-23: added /scanner/results (internal API endpoint).
|
||||
* 2020-02-06: added /reviewers/addon/(int:addon_id)/allow_resubmission/ and /reviewers/addon/(int:addon_id)/deny_resubmission/. https://github.com/mozilla/addons-server/issues/13409
|
||||
* 2020-02-20: added ``addon_install_source_url`` to abuse report endpoint
|
||||
* 2020-03-19: added /blocklist/block endpoint to expose add-on blocks https://github.com/mozilla/addons-server/issues/13706.
|
||||
|
||||
.. _`#11380`: https://github.com/mozilla/addons-server/issues/11380/
|
||||
.. _`#11379`: https://github.com/mozilla/addons-server/issues/11379/
|
||||
|
|
|
@ -23,12 +23,13 @@ v4_api_urls = [
|
|||
url(r'^accounts/', include(accounts_v4)),
|
||||
url(r'^activity/', include('olympia.activity.urls')),
|
||||
url(r'^addons/', include(addons_v4)),
|
||||
url(r'^blocklist/', include('olympia.blocklist.urls')),
|
||||
url(r'^', include('olympia.discovery.api_urls')),
|
||||
url(r'^hero/', include('olympia.hero.urls')),
|
||||
url(r'^ratings/', include(ratings_v4.urls)),
|
||||
url(r'^reviewers/', include('olympia.reviewers.api_urls')),
|
||||
url(r'^', include('olympia.signing.urls')),
|
||||
url(r'^', include(amo_api_patterns)),
|
||||
url(r'^hero/', include('olympia.hero.urls')),
|
||||
url(r'^scanner/', include('olympia.scanners.api_urls')),
|
||||
]
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from olympia.amo.urlresolvers import get_outgoing_url
|
||||
|
||||
from .models import Block
|
||||
|
||||
|
||||
class BlockSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = Block
|
||||
fields = (
|
||||
'id', 'created', 'modified', 'guid', 'min_version', 'max_version',
|
||||
'reason', 'url')
|
||||
|
||||
def to_representation(self, obj):
|
||||
data = super().to_representation(obj)
|
||||
|
||||
if ('request' in self.context and
|
||||
'wrap_outgoing_links' in self.context['request'].GET and
|
||||
'url' in data):
|
||||
data['url'] = get_outgoing_url(data['url'])
|
||||
|
||||
return data
|
|
@ -0,0 +1,36 @@
|
|||
from rest_framework.test import APIRequestFactory
|
||||
|
||||
from olympia.amo.tests import TestCase, user_factory
|
||||
from olympia.amo.urlresolvers import get_outgoing_url
|
||||
from olympia.blocklist.models import Block
|
||||
from olympia.blocklist.serializers import BlockSerializer
|
||||
|
||||
|
||||
class TestBlockSerializer(TestCase):
|
||||
def setUp(self):
|
||||
self.block = Block.objects.create(
|
||||
guid='foo@baa',
|
||||
min_version='45',
|
||||
reason='something happened',
|
||||
url='https://goo.gol',
|
||||
updated_by=user_factory())
|
||||
|
||||
def test_basic(self):
|
||||
serializer = BlockSerializer(instance=self.block)
|
||||
assert serializer.data == {
|
||||
'id': self.block.id,
|
||||
'guid': 'foo@baa',
|
||||
'min_version': '45',
|
||||
'max_version': '*',
|
||||
'reason': 'something happened',
|
||||
'url': 'https://goo.gol',
|
||||
'created': self.block.created.isoformat()[:-7] + 'Z',
|
||||
'modified': self.block.modified.isoformat()[:-7] + 'Z',
|
||||
}
|
||||
|
||||
def test_wrap_outgoing_links(self):
|
||||
request = APIRequestFactory().get('/', {'wrap_outgoing_links': 1})
|
||||
serializer = BlockSerializer(
|
||||
instance=self.block, context={'request': request})
|
||||
|
||||
assert serializer.data['url'] == get_outgoing_url(self.block.url)
|
|
@ -0,0 +1,32 @@
|
|||
from olympia.amo.tests import reverse_ns, TestCase, user_factory
|
||||
from olympia.amo.urlresolvers import get_outgoing_url
|
||||
from olympia.blocklist.models import Block
|
||||
from olympia.blocklist.serializers import BlockSerializer
|
||||
|
||||
|
||||
class TestBlockViewSet(TestCase):
|
||||
def setUp(self):
|
||||
self.block = Block.objects.create(
|
||||
guid='foo@baa',
|
||||
min_version='45',
|
||||
reason='something happened',
|
||||
url='https://goo.gol',
|
||||
updated_by=user_factory())
|
||||
|
||||
def test_get_pk(self):
|
||||
url = reverse_ns('blocklist-block-detail', args=(str(self.block.id),))
|
||||
response = self.client.get(url)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == BlockSerializer(instance=self.block).data
|
||||
|
||||
def test_get_guid(self):
|
||||
url = reverse_ns('blocklist-block-detail', args=(self.block.guid,))
|
||||
response = self.client.get(url)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == BlockSerializer(instance=self.block).data
|
||||
|
||||
def test_wrap_outgoing_links(self):
|
||||
url = reverse_ns('blocklist-block-detail', args=(self.block.guid,))
|
||||
response = self.client.get(url + '?wrap_outgoing_links')
|
||||
assert response.status_code == 200
|
||||
assert response.json()['url'] == get_outgoing_url(self.block.url)
|
|
@ -0,0 +1,14 @@
|
|||
from django.conf.urls import include, url
|
||||
|
||||
from rest_framework.routers import SimpleRouter
|
||||
|
||||
from . import views
|
||||
|
||||
|
||||
block = SimpleRouter()
|
||||
block.register('block', views.BlockViewSet,
|
||||
basename='blocklist-block')
|
||||
|
||||
urlpatterns = [
|
||||
url(r'', include(block.urls)),
|
||||
]
|
|
@ -0,0 +1,16 @@
|
|||
from rest_framework.mixins import RetrieveModelMixin
|
||||
from rest_framework.viewsets import GenericViewSet
|
||||
|
||||
from .models import Block
|
||||
from .serializers import BlockSerializer
|
||||
|
||||
|
||||
class BlockViewSet(RetrieveModelMixin, GenericViewSet):
|
||||
queryset = Block.objects
|
||||
serializer_class = BlockSerializer
|
||||
|
||||
def get_object(self):
|
||||
identifier = self.kwargs.pop('pk')
|
||||
self.lookup_field = 'pk' if identifier.isdigit() else 'guid'
|
||||
self.kwargs[self.lookup_field] = identifier
|
||||
return super().get_object()
|
Загрузка…
Ссылка в новой задаче