Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions lib/open_api/type.ex
Original file line number Diff line number Diff line change
Expand Up @@ -4,50 +4,49 @@ defmodule EctoCommand.OpenApi.Type do
alias OpenApiSpex.Schema

def uuid(options \\ []) do
[format: :uuid, description: "UUID", example: "defa2814-3686-4a73-9f64-a17cdfd7f1a1"] ++ options
[format: :uuid, description: "UUID"] ++ options
end

def enum(values, options \\ []) do
[example: List.first(values)] ++ options
def email(options \\ []) do
[format: :email, description: "Email", example: "user@domain.com"] ++ options
end

def datetime(options \\ []) do
[format: :"date-time", example: "2023-04-03T10:21:00Z"] ++ options
def password(options \\ []) do
[format: :password, description: "Password", example: "Abcd123!!"] ++ options
end

def date(options \\ []) do
[format: :date, example: "2023-04-03"] ++ options
def phone(options \\ []) do
[format: :telephone, description: "Telephone", example: "(425) 123-4567"] ++ options
end

def boolean(options \\ []) do
[example: true] ++ options
@deprecated "Automatically inferred from command schema when type is one of `:utc_datetime`, `:utc_datetime_usec`, `:naive_datetime`, `:naive_datetime_usec`"
def datetime(options \\ []) do
[format: :"date-time"] ++ options
end

def email(options \\ []) do
[format: :email, description: "Email", example: "user@domain.com"] ++ options
@deprecated "Automatically inferred from command schema when type is `:date`"
def date(options \\ []) do
[format: :date] ++ options
end

def password(options \\ []) do
[format: :password, description: "Password", example: "Abcd123!!"] ++ options
@deprecated "Automatically inferred from command schema when type is `Ecto.Enum` or `inclusion` opt is used"
def enum(values, options \\ []) do
[example: List.first(values)] ++ options
end

def phone(options \\ []) do
[format: :telephone, description: "Telephone", example: "(425) 123-4567"] ++ options
@deprecated "Automatically inferred from command schema when type is `:boolean`"
def boolean(options \\ []) do
[example: true] ++ options
end

def example_for(%Schema{type: :array, items: [%{enum: values}]} = _schema) when is_list(values),
do: Enum.take(values, 2)

def example_for(%Schema{default: default}) when not is_nil(default), do: default
def example_for(%Schema{enum: values}) when is_list(values), do: List.first(values)
def example_for(%Schema{type: :string, format: :date}), do: Keyword.get(date(), :example)
def example_for(%Schema{type: :string, format: :"date-time"}), do: Keyword.get(datetime(), :example)
def example_for(%Schema{type: :string, format: :uuid}), do: Keyword.get(uuid(), :example)
def example_for(%Schema{type: :string, format: :email}), do: Keyword.get(email(), :example)
def example_for(%Schema{type: :string, format: :telephone}), do: Keyword.get(phone(), :example)
def example_for(%Schema{type: :string, format: :password}), do: Keyword.get(password(), :example)
def example_for(%Schema{type: :string}), do: "string"
def example_for(%Schema{type: :boolean}), do: true
def example_for(%Schema{type: :integer} = schema), do: trunc(number_example(schema))
def example_for(%Schema{type: :number} = schema), do: number_example(schema)
def example_for(%Schema{type: :array, items: [%{example: nil}]}), do: []
Expand All @@ -59,6 +58,7 @@ defmodule EctoCommand.OpenApi.Type do
end)
end

def example_for(%Schema{} = schema), do: Schema.example(schema)
def example_for(_schema), do: nil

defp number_example(%Schema{not: %{enum: [n]}}), do: (n + 1) / 1
Expand Down
41 changes: 20 additions & 21 deletions test/unit/command/open_api/open_api_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do

param :mime_type, :string,
required: true,
inclusion: ["image/jpeg", "image/png"],
doc: Type.enum(["image/jpeg", "image/png"])
inclusion: ["image/jpeg", "image/png"]

param :an_enum, Ecto.Enum, values: [:a, :b]
param :an_enum_stored_as_int, Ecto.Enum, values: [a: 1, b: 2]
Expand All @@ -32,9 +31,9 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do
param :an_integer_c, :integer, number: [greater_than: 18, less_than_or_equal_to: 100], doc: [example: 30]
param :a_float, :float, number: [greater_than: 10, less_than_or_equal_to: 100]
param :type_id, :string
param :accepts, :boolean, default: false, doc: Type.boolean()
param :folder_id, :string, change: &String.valid?/1
param :uploaded_at, :utc_datetime, doc: Type.datetime()
param :accepts, :boolean, default: false
param :folder_id, :string, change: &String.valid?/1, doc: [example: "a_folder_id"]
param :uploaded_at, :utc_datetime
param :a_date, :date
param :a_list_of_strings_a, {:array, :string}, default: []
param :a_list_of_strings_b, {:array, :string}, doc: [description: "A list of strings A"]
Expand All @@ -50,7 +49,7 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do

test "all properties docs are generated correctly" do
assert %{
accepts: %OpenApiSpex.Schema{example: true, type: :boolean, default: false},
accepts: %OpenApiSpex.Schema{example: false, type: :boolean, default: false},
an_integer_a: %OpenApiSpex.Schema{
exclusiveMaximum: false,
exclusiveMinimum: false,
Expand Down Expand Up @@ -93,10 +92,10 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do
type: :string
},
extension: %OpenApiSpex.Schema{example: "png", maxLength: 3, type: :string},
folder_id: %OpenApiSpex.Schema{type: :string, example: "string"},
folder_id: %OpenApiSpex.Schema{type: :string, example: "a_folder_id"},
id: %OpenApiSpex.Schema{
description: "UUID",
example: "defa2814-3686-4a73-9f64-a17cdfd7f1a1",
example: "02ef9c5f-29e6-48fc-9ec3-7ed57ed351f6",
format: :uuid,
type: :string
},
Expand All @@ -110,13 +109,13 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do
minLength: 9,
type: :string
},
type_id: %OpenApiSpex.Schema{type: :string, example: "string"},
type_id: %OpenApiSpex.Schema{type: :string, example: ""},
uploaded_at: %OpenApiSpex.Schema{
example: "2023-04-03T10:21:00Z",
example: "2020-04-20T16:20:00Z",
format: :"date-time",
type: :string
},
a_date: %OpenApiSpex.Schema{type: :string, format: :date, example: "2023-04-03"},
a_date: %OpenApiSpex.Schema{type: :string, format: :date, example: "2020-04-20"},
a_list_of_enums: %OpenApiSpex.Schema{
type: :array,
items: [%OpenApiSpex.Schema{enum: ["a", "b", "c"], type: :string, example: "a"}],
Expand All @@ -125,15 +124,15 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do
},
a_list_of_strings_a: %OpenApiSpex.Schema{
type: :array,
items: [%OpenApiSpex.Schema{type: :string, example: "string"}],
items: [%OpenApiSpex.Schema{type: :string, example: ""}],
default: [],
example: []
},
a_list_of_strings_b: %OpenApiSpex.Schema{
type: :array,
items: [%OpenApiSpex.Schema{type: :string, example: "string"}],
items: [%OpenApiSpex.Schema{type: :string, example: ""}],
description: "A list of strings A",
example: ["string"]
example: [""]
},
a_list_of_strings_c: %OpenApiSpex.Schema{
type: :array,
Expand Down Expand Up @@ -162,15 +161,15 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do

test "example is generated accordingly to properties" do
assert %{
a_date: "2023-04-03",
a_date: "2020-04-20",
a_float: 55.5,
a_list_of_enums: ["a", "b"],
a_list_of_strings_a: [],
a_list_of_strings_b: ["string"],
a_list_of_strings_b: [""],
a_list_of_strings_c: ["a", "b"],
a_map: %{},
a_map_with_int_values: %{a: 1},
accepts: true,
accepts: false,
an_enum: "a",
an_enum_stored_as_int: "a",
an_integer_a: 20,
Expand All @@ -179,14 +178,14 @@ defmodule Unit.EctoCommand.OpenApi.OpenApiTest do
count: 58,
email: "user@domain.com",
extension: "png",
folder_id: "string",
id: "defa2814-3686-4a73-9f64-a17cdfd7f1a1",
folder_id: "a_folder_id",
id: "02ef9c5f-29e6-48fc-9ec3-7ed57ed351f6",
numeric_id: 10,
mime_type: "image/jpeg",
name: "Mario",
phone: "(425) 123-4567",
type_id: "string",
uploaded_at: "2023-04-03T10:21:00Z"
type_id: "",
uploaded_at: "2020-04-20T16:20:00Z"
} == Sample.schema().example
end

Expand Down
18 changes: 7 additions & 11 deletions test/unit/command/open_api/type_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -113,20 +113,16 @@ defmodule Unit.EctoCommand.OpenApi.TypeTest do
assert 9.5 == Type.example_for(schema)
end

test "for booleans" do
assert true == Type.example_for(%Schema{type: :boolean})
end

test "for dates" do
assert "2023-04-03" == Type.example_for(%Schema{type: :string, format: :date})
assert "2020-04-20" == Type.example_for(%Schema{type: :string, format: :date})
end

test "for datetimes" do
assert "2023-04-03T10:21:00Z" == Type.example_for(%Schema{type: :string, format: :"date-time"})
assert "2020-04-20T16:20:00Z" == Type.example_for(%Schema{type: :string, format: :"date-time"})
end

test "for UUIDs" do
assert "defa2814-3686-4a73-9f64-a17cdfd7f1a1" == Type.example_for(%Schema{type: :string, format: :uuid})
assert "02ef9c5f-29e6-48fc-9ec3-7ed57ed351f6" == Type.example_for(%Schema{type: :string, format: :uuid})
end

test "for emails" do
Expand Down Expand Up @@ -163,19 +159,19 @@ defmodule Unit.EctoCommand.OpenApi.TypeTest do
id: %OpenApiSpex.Schema{type: :string},
name: %OpenApiSpex.Schema{type: :string},
type: %OpenApiSpex.Schema{enum: ["a", "b"], type: :string, example: "a"},
tags: %OpenApiSpex.Schema{type: :array, items: [%OpenApiSpex.Schema{type: :string, default: []}]},
tags: %OpenApiSpex.Schema{type: :array, items: [%OpenApiSpex.Schema{type: :string}], default: []},
non_required_id: %OpenApiSpex.Schema{type: :string}
}
}

assert %{
active: true,
count: 11,
id: "string",
name: "string",
id: "",
name: "",
type: "a",
tags: [],
non_required_id: "string"
non_required_id: ""
} == Type.example_for(schema)
end
end
Expand Down