Skip to content
This repository has been archived by the owner on Mar 15, 2018. It is now read-only.

Commit

Permalink
manifest-refresh API (bug 883263)
Browse files Browse the repository at this point in the history
  • Loading branch information
Allen Short committed Jul 26, 2013
1 parent 2946307 commit c2cc241
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 3 deletions.
14 changes: 14 additions & 0 deletions docs/api/topics/apps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -363,4 +363,18 @@ Payments
:status 400: app is not valid for checking, examine response content.
:status 403: not allowed.


Manifest refresh
================

.. note:: Requires authentication and a successfully created hosted app.

.. http:post:: /api/v1/apps/app/(int:id|string:slug)/refresh-manifest/
**Response**
:status 204: Refresh triggered.
:status 400: App is packaged, not hosted, so no manifest to refresh.
:status 403: Not an app you own.
:status 404: No such app.

.. _`mobile country code`: http://en.wikipedia.org/wiki/List_of_mobile_country_codes
1 change: 1 addition & 0 deletions mkt/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,7 @@ class AppRouter(SimpleRouter):
mapping={
'get': 'retrieve',
'put': 'update',
'post': 'detail_post',
'patch': 'partial_update',
'delete': 'destroy'
},
Expand Down
21 changes: 20 additions & 1 deletion mkt/api/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@

from mkt.api.authentication import (SharedSecretAuthentication,
OptionalOAuthAuthentication)
from mkt.api.authorization import AppOwnerAuthorization, OwnerAuthorization
from mkt.api.authorization import (AllowAppOwner, AppOwnerAuthorization,
OwnerAuthorization)
from mkt.api.base import (CORSResource, CORSViewSet, GenericObject,
http_error, MarketplaceModelResource,
MarketplaceResource)
Expand All @@ -43,6 +44,7 @@
from mkt.regions import get_region, get_region_id, REGIONS_DICT
from mkt.submit.forms import AppDetailsBasicForm
from mkt.webapps.models import get_excluded_in
from mkt.webapps.tasks import _update_manifest
from mkt.webapps.utils import app_to_dict, update_with_reviewer_data

log = commonware.log.getLogger('z.api')
Expand Down Expand Up @@ -432,3 +434,20 @@ def error_reporter(request):
client = raven.base.Client(settings.SENTRY_DSN)
client.capture('raven.events.Exception', data=request.DATA)
return Response(status=204)


class RefreshManifestViewSet(CORSViewSet):
model = Webapp
permission_classes = [AllowAppOwner]
cors_allowed_methods = ('post',)
slug_lookup = 'app_slug'

def detail_post(self, request, **kwargs):
obj = self.get_object()
self.check_object_permissions(request, obj)
if obj.is_packaged:
return Response(
status=400,
data={'reason': 'App is a packaged app.'})
_update_manifest(obj.pk, True, {})
return Response(status=204)
58 changes: 58 additions & 0 deletions mkt/api/tests/test_handlers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
import os
from StringIO import StringIO
import tempfile

from django.core.urlresolvers import reverse
Expand Down Expand Up @@ -794,3 +795,60 @@ def test_report_stack(self, Client):
eq_(res.status_code, 204)
Client().capture.assert_called_with(
'raven.events.Exception', data={u'stack': stack, u'message': msg})

MANIFEST = """
{"name": "Steamcubev2!",
"icons": {"128": "http://testmanifest.com/icon-128.png", "48":
"http://testmanifest.com/icon-48.png", "16":
"http://testmanifest.com/icon-16.png"}, "installs_allowed_from": ["*"],
"description":
"This app has been automatically generated by testmanifest.com",
"version": "1.0",
"developer": {"url": "http://mozilla.com", "name": "Mozilla Marketplace"}}
"""


@patch('mkt.developers.tasks._fetch_content')
@patch('mkt.developers.tasks.validator')
class TestRefreshManifest(RestOAuth):
fixtures = fixture('user_2519', 'webapp_337141', 'platform_all')
def setUp(self):
super(TestRefreshManifest, self).setUp()
self.url = reverse('app-refresh-manifest-detail', kwargs={'pk': 337141})

def test_anon(self, validator, fetch):
res = self.anon.post(self.url)
eq_(res.status_code, 403)
assert not fetch.called

def test_non_owner(self, validator, fetch):
res = self.client.post(self.url)
eq_(res.status_code, 403)
assert not fetch.called

def test_refresh(self, validator, fetch):
validator.side_effect = lambda pk: setattr(
FileUpload.objects.get(pk=pk), 'validation',
json.dumps({'success': True, 'messages': []}))
content = StringIO(MANIFEST)
content.headers = {'Content-Type': 'application/x-web-app-manifest+json'}
fetch.return_value = content
AddonUser.objects.create(addon_id=337141, user_id=self.user.pk)
res = self.client.post(self.url)
eq_(res.status_code, 204)
assert fetch.called

def test_failed_refresh(self, validator, fetch):
fetch.side_effect = Exception
AddonUser.objects.create(addon_id=337141, user_id=self.user.pk)
res = self.client.post(self.url)
eq_(res.status_code, 204)
assert fetch.called
assert not validator.called

def test_no_packaged(self, validator, fetch):
AddonUser.objects.create(addon_id=337141, user_id=self.user.pk)
Webapp.objects.filter(pk=337141).update(is_packaged=True)
res = self.client.post(self.url)
eq_(res.status_code, 400)
eq_(res.json, {'reason': 'App is a packaged app.'})
9 changes: 7 additions & 2 deletions mkt/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
from tastypie.api import Api
from tastypie_services.services import (ErrorResource, SettingsResource)
from mkt.submit.api import PreviewResource, StatusResource, ValidationResource
from mkt.api.base import handle_500, SlugRouter
from mkt.api.base import AppRouter, handle_500, SlugRouter
from mkt.api.resources import (AppResource, CarrierResource, CategoryViewSet,
ConfigResource, error_reporter, RegionResource)
ConfigResource, error_reporter,
RefreshManifestViewSet, RegionResource)
from mkt.features.views import AppFeaturesList
from mkt.stats.api import GlobalStatsResource
from mkt.ratings.resources import RatingResource
Expand All @@ -24,6 +25,9 @@

apps = SlugRouter()
apps.register(r'category', CategoryViewSet, base_name='app-category')
subapps = AppRouter()
subapps.register('refresh-manifest', RefreshManifestViewSet,
base_name='app-refresh-manifest')

stats_api = Api(api_name='stats')
stats_api.register(GlobalStatsResource())
Expand All @@ -41,6 +45,7 @@
urlpatterns = patterns('',
url(r'^', include(api.urls)),
url(r'^apps/', include(apps.urls)),
url(r'^apps/app/', include(subapps.urls)),
url(r'^', include(stats_api.urls)),
url(r'^', include(services.urls)),
url(r'^fireplace/report_error', error_reporter, name='error-reporter'),
Expand Down

0 comments on commit c2cc241

Please sign in to comment.