zf

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

commit 2ae2f0164ab1eaf6194f4c52d442df0c2c69230a
parent ed4eac2ed707067e2525dfb20467f84939505715
Author: srfsh <dev@srf.sh>
Date:   Tue, 23 Aug 2022 09:48:42 +0300

Zenflows{Test,}.VF.RecipeFlow: add paging support and small improvements

Diffstat:
Msrc/zenflows/vf/recipe_flow/domain.ex | 50++++++++++++++++++++++++++------------------------
Msrc/zenflows/vf/recipe_flow/resolv.ex | 33+++++++++++++++++----------------
Msrc/zenflows/vf/recipe_flow/type.ex | 75++++++++++++++++++++++++++++++++++++---------------------------------------
Mtest/vf/recipe_flow/domain.test.exs | 229++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mtest/vf/recipe_flow/type.test.exs | 275++++++++++++++++++++++++++-----------------------------------------------------
5 files changed, 285 insertions(+), 377 deletions(-)

diff --git a/src/zenflows/vf/recipe_flow/domain.ex b/src/zenflows/vf/recipe_flow/domain.ex @@ -20,6 +20,7 @@ defmodule Zenflows.VF.RecipeFlow.Domain do alias Ecto.Multi alias Zenflows.DB.Repo +alias Zenflows.GQL.Paging alias Zenflows.VF.{ Action, Measure, @@ -28,31 +29,43 @@ alias Zenflows.VF.{ @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()) :: RecipeFlow.t() | nil -def by_id(repo \\ Repo, id) do - repo.get(RecipeFlow, id) +@spec one(repo(), id() | map() | Keyword.t()) + :: {:ok, RecipeFlow.t()} | {:error, String.t()} +def one(repo \\ Repo, _) +def one(repo, id) when is_binary(id), do: one(repo, id: id) +def one(repo, clauses) do + case repo.get_by(RecipeFlow, clauses) do + nil -> {:error, "not found"} + found -> {:ok, found} + end +end + +@spec all(Paging.params()) :: Paging.result(RecipeFlow.t()) +def all(params) do + Paging.page(RecipeFlow, params) end @spec create(params()) :: {:ok, RecipeFlow.t()} | {:error, chgset()} def create(params) do Multi.new() - |> Multi.insert(:rec_flow, RecipeFlow.chgset(params)) + |> Multi.insert(:insert, RecipeFlow.chgset(params)) |> Repo.transaction() |> case do - {:ok, %{rec_flow: rf}} -> {:ok, rf} + {:ok, %{insert: rf}} -> {:ok, rf} {:error, _, cset, _} -> {:error, cset} end end -@spec update(id(), params()) :: {:ok, RecipeFlow.t()} | {:error, chgset()} +@spec update(id(), params()) + :: {:ok, RecipeFlow.t()} | {:error, String.t() | chgset()} def update(id, params) do Multi.new() - |> Multi.run(:get, multi_get(id)) - |> Multi.update(:update, &RecipeFlow.chgset(&1.get, params)) + |> Multi.put(:id, id) + |> Multi.run(:one, &one/2) + |> Multi.update(:update, &RecipeFlow.chgset(&1.one, params)) |> Repo.transaction() |> case do {:ok, %{update: rf}} -> {:ok, rf} @@ -60,11 +73,12 @@ def update(id, params) do end end -@spec delete(id()) :: {:ok, RecipeFlow.t()} | {:error, chgset()} +@spec delete(id()) :: {:ok, RecipeFlow.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/2) + |> Multi.delete(:delete, & &1.one) |> Repo.transaction() |> case do {:ok, %{delete: rf}} -> {:ok, rf} @@ -103,16 +117,4 @@ end def preload(rec_flow, :recipe_clause_of) do Repo.preload(rec_flow, :recipe_clause_of) end - -# Returns a RecipeFlow 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, RecipeFlow.t()} | {:error, String.t()}) -defp multi_get(id) do - fn repo, _ -> - case by_id(repo, id) do - nil -> {:error, "not found"} - rf -> {:ok, rf} - end - end -end end diff --git a/src/zenflows/vf/recipe_flow/resolv.ex b/src/zenflows/vf/recipe_flow/resolv.ex @@ -20,64 +20,65 @@ defmodule Zenflows.VF.RecipeFlow.Resolv do use Absinthe.Schema.Notation -alias Zenflows.VF.{ - RecipeFlow, - RecipeFlow.Domain, -} +alias Zenflows.VF.RecipeFlow.Domain -def recipe_flow(%{id: id}, _info) do - {:ok, Domain.by_id(id)} +def recipe_flow(params, _) do + Domain.one(params) end -def create_recipe_flow(%{recipe_flow: params}, _info) do +def recipe_flows(params, _) do + Domain.all(params) +end + +def create_recipe_flow(%{recipe_flow: params}, _) do with {:ok, rec_flow} <- Domain.create(params) do {:ok, %{recipe_flow: rec_flow}} end end -def update_recipe_flow(%{recipe_flow: %{id: id} = params}, _info) do +def update_recipe_flow(%{recipe_flow: %{id: id} = params}, _) do with {:ok, rec_flow} <- Domain.update(id, params) do {:ok, %{recipe_flow: rec_flow}} end end -def delete_recipe_flow(%{id: id}, _info) do +def delete_recipe_flow(%{id: id}, _) do with {:ok, _} <- Domain.delete(id) do {:ok, true} end end -def resource_quantity(%RecipeFlow{} = rec_flow, _args, _info) do +def resource_quantity(rec_flow, _, _) do rec_flow = Domain.preload(rec_flow, :resource_quantity) {:ok, rec_flow.resource_quantity} end -def effort_quantity(%RecipeFlow{} = rec_flow, _args, _info) do +def effort_quantity(rec_flow, _, _) do rec_flow = Domain.preload(rec_flow, :effort_quantity) {:ok, rec_flow.effort_quantity} end -def recipe_flow_resource(%RecipeFlow{} = rec_flow, _args, _info) do +def recipe_flow_resource(rec_flow, _, _) do rec_flow = Domain.preload(rec_flow, :recipe_flow_resource) {:ok, rec_flow.recipe_flow_resource} end -def action(%RecipeFlow{} = rec_flow, _args, _info) do +def action(rec_flow, _, _) do rec_flow = Domain.preload(rec_flow, :action) {:ok, rec_flow.action} end -def recipe_input_of(%RecipeFlow{} = rec_flow, _args, _info) do +def recipe_input_of(rec_flow, _, _) do rec_flow = Domain.preload(rec_flow, :recipe_input_of) {:ok, rec_flow.recipe_input_of} end -def recipe_output_of(%RecipeFlow{} = rec_flow, _args, _info) do +def recipe_output_of(rec_flow, _, _) do rec_flow = Domain.preload(rec_flow, :recipe_output_of) {:ok, rec_flow.recipe_output_of} end -def recipe_clause_of(%RecipeFlow{} = rec_flow, _args, _info) do +def recipe_clause_of(rec_flow, _, _) do rec_flow = Domain.preload(rec_flow, :recipe_clause_of) {:ok, rec_flow.recipe_clause_of} end diff --git a/src/zenflows/vf/recipe_flow/type.ex b/src/zenflows/vf/recipe_flow/type.ex @@ -33,13 +33,18 @@ or other measures of effort or usefulness. @recipe_flow_resource """ The resource definition referenced by this flow in the recipe. """ +@recipe_flow_resource_id "(`RecipeResource`) #{@recipe_flow_resource}" @action """ Relates a process input or output to a verb, such as consume, produce, work, modify, etc. """ +@action_id "(`Action`) #{@action}" @recipe_input_of "Relates an input flow to its process in a recipe." +@recipe_input_of_id "(`RecipeProcess`) #{@recipe_input_of}" @recipe_output_of "Relates an output flow to its process in a recipe." +@recipe_output_of_id "(`RecipeProcess`) #{@recipe_output_of}" @recipe_clause_of "Relates a flow to its exchange agreement in a recipe." +@recipe_clause_of_id "(`RecipeExchange`) #{@recipe_clause_of}" @note "A textual description or comment." @desc """ @@ -80,10 +85,6 @@ object :recipe_flow do field :note, :string end -object :recipe_flow_response do - field :recipe_flow, non_null(:recipe_flow) -end - input_object :recipe_flow_create_params do @desc @resource_quantity field :resource_quantity, :imeasure @@ -91,32 +92,20 @@ input_object :recipe_flow_create_params do @desc @effort_quantity field :effort_quantity, :imeasure - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeResource`) " <> @recipe_flow_resource + @desc @recipe_flow_resource_id field :recipe_flow_resource_id, non_null(:id), name: "recipe_flow_resource" - @desc "(`Action`) " <> @action + @desc @action_id field :action_id, non_null(:string), name: "action" - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeProcess`) " <> @recipe_input_of + @desc @recipe_input_of_id field :recipe_input_of_id, :id, name: "recipe_input_of" - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeProcess`) " <> @recipe_output_of + @desc @recipe_output_of_id field :recipe_output_of_id, :id, name: "recipe_output_of" - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeExchange`) " <> @recipe_clause_of + @desc @recipe_clause_of_id field :recipe_clause_of_id, :id, name: "recipe_clause_of" @desc @note @@ -132,44 +121,52 @@ input_object :recipe_flow_update_params do @desc @effort_quantity field :effort_quantity, :imeasure - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeResource`) " <> @recipe_flow_resource + @desc @recipe_flow_resource_id field :recipe_flow_resource_id, :id, name: "recipe_flow_resource" - @desc "(`Action`) " <> @action + @desc @action_id field :action_id, :string, name: "action" - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeProcess`) " <> @recipe_input_of + @desc @recipe_input_of_id field :recipe_input_of_id, :id, name: "recipe_input_of" - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeProcess`) " <> @recipe_output_of + @desc @recipe_output_of_id field :recipe_output_of_id, :id, name: "recipe_output_of" - # TODO: When - # https://github.com/absinthe-graphql/absinthe/issues/1126 results, - # apply the correct changes if any. - @desc "(`RecipeExchange`) " <> @recipe_clause_of + @desc @recipe_clause_of_id field :recipe_clause_of_id, :id, name: "recipe_clause_of" @desc @note field :note, :string end +object :recipe_flow_response do + field :recipe_flow, non_null(:recipe_flow) +end + +object :recipe_flow_edge do + field :cursor, non_null(:id) + field :node, non_null(:recipe_flow) +end + +object :recipe_flow_connection do + field :page_info, non_null(:page_info) + field :edges, non_null(list_of(non_null(:recipe_flow_edge))) +end + object :query_recipe_flow do field :recipe_flow, :recipe_flow do arg :id, non_null(:id) resolve &Resolv.recipe_flow/2 end - #recipeFlow(start: ID, limit: Int): [RecipeFlow!] + field :recipe_flows, :recipe_flow_connection do + arg :first, :integer + arg :after, :id + arg :last, :integer + arg :before, :id + resolve &Resolv.recipe_flows/2 + end end object :mutation_recipe_flow do diff --git a/test/vf/recipe_flow/domain.test.exs b/test/vf/recipe_flow/domain.test.exs @@ -29,86 +29,83 @@ alias Zenflows.VF.{ RecipeResource, } -setup ctx do - params = %{ - action_id: Factory.build(:action_id), - recipe_input_of_id: Factory.insert!(:recipe_process).id, - recipe_output_of_id: Factory.insert!(:recipe_process).id, - recipe_flow_resource_id: Factory.insert!(:recipe_resource).id, - resource_quantity: %{ - has_unit_id: Factory.insert!(:unit).id, - has_numerical_value: Factory.float(), - }, - effort_quantity: %{ - has_unit_id: Factory.insert!(:unit).id, - has_numerical_value: Factory.float(), - }, - recipe_clause_of_id: Factory.insert!(:recipe_exchange).id, - note: Factory.uniq("some note"), - } +setup do + %{ + params: %{ + action_id: Factory.build(:action_id), + recipe_input_of_id: Factory.insert!(:recipe_process).id, + recipe_output_of_id: Factory.insert!(:recipe_process).id, + recipe_flow_resource_id: Factory.insert!(:recipe_resource).id, + resource_quantity: %{ + has_unit_id: Factory.insert!(:unit).id, + has_numerical_value: Factory.float(), + }, + effort_quantity: %{ + has_unit_id: Factory.insert!(:unit).id, + has_numerical_value: Factory.float(), + }, + recipe_clause_of_id: Factory.insert!(:recipe_exchange).id, + note: Factory.uniq("some note"), + }, + inserted: Factory.insert!(:recipe_flow), + } +end - if ctx[:no_insert] do - %{params: params} - else - %{params: params, recipe_flow: Factory.insert!(:recipe_flow)} +describe "one/1" do + test "with good id: finds the RecipeFlow", %{inserted: %{id: id}} do + assert {:ok, %RecipeFlow{}} = Domain.one(id) end -end -test "by_id/1 returns a RecipeFlow", %{recipe_flow: rec_flow} do - assert %RecipeFlow{} = Domain.by_id(rec_flow.id) + test "with bad id: doesn't find the RecipeFlow" do + assert {:error, "not found"} = Domain.one(Factory.id()) + end end describe "create/1" do - @tag :no_insert - test "creates a RecipeFlow with valid params without `:effort_quantity`", %{params: params} do + test "with good params (with :resource_quantity): creates a RecipeFlow", %{params: params} do params = Map.delete(params, :effort_quantity) - - assert {:ok, %RecipeFlow{} = rec_flow} = Domain.create(params) - assert rec_flow.note == params.note - assert rec_flow.action_id == params.action_id - assert rec_flow.recipe_input_of_id == params.recipe_input_of_id - assert rec_flow.recipe_output_of_id == params.recipe_output_of_id - assert rec_flow.recipe_flow_resource_id == params.recipe_flow_resource_id - assert rec_flow.recipe_clause_of_id == params.recipe_clause_of_id - assert rec_flow.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id - assert rec_flow.resource_quantity_has_numerical_value == params.resource_quantity.has_numerical_value - assert rec_flow.effort_quantity_has_unit_id == nil - assert rec_flow.effort_quantity_has_numerical_value == nil + assert {:ok, %RecipeFlow{} = new} = Domain.create(params) + assert new.note == params.note + assert new.action_id == params.action_id + assert new.recipe_input_of_id == params.recipe_input_of_id + assert new.recipe_output_of_id == params.recipe_output_of_id + assert new.recipe_flow_resource_id == params.recipe_flow_resource_id + assert new.recipe_clause_of_id == params.recipe_clause_of_id + assert new.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id + assert new.resource_quantity_has_numerical_value == params.resource_quantity.has_numerical_value + assert new.effort_quantity_has_unit_id == nil + assert new.effort_quantity_has_numerical_value == nil end - @tag :no_insert - test "creates a RecipeFlow with valid params without :resource_quantity", %{params: params} do + test "with good params (with :effort_quantity): creates a RecipeFlow", %{params: params} do params = Map.delete(params, :resource_quantity) - - assert {:ok, %RecipeFlow{} = rec_flow} = Domain.create(params) - assert rec_flow.note == params.note - assert rec_flow.action_id == params.action_id - assert rec_flow.recipe_input_of_id == params.recipe_input_of_id - assert rec_flow.recipe_output_of_id == params.recipe_output_of_id - assert rec_flow.recipe_flow_resource_id == params.recipe_flow_resource_id - assert rec_flow.recipe_clause_of_id == params.recipe_clause_of_id - assert rec_flow.resource_quantity_has_unit_id == nil - assert rec_flow.resource_quantity_has_numerical_value == nil - assert rec_flow.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id - assert rec_flow.effort_quantity_has_numerical_value == params.effort_quantity.has_numerical_value + assert {:ok, %RecipeFlow{} = new} = Domain.create(params) + assert new.note == params.note + assert new.action_id == params.action_id + assert new.recipe_input_of_id == params.recipe_input_of_id + assert new.recipe_output_of_id == params.recipe_output_of_id + assert new.recipe_flow_resource_id == params.recipe_flow_resource_id + assert new.recipe_clause_of_id == params.recipe_clause_of_id + assert new.resource_quantity_has_unit_id == nil + assert new.resource_quantity_has_numerical_value == nil + assert new.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id + assert new.effort_quantity_has_numerical_value == params.effort_quantity.has_numerical_value end - @tag :no_insert - test "creates a RecipeFlow with valid params", %{params: params} do - assert {:ok, %RecipeFlow{} = rec_flow} = Domain.create(params) - assert rec_flow.note == params.note - assert rec_flow.action_id == params.action_id - assert rec_flow.recipe_input_of_id == params.recipe_input_of_id - assert rec_flow.recipe_output_of_id == params.recipe_output_of_id - assert rec_flow.recipe_flow_resource_id == params.recipe_flow_resource_id - assert rec_flow.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id - assert rec_flow.resource_quantity_has_numerical_value == params.resource_quantity.has_numerical_value - assert rec_flow.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id - assert rec_flow.effort_quantity_has_numerical_value == params.effort_quantity.has_numerical_value + test "with good params (with :resource_quantity and :effort_quantity): creates a RecipeFlow", %{params: params} do + assert {:ok, %RecipeFlow{} = new} = Domain.create(params) + assert new.note == params.note + assert new.action_id == params.action_id + assert new.recipe_input_of_id == params.recipe_input_of_id + assert new.recipe_output_of_id == params.recipe_output_of_id + assert new.recipe_flow_resource_id == params.recipe_flow_resource_id + assert new.resource_quantity_has_unit_id == params.resource_quantity.has_unit_id + assert new.resource_quantity_has_numerical_value == params.resource_quantity.has_numerical_value + assert new.effort_quantity_has_unit_id == params.effort_quantity.has_unit_id + assert new.effort_quantity_has_numerical_value == params.effort_quantity.has_numerical_value end - @tag :no_insert - test "doesn't create a RecipeFlow with valid params without `:resource_quantity` and `:effort_quantity`", %{params: params} do + test "with bad params (without :resource_qunatity and :effort_quantit): doesn't create a RecipeFlow", %{params: params} do params = params |> Map.delete(:resource_quantity) @@ -119,38 +116,14 @@ describe "create/1" do assert Keyword.has_key?(errs, :effort_quantity) end - test "doesn't create a RecipeFlow with invalid params" do + test "with bad params: doesn't create a RecipeFlow" do assert {:error, %Changeset{}} = Domain.create(%{}) end end describe "update/2" do - test "doesn't update a RecipeFlow", %{recipe_flow: old} do - assert {:ok, %RecipeFlow{} = new} = Domain.update(old.id, %{}) - assert new.note == old.note - assert new.action_id == old.action_id - assert new.recipe_input_of_id == old.recipe_input_of_id - assert new.recipe_output_of_id == old.recipe_output_of_id - assert new.recipe_flow_resource_id == old.recipe_flow_resource_id - assert new.recipe_clause_of_id == old.recipe_clause_of_id - assert new.resource_quantity_has_unit_id == old.resource_quantity_has_unit_id - assert new.resource_quantity_has_numerical_value == old.resource_quantity_has_numerical_value - assert new.effort_quantity_has_unit_id == old.effort_quantity_has_unit_id - assert new.effort_quantity_has_numerical_value == old.effort_quantity_has_numerical_value - end - - test "doesn't update a RecipeFlow with valid params with `:resource_quantity` and `:effort_quantity` set to nil", %{params: params, recipe_flow: old} do - params = - params - |> Map.put(:resource_quantity, nil) - |> Map.put(:effort_quantity, nil) - - assert {:error, %Changeset{}} = Domain.update(old.id, params) - end - - test "updates a RecipeFlow with valid params without `:effort_quantity`", %{params: params, recipe_flow: old} do + test "with good params (with :resource_quantity): updates the RecipeFlow", %{params: params, inserted: old} do params = Map.delete(params, :effort_quantity) - assert {:ok, %RecipeFlow{} = new} = Domain.update(old.id, params) assert new.note == params.note assert new.action_id == params.action_id @@ -164,9 +137,8 @@ describe "update/2" do assert new.effort_quantity_has_numerical_value == old.effort_quantity_has_numerical_value end - test "updates a RecipeFlow with valid params without `:resource_quantity`", %{params: params, recipe_flow: old} do + test "with good params (with :effort_quantity): updates the RecipeFlow", %{params: params, inserted: old} do params = Map.delete(params, :resource_quantity) - assert {:ok, %RecipeFlow{} = new} = Domain.update(old.id, params) assert new.note == params.note assert new.action_id == params.action_id @@ -180,11 +152,11 @@ describe "update/2" do assert new.effort_quantity_has_numerical_value == params.effort_quantity.has_numerical_value end - test "updates a RecipeFlow with valid params with a new `:resource_quantity` set to `nil`", %{params: params, recipe_flow: old} do - params = - params - |> Map.delete(:effort_quantity) - |> Map.put(:resource_quantity, nil) + test "with good params (with :resource_quantity set to nil): updates the RecipeFlow", %{params: params, inserted: old} do + params = + params + |> Map.delete(:effort_quantity) + |> Map.put(:resource_quantity, nil) assert {:ok, %RecipeFlow{} = new} = Domain.update(old.id, params) assert new.note == params.note @@ -199,11 +171,11 @@ describe "update/2" do assert new.effort_quantity_has_numerical_value == old.effort_quantity_has_numerical_value end - test "updates a RecipeFlow with valid params with a new `:effort_quantity` set to `nil`", %{params: params, recipe_flow: old} do - params = - params - |> Map.delete(:resource_quantity) - |> Map.put(:effort_quantity, nil) + test "with good params (with :effort_quantity set to nil): updates the RecipeFlow", %{params: params, inserted: old} do + params = + params + |> Map.delete(:resource_quantity) + |> Map.put(:effort_quantity, nil) assert {:ok, %RecipeFlow{} = new} = Domain.update(old.id, params) assert new.note == params.note @@ -217,53 +189,82 @@ describe "update/2" do assert new.effort_quantity_has_unit_id == nil assert new.effort_quantity_has_numerical_value == nil end + + test "with bad params: doesn't update the RecipeFlow", %{inserted: old} do + assert {:ok, %RecipeFlow{} = new} = Domain.update(old.id, %{}) + assert new.note == old.note + assert new.action_id == old.action_id + assert new.recipe_input_of_id == old.recipe_input_of_id + assert new.recipe_output_of_id == old.recipe_output_of_id + assert new.recipe_flow_resource_id == old.recipe_flow_resource_id + assert new.recipe_clause_of_id == old.recipe_clause_of_id + assert new.resource_quantity_has_unit_id == old.resource_quantity_has_unit_id + assert new.resource_quantity_has_numerical_value == old.resource_quantity_has_numerical_value + assert new.effort_quantity_has_unit_id == old.effort_quantity_has_unit_id + assert new.effort_quantity_has_numerical_value == old.effort_quantity_has_numerical_value + end + + test "with bad params (with :resource_quantity and :effort_quantity set to nil): doesn't update the RecipeFlow", %{params: params, inserted: old} do + params = + params + |> Map.put(:resource_quantity, nil) + |> Map.put(:effort_quantity, nil) + + assert {:error, %Changeset{}} = Domain.update(old.id, params) + end end -test "delete/1 deletes a RecipeFlow", %{recipe_flow: %{id: id}} do - assert {:ok, %RecipeFlow{id: ^id}} = Domain.delete(id) - assert Domain.by_id(id) == nil +describe "delete/1" do + test "with good id: deletes the RecipeFlow", %{inserted: %{id: id}} do + assert {:ok, %RecipeFlow{id: ^id}} = Domain.delete(id) + assert {:error, "not found"} = Domain.one(id) + end + + test "with bad id: doesn't delete the RecipeFlow" do + assert {:error, "not found"} = Domain.delete(Factory.id()) + end end describe "preload/2" do - test "preloads :resource_quantity", %{recipe_flow: rec_flow} do + test "preloads :resource_quantity", %{inserted: rec_flow} do rec_flow = Domain.preload(rec_flow, :resource_quantity) assert res_qty = %Measure{} = rec_flow.resource_quantity assert res_qty.has_unit_id == rec_flow.resource_quantity_has_unit_id assert res_qty.has_numerical_value == rec_flow.resource_quantity_has_numerical_value end - test "preloads :effort_quantity", %{recipe_flow: rec_flow} do + test "preloads :effort_quantity", %{inserted: rec_flow} do rec_flow = Domain.preload(rec_flow, :effort_quantity) assert eff_qty = %Measure{} = rec_flow.effort_quantity assert eff_qty.has_unit_id == rec_flow.effort_quantity_has_unit_id assert eff_qty.has_numerical_value == rec_flow.effort_quantity_has_numerical_value end - test "preloads :recipe_flow_resource", %{recipe_flow: rec_flow} do + test "preloads :recipe_flow_resource", %{inserted: rec_flow} do rec_flow = Domain.preload(rec_flow, :recipe_flow_resource) assert rec_flow_res = %RecipeResource{} = rec_flow.recipe_flow_resource assert rec_flow_res.id == rec_flow.recipe_flow_resource_id end - test "preloads :action", %{recipe_flow: rec_flow} do + test "preloads :action", %{inserted: rec_flow} do rec_flow = Domain.preload(rec_flow, :action) assert action = %Action{} = rec_flow.action assert action.id == rec_flow.action_id end - test "preloads :recipe_input_of", %{recipe_flow: rec_flow} do + test "preloads :recipe_input_of", %{inserted: rec_flow} do rec_flow = Domain.preload(rec_flow, :recipe_input_of) assert rec_in_of = %RecipeProcess{} = rec_flow.recipe_input_of assert rec_in_of.id == rec_flow.recipe_input_of_id end - test "preloads :recipe_output_of", %{recipe_flow: rec_flow} do + test "preloads :recipe_output_of", %{inserted: rec_flow} do rec_flow = Domain.preload(rec_flow, :recipe_output_of) assert rec_out_of = %RecipeProcess{} = rec_flow.recipe_output_of assert rec_out_of.id == rec_flow.recipe_output_of_id end - test "preloads :recipe_clause_of", %{recipe_flow: rec_flow} do + test "preloads :recipe_clause_of", %{inserted: rec_flow} do rec_flow = Domain.preload(rec_flow, :recipe_clause_of) assert rec_clause_of = %RecipeExchange{} = rec_flow.recipe_clause_of assert rec_clause_of.id == rec_flow.recipe_clause_of_id diff --git a/test/vf/recipe_flow/type.test.exs b/test/vf/recipe_flow/type.test.exs @@ -18,221 +18,128 @@ defmodule ZenflowsTest.VF.RecipeFlow.Type do use ZenflowsTest.Help.AbsinCase, async: true -alias Zenflows.VF.RecipeFlow.Domain - setup do %{ params: %{ - note: Factory.uniq("some note"), - action_id: Factory.build(:action_id), - recipe_input_of_id: Factory.insert!(:recipe_process).id, - recipe_output_of_id: Factory.insert!(:recipe_process).id, - recipe_flow_resource_id: Factory.insert!(:recipe_resource).id, - resource_quantity: %{ - has_unit_id: Factory.insert!(:unit).id, - has_numerical_value: Factory.float(), + "note" => Factory.uniq("some note"), + "action" => Factory.build(:action_id), + "recipeInputOf" => Factory.insert!(:recipe_process).id, + "recipeOutputOf" => Factory.insert!(:recipe_process).id, + "recipeFlowResource" => Factory.insert!(:recipe_resource).id, + "resourceQuantity" => %{ + "hasUnit" => Factory.insert!(:unit).id, + "hasNumericalValue" => Factory.float(), }, - effort_quantity: %{ - has_unit_id: Factory.insert!(:unit).id, - has_numerical_value: Factory.float(), + "effortQuantity" => %{ + "hasUnit" => Factory.insert!(:unit).id, + "hasNumericalValue" => Factory.float(), }, - recipe_clause_of_id: Factory.insert!(:recipe_exchange).id, + "recipeClauseOf" => Factory.insert!(:recipe_exchange).id, }, - recipe_flow: - Factory.insert!(:recipe_flow) - |> Domain.preload(:action) - |> Domain.preload(:resource_quantity) - |> Domain.preload(:effort_quantity) - |> Domain.preload(:recipe_flow_resource) - |> Domain.preload(:recipe_input_of) - |> Domain.preload(:recipe_output_of) - |> Domain.preload(:recipe_clause_of) + inserted: Factory.insert!(:recipe_flow), } end -describe "Query" do - test "recipeFlow()", %{recipe_flow: rec_flow} do - %{ - action: action, - resource_quantity: res_qty, - effort_quantity: eff_qty, - recipe_flow_resource: rec_flow_res, - recipe_input_of: rec_in_of, - recipe_output_of: rec_out_of, - recipe_clause_of: rec_clause_of, - } = rec_flow +@frag """ +fragment recipeFlow on RecipeFlow { + id + note + action {id} + resourceQuantity { + hasUnit {id} + hasNumericalValue + } + effortQuantity { + hasUnit {id} + hasNumericalValue + } + recipeFlowResource {id} + recipeInputOf {id} + recipeOutputOf {id} + recipeClauseOf {id} +} +""" +describe "Query" do + test "recipeFlow", %{inserted: new} do assert %{data: %{"recipeFlow" => data}} = - query!(""" - recipeFlow(id: "#{rec_flow.id}") { - id - note - action { id label resourceEffect onhandEffect inputOutput pairsWith } - resourceQuantity { - hasUnit { id } - hasNumericalValue - } - effortQuantity { - hasUnit { id } - hasNumericalValue - } - recipeFlowResource { id } - recipeInputOf { id } - recipeOutputOf { id } - recipeClauseOf { id } + run!(""" + #{@frag} + query ($id: ID!) { + recipeFlow(id: $id) {...recipeFlow} } - """) + """, vars: %{"id" => new.id}) - assert data["id"] == rec_flow.id - assert data["note"] == rec_flow.note - assert data["action"]["id"] == action.id - assert data["action"]["label"] == action.label - assert data["action"]["resourceEffect"] == action.resource_effect - assert data["action"]["onhandEffect"] == action.onhand_effect - assert data["action"]["inputOutput"] == action.input_output - assert data["action"]["pairsWith"] == action.pairs_with - assert data["resourceQuantity"]["hasUnit"]["id"] == res_qty.has_unit_id - assert data["resourceQuantity"]["hasNumericalValue"] == res_qty.has_numerical_value - assert data["effortQuantity"]["hasUnit"]["id"] == eff_qty.has_unit_id - assert data["effortQuantity"]["hasNumericalValue"] == eff_qty.has_numerical_value - assert data["recipeFlowResource"]["id"] == rec_flow_res.id - assert data["recipeInputOf"]["id"] == rec_in_of.id - assert data["recipeOutputOf"]["id"] == rec_out_of.id - assert data["recipeClauseOf"]["id"] == rec_clause_of.id + assert data["id"] == new.id + assert data["note"] == new.note + assert data["action"]["id"] == new.action_id + assert data["resourceQuantity"]["hasUnit"]["id"] == new.resource_quantity_has_unit_id + assert data["resourceQuantity"]["hasNumericalValue"] == new.resource_quantity_has_numerical_value + assert data["effortQuantity"]["hasUnit"]["id"] == new.effort_quantity_has_unit_id + assert data["effortQuantity"]["hasNumericalValue"] == new.effort_quantity_has_numerical_value + assert data["recipeFlowResource"]["id"] == new.recipe_flow_resource_id + assert data["recipeInputOf"]["id"] == new.recipe_input_of_id + assert data["recipeOutputOf"]["id"] == new.recipe_output_of_id + assert data["recipeClauseOf"]["id"] == new.recipe_clause_of_id end end describe "Mutation" do - test "createRecipeFlow()", %{params: params} do - %{ - action_id: action_id, - resource_quantity: res_qty, - effort_quantity: eff_qty, - recipe_flow_resource_id: rec_flow_res_id, - recipe_input_of_id: rec_in_of_id, - recipe_output_of_id: rec_out_of_id, - recipe_clause_of_id: rec_clause_of_id, - } = params - + test "createRecipeFlow", %{params: params} do assert %{data: %{"createRecipeFlow" => %{"recipeFlow" => data}}} = - mutation!(""" - createRecipeFlow(recipeFlow: { - note: "#{params.note}" - action: "#{action_id}" - resourceQuantity: { - hasUnit: "#{res_qty.has_unit_id}" - hasNumericalValue: #{res_qty.has_numerical_value} - } - effortQuantity: { - hasUnit: "#{eff_qty.has_unit_id}" - hasNumericalValue: #{eff_qty.has_numerical_value} - } - recipeFlowResource: "#{rec_flow_res_id}" - recipeInputOf: "#{rec_in_of_id}" - recipeOutputOf: "#{rec_out_of_id}" - recipeClauseOf: "#{rec_clause_of_id}" - }) { - recipeFlow { - id - note - action { id label resourceEffect onhandEffect inputOutput pairsWith } - resourceQuantity { - hasUnit { id } - hasNumericalValue - } - effortQuantity { - hasUnit { id } - hasNumericalValue - } - recipeFlowResource { id } - recipeInputOf { id } - recipeOutputOf { id } - recipeClauseOf { id } + run!(""" + #{@frag} + mutation ($recipeFlow: RecipeFlowCreateParams!) { + createRecipeFlow(recipeFlow: $recipeFlow) { + recipeFlow {...recipeFlow} } } - """) + """, vars: %{"recipeFlow" => params}) assert {:ok, _} = Zenflows.DB.ID.cast(data["id"]) - assert data["note"] == params.note - assert data["action"]["id"] == action_id - assert data["resourceQuantity"]["hasUnit"]["id"] == res_qty.has_unit_id - assert data["resourceQuantity"]["hasNumericalValue"] == res_qty.has_numerical_value - assert data["effortQuantity"]["hasUnit"]["id"] == eff_qty.has_unit_id - assert data["effortQuantity"]["hasNumericalValue"] == eff_qty.has_numerical_value - assert data["recipeFlowResource"]["id"] == rec_flow_res_id - assert data["recipeInputOf"]["id"] == rec_in_of_id - assert data["recipeOutputOf"]["id"] == rec_out_of_id - assert data["recipeClauseOf"]["id"] == rec_clause_of_id + assert data["note"] == params["note"] + assert data["action"]["id"] == params["action"] + assert data["resourceQuantity"]["hasUnit"]["id"] == params["resourceQuantity"]["hasUnit"] + assert data["resourceQuantity"]["hasNumericalValue"] == params["resourceQuantity"]["hasNumericalValue"] + assert data["effortQuantity"]["hasUnit"]["id"] == params["effortQuantity"]["hasUnit"] + assert data["effortQuantity"]["hasNumericalValue"] == params["effortQuantity"]["hasNumericalValue"] + assert data["recipeFlowResource"]["id"] == params["recipeFlowResource"] + assert data["recipeInputOf"]["id"] == params["recipeInputOf"] + assert data["recipeOutputOf"]["id"] == params["recipeOutputOf"] + assert data["recipeClauseOf"]["id"] == params["recipeClauseOf"] end - test "updateRecipeFlow()", %{params: params, recipe_flow: rec_flow} do - %{ - action_id: action_id, - resource_quantity: res_qty, - effort_quantity: eff_qty, - recipe_flow_resource_id: rec_flow_res_id, - recipe_input_of_id: rec_in_of_id, - recipe_output_of_id: rec_out_of_id, - recipe_clause_of_id: rec_clause_of_id, - } = params - + test "updateRecipeFlow", %{params: params, inserted: old} do assert %{data: %{"updateRecipeFlow" => %{"recipeFlow" => data}}} = - mutation!(""" - updateRecipeFlow(recipeFlow: { - id: "#{rec_flow.id}" - note: "#{params.note}" - action: "#{action_id}" - resourceQuantity: { - hasUnit: "#{res_qty.has_unit_id}" - hasNumericalValue: #{res_qty.has_numerical_value} - } - effortQuantity: { - hasUnit: "#{eff_qty.has_unit_id}" - hasNumericalValue: #{eff_qty.has_numerical_value} - } - recipeFlowResource: "#{rec_flow_res_id}" - recipeInputOf: "#{rec_in_of_id}" - recipeOutputOf: "#{rec_out_of_id}" - recipeClauseOf: "#{rec_clause_of_id}" - }) { - recipeFlow { - id - note - action { id label resourceEffect onhandEffect inputOutput pairsWith } - resourceQuantity { - hasUnit { id } - hasNumericalValue - } - effortQuantity { - hasUnit { id } - hasNumericalValue - } - recipeFlowResource { id } - recipeInputOf { id } - recipeOutputOf { id } - recipeClauseOf { id } + run!(""" + #{@frag} + mutation ($recipeFlow: RecipeFlowUpdateParams!) { + updateRecipeFlow(recipeFlow: $recipeFlow) { + recipeFlow {...recipeFlow} } } - """) + """, vars: %{"recipeFlow" => Map.put(params, "id", old.id)}) - assert data["id"] == rec_flow.id - assert data["note"] == params.note - assert data["action"]["id"] == action_id - assert data["resourceQuantity"]["hasUnit"]["id"] == res_qty.has_unit_id - assert data["resourceQuantity"]["hasNumericalValue"] == res_qty.has_numerical_value - assert data["effortQuantity"]["hasUnit"]["id"] == eff_qty.has_unit_id - assert data["effortQuantity"]["hasNumericalValue"] == eff_qty.has_numerical_value - assert data["recipeFlowResource"]["id"] == rec_flow_res_id - assert data["recipeInputOf"]["id"] == rec_in_of_id - assert data["recipeOutputOf"]["id"] == rec_out_of_id - assert data["recipeClauseOf"]["id"] == rec_clause_of_id + assert data["id"] == old.id + assert data["note"] == params["note"] + assert data["action"]["id"] == params["action"] + assert data["resourceQuantity"]["hasUnit"]["id"] == params["resourceQuantity"]["hasUnit"] + assert data["resourceQuantity"]["hasNumericalValue"] == params["resourceQuantity"]["hasNumericalValue"] + assert data["effortQuantity"]["hasUnit"]["id"] == params["effortQuantity"]["hasUnit"] + assert data["effortQuantity"]["hasNumericalValue"] == params["effortQuantity"]["hasNumericalValue"] + assert data["recipeFlowResource"]["id"] == params["recipeFlowResource"] + assert data["recipeInputOf"]["id"] == params["recipeInputOf"] + assert data["recipeOutputOf"]["id"] == params["recipeOutputOf"] + assert data["recipeClauseOf"]["id"] == params["recipeClauseOf"] end - test "deleteRecipeFlow()", %{recipe_flow: %{id: id}} do + test "deleteRecipeFlow", %{inserted: %{id: id}} do assert %{data: %{"deleteRecipeFlow" => true}} = - mutation!(""" - deleteRecipeFlow(id: "#{id}") - """) + run!(""" + mutation ($id: ID!) { + deleteRecipeFlow(id: $id) + } + """, vars: %{"id" => id}) end end end