Skip to content

Commit

Permalink
Merge pull request #5315 from hypothesis/api-index
Browse files Browse the repository at this point in the history
Factor out new `h.views.api.index` module
  • Loading branch information
lyzadanger committed Sep 27, 2018
2 parents 8ce91ca + 6872776 commit 3a72a63
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 84 deletions.
48 changes: 0 additions & 48 deletions h/views/api/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,36 +39,6 @@
_ = i18n.TranslationStringFactory(__package__)


@api_config(route_name='api.index')
def index(context, request):
"""Return the API descriptor document.
Clients may use this to discover endpoints for the API.
"""

api_links = request.registry.api_links

# We currently need to keep a list of the parameter names we use in our API
# paths and pass these explicitly into the templater. As and when new
# parameter names are added, we'll need to add them here, or this view will
# break (and get caught by the `test_api_index` functional test).
templater = AngularRouteTemplater(request.route_url,
params=['id', 'pubid', 'user', 'userid'])

links = {}
for link in api_links:
method_info = {
'method': link['method'],
'url': templater.route_template(link['route_name']),
'desc': link['description'],
}
_set_at_path(links, link['name'].split('.'), method_info)

return {
'links': links,
}


@api_config(route_name='api.links',
link_name='links',
renderer='json_sorted',
Expand Down Expand Up @@ -241,24 +211,6 @@ def _publish_annotation_event(request,
request.notify_after_commit(event)


def _set_at_path(dict_, path, value):
"""
Set the value at a given `path` within a nested `dict`.
:param dict_: The root `dict` to update
:param path: List of path components
:param value: Value to assign
"""
key = path[0]
if key not in dict_:
dict_[key] = {}

if len(path) == 1:
dict_[key] = value
else:
_set_at_path(dict_[key], path[1:], value)


def _annotation_resource(request, annotation):
group_service = request.find_service(IGroupService)
links_service = request.find_service(name='links')
Expand Down
53 changes: 53 additions & 0 deletions h/views/api/index.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-

from __future__ import unicode_literals

from h.views.api.config import api_config, AngularRouteTemplater


@api_config(route_name='api.index')
def index(context, request):
"""Return the API descriptor document.
Clients may use this to discover endpoints for the API.
"""

api_links = request.registry.api_links

# We currently need to keep a list of the parameter names we use in our API
# paths and pass these explicitly into the templater. As and when new
# parameter names are added, we'll need to add them here, or this view will
# break (and get caught by the `test_api_index` functional test).
templater = AngularRouteTemplater(request.route_url,
params=['id', 'pubid', 'user', 'userid'])

links = {}
for link in api_links:
method_info = {
'method': link['method'],
'url': templater.route_template(link['route_name']),
'desc': link['description'],
}
_set_at_path(links, link['name'].split('.'), method_info)

return {
'links': links,
}


def _set_at_path(dict_, path, value):
"""
Set the value at a given `path` within a nested `dict`.
:param dict_: The root `dict` to update
:param path: List of path components
:param value: Value to assign
"""
key = path[0]
if key not in dict_:
dict_[key] = {}

if len(path) == 1:
dict_[key] = value
else:
_set_at_path(dict_[key], path[1:], value)
36 changes: 0 additions & 36 deletions tests/h/views/api/annotations_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,48 +6,12 @@
from webob.multidict import NestedMultiDict, MultiDict

from pyramid import testing
from pyramid.config import Configurator

from h.schemas import ValidationError
from h.search.core import SearchResult
from h.views.api import annotations as views


class TestIndex(object):

def test_it_returns_the_right_links(self, pyramid_config, pyramid_request):

# Scan `h.views.api_annotations` for API link metadata specified in @api_config
# declarations.
config = Configurator()
config.scan('h.views.api.annotations')
pyramid_request.registry.api_links = config.registry.api_links

pyramid_config.add_route('api.search', '/dummy/search')
pyramid_config.add_route('api.annotations', '/dummy/annotations')
pyramid_config.add_route('api.annotation', '/dummy/annotations/:id')
pyramid_config.add_route('api.links', '/dummy/links')

result = views.index(testing.DummyResource(), pyramid_request)

host = 'http://example.com' # Pyramid's default host URL'
links = result['links']
assert links['annotation']['create']['method'] == 'POST'
assert links['annotation']['create']['url'] == (
host + '/dummy/annotations')
assert links['annotation']['delete']['method'] == 'DELETE'
assert links['annotation']['delete']['url'] == (
host + '/dummy/annotations/:id')
assert links['annotation']['read']['method'] == 'GET'
assert links['annotation']['read']['url'] == (
host + '/dummy/annotations/:id')
assert links['annotation']['update']['method'] == 'PATCH'
assert links['annotation']['update']['url'] == (
host + '/dummy/annotations/:id')
assert links['search']['method'] == 'GET'
assert links['search']['url'] == host + '/dummy/search'


class TestLinks(object):

def test_it_returns_the_right_links(self, pyramid_config, pyramid_request):
Expand Down
43 changes: 43 additions & 0 deletions tests/h/views/api/index_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# -*- coding: utf-8 -*-

from __future__ import unicode_literals

from pyramid import testing
from pyramid.config import Configurator

from h.views.api import index as views


class TestIndex(object):

def test_it_returns_the_right_links(self, pyramid_config, pyramid_request):

# Scan `h.views.api_annotations` for API link metadata specified in @api_config
# declarations.
config = Configurator()
config.scan('h.views.api.annotations')
pyramid_request.registry.api_links = config.registry.api_links

pyramid_config.add_route('api.search', '/dummy/search')
pyramid_config.add_route('api.annotations', '/dummy/annotations')
pyramid_config.add_route('api.annotation', '/dummy/annotations/:id')
pyramid_config.add_route('api.links', '/dummy/links')

result = views.index(testing.DummyResource(), pyramid_request)

host = 'http://example.com' # Pyramid's default host URL'
links = result['links']
assert links['annotation']['create']['method'] == 'POST'
assert links['annotation']['create']['url'] == (
host + '/dummy/annotations')
assert links['annotation']['delete']['method'] == 'DELETE'
assert links['annotation']['delete']['url'] == (
host + '/dummy/annotations/:id')
assert links['annotation']['read']['method'] == 'GET'
assert links['annotation']['read']['url'] == (
host + '/dummy/annotations/:id')
assert links['annotation']['update']['method'] == 'PATCH'
assert links['annotation']['update']['url'] == (
host + '/dummy/annotations/:id')
assert links['search']['method'] == 'GET'
assert links['search']['url'] == host + '/dummy/search'

0 comments on commit 3a72a63

Please sign in to comment.