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:
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