zf

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

commit 2c8deac62dbd767a4aa4bf99cedec63dc8a2c7f2
parent bd1f61de42b733a35982299c5247a14d853ea914
Author: srfsh <dev@srf.sh>
Date:   Tue, 16 Aug 2022 13:31:06 +0300

Zenflows{Test,}.VF.ProposedIntent: init

Diffstat:
Asrc/zenflows/vf/proposed_intent/domain.ex | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/zenflows/vf/proposed_intent/resolv.ex | 44++++++++++++++++++++++++++++++++++++++++++++
Atest/vf/proposed_intent/domain.test.exs | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/vf/proposed_intent/type.test.exs | 71+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 281 insertions(+), 0 deletions(-)

diff --git a/src/zenflows/vf/proposed_intent/domain.ex b/src/zenflows/vf/proposed_intent/domain.ex @@ -0,0 +1,78 @@ +# Zenflows is designed to implement the Valueflows vocabulary, +# written and maintained by srfsh <info@dyne.org>. +# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +defmodule Zenflows.VF.ProposedIntent.Domain do +@moduledoc "Domain logic of ProposedIntents." + +alias Ecto.Multi +alias Zenflows.DB.Repo +alias Zenflows.VF.ProposedIntent + +@typep repo() :: Ecto.Repo.t() +@typep chgset() :: Ecto.Changeset.t() +@typep id() :: Zenflows.DB.Schema.id() +@typep params() :: Zenflows.DB.Schema.params() + +@spec one(repo(), id()) :: {:ok, ProposedIntent.t()} | {:error, String.t()} +def one(repo \\ Repo, id) do + one_by(repo, id: id) +end + +@spec one_by(repo(), map() | Keyword.t()) + :: {:ok, ProposedIntent.t()} | {:error, String.t()} +def one_by(repo \\ Repo, clauses) do + case repo.get_by(ProposedIntent, clauses) do + nil -> {:error, "not found"} + found -> {:ok, found} + end +end + +@spec create(params()) :: {:ok, ProposedIntent.t()} | {:error, chgset()} +def create(params) do + Multi.new() + |> Multi.insert(:insert, ProposedIntent.chgset(params)) + |> Repo.transaction() + |> case do + {:ok, %{insert: pi}} -> {:ok, pi} + {:error, _, cset, _} -> {:error, cset} + end +end + +@spec delete(id()) + :: {:ok, ProposedIntent.t()} | {:error, String.t() | chgset()} +def delete(id) do + Multi.new() + |> Multi.put(:id, id) + |> Multi.run(:one, &one_by/2) + |> Multi.delete(:delete, &(&1.one)) + |> Repo.transaction() + |> case do + {:ok, %{delete: pi}} -> {:ok, pi} + {:error, _, msg_or_cset, _} -> {:error, msg_or_cset} + end +end + +@spec preload(ProposedIntent.t(), :published_in | :publishes) + :: ProposedIntent.t() +def preload(prop_int, :published_in) do + Repo.preload(prop_int, :published_in) +end + +def preload(prop_int, :publishes) do + Repo.preload(prop_int, :publishes) +end +end diff --git a/src/zenflows/vf/proposed_intent/resolv.ex b/src/zenflows/vf/proposed_intent/resolv.ex @@ -0,0 +1,44 @@ +# Zenflows is designed to implement the Valueflows vocabulary, +# written and maintained by srfsh <info@dyne.org>. +# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +defmodule Zenflows.VF.ProposedIntent.Resolv do +@moduledoc "Resolvers of ProposedIntent." + +alias Zenflows.VF.ProposedIntent.Domain + +def published_in(prop_int, _, _) do + prop_int = Domain.preload(prop_int, :published_in) + {:ok, prop_int.published_in} +end + +def publishes(prop_int, _, _) do + prop_int = Domain.preload(prop_int, :publishes) + {:ok, prop_int.publishes} +end + +def propose_intent(params, _) do + with {:ok, prop_int} <- Domain.create(params) do + {:ok, %{proposed_intent: prop_int}} + end +end + +def delete_proposed_intent(%{id: id}, _) do + with {:ok, _} <- Domain.delete(id) do + {:ok, true} + end +end +end diff --git a/test/vf/proposed_intent/domain.test.exs b/test/vf/proposed_intent/domain.test.exs @@ -0,0 +1,88 @@ +# Zenflows is designed to implement the Valueflows vocabulary, +# written and maintained by srfsh <info@dyne.org>. +# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +defmodule ZenflowsTest.VF.ProposedIntent.Domain do +use ZenflowsTest.Help.EctoCase, async: true + +alias Ecto.Changeset +alias Zenflows.VF.{ + Intent, + Proposal, + ProposedIntent, + ProposedIntent.Domain, +} + +setup do + %{ + params: %{ + reciprocal: Factory.bool(), + publishes_id: Factory.insert!(:intent).id, + published_in_id: Factory.insert!(:proposal).id, + }, + inserted: Factory.insert!(:proposed_intent), + id: Factory.id(), + } +end + +describe "one/1" do + test "with good id: finds the ProposedIntent", %{inserted: %{id: id}} do + assert {:ok, %ProposedIntent{}} = Domain.one(id) + end + + test "with bad id: doesn't find the ProposedIntent", %{id: id} do + assert {:error, "not found"} = Domain.one(id) + end +end + +describe "create/1" do + test "with good params: creates a ProposedIntent", %{params: params} do + assert {:ok, %ProposedIntent{} = prop_int} = Domain.create(params) + assert prop_int.reciprocal == params.reciprocal + assert prop_int.publishes_id == params.publishes_id + assert prop_int.published_in_id == params.published_in_id + end + + test "with bad params: doesn't create a ProposedIntent" do + assert {:error, %Changeset{}} = Domain.create(%{}) + end +end + +describe "delete/1" do + test "with good id: deletes the ProposedIntent", %{inserted: %{id: id}} do + assert {:ok, %ProposedIntent{id: ^id}} = Domain.delete(id) + assert {:error, "not found"} = Domain.one(id) + end + + test "with bad id: doesn't delete the ProposedIntent", %{id: id} do + assert {:error, "not found"} = Domain.delete(id) + end +end + +describe "preload/2" do + test "preloads `:published_in`", %{inserted: %{id: id}} do + assert {:ok, prop} = Domain.one(id) + prop = Domain.preload(prop, :published_in) + assert %Proposal{} = prop.published_in + end + + test "preloads `:publishes`", %{inserted: %{id: id}} do + assert {:ok, prop} = Domain.one(id) + prop = Domain.preload(prop, :publishes) + assert %Intent{} = prop.publishes + end +end +end diff --git a/test/vf/proposed_intent/type.test.exs b/test/vf/proposed_intent/type.test.exs @@ -0,0 +1,71 @@ +# Zenflows is designed to implement the Valueflows vocabulary, +# written and maintained by srfsh <info@dyne.org>. +# Copyright (C) 2021-2022 Dyne.org foundation <foundation@dyne.org>. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <https://www.gnu.org/licenses/>. + +defmodule ZenflowsTest.VF.ProposedIntent.Type do +use ZenflowsTest.Help.AbsinCase, async: true + +setup do + %{ + params: %{ + "reciprocal" => Factory.bool(), + "publishedIn" => Factory.insert!(:proposal).id, + "publishes" => Factory.insert!(:intent).id + }, + inserted: Factory.insert!(:proposed_intent), + } +end + +describe "Mutation" do + test "proposeIntent", %{params: params} do + assert %{data: %{"proposeIntent" => %{"proposedIntent" => data}}} = + run!(""" + mutation ( + $reciprocal: Boolean! + $publishedIn: ID! + $publishes: ID! + ) { + proposeIntent( + reciprocal: $reciprocal + publishedIn: $publishedIn + publishes: $publishes + ) { + proposedIntent { + id + reciprocal + publishedIn {id} + publishes {id} + } + } + } + """, vars: params) + + assert {:ok, _} = Zenflows.DB.ID.cast(data["id"]) + assert data["reciprocal"] == params["reciprocal"] + assert data["publishedIn"]["id"] == params["publishedIn"] + assert data["publishes"]["id"] == params["publishes"] + end + + test "deleteProposedIntent", %{inserted: %{id: id}} do + assert %{data: %{"deleteProposedIntent" => true}} = + run!(""" + mutation ($id: ID!) { + deleteProposedIntent(id: $id) + } + """, vars: %{"id" => id}) + end +end +end