Skip to content

Commit

Permalink
Merge pull request #58 from brainn-co/fix#7/api-blueprint-uri-template
Browse files Browse the repository at this point in the history
Fix#7/api blueprint uri template
  • Loading branch information
Danielwsx64 authored Nov 30, 2020
2 parents 5bd5d19 + 19d422f commit e385d9e
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 10 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.7.8] - 2020-11-27

### Fixed

- Add query strings to API Blueprint formatter

## [0.7.7] - 2020-11-27

### Fixed
Expand Down Expand Up @@ -107,7 +113,8 @@ Improve CI/CD flow:
- New "tags" parameter to operations object in Swagger format.
- Add changelog and Makefile.

[unreleased]: https://github.com/brainn-co/xcribe/compare/v0.7.7...master
[unreleased]: https://github.com/brainn-co/xcribe/compare/v0.7.8...master
[0.7.8]: https://github.com/brainn-co/xcribe/compare/v0.7.7...v0.7.8
[0.7.7]: https://github.com/brainn-co/xcribe/compare/v0.7.6...v0.7.7
[0.7.6]: https://github.com/brainn-co/xcribe/compare/v0.7.5...v0.7.6
[0.7.5]: https://github.com/brainn-co/xcribe/compare/v0.7.4...v0.7.5
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ mix.exs
```elixir
def deps do
[
{:xcribe, "~> 0.7.7"}
{:xcribe, "~> 0.7.8"}
]
end
```
Expand Down
24 changes: 22 additions & 2 deletions lib/xcribe/api_blueprint/apib.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,14 @@ defmodule Xcribe.ApiBlueprint.APIB do
resource(name, uri) <> parameters(params) <> reduce_resource_actions(actions)
end

def full_action(uri, %{name: name, parameters: params, requests: requests}) do
action(name, uri) <> parameters(params) <> reduce_action_requests(requests)
def full_action(uri, %{
name: name,
parameters: params,
query_parameters: query_parameters,
requests: requests
}) do
action(name, action_uri(uri, query_parameters)) <>
parameters(Map.merge(params, query_parameters)) <> reduce_action_requests(requests)
end

def full_request(name, request) do
Expand Down Expand Up @@ -106,6 +112,11 @@ defmodule Xcribe.ApiBlueprint.APIB do
)
end

defp action_uri(uri, query_parameters),
do: Enum.reduce(query_parameters, uri, &add_query_parameter/2)

defp add_query_parameter({param, _value}, uri), do: uri <> "{?#{param}}"

defp reduce_group_resources(resources) do
Enum.reduce(resources, "", fn {name, res}, acc -> acc <> full_resource(name, res) end)
end
Expand All @@ -121,6 +132,15 @@ defmodule Xcribe.ApiBlueprint.APIB do
defp reduce_parameters_items(parameters),
do: Enum.reduce(parameters, "", &parameter_item/2)

defp parameter_item({name, %{items: items, type: "array"}}, acc) do
acc <>
apply_template(@item_template,
name: name,
value: items[:example],
type: "array(#{items[:type]})"
)
end

defp parameter_item({name, %{example: ex, type: type}}, acc),
do: acc <> apply_template(@item_template, name: name, value: ex, type: type)

Expand Down
20 changes: 19 additions & 1 deletion lib/xcribe/api_blueprint/formatter.ex
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ defmodule Xcribe.ApiBlueprint.Formatter do
summary: "",
description: "",
parameters: action_parameters(request),
query_parameters: action_query_parameters(request),
requests: request_object(request)
}
}
Expand Down Expand Up @@ -76,6 +77,10 @@ defmodule Xcribe.ApiBlueprint.Formatter do
Enum.reduce(path_params, %{}, &reduce_path_params/2)
end

def action_query_parameters(%Request{query_params: query_params}) do
Enum.reduce(query_params, %{}, &reduce_query_params/2)
end

def resource_parameters(%Request{path: path, path_params: path_params}) do
path_params
|> Map.take(url_params(path))
Expand Down Expand Up @@ -155,7 +160,11 @@ defmodule Xcribe.ApiBlueprint.Formatter do
end

defp merge_action(action, new_request) do
%{action | requests: Map.merge(action.requests, new_request.requests)}
%{
action
| requests: Map.merge(action.requests, new_request.requests),
query_parameters: Map.merge(action.query_parameters, new_request.query_parameters)
}
end

defp object_key(%{} = request) do
Expand Down Expand Up @@ -191,6 +200,14 @@ defmodule Xcribe.ApiBlueprint.Formatter do
)
end

defp reduce_query_params({param, value}, parameters) do
Map.put(
parameters,
param,
schema_for(value, false)
)
end

defp schema_for(value, required) do
{nil, value}
|> JsonSchema.schema_for()
Expand All @@ -200,6 +217,7 @@ defmodule Xcribe.ApiBlueprint.Formatter do
defp headers(headers), do: headers |> Enum.into(%{}) |> Map.delete("content-type")

defp add_required(map, true), do: Map.put(map, :required, true)
defp add_required(map, false), do: map

defp url_params(path) do
case Regex.run(~r/\{(.*?)\}.+/, path, capture: :all_but_first) do
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule Xcribe.MixProject do
use Mix.Project

@version "0.7.7"
@version "0.7.8"
@description "A lib to generate API documentation from test specs"
@links %{"GitHub" => "https://github.com/brainn-co/xcribe"}

Expand Down
67 changes: 67 additions & 0 deletions test/xcribe/api_blueprint/apib_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,18 @@ defmodule Xcribe.ApiBlueprint.APIBTest do
"""
end

test "parameters with array" do
parameters = %{
"financialAccounts" => %{
items: %{example: "12", type: "string"},
type: "array"
}
}

assert APIB.parameters(parameters) ==
"+ Parameters\n\n + financialAccounts: `12` (array(string))\n\n"
end
end

describe "body/1" do
Expand Down Expand Up @@ -403,6 +415,61 @@ defmodule Xcribe.ApiBlueprint.APIBTest do
"""
end

test "action with query parameters" do
[{key, action}] =
RequestsGenerator.users_index()
|> Map.put(:query_params, %{"limit" => "6"})
|> Formatter.action_object()
|> Map.to_list()

assert APIB.full_action(key, action) == """
### Users index [GET /users{?limit}]
+ Parameters
+ limit: `6` (string)
+ Request show users (application/json)
+ Response 200 (application/json)
+ Headers
cache-control: max-age=0, private, must-revalidate
+ Body
[
{
"id": 1,
"name": "user 1"
},
{
"id": 2,
"name": "user 2"
}
]
+ Schema
{
"items": {
"properties": {
"id": {
"example": 1,
"format": "int32",
"type": "number"
},
"name": {
"example": "user 1",
"type": "string"
}
},
"type": "object"
},
"type": "array"
}
"""
end
end

describe "full_resource/2" do
Expand Down
41 changes: 37 additions & 4 deletions test/xcribe/api_blueprint/formatter_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,18 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do

test "merge two request objects" do
base_request = RequestsGenerator.users_index()
request_one = %{base_request | description: "Cool description"}
request_two = %{base_request | description: "Other description"}

request_one = %{
base_request
| description: "Cool description",
query_params: %{"user_age" => "32"}
}

request_two = %{
base_request
| description: "Other description",
query_params: %{"limit" => "5"}
}

full_request_one = Formatter.full_request_object(request_one)
full_request_two = Formatter.full_request_object(request_two)
Expand All @@ -36,6 +46,10 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do
description: "",
summary: "",
parameters: %{},
query_parameters: %{
"limit" => %{example: "5", type: "string"},
"user_age" => %{example: "32", type: "string"}
},
requests: %{
"Cool description" => %{
content_type: "application/json",
Expand Down Expand Up @@ -137,6 +151,7 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do
description: "",
summary: "",
parameters: %{},
query_parameters: %{},
requests: %{
"get all user posts" => %{
content_type: "application/json",
Expand Down Expand Up @@ -202,7 +217,7 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do
params: %{"users_id" => "1"},
path: "/users/{users_id}/posts/{id}",
path_params: %{"users_id" => "1", "id" => "2"},
query_params: %{},
query_params: %{"user_age" => "34"},
request_body: %{},
resource: "users_posts",
resource_group: :api,
Expand Down Expand Up @@ -230,6 +245,7 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do
"id" => %{example: "2", required: true, type: "string"},
"usersId" => %{example: "1", required: true, type: "string"}
},
query_parameters: %{"user_age" => %{example: "34", type: "string"}},
requests: %{
"get all user posts" => %{
content_type: "application/json",
Expand Down Expand Up @@ -271,7 +287,7 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do
params: %{"users_id" => "1"},
path: "/users/{users_id}/posts/{id}",
path_params: %{"users_id" => "1", "id" => "2"},
query_params: %{},
query_params: %{"user_age" => "16"},
request_body: %{},
resource: "users_posts",
resource_group: :api,
Expand All @@ -293,6 +309,7 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do
"id" => %{example: "2", required: true, type: "string"},
"usersId" => %{example: "1", required: true, type: "string"}
},
query_parameters: %{"user_age" => %{example: "16", type: "string"}},
requests: %{
"get all user posts" => %{
content_type: "application/json",
Expand Down Expand Up @@ -442,6 +459,22 @@ defmodule Xcribe.ApiBlueprint.FormatterTest do
end
end

describe "action_query_parameters/1" do
test "format action URI query parameters" do
struct = %Request{query_params: %{"user_age" => "15"}}

assert Formatter.action_query_parameters(struct) == %{
"user_age" => %{example: "15", type: "string"}
}
end

test "with no parameters" do
struct = %Request{query_params: %{}}

assert Formatter.action_query_parameters(struct) == %{}
end
end

describe "response_schema/1" do
test "return response schema for json content" do
struct = %Request{
Expand Down

0 comments on commit e385d9e

Please sign in to comment.