Merge pull request #5334 from Woile/woile-nested-docs-fix

Fix docs multiple nested and multiple methods
This commit is contained in:
Carlton Gibson 2017-08-18 11:05:06 +02:00 committed by GitHub
commit 4d5e846ca7
7 changed files with 352 additions and 9 deletions

View File

@ -2,6 +2,14 @@ var responseDisplay = 'data'
var coreapi = window.coreapi
var schema = window.schema
function normalizeKeys (arr) {
var _normarr = [];
for (var i = 0; i < arr.length; i++) {
_normarr = _normarr.concat(arr[i].split(' > '));
}
return _normarr;
}
function normalizeHTTPHeader (str) {
// Capitalize HTTP headers for display.
return (str.charAt(0).toUpperCase() + str.substring(1))
@ -94,7 +102,7 @@ $(function () {
var $requestAwaiting = $form.find('.request-awaiting')
var $responseRaw = $form.find('.response-raw')
var $responseData = $form.find('.response-data')
var key = $form.data('key')
var key = normalizeKeys($form.data('key'))
var params = {}
var entries = formEntries($form.get()[0])
@ -212,7 +220,6 @@ $(function () {
}
var client = new coreapi.Client(options)
client.action(schema, key, params).then(function (data) {
var response = JSON.stringify(data, null, 2)
$requestAwaiting.addClass('hide')

View File

@ -20,7 +20,7 @@
</a></h2>
{% endif %}
{% for link_key, link in section.links|items %}
{% for link_key, link in section|schema_links|items %}
{% include "rest_framework/docs/link.html" %}
{% endfor %}
{% endfor %}

View File

@ -1,7 +1,7 @@
{% load rest_framework %}
<!-- Modal -->
<div class="modal fade api-modal" id="{{ section_key }}_{{ link_key }}_modal" tabindex="-1" role="dialog" aria-labelledby="api explorer modal">
<div class="modal fade api-modal" id="{{ section_key }}_{{ link_key|slugify }}_modal" tabindex="-1" role="dialog" aria-labelledby="api explorer modal">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">

View File

@ -6,11 +6,11 @@
class="btn btn-sm btn-success"
style="float: right; margin-top: 20px"
data-toggle="modal"
data-target="#{{ section_key }}_{{ link_key }}_modal">
data-target="#{{ section_key }}_{{ link_key|slugify }}_modal">
<i class="fa fa-exchange"></i> Interact
</button>
<h3 id="{{ section_key }}-{{ link_key }}" class="coredocs-link-title">{{ link.title|default:link_key }} <a href="#{{ section_key }}-{{ link_key }}"><i class="fa fa-link" aria-hidden="true"></i>
<h3 id="{{ section_key }}-{{ link_key|slugify }}" class="coredocs-link-title">{{ link.title|default:link_key }} <a href="#{{ section_key }}-{{ link_key|slugify }}"><i class="fa fa-link" aria-hidden="true"></i>
</a></h3>
<div class="meta">

View File

@ -10,8 +10,8 @@
<li data-toggle="collapse" data-target="#{{ section_key }}-dropdown" class="collapsed">
<a><i class="fa fa-dot-circle-o fa-lg"></i> {% if section_key %}{{ section_key }}{% else %}API Endpoints{% endif %} <span class="arrow"></span></a>
<ul class="sub-menu {% if section_key %}collapse{% endif %}" id="{{ section_key }}-dropdown">
{% for link_key, link in section.links|items %}
<li><a href="#{{ section_key }}-{{ link_key }}">{{ link.title|default:link_key }}</a></li>
{% for link_key, link in section|schema_links|items %}
<li><a href="#{{ section_key }}-{{ link_key|slugify }}">{{ link.title|default:link_key }}</a></li>
{% endfor %}
</ul>
</li>

View File

@ -244,6 +244,29 @@ def items(value):
return value.items()
@register.filter
def schema_links(section, sec_key=None):
"""
Recursively find every link in a schema, even nested.
"""
NESTED_FORMAT = '%s > %s' # this format is used in docs/js/api.js:normalizeKeys
links = section.links
if section.data:
data = section.data.items()
for sub_section_key, sub_section in data:
new_links = schema_links(sub_section, sec_key=sub_section_key)
links.update(new_links)
if sec_key is not None:
new_links = OrderedDict()
for link_key, link in links.items():
new_key = NESTED_FORMAT % (sec_key, link_key)
new_links.update({new_key: link})
return new_links
return links
@register.filter
def add_nested_class(value):
if isinstance(value, dict):

View File

@ -1,13 +1,16 @@
# encoding: utf-8
from __future__ import unicode_literals
import unittest
from django.test import TestCase
from rest_framework.compat import coreapi, coreschema
from rest_framework.relations import Hyperlink
from rest_framework.templatetags import rest_framework
from rest_framework.templatetags.rest_framework import (
add_nested_class, add_query_param, as_string, break_long_headers,
format_value, get_pagination_html, urlize_quoted_links
format_value, get_pagination_html, schema_links, urlize_quoted_links
)
from rest_framework.test import APIRequestFactory
@ -300,3 +303,313 @@ class URLizerTests(TestCase):
data['"foo_set": [\n "http://api/foos/1/"\n], '] = \
'&quot;foo_set&quot;: [\n &quot;<a href="http://api/foos/1/">http://api/foos/1/</a>&quot;\n], '
self._urlize_dict_check(data)
@unittest.skipUnless(coreapi, 'coreapi is not installed')
class SchemaLinksTests(TestCase):
def test_schema_with_empty_links(self):
schema = coreapi.Document(
url='',
title='Example API',
content={
'users': {
'list': {}
}
}
)
section = schema['users']
flat_links = schema_links(section)
assert len(flat_links) is 0
def test_single_action(self):
schema = coreapi.Document(
url='',
title='Example API',
content={
'users': {
'list': coreapi.Link(
url='/users/',
action='get',
fields=[]
)
}
}
)
section = schema['users']
flat_links = schema_links(section)
assert len(flat_links) is 1
assert 'list' in flat_links
def test_default_actions(self):
schema = coreapi.Document(
url='',
title='Example API',
content={
'users': {
'create': coreapi.Link(
url='/users/',
action='post',
fields=[]
),
'list': coreapi.Link(
url='/users/',
action='get',
fields=[]
),
'read': coreapi.Link(
url='/users/{id}/',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'update': coreapi.Link(
url='/users/{id}/',
action='patch',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
}
}
)
section = schema['users']
flat_links = schema_links(section)
assert len(flat_links) is 4
assert 'list' in flat_links
assert 'create' in flat_links
assert 'read' in flat_links
assert 'update' in flat_links
def test_default_actions_and_single_custom_action(self):
schema = coreapi.Document(
url='',
title='Example API',
content={
'users': {
'create': coreapi.Link(
url='/users/',
action='post',
fields=[]
),
'list': coreapi.Link(
url='/users/',
action='get',
fields=[]
),
'read': coreapi.Link(
url='/users/{id}/',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'update': coreapi.Link(
url='/users/{id}/',
action='patch',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'friends': coreapi.Link(
url='/users/{id}/friends',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
}
}
)
section = schema['users']
flat_links = schema_links(section)
assert len(flat_links) is 5
assert 'list' in flat_links
assert 'create' in flat_links
assert 'read' in flat_links
assert 'update' in flat_links
assert 'friends' in flat_links
def test_default_actions_and_single_custom_action_two_methods(self):
schema = coreapi.Document(
url='',
title='Example API',
content={
'users': {
'create': coreapi.Link(
url='/users/',
action='post',
fields=[]
),
'list': coreapi.Link(
url='/users/',
action='get',
fields=[]
),
'read': coreapi.Link(
url='/users/{id}/',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'update': coreapi.Link(
url='/users/{id}/',
action='patch',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'friends': {
'list': coreapi.Link(
url='/users/{id}/friends',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'create': coreapi.Link(
url='/users/{id}/friends',
action='post',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
}
}
}
)
section = schema['users']
flat_links = schema_links(section)
assert len(flat_links) is 6
assert 'list' in flat_links
assert 'create' in flat_links
assert 'read' in flat_links
assert 'update' in flat_links
assert 'friends > list' in flat_links
assert 'friends > create' in flat_links
def test_multiple_nested_routes(self):
schema = coreapi.Document(
url='',
title='Example API',
content={
'animals': {
'dog': {
'vet': {
'list': coreapi.Link(
url='/animals/dog/{id}/vet',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
},
'read': coreapi.Link(
url='/animals/dog/{id}',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
},
'cat': {
'list': coreapi.Link(
url='/animals/cat/',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'create': coreapi.Link(
url='/aniamls/cat',
action='post',
fields=[]
)
}
}
}
)
section = schema['animals']
flat_links = schema_links(section)
assert len(flat_links) is 4
assert 'cat > create' in flat_links
assert 'cat > list' in flat_links
assert 'dog > read' in flat_links
assert 'dog > vet > list' in flat_links
def test_multiple_resources_with_multiple_nested_routes(self):
schema = coreapi.Document(
url='',
title='Example API',
content={
'animals': {
'dog': {
'vet': {
'list': coreapi.Link(
url='/animals/dog/{id}/vet',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
},
'read': coreapi.Link(
url='/animals/dog/{id}',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
},
'cat': {
'list': coreapi.Link(
url='/animals/cat/',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
),
'create': coreapi.Link(
url='/aniamls/cat',
action='post',
fields=[]
)
}
},
'farmers': {
'silo': {
'soy': {
'list': coreapi.Link(
url='/farmers/silo/{id}/soy',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
},
'list': coreapi.Link(
url='/farmers/silo',
action='get',
fields=[
coreapi.Field('id', required=True, location='path', schema=coreschema.String())
]
)
}
}
}
)
section = schema['animals']
flat_links = schema_links(section)
assert len(flat_links) is 4
assert 'cat > create' in flat_links
assert 'cat > list' in flat_links
assert 'dog > read' in flat_links
assert 'dog > vet > list' in flat_links
section = schema['farmers']
flat_links = schema_links(section)
assert len(flat_links) is 2
assert 'silo > list' in flat_links
assert 'silo > soy > list' in flat_links