From c55d65ec6686ea663c76832f4c5831686ac1b143 Mon Sep 17 00:00:00 2001 From: Dayton Nolan Date: Mon, 4 May 2020 19:42:30 -0500 Subject: [PATCH] Add changeset function, use real db in tests --- CHANGELOG.md | 14 + lib/ecto_resource.ex | 22 +- lib/option_parser.ex | 68 +++-- lib/resource_functions.ex | 2 +- .../20200410023114_create_people.exs | 6 +- test/ecto_resource/defaults_test.exs | 250 +++++++++++++++-- test/ecto_resource/except_filter_test.exs | 258 ++++++++++++++++++ test/ecto_resource/only_filter_test.exs | 173 ++++++++++++ .../option_parser_test.exs | 16 ++ test/ecto_resource/read_test.exs | 189 +++++++++++++ test/ecto_resource/read_write_test.exs | 227 +++++++++++++++ test/ecto_resource/without_suffix_test.exs | 257 +++++++++++++++++ test/ecto_resource_except_test.exs | 59 ---- test/ecto_resource_only_test.exs | 41 --- test/ecto_resource_pluralize_test.exs | 48 ---- test/ecto_resource_read_test.exs | 77 ------ test/ecto_resource_read_write_test.exs | 122 --------- test/ecto_resource_test.exs | 106 ------- test/no_suffix_test.exs | 48 ---- test/resources_test.exs | 49 ---- {lib => test/support}/test_schema/person.ex | 4 +- 21 files changed, 1429 insertions(+), 607 deletions(-) create mode 100644 test/ecto_resource/except_filter_test.exs create mode 100644 test/ecto_resource/only_filter_test.exs rename test/{ => ecto_resource}/option_parser_test.exs (93%) create mode 100644 test/ecto_resource/read_test.exs create mode 100644 test/ecto_resource/read_write_test.exs create mode 100644 test/ecto_resource/without_suffix_test.exs delete mode 100644 test/ecto_resource_except_test.exs delete mode 100644 test/ecto_resource_only_test.exs delete mode 100644 test/ecto_resource_pluralize_test.exs delete mode 100644 test/ecto_resource_read_test.exs delete mode 100644 test/ecto_resource_read_write_test.exs delete mode 100644 test/ecto_resource_test.exs delete mode 100644 test/no_suffix_test.exs delete mode 100644 test/resources_test.exs rename {lib => test/support}/test_schema/person.ex (68%) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7892c4..dfeed37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Security +[1.3.0] +------------ + +### Added +- `changeset` convenience function added + +### Changed + +### Removed + +### Fixed + +### Security + [1.2.0] - 2019-09-17 -------------------- ### Added diff --git a/lib/ecto_resource.ex b/lib/ecto_resource.ex index 241980a..03b597f 100644 --- a/lib/ecto_resource.ex +++ b/lib/ecto_resource.ex @@ -114,7 +114,7 @@ defmodule EctoResource do :change -> @doc """ - Creates a #{schema_name} changeset. + Creates a #{schema_name} changeset from an existing schema struct. #{name}(%#{schema_name}{}, %{}) @@ -132,8 +132,23 @@ defmodule EctoResource do ResourceFunctions.change(unquote(schema), changeable, changes) end - @spec changeset() :: Ecto.Changeset.t() - def changeset() do + :changeset -> + + @doc """ + Creates a blank changeset. + + changeset() + + #Ecto.Changeset< + action: nil, + changes: %{}, + errors: [], + data: ##{schema_name}<>, + valid?: true + > + """ + @spec unquote(name)() :: Ecto.Changeset.t() + def unquote(name)() do ResourceFunctions.changeset(unquote(schema)) end @@ -164,6 +179,7 @@ defmodule EctoResource do #{name}(%{invalid: "invalid"}) ** (Ecto.InvalidChangesetError) """ + @spec unquote(name)(map()) :: Ecto.Schema.t() | Ecto.InvalidChangesetError def unquote(name)(attributes) do ResourceFunctions.create!(@repo, unquote(schema), attributes) end diff --git a/lib/option_parser.ex b/lib/option_parser.ex index cd7cbae..639b893 100644 --- a/lib/option_parser.ex +++ b/lib/option_parser.ex @@ -4,18 +4,19 @@ defmodule EctoResource.OptionParser do alias EctoResource.Helpers @functions [ - { "update!", 2 }, - { "update", 2 }, - { "get_by!", 2 }, - { "get_by", 2 }, - { "get!", 2 }, - { "get", 2 }, - { "delete!", 1 }, - { "delete", 1 }, - { "create!", 1 }, - { "create", 1 }, - { "change", 1 }, - { "all", 1 } + {"all", 1}, + {"change", 1}, + {"changeset", 0}, + {"create!", 1}, + {"create", 1}, + {"delete!", 1}, + {"delete", 1}, + {"get!", 2}, + {"get", 2}, + {"get_by!", 2}, + {"get_by", 2}, + {"update!", 2}, + {"update", 2} ] @spec parse(String.t(), list() | atom()) :: map() @@ -32,8 +33,23 @@ defmodule EctoResource.OptionParser do def parse(suffix, :read), do: parse(suffix, only: [:all, :get, :get!, :get_by, :get_by!]) - def parse(suffix, :read_write), - do: parse(suffix, only: [:all, :get, :get!, :get_by, :get_by!, :change, :create, :create!, :update, :update!]) + def parse(suffix, :read_write) do + parse(suffix, + only: [ + :all, + :get, + :get!, + :get_by, + :get_by!, + :change, + :changeset, + :create, + :create!, + :update, + :update! + ] + ) + end def parse(suffix, options) do @functions @@ -47,7 +63,7 @@ defmodule EctoResource.OptionParser do end @spec create_suffix(module, list()) :: String.t() - def create_suffix(_, [suffix: false]), do: "" + def create_suffix(_, suffix: false), do: "" def create_suffix(schema, _), do: Helpers.underscore_module_name(schema) defp function_name(function, ""), do: String.to_atom(function) @@ -61,16 +77,20 @@ defmodule EctoResource.OptionParser do String.to_atom("get_#{suffix}_by!") end + defp function_name("changeset", suffix) do + String.to_atom("#{suffix}_changeset") + end + defp function_name(function, suffix) do case function =~ ~r/!/ do true -> String.replace_suffix(function, "!", "") <> "_" <> suffix <> "!" false -> function <> "_" <> suffix end - |> String.to_atom + |> String.to_atom() end defp function_description(function, arity, "") do - function <> "/" <> Integer.to_string(arity) + function <> "/" <> Integer.to_string(arity) end defp function_description("all", arity, suffix) do @@ -79,30 +99,36 @@ defmodule EctoResource.OptionParser do defp function_description("get_by", arity, suffix) do arity = Integer.to_string(arity) - "get_" <> suffix <> "_by" <> "/" <> arity + "get_" <> suffix <> "_by" <> "/" <> arity end defp function_description("get_by!", arity, suffix) do - arity = Integer.to_string(arity) + arity = Integer.to_string(arity) "get_" <> suffix <> "_by!" <> "/" <> arity end + defp function_description("changeset", arity, suffix) do + arity = Integer.to_string(arity) + suffix <> "_changeset" <> "/" <> arity + end + defp function_description(function, arity, suffix) do arity = Integer.to_string(arity) + case function =~ ~r/!/ do true -> String.replace_suffix(function, "!", "") <> "_" <> suffix <> "!" <> "/" <> arity false -> function <> "_" <> suffix <> "/" <> arity end end - defp filter_functions(functions, [except: filters]) do + defp filter_functions(functions, except: filters) do Enum.reject(functions, fn {function, _} -> function = String.to_atom(function) Enum.member?(filters, function) end) end - defp filter_functions(functions, [only: filters]) do + defp filter_functions(functions, only: filters) do Enum.filter(functions, fn {function, _} -> function = String.to_atom(function) Enum.member?(filters, function) diff --git a/lib/resource_functions.ex b/lib/resource_functions.ex index ef43ba9..1cc4c3f 100644 --- a/lib/resource_functions.ex +++ b/lib/resource_functions.ex @@ -13,7 +13,7 @@ defmodule EctoResource.ResourceFunctions do schema.changeset(struct(schema), %{}) end - @spec create!(Ecto.Repo.t(), module, map()) :: + @spec create(Ecto.Repo.t(), module, map()) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()} def create(repo, schema, attributes) do schema diff --git a/priv/test_repo/migrations/20200410023114_create_people.exs b/priv/test_repo/migrations/20200410023114_create_people.exs index ac9af5f..a5fe904 100644 --- a/priv/test_repo/migrations/20200410023114_create_people.exs +++ b/priv/test_repo/migrations/20200410023114_create_people.exs @@ -3,9 +3,9 @@ defmodule EctoResource.TestRepo.Migrations.CreatePeople do def change do create table(:people) do - add(:first_name, :string) - add(:last_name, :string) - add(:age, :integer) + add(:first_name, :string, null: false) + add(:last_name, :string, null: false) + add(:age, :integer, null: false) end end end diff --git a/test/ecto_resource/defaults_test.exs b/test/ecto_resource/defaults_test.exs index 239cba0..9794282 100644 --- a/test/ecto_resource/defaults_test.exs +++ b/test/ecto_resource/defaults_test.exs @@ -1,4 +1,4 @@ -defmodule EctoResource.TestContext.People do +defmodule EctoResource.DefaultsTestContext.People do @moduledoc false alias EctoResource.TestRepo @@ -12,20 +12,30 @@ defmodule EctoResource.TestContext.People do end defmodule EctoResource.DefaultsTest do - use ExUnit.Case + use EctoResource.RepoCase - alias EctoResource.TestRepo, as: Repo alias EctoResource.TestSchema.Person - alias EctoResource.TestContext.People + alias EctoResource.DefaultsTestContext.People - setup do - :ok = Ecto.Adapters.SQL.Sandbox.checkout(Repo) - end + @person_attributes %{ + first_name: "Test", + last_name: "Person", + age: 42 + } - describe "changeset" do - test "it returns an empty changeset" do - expected_changeset = Person.changeset(%Person{}, %{}) - assert People.changeset() == expected_changeset + @updated_person_attributes %{ + first_name: "Updated Test", + last_name: "Updated Person", + age: 33 + } + + describe "all" do + test "it returns all the records" do + person = struct(Person, @person_attributes) + + Repo.insert(person) + + assert [person] = People.all_people() end end @@ -37,27 +47,211 @@ defmodule EctoResource.DefaultsTest do age: 0 } - expected_changes = %{ - first_name: "Test", - last_name: "Person", - age: 42 - } + %{changes: changes} = People.change_person(person, @person_attributes) + + assert changes == @person_attributes + end + end + + describe "changeset" do + test "it returns an empty changeset" do + expected_changeset = Person.changeset(%Person{}, %{}) + assert People.person_changeset() == expected_changeset + end + end + + describe "create" do + test "with valid attributbes, it creates a new record" do + {:ok, person} = People.create_person(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it returns an error tuple with a changeset" do + assert {:error, %Ecto.Changeset{}} = People.create_person(%{}) + end + end + + describe "create!" do + test "whith valid attributes, it creates a new record" do + person = People.create_person!(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it raises an error" do + assert_raise Ecto.InvalidChangesetError, fn -> + People.create_person!(%{}) + end + end + end + + describe "delete" do + test "with an existing record, it deletes a given record" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert Repo.all(Person) == [person] + + People.delete_person(person) + + assert Repo.all(Person) == [] + end + + test "with a non-existent record, it raises an error" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + Repo.delete(person) + + assert_raise Ecto.StaleEntryError, fn -> + People.delete_person(person) + end + end + end + + describe "delete!" do + test "with an existing record it deletes the given record" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert Repo.all(Person) == [person] - %{changes: changes} = People.change_person(person, expected_changes) + People.delete_person!(person) - assert changes == expected_changes + assert Repo.all(Person) == [] + end + + test "with a non-existent record, it raises an error" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + Repo.delete(person) + + assert_raise Ecto.StaleEntryError, fn -> + People.delete_person!(person) + end end end - # describe "all" do - # test "it returns all the records" do - # TestRepo.insert(%Person{ - # first_name: "Test", - # last_name: "Person", - # age: 42 - # }) + describe "get" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person(person.id) + end + + test "with a non-existent record, it returns nil" do + assert nil == People.get_person(999) + end + end + + describe "get!" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person!(person.id) + end + + test "with a non-existent record, it raises an error" do + assert_raise Ecto.NoResultsError, fn -> + People.get_person!(999) + end + end + end + + describe "get_by" do + test "with an existing record, it returns a single schema matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by(age: @person_attributes.age) == person + end + + test "with a non-existent record, it returns nil" do + assert People.get_person_by(age: @person_attributes.age) == nil + end + end - # assert [%Person{}] = People.all() - # end - # end + describe "get_by!" do + test "with an existing record, it returns a single schema, matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by!(age: @person_attributes.age) == person + end + end + + describe "update" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + {:ok, updated_person} = People.update_person(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert {:error, changeset} = + People.update_person(person, %{first_name: nil, last_name: nil, age: nil}) + + refute changeset.valid? + end + end + + describe "update!" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + updated_person = People.update_person!(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise Ecto.InvalidChangesetError, fn -> + People.update_person!(person, %{first_name: nil, last_name: nil, age: nil}) + end + end + end end diff --git a/test/ecto_resource/except_filter_test.exs b/test/ecto_resource/except_filter_test.exs new file mode 100644 index 0000000..a6346ad --- /dev/null +++ b/test/ecto_resource/except_filter_test.exs @@ -0,0 +1,258 @@ +defmodule EctoResource.ExceptFilterTestContext.People do + @moduledoc false + + alias EctoResource.TestRepo + alias EctoResource.TestSchema.Person + + use EctoResource + + using_repo TestRepo do + resource(Person, except: [:change, :changeset]) + end +end + +defmodule EctoResource.ExceptFilterTest do + use EctoResource.RepoCase + + alias EctoResource.TestSchema.Person + alias EctoResource.ExceptFilterTestContext.People + + @person_attributes %{ + first_name: "Test", + last_name: "Person", + age: 42 + } + + @updated_person_attributes %{ + first_name: "Updated Test", + last_name: "Updated Person", + age: 33 + } + + describe "all" do + test "it returns all the records" do + person = struct(Person, @person_attributes) + + Repo.insert(person) + + assert [person] = People.all_people() + end + end + + describe "change" do + test "doesn't create a change function" do + person = %Person{ + first_name: "Initial", + last_name: "Value", + age: 0 + } + + assert_raise UndefinedFunctionError, fn -> + People.change_person(person, @person_attributes) + end + end + end + + describe "changeset" do + test "it doesn't create a changeset function" do + assert_raise UndefinedFunctionError, fn -> + People.person_changeset() + end + end + end + + describe "create" do + test "with valid attributbes, it creates a new record" do + {:ok, person} = People.create_person(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it returns an error tuple with a changeset" do + assert {:error, %Ecto.Changeset{}} = People.create_person(%{}) + end + end + + describe "create!" do + test "whith valid attributes, it creates a new record" do + person = People.create_person!(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it raises an error" do + assert_raise Ecto.InvalidChangesetError, fn -> + People.create_person!(%{}) + end + end + end + + describe "delete" do + test "with an existing record, it deletes a given record" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert Repo.all(Person) == [person] + + People.delete_person(person) + + assert Repo.all(Person) == [] + end + + test "with a non-existent record, it raises an error" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + Repo.delete(person) + + assert_raise Ecto.StaleEntryError, fn -> + People.delete_person(person) + end + end + end + + describe "delete!" do + test "with an existing record it deletes the given record" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert Repo.all(Person) == [person] + + People.delete_person!(person) + + assert Repo.all(Person) == [] + end + + test "with a non-existent record, it raises an error" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + Repo.delete(person) + + assert_raise Ecto.StaleEntryError, fn -> + People.delete_person!(person) + end + end + end + + describe "get" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person(person.id) + end + + test "with a non-existent record, it returns nil" do + assert nil == People.get_person(999) + end + end + + describe "get!" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person!(person.id) + end + + test "with a non-existent record, it raises an error" do + assert_raise Ecto.NoResultsError, fn -> + People.get_person!(999) + end + end + end + + describe "get_by" do + test "with an existing record, it returns a single schema matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by(age: @person_attributes.age) == person + end + + test "with a non-existent record, it returns nil" do + assert People.get_person_by(age: @person_attributes.age) == nil + end + end + + describe "get_by!" do + test "with an existing record, it returns a single schema, matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by!(age: @person_attributes.age) == person + end + end + + describe "update" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + {:ok, updated_person} = People.update_person(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert {:error, changeset} = + People.update_person(person, %{first_name: nil, last_name: nil, age: nil}) + + refute changeset.valid? + end + end + + describe "update!" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + updated_person = People.update_person!(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise Ecto.InvalidChangesetError, fn -> + People.update_person!(person, %{first_name: nil, last_name: nil, age: nil}) + end + end + end +end diff --git a/test/ecto_resource/only_filter_test.exs b/test/ecto_resource/only_filter_test.exs new file mode 100644 index 0000000..e0273dd --- /dev/null +++ b/test/ecto_resource/only_filter_test.exs @@ -0,0 +1,173 @@ +defmodule EctoResource.OnlyFilterTestContext.People do + @moduledoc false + + alias EctoResource.TestRepo + alias EctoResource.TestSchema.Person + + use EctoResource + + using_repo TestRepo do + resource(Person, only: [:all, :change]) + end +end + +defmodule EctoResource.OnlyFilterTest do + use EctoResource.RepoCase + + alias EctoResource.TestSchema.Person + alias EctoResource.OnlyFilterTestContext.People + + @person_attributes %{ + first_name: "Test", + last_name: "Person", + age: 42 + } + + @updated_person_attributes %{ + first_name: "Updated Test", + last_name: "Updated Person", + age: 33 + } + + describe "all" do + test "it returns all the records" do + person = struct(Person, @person_attributes) + + Repo.insert(person) + + assert [person] = People.all_people() + end + end + + describe "change" do + test "it returns a changeset with changes" do + person = %Person{ + first_name: "Initial", + last_name: "Value", + age: 0 + } + + %{changes: changes} = People.change_person(person, @person_attributes) + + assert changes == @person_attributes + end + end + + describe "changeset" do + test "it doesn't create a changeset function" do + assert_raise UndefinedFunctionError, fn -> + People.person_changeset() + end + end + end + + describe "create" do + test "it doesn't create a create function" do + assert_raise UndefinedFunctionError, fn -> + People.create_person(@person_attributes) + end + end + end + + describe "create!" do + test "it doesn't create a create! function" do + assert_raise UndefinedFunctionError, fn -> + People.create_person!(@person_attributes) + end + end + end + + describe "delete" do + test "doesn't create a delete function" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.delete_person(person) + end + end + end + + describe "delete!" do + test "doesn't create a delete! function" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.delete_person!(person) + end + end + end + + describe "get" do + test "it doesn't create a get function" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.get_person(person.id) + end + end + end + + describe "get!" do + test "it doesn't create a get! function" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.get_person!(person.id) + end + end + end + + describe "get_by" do + test "doesn't create a get_by function" do + assert_raise UndefinedFunctionError, fn -> + People.get_person_by(age: @person_attributes.age) + end + end + end + + describe "get_by!" do + test "doesn't create a get_by! function" do + assert_raise UndefinedFunctionError, fn -> + People.get_person_by!(age: @person_attributes.age) + end + end + end + + describe "update" do + test "doesn't create an update function" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.update_person(person, @updated_person_attributes) + end + end + end + + describe "update!" do + test "doesn't create an update! function" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.update_person!(person, @updated_person_attributes) + end + end + end +end diff --git a/test/option_parser_test.exs b/test/ecto_resource/option_parser_test.exs similarity index 93% rename from test/option_parser_test.exs rename to test/ecto_resource/option_parser_test.exs index b0fac79..d89655e 100644 --- a/test/option_parser_test.exs +++ b/test/ecto_resource/option_parser_test.exs @@ -14,6 +14,10 @@ defmodule EctoResource.OptionParserTest do name: :change_suffix, description: "change_suffix/1" }, + changeset: %{ + name: :suffix_changeset, + description: "suffix_changeset/0" + }, create: %{ name: :create_suffix, description: "create_suffix/1" @@ -84,6 +88,10 @@ defmodule EctoResource.OptionParserTest do name: :change_suffix, description: "change_suffix/1" }, + changeset: %{ + name: :suffix_changeset, + description: "suffix_changeset/0" + }, delete: %{ name: :delete_suffix, description: "delete_suffix/1" @@ -166,6 +174,10 @@ defmodule EctoResource.OptionParserTest do name: :change_suffix, description: "change_suffix/1" }, + changeset: %{ + name: :suffix_changeset, + description: "suffix_changeset/0" + }, create: %{ name: :create_suffix, description: "create_suffix/1" @@ -195,6 +207,10 @@ defmodule EctoResource.OptionParserTest do name: :change_suffix, description: "change_suffix/1" }, + changeset: %{ + name: :suffix_changeset, + description: "suffix_changeset/0" + }, create: %{ name: :create_suffix, description: "create_suffix/1" diff --git a/test/ecto_resource/read_test.exs b/test/ecto_resource/read_test.exs new file mode 100644 index 0000000..88b94cf --- /dev/null +++ b/test/ecto_resource/read_test.exs @@ -0,0 +1,189 @@ +defmodule EctoResource.ReadTestContext.People do + @moduledoc false + + alias EctoResource.TestRepo + alias EctoResource.TestSchema.Person + + use EctoResource + + using_repo TestRepo do + resource(Person, :read) + end +end + +defmodule EctoResource.ReadTest do + use EctoResource.RepoCase + + alias EctoResource.TestSchema.Person + alias EctoResource.ReadTestContext.People + + @person_attributes %{ + first_name: "Test", + last_name: "Person", + age: 42 + } + + @updated_person_attributes %{ + first_name: "Updated Test", + last_name: "Updated Person", + age: 33 + } + + describe "all" do + test "it returns all the records" do + person = struct(Person, @person_attributes) + + Repo.insert(person) + + assert [person] = People.all_people() + end + end + + describe "change" do + test "it doesn't create a change function" do + person = %Person{ + first_name: "Initial", + last_name: "Value", + age: 0 + } + + assert_raise UndefinedFunctionError, fn -> + People.change_person(person, @person_attributes) + end + end + end + + describe "changeset" do + test "it doesn't create a changeset function" do + assert_raise UndefinedFunctionError, fn -> + People.person_changeset() + end + end + end + + describe "create" do + test "it doesn't create a create function" do + assert_raise UndefinedFunctionError, fn -> + People.create_person(@person_attributes) + end + end + end + + describe "create!" do + test "it doesn't create a create! function" do + assert_raise UndefinedFunctionError, fn -> + People.create_person!(@person_attributes) + end + end + end + + describe "delete" do + test "it doesn't create a delete function" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.delete_person(person) + end + end + end + + describe "delete!" do + test "it doesn't create a delete! function" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.delete_person!(person) + end + end + end + + describe "get" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person(person.id) + end + + test "with a non-existent record, it returns nil" do + assert nil == People.get_person(999) + end + end + + describe "get!" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person!(person.id) + end + + test "with a non-existent record, it raises an error" do + assert_raise Ecto.NoResultsError, fn -> + People.get_person!(999) + end + end + end + + describe "get_by" do + test "with an existing record, it returns a single schema matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by(age: @person_attributes.age) == person + end + + test "with a non-existent record, it returns nil" do + assert People.get_person_by(age: @person_attributes.age) == nil + end + end + + describe "get_by!" do + test "with an existing record, it returns a single schema, matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by!(age: @person_attributes.age) == person + end + end + + describe "update" do + test "it doesn't create an update function" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.update_person(person, @updated_person_attributes) + end + end + end + + describe "update!" do + test "it doesn't create an update function" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.update_person!(person, @updated_person_attributes) + end + end + end +end diff --git a/test/ecto_resource/read_write_test.exs b/test/ecto_resource/read_write_test.exs new file mode 100644 index 0000000..3a14aa9 --- /dev/null +++ b/test/ecto_resource/read_write_test.exs @@ -0,0 +1,227 @@ +defmodule EctoResource.ReadWriteContext.People do + @moduledoc false + + alias EctoResource.TestRepo + alias EctoResource.TestSchema.Person + + use EctoResource + + using_repo TestRepo do + resource(Person, :read_write) + end +end + +defmodule EctoResource.ReadWrite do + use EctoResource.RepoCase + + alias EctoResource.TestSchema.Person + alias EctoResource.ReadWriteContext.People + + @person_attributes %{ + first_name: "Test", + last_name: "Person", + age: 42 + } + + @updated_person_attributes %{ + first_name: "Updated Test", + last_name: "Updated Person", + age: 33 + } + + describe "all" do + test "it returns all the records" do + person = struct(Person, @person_attributes) + + Repo.insert(person) + + assert [person] = People.all_people() + end + end + + describe "change" do + test "it returns a changeset with changes" do + person = %Person{ + first_name: "Initial", + last_name: "Value", + age: 0 + } + + %{changes: changes} = People.change_person(person, @person_attributes) + + assert changes == @person_attributes + end + end + + describe "changeset" do + test "it returns an empty changeset" do + expected_changeset = Person.changeset(%Person{}, %{}) + assert People.person_changeset() == expected_changeset + end + end + + describe "create" do + test "with valid attributbes, it creates a new record" do + {:ok, person} = People.create_person(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it returns an error tuple with a changeset" do + assert {:error, %Ecto.Changeset{}} = People.create_person(%{}) + end + end + + describe "create!" do + test "whith valid attributes, it creates a new record" do + person = People.create_person!(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it raises an error" do + assert_raise Ecto.InvalidChangesetError, fn -> + People.create_person!(%{}) + end + end + end + + describe "delete" do + test "it doesn't create a delete method" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.delete_person(person) + end + end + end + + describe "delete!" do + test "doesn't create a delete! method" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert_raise UndefinedFunctionError, fn -> + People.delete_person!(person) + end + end + end + + describe "get" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person(person.id) + end + + test "with a non-existent record, it returns nil" do + assert nil == People.get_person(999) + end + end + + describe "get!" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get_person!(person.id) + end + + test "with a non-existent record, it raises an error" do + assert_raise Ecto.NoResultsError, fn -> + People.get_person!(999) + end + end + end + + describe "get_by" do + test "with an existing record, it returns a single schema matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by(age: @person_attributes.age) == person + end + + test "with a non-existent record, it returns nil" do + assert People.get_person_by(age: @person_attributes.age) == nil + end + end + + describe "get_by!" do + test "with an existing record, it returns a single schema, matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_person_by!(age: @person_attributes.age) == person + end + end + + describe "update" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + {:ok, updated_person} = People.update_person(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert {:error, changeset} = + People.update_person(person, %{first_name: nil, last_name: nil, age: nil}) + + refute changeset.valid? + end + end + + describe "update!" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + updated_person = People.update_person!(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise Ecto.InvalidChangesetError, fn -> + People.update_person!(person, %{first_name: nil, last_name: nil, age: nil}) + end + end + end +end diff --git a/test/ecto_resource/without_suffix_test.exs b/test/ecto_resource/without_suffix_test.exs new file mode 100644 index 0000000..4f548a9 --- /dev/null +++ b/test/ecto_resource/without_suffix_test.exs @@ -0,0 +1,257 @@ +defmodule EctoResource.WithoutSuffixTestContext.People do + @moduledoc false + + alias EctoResource.TestRepo + alias EctoResource.TestSchema.Person + + use EctoResource + + using_repo TestRepo do + resource(Person, suffix: false) + end +end + +defmodule EctoResource.WithoutSuffixTest do + use EctoResource.RepoCase + + alias EctoResource.TestSchema.Person + alias EctoResource.WithoutSuffixTestContext.People + + @person_attributes %{ + first_name: "Test", + last_name: "Person", + age: 42 + } + + @updated_person_attributes %{ + first_name: "Updated Test", + last_name: "Updated Person", + age: 33 + } + + describe "all" do + test "it returns all the records" do + person = struct(Person, @person_attributes) + + Repo.insert(person) + + assert [person] = People.all() + end + end + + describe "change" do + test "it returns a changeset with changes" do + person = %Person{ + first_name: "Initial", + last_name: "Value", + age: 0 + } + + %{changes: changes} = People.change(person, @person_attributes) + + assert changes == @person_attributes + end + end + + describe "changeset" do + test "it returns an empty changeset" do + expected_changeset = Person.changeset(%Person{}, %{}) + assert People.changeset() == expected_changeset + end + end + + describe "create" do + test "with valid attributbes, it creates a new record" do + {:ok, person} = People.create(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it returns an error tuple with a changeset" do + assert {:error, %Ecto.Changeset{}} = People.create(%{}) + end + end + + describe "create!" do + test "whith valid attributes, it creates a new record" do + person = People.create!(@person_attributes) + + assert Repo.all(Person) == [person] + end + + test "with invalid attributes, it raises an error" do + assert_raise Ecto.InvalidChangesetError, fn -> + People.create!(%{}) + end + end + end + + describe "delete" do + test "with an existing record, it deletes a given record" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert Repo.all(Person) == [person] + + People.delete(person) + + assert Repo.all(Person) == [] + end + + test "with a non-existent record, it raises an error" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + Repo.delete(person) + + assert_raise Ecto.StaleEntryError, fn -> + People.delete(person) + end + end + end + + describe "delete!" do + test "with an existing record it deletes the given record" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + assert Repo.all(Person) == [person] + + People.delete!(person) + + assert Repo.all(Person) == [] + end + + test "with a non-existent record, it raises an error" do + {:ok, person} = + %Person{} + |> Person.changeset(@person_attributes) + |> Repo.insert() + + Repo.delete(person) + + assert_raise Ecto.StaleEntryError, fn -> + People.delete!(person) + end + end + end + + describe "get" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get(person.id) + end + + test "with a non-existent record, it returns nil" do + assert nil == People.get(999) + end + end + + describe "get!" do + test "with an existing record, it returns the schema" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert person == People.get!(person.id) + end + + test "with a non-existent record, it raises an error" do + assert_raise Ecto.NoResultsError, fn -> + People.get!(999) + end + end + end + + describe "get_by" do + test "with an existing record, it returns a single schema matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_by(age: @person_attributes.age) == person + end + + test "with a non-existent record, it returns nil" do + assert People.get_by(age: @person_attributes.age) == nil + end + end + + describe "get_by!" do + test "with an existing record, it returns a single schema, matching the criteria" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert People.get_by!(age: @person_attributes.age) == person + end + end + + describe "update" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + {:ok, updated_person} = People.update(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert {:error, changeset} = + People.update(person, %{first_name: nil, last_name: nil, age: nil}) + + refute changeset.valid? + end + end + + describe "update!" do + test "with valid attributes, it updates the values" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + updated_person = People.update!(person, @updated_person_attributes) + + assert person.id == updated_person.id + assert person.first_name != updated_person.first_name + assert person.last_name != updated_person.last_name + assert person.age != updated_person.age + end + + test "with invalid attributes, it returns an error changeset tuple" do + {:ok, person} = + Person + |> struct(@person_attributes) + |> Repo.insert() + + assert_raise Ecto.InvalidChangesetError, fn -> + People.update!(person, %{first_name: nil, last_name: nil, age: nil}) + end + end + end +end diff --git a/test/ecto_resource_except_test.exs b/test/ecto_resource_except_test.exs deleted file mode 100644 index f09690e..0000000 --- a/test/ecto_resource_except_test.exs +++ /dev/null @@ -1,59 +0,0 @@ -defmodule EctoResourceExceptTest do - use ExUnit.Case - import Mox - alias MockRepo, as: Repo - - defmodule MySchema do - use Ecto.Schema - import Ecto.Changeset - - schema "my_schemas" do - field(:something_interesting, :string) - end - - def changeset(my_schema, attrs) do - my_schema - |> cast(attrs, [:something_interesting]) - end - end - - describe "crud resource" do - defmodule FakeContext do - use EctoResource - - using_repo(Repo) do - resource(MySchema, - except: [ - :all, - :create, - :create!, - :delete, - :delete!, - :get, - :get_by, - :get_by!, - :update, - :update! - ] - ) - end - end - - test "generates __resource__(:resources)/0 for introspection" do - assert FakeContext.__resource__(:resources) == [ - {Repo, MySchema, ["change_my_schema/1", "get_my_schema!/2"]} - ] - end - - test "generates a get!/2 function for the defined resources" do - Repo - |> expect(:get!, fn _query, 123, [] -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema!(123) - end - - test "generates a change/1 function for the defined resources" do - assert %Ecto.Changeset{data: %MySchema{}} = FakeContext.change_my_schema(%MySchema{id: 123}) - end - end -end diff --git a/test/ecto_resource_only_test.exs b/test/ecto_resource_only_test.exs deleted file mode 100644 index 0569cbf..0000000 --- a/test/ecto_resource_only_test.exs +++ /dev/null @@ -1,41 +0,0 @@ -defmodule EctoResourceOnlyTest do - use ExUnit.Case - import Mox - alias MockRepo, as: Repo - - defmodule MySchema do - use Ecto.Schema - import Ecto.Changeset - - schema "my_schemas" do - field(:something_interesting, :string) - end - - def changeset(my_schema, attrs) do - my_schema - |> cast(attrs, [:something_interesting]) - end - end - - describe "crud resource" do - defmodule FakeContext do - use EctoResource - - using_repo(Repo) do - resource(MySchema, only: [:create]) - end - end - - test "generates __resource__(:resources)/0 for introspection" do - assert FakeContext.__resource__(:resources) == [{Repo, MySchema, ["create_my_schema/1"]}] - end - - test "generates a create/1 function for the defined resources" do - Repo - |> expect(:insert, fn _query, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = - FakeContext.create_my_schema(%{something_interesting: "You can totally do this"}) - end - end -end diff --git a/test/ecto_resource_pluralize_test.exs b/test/ecto_resource_pluralize_test.exs deleted file mode 100644 index 0cd41c5..0000000 --- a/test/ecto_resource_pluralize_test.exs +++ /dev/null @@ -1,48 +0,0 @@ -defmodule EctoResourcePluralizeTest do - use ExUnit.Case - alias MockRepo, as: Repo - - defmodule Person do - use Ecto.Schema - import Ecto.Changeset - - schema "people" do - field(:something_interesting, :string) - end - - def changeset(my_person, attrs) do - my_person - |> cast(attrs, [:something_interesting]) - end - end - - describe "crud resource" do - defmodule FakeContext do - use EctoResource - - using_repo(Repo) do - resource(Person) - end - end - - test "generates __resource__(:resources)/0 for introspection" do - assert FakeContext.__resource__(:resources) == [ - {Repo, Person, - [ - "all_people/1", - "change_person/1", - "create_person/1", - "create_person!/1", - "delete_person/1", - "delete_person!/1", - "get_person/2", - "get_person!/2", - "get_person_by/2", - "get_person_by!/2", - "update_person/2", - "update_person!/2" - ]} - ] - end - end -end diff --git a/test/ecto_resource_read_test.exs b/test/ecto_resource_read_test.exs deleted file mode 100644 index 440b047..0000000 --- a/test/ecto_resource_read_test.exs +++ /dev/null @@ -1,77 +0,0 @@ -defmodule EctoResourceReadTest do - use ExUnit.Case - alias MockRepo, as: Repo - import Mox - - defmodule MySchema do - use Ecto.Schema - import Ecto.Changeset - - schema "my_schemas" do - field(:something_interesting, :string) - end - - def changeset(my_schema, attrs) do - my_schema - |> cast(attrs, [:something_interesting]) - end - end - - describe "readable resource" do - defmodule FakeContext do - use EctoResource - - using_repo(Repo) do - resource(MySchema, :read) - end - end - - test "generates __resource__(:resources)/0 for introspection" do - assert FakeContext.__resource__(:resources) == [ - {Repo, MySchema, - [ - "all_my_schemas/1", - "get_my_schema/2", - "get_my_schema!/2", - "get_my_schema_by/2", - "get_my_schema_by!/2" - ]} - ] - end - - test "generates a get/2 function for the defined resources" do - Repo - |> expect(:get, fn _query, 123, [] -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema(123) - end - - test "generates a get!/2 function for the defined resources" do - Repo - |> expect(:get!, fn _query, 123, [] -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema!(123) - end - - test "generates an all/1 function for the defined resources" do - Repo - |> expect(:all, fn _query, [] -> [%MySchema{id: 123}] end) - - assert [%MySchema{id: 123}] = FakeContext.all_my_schemas() - end - - test "generates a get_by/2 function for the defined resources" do - Repo - |> expect(:get_by, fn _schema, _attributes, _opts -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema_by(id: 123) - end - - test "generates a get_by!/2 function for the defined resources" do - Repo - |> expect(:get_by!, fn _schema, _attributes, _opts -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema_by!(id: 123) - end - end -end diff --git a/test/ecto_resource_read_write_test.exs b/test/ecto_resource_read_write_test.exs deleted file mode 100644 index 6765590..0000000 --- a/test/ecto_resource_read_write_test.exs +++ /dev/null @@ -1,122 +0,0 @@ -defmodule EctoResourceReadWriteTest do - use ExUnit.Case - alias MockRepo, as: Repo - import Mox - - defmodule MySchema do - use Ecto.Schema - import Ecto.Changeset - - schema "my_schemas" do - field(:something_interesting, :string) - end - - def changeset(my_schema, attrs) do - my_schema - |> cast(attrs, [:something_interesting]) - end - end - - describe "writeable resource" do - defmodule FakeContext do - use EctoResource - - using_repo(Repo) do - resource(MySchema, :read_write) - end - end - - test "generates __resource__(:resources)/0 for introspection" do - assert FakeContext.__resource__(:resources) == [ - {Repo, MySchema, - [ - "all_my_schemas/1", - "change_my_schema/1", - "create_my_schema/1", - "create_my_schema!/1", - "get_my_schema/2", - "get_my_schema!/2", - "get_my_schema_by/2", - "get_my_schema_by!/2", - "update_my_schema/2", - "update_my_schema!/2" - ]} - ] - end - - test "generates a get/2 function for the defined resources" do - Repo - |> expect(:get, fn _query, 123, [] -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema(123) - end - - test "generates a get!/2 function for the defined resources" do - Repo - |> expect(:get!, fn _query, 123, [] -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema!(123) - end - - test "generates an all/1 function for the defined resources" do - Repo - |> expect(:all, fn _query, [] -> [%MySchema{id: 123}] end) - - assert [%MySchema{id: 123}] = FakeContext.all_my_schemas() - end - - test "generates a get_by/2 function for the defined resources" do - Repo - |> expect(:get_by, fn _schema, _attributes, _opts -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema_by(id: 123) - end - - test "generates a get_by!/2 function for the defined resources" do - Repo - |> expect(:get_by!, fn _schema, _attributes, _opts -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema_by!(id: 123) - end - - test "generates a change/1 function for the defined resources" do - assert %Ecto.Changeset{data: %MySchema{}} = FakeContext.change_my_schema(%MySchema{id: 123}) - end - - test "generates a create/1 function for the defined resources" do - Repo - |> expect(:insert, fn _query, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = - FakeContext.create_my_schema(%{something_interesting: "You can totally do this"}) - end - - test "generates a create!/1 function for the defined resources" do - Repo - |> expect(:insert!, fn _query, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = - FakeContext.create_my_schema!(%{something_interesting: "You can totally do this"}) - end - - test "generates a update/2 function for the defined resources" do - Repo - |> expect(:update, fn _query, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = - FakeContext.update_my_schema(%MySchema{}, %{ - someting_interesting: "Take the risk or lose the chance" - }) - end - - test "generates a update!/2 function for the defined resources" do - Repo - |> expect(:update!, fn _query, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = - FakeContext.update_my_schema!(%MySchema{}, %{ - someting_interesting: "Take the risk or lose the chance" - }) - end - end -end diff --git a/test/ecto_resource_test.exs b/test/ecto_resource_test.exs deleted file mode 100644 index ca5a019..0000000 --- a/test/ecto_resource_test.exs +++ /dev/null @@ -1,106 +0,0 @@ -defmodule EctoResourceTest do - use ExUnit.Case - alias MockRepo, as: Repo - import Mox - - defmodule MySchema do - use Ecto.Schema - import Ecto.Changeset - - schema "my_schemas" do - field(:something_interesting, :string) - end - - def changeset(my_schema, attrs) do - my_schema - |> cast(attrs, [:something_interesting]) - end - end - - describe "crud resource" do - defmodule FakeContext do - use EctoResource - - using_repo(Repo) do - resource(MySchema) - end - end - - test "generates __resource__(:resources)/0 for introspection" do - assert FakeContext.__resource__(:resources) == [ - {Repo, MySchema, - [ - "all_my_schemas/1", - "change_my_schema/1", - "create_my_schema/1", - "create_my_schema!/1", - "delete_my_schema/1", - "delete_my_schema!/1", - "get_my_schema/2", - "get_my_schema!/2", - "get_my_schema_by/2", - "get_my_schema_by!/2", - "update_my_schema/2", - "update_my_schema!/2" - ]} - ] - end - - test "generates a change/1 function for the defined resources" do - assert %Ecto.Changeset{data: %MySchema{}} = FakeContext.change_my_schema(%MySchema{id: 123}) - end - - test "generates a create/1 function for the defined resources" do - Repo - |> expect(:insert, fn _query, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = - FakeContext.create_my_schema(%{something_interesting: "You can totally do this"}) - end - - test "generates a delete/1 function for the defined resources" do - Repo - |> expect(:delete, fn _schema, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = FakeContext.delete_my_schema(%MySchema{id: 123}) - end - - test "generates a get/2 function for the defined resources" do - Repo - |> expect(:get, fn _query, 123, [] -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema(123) - end - - test "generates a get_by/2 function for the defined resources" do - Repo - |> expect(:get_by, fn _schema, _attributes, _opts -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema_by(id: 123) - end - - test "generates a get_by!/2 function for the defined resources" do - Repo - |> expect(:get_by!, fn _schema, _attributes, _opts -> %MySchema{id: 123} end) - - assert %MySchema{id: 123} = FakeContext.get_my_schema_by!(id: 123) - end - - test "generates an all/1 function for the defined resources" do - Repo - |> expect(:all, fn _query, [] -> [%MySchema{id: 123}] end) - - assert [%MySchema{id: 123}] = FakeContext.all_my_schemas() - end - - test "generates a update/2 function for the defined resources" do - Repo - |> expect(:update, fn _query, [] -> {:ok, %MySchema{id: 123}} end) - - assert {:ok, %MySchema{id: 123}} = - FakeContext.update_my_schema(%MySchema{}, %{ - someting_interesting: "Take the risk or lose the chance" - }) - end - end -end diff --git a/test/no_suffix_test.exs b/test/no_suffix_test.exs deleted file mode 100644 index 0e1e18c..0000000 --- a/test/no_suffix_test.exs +++ /dev/null @@ -1,48 +0,0 @@ -defmodule EctoResourceNoSuffixTest do - use ExUnit.Case - alias MockRepo, as: Repo - - defmodule MySchema do - use Ecto.Schema - import Ecto.Changeset - - schema "my_schemas" do - field(:something_interesting, :string) - end - - def changeset(my_schema, attrs) do - my_schema - |> cast(attrs, [:something_interesting]) - end - end - - describe "readable resource" do - defmodule FakeContext do - use EctoResource - - using_repo(Repo) do - resource(MySchema, suffix: false) - end - end - - test "generates __resource__(:resources)/0 for introspection" do - assert FakeContext.__resource__(:resources) == [ - {Repo, MySchema, - [ - "all/1", - "change/1", - "create/1", - "create!/1", - "delete/1", - "delete!/1", - "get/2", - "get!/2", - "get_by/2", - "get_by!/2", - "update/2", - "update!/2" - ]} - ] - end - end -end diff --git a/test/resources_test.exs b/test/resources_test.exs deleted file mode 100644 index b649ff0..0000000 --- a/test/resources_test.exs +++ /dev/null @@ -1,49 +0,0 @@ -defmodule Mix.Tasks.EctoResource.ResourcesTest do - use ExUnit.Case - import ExUnit.CaptureLog - alias Mix.Tasks.EctoResource.Resources - alias MockRepo - - defmodule FakeData do - use Ecto.Schema - import Ecto.Changeset - - schema "fake_datas" do - field(:something_interesting, :string) - end - - def changeset(fake_data, attrs) do - fake_data - |> cast(attrs, [:something_interesting]) - end - end - - describe "for a resource context" do - defmodule FakeContext do - use EctoResource - - using_repo(MockRepo) do - resource(FakeData) - end - end - - test "prints generated functions for resource" do - repo_name = "Elixir.MockRepo" - context_name = "Mix.Tasks.EctoResource.ResourcesTest.FakeContext" - schema_name = "Mix.Tasks.EctoResource.ResourcesTest.FakeData" - - log = capture_log([level: :info], fn -> Resources.run([context_name]) end) - - assert log =~ "Within the context #{context_name}" - assert log =~ "#{schema_name} using the repo #{repo_name}" - assert log =~ "- #{context_name}.create_fake_data/1" - end - end - - describe "without a context provided" do - test "prints a helpful message" do - assert capture_log([level: :error], fn -> Resources.run([]) end) =~ - "$ mix ecto_resource.resources MyApp.MyContext" - end - end -end diff --git a/lib/test_schema/person.ex b/test/support/test_schema/person.ex similarity index 68% rename from lib/test_schema/person.ex rename to test/support/test_schema/person.ex index 128d741..7a8bd8e 100644 --- a/lib/test_schema/person.ex +++ b/test/support/test_schema/person.ex @@ -10,6 +10,8 @@ defmodule EctoResource.TestSchema.Person do @doc false def changeset(person, attrs) do - cast(person, attrs, [:first_name, :last_name, :age]) + person + |> cast(attrs, [:first_name, :last_name, :age]) + |> validate_required([:first_name, :last_name, :age]) end end