zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

commit dae518d958bba4756d77a0c6cd82d53ce6a0e008
parent 79debdb875d3ab255895a236d4472bfd950ee68a
Author: srfsh <dev@srf.sh>
Date:   Tue, 16 Aug 2022 17:41:41 +0300

Zenflows{Test,}.VF.ResourceSpecification: refactor

To add support for optional repo to create/1 (now /2).

Diffstat:
Msrc/zenflows/vf/resource_specification/domain.ex | 57+++++++++++++++++++++++++++++----------------------------
Msrc/zenflows/vf/resource_specification/resolv.ex | 2+-
Mtest/vf/resource_specification/domain.test.exs | 52+++++++++++++++++++++++++++++++---------------------
3 files changed, 61 insertions(+), 50 deletions(-)

diff --git a/src/zenflows/vf/resource_specification/domain.ex b/src/zenflows/vf/resource_specification/domain.ex @@ -24,31 +24,41 @@ alias Zenflows.VF.ResourceSpecification @typep repo() :: Ecto.Repo.t() @typep chgset() :: Ecto.Changeset.t() -@typep changes() :: Ecto.Multi.changes() @typep id() :: Zenflows.DB.Schema.id() @typep params() :: Zenflows.DB.Schema.params() -@spec by_id(repo(), id()) :: ResourceSpecification.t() | nil -def by_id(repo \\ Repo, id) do - repo.get(ResourceSpecification, id) +@spec one(repo(), id()) :: {:ok, ResourceSpecification.t()} | {:error, String.t()} +def one(repo \\ Repo, id) do + one_by(repo, id: id) end -@spec create(params()) :: {:ok, ResourceSpecification.t()} | {:error, chgset()} -def create(params) do +@spec one_by(repo(), map() | Keyword.t()) + :: {:ok, ResourceSpecification.t()} | {:error, String.t()} +def one_by(repo \\ Repo, clauses) do + case repo.get_by(ResourceSpecification, clauses) do + nil -> {:error, "not found"} + found -> {:ok, found} + end +end + +@spec create(repo(), params()) :: {:ok, ResourceSpecification.t()} | {:error, chgset()} +def create(repo \\ Repo, params) do Multi.new() - |> Multi.insert(:res_spec, ResourceSpecification.chgset(params)) - |> Repo.transaction() + |> Multi.insert(:insert, ResourceSpecification.chgset(params)) + |> repo.transaction() |> case do - {:ok, %{res_spec: rs}} -> {:ok, rs} + {:ok, %{insert: rs}} -> {:ok, rs} {:error, _, cset, _} -> {:error, cset} end end -@spec update(id(), params()) :: {:ok, ResourceSpecification.t()} | {:error, chgset()} +@spec update(id(), params()) + :: {:ok, ResourceSpecification.t()} | {:error, String.t() | chgset()} def update(id, params) do Multi.new() - |> Multi.run(:get, multi_get(id)) - |> Multi.update(:update, &ResourceSpecification.chgset(&1.get, params)) + |> Multi.put(:id, id) + |> Multi.run(:one, &one_by/2) + |> Multi.update(:update, &ResourceSpecification.chgset(&1.one, params)) |> Repo.transaction() |> case do {:ok, %{update: rs}} -> {:ok, rs} @@ -56,11 +66,13 @@ def update(id, params) do end end -@spec delete(id()) :: {:ok, ResourceSpecification.t()} | {:error, chgset()} +@spec delete(id()) + :: {:ok, ResourceSpecification.t()} | {:error, String.t() | chgset()} def delete(id) do Multi.new() - |> Multi.run(:get, multi_get(id)) - |> Multi.delete(:delete, &(&1.get)) + |> Multi.put(:id, id) + |> Multi.run(:one, &one_by/2) + |> Multi.delete(:delete, &(&1.one)) |> Repo.transaction() |> case do {:ok, %{delete: rs}} -> {:ok, rs} @@ -68,7 +80,8 @@ def delete(id) do end end -@spec preload(ResourceSpecification.t(), :default_unit_of_resource | :default_unit_of_effort) +@spec preload(ResourceSpecification.t(), + :default_unit_of_resource | :default_unit_of_effort) :: ResourceSpecification.t() def preload(res_spec, :default_unit_of_resource) do Repo.preload(res_spec, :default_unit_of_resource) @@ -77,16 +90,4 @@ end def preload(res_spec, :default_unit_of_effort) do Repo.preload(res_spec, :default_unit_of_effort) end - -# Returns a ResourceSpecification in ok-err tuple from given ID. -# Used inside Ecto.Multi.run/5 to get a record in transaction. -@spec multi_get(id()) :: (repo(), changes() -> {:ok, ResourceSpecification.t()} | {:error, String.t()}) -defp multi_get(id) do - fn repo, _ -> - case by_id(repo, id) do - nil -> {:error, "not found"} - rs -> {:ok, rs} - end - end -end end diff --git a/src/zenflows/vf/resource_specification/resolv.ex b/src/zenflows/vf/resource_specification/resolv.ex @@ -24,7 +24,7 @@ alias Zenflows.VF.{ } def resource_specification(%{id: id}, _info) do - {:ok, Domain.by_id(id)} + Domain.one(id) end def create_resource_specification(%{resource_specification: params}, _info) do diff --git a/test/vf/resource_specification/domain.test.exs b/test/vf/resource_specification/domain.test.exs @@ -35,18 +35,24 @@ setup do default_unit_of_effort_id: Factory.insert!(:unit).id, default_unit_of_resource_id: Factory.insert!(:unit).id, }, - resource_specification: Factory.insert!(:resource_specification), + inserted: Factory.insert!(:resource_specification), + id: Factory.id() } end -test "by_id/1 returns a ResourceSpecification", %{resource_specification: res_spec} do - assert %ResourceSpecification{} = Domain.by_id(res_spec.id) +describe "one/1" do + test "with good id: finds the ResourceSpecification", %{inserted: %{id: id}} do + assert {:ok, %ResourceSpecification{}} = Domain.one(id) + end + + test "with bad id: doesn't find the ResourceSpecification", %{id: id} do + assert {:error, "not found"} = Domain.one(id) + end end describe "create/1" do - test "creates a ResourceSpecification with valid params", %{params: params} do + test "with good params: creates a ResourceSpecification", %{params: params} do assert {:ok, %ResourceSpecification{} = res_spec} = Domain.create(params) - assert res_spec.name == params.name assert res_spec.resource_classified_as == params.resource_classified_as assert res_spec.note == params.note @@ -55,15 +61,14 @@ describe "create/1" do assert res_spec.default_unit_of_effort_id == params.default_unit_of_effort_id end - test "doesn't create a ResourceSpecification with invalid params" do + test "with bad params: doesn't create a ResourceSpecification" do assert {:error, %Changeset{}} = Domain.create(%{}) end end describe "update/2" do - test "updates a ResourceSpecification with valid params", %{params: params, resource_specification: old} do + test "with good params: updates the ResourceSpecification", %{params: params, inserted: old} do assert {:ok, %ResourceSpecification{} = new} = Domain.update(old.id, params) - assert new.name == params.name assert new.resource_classified_as == params.resource_classified_as assert new.note == params.note @@ -72,9 +77,8 @@ describe "update/2" do assert new.default_unit_of_effort_id == params.default_unit_of_effort_id end - test "doesn't update a ResourceSpecification", %{resource_specification: old} do + test "with bad params: doesn't update the ResourceSpecification", %{inserted: old} do assert {:ok, %ResourceSpecification{} = new} = Domain.update(old.id, %{}) - assert new.name == old.name assert new.resource_classified_as == old.resource_classified_as assert new.note == old.note @@ -84,22 +88,28 @@ describe "update/2" do end end -test "delete/1 deletes a ResourceSpecification", %{resource_specification: %{id: id}} do - assert {:ok, %ResourceSpecification{id: ^id}} = Domain.delete(id) - assert Domain.by_id(id) == nil +describe "delete/1" do + test "with good id: deletes the ResourceSpecification", %{inserted: %{id: id}} do + assert {:ok, %ResourceSpecification{id: ^id}} = Domain.delete(id) + assert {:error, "not found"} = Domain.one(id) + end + + test "with bad id: doesn't delete the ResourceSpecification", %{id: id} do + assert {:error, "not found"} = Domain.delete(id) + end end describe "preload/2" do - test "preloads :default_unit_of_resource", %{resource_specification: res_spec} do + test "preloads `:default_unit_of_resource`", %{inserted: %{id: id}} do + assert {:ok, res_spec} = Domain.one(id) res_spec = Domain.preload(res_spec, :default_unit_of_resource) - assert unit_res = %Unit{} = res_spec.default_unit_of_resource - assert unit_res.id == res_spec.default_unit_of_resource_id - end + assert %Unit{} = res_spec.default_unit_of_resource + end - test "preloads :default_unit_of_effort", %{resource_specification: res_spec} do + test "preloads `:default_unit_of_effort`", %{inserted: %{id: id}} do + assert {:ok, res_spec} = Domain.one(id) res_spec = Domain.preload(res_spec, :default_unit_of_effort) - assert unit_eff = %Unit{} = res_spec.default_unit_of_effort - assert unit_eff.id == res_spec.default_unit_of_effort_id - end + assert %Unit{} = res_spec.default_unit_of_effort + end end end