Page MenuHomePhorge

No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/open_api_spex/open_api.ex b/lib/open_api_spex/open_api.ex
index fb43869..ce2681f 100644
--- a/lib/open_api_spex/open_api.ex
+++ b/lib/open_api_spex/open_api.ex
@@ -1,101 +1,101 @@
defmodule OpenApiSpex.OpenApi do
@moduledoc """
Defines the `OpenApiSpex.OpenApi.t` type and the behaviour for application modules that
construct an `OpenApiSpex.OpenApi.t` at runtime.
"""
alias OpenApiSpex.{
Extendable, Info, Server, Paths, Components,
SecurityRequirement, Tag, ExternalDocumentation,
OpenApi
}
@enforce_keys [:info, :paths]
defstruct [
openapi: "3.0.0",
info: nil,
servers: [],
paths: nil,
components: nil,
security: [],
tags: [],
externalDocs: nil,
extensions: nil
]
@typedoc """
[OpenAPI Object](https://swagger.io/specification/#oasObject)
This is the root document object of the OpenAPI document.
"""
@type t :: %OpenApi{
openapi: String.t,
info: Info.t,
servers: [Server.t] | nil,
paths: Paths.t,
components: Components.t | nil,
security: [SecurityRequirement.t] | nil,
tags: [Tag.t] | nil,
externalDocs: ExternalDocumentation.t | nil,
extensions: %{String.t() => any()} | nil,
}
@doc """
A spec/0 callback function is required for use with the `OpenApiSpex.Plug.PutApiSpec` plug.
## Example
@impl OpenApiSpex.OpenApi
def spec do
%OpenApi{
servers: [
# Populate the Server info from a phoenix endpoint
- Server.from_endpoint(MyAppWeb.Endpoint, otp_app: :my_app)
+ Server.from_endpoint(MyAppWeb.Endpoint)
],
info: %Info{
title: "My App",
version: "1.0"
},
# populate the paths from a phoenix router
paths: Paths.from_router(MyAppWeb.Router)
}
|> OpenApiSpex.resolve_schema_modules() # discover request/response schemas from path specs
end
"""
@callback spec() :: t
@json_encoder Enum.find([Jason, Poison], &Code.ensure_loaded?/1)
def json_encoder, do: @json_encoder
for encoder <- [Poison.Encoder, Jason.Encoder] do
if Code.ensure_loaded?(encoder) do
defimpl encoder do
def encode(api_spec = %OpenApi{}, options) do
api_spec
|> to_json()
|> unquote(encoder).encode(options)
end
defp to_json(%Regex{source: source}), do: source
defp to_json(value = %{__struct__: _}) do
value
|> Extendable.to_map()
|> to_json()
end
defp to_json(value) when is_map(value) do
value
|> Stream.map(fn {k,v} -> {to_string(k), to_json(v)} end)
|> Stream.filter(fn {_, nil} -> false; _ -> true end)
|> Enum.into(%{})
end
defp to_json(value) when is_list(value) do
Enum.map(value, &to_json/1)
end
defp to_json(nil), do: nil
defp to_json(true), do: true
defp to_json(false), do: false
defp to_json(value) when is_atom(value), do: to_string(value)
defp to_json(value), do: value
end
end
end
end
diff --git a/lib/open_api_spex/server.ex b/lib/open_api_spex/server.ex
index 589351d..c0dc47f 100644
--- a/lib/open_api_spex/server.ex
+++ b/lib/open_api_spex/server.ex
@@ -1,40 +1,44 @@
defmodule OpenApiSpex.Server do
@moduledoc """
Defines the `OpenApiSpex.Server.t` type.
"""
alias OpenApiSpex.{Server, ServerVariable}
@enforce_keys :url
defstruct [
:url,
:description,
variables: %{}
]
@typedoc """
[Server Object](https://swagger.io/specification/#serverObject)
An object representing a Server.
"""
@type t :: %Server{
url: String.t,
description: String.t | nil,
variables: %{String.t => ServerVariable.t}
}
@doc """
Builds a Server from a phoenix Endpoint module
"""
- @spec from_endpoint(module, [otp_app: atom]) :: t
- def from_endpoint(endpoint, opts) do
- app = opts[:otp_app]
- url_config = Application.get_env(app, endpoint, []) |> Keyword.get(:url, [])
- scheme = Keyword.get(url_config, :scheme, "http")
- host = Keyword.get(url_config, :host, "localhost")
- port = Keyword.get(url_config, :port, "80")
- path = Keyword.get(url_config, :path, "/")
+ @deprecated "Use from_endpoint/1 instead"
+ @spec from_endpoint(module, ignored :: any()) :: t
+ def from_endpoint(endpoint, _opts) do
+ from_endpoint(endpoint)
+ end
+
+ @doc """
+ Builds a Server from a phoenix Endpoint module
+ """
+ @spec from_endpoint(module) :: t
+ def from_endpoint(endpoint) do
+ uri = apply(endpoint, :struct_url, [])
%Server{
- url: "#{scheme}://#{host}:#{port}#{path}"
+ url: URI.to_string(uri)
}
end
end
diff --git a/test/server_test.exs b/test/server_test.exs
index 0cff345..d5555d6 100644
--- a/test/server_test.exs
+++ b/test/server_test.exs
@@ -1,20 +1,41 @@
defmodule OpenApiSpex.ServerTest do
use ExUnit.Case
alias OpenApiSpex.{Server}
- alias OpenApiSpexText.Endpoint
+ alias OpenApiSpexTest.Endpoint
+
+ @otp_app :open_api_spex_test
describe "Server" do
- test "from_endpoint" do
- Application.put_env(:phoenix_swagger, Endpoint, [
- url: [host: "example.com", port: 1234, path: "/api/v1/", scheme: :https],
- ])
+ test "from_endpoint/1" do
+ setup_endpoint()
- server = Server.from_endpoint(Endpoint, otp_app: :phoenix_swagger)
+ server = Server.from_endpoint(Endpoint)
assert %{
url: "https://example.com:1234/api/v1/"
} = server
end
+
+ test "from_endpoint/2" do
+ setup_endpoint()
+
+ expected = Server.from_endpoint(Endpoint)
+ actual = Server.from_endpoint(Endpoint, [opt_app: @otp_app])
+
+ assert ^expected = actual
+ end
+ end
+
+ defp setup_endpoint do
+ Application.put_env(@otp_app, Endpoint, [
+ url: [
+ scheme: "https",
+ host: "example.com",
+ port: 1234,
+ path: "/api/v1/"
+ ]
+ ])
+ Endpoint.start_link()
end
+end
-end
\ No newline at end of file
diff --git a/test/support/endpoint.ex b/test/support/endpoint.ex
new file mode 100644
index 0000000..7ee48fc
--- /dev/null
+++ b/test/support/endpoint.ex
@@ -0,0 +1,4 @@
+defmodule OpenApiSpexTest.Endpoint do
+ use Phoenix.Endpoint, otp_app: :open_api_spex_test
+end
+

File Metadata

Mime Type
text/x-diff
Expires
Thu, Nov 28, 10:31 PM (1 d, 21 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41109
Default Alt Text
(6 KB)

Event Timeline