commit c36edb0e6e0e557ac27766e4df51a2ad9360f1e1
parent c0287c8f5d4d9803c17b13b96722774696e523ea
Author: srfsh <dev@srf.sh>
Date: Tue, 23 Aug 2022 08:58:26 +0300
Zenflows{Test,}.VF.Proposal: add paging support and small improvements
Diffstat:
5 files changed, 86 insertions(+), 127 deletions(-)
diff --git a/src/zenflows/vf/proposal/domain.ex b/src/zenflows/vf/proposal/domain.ex
@@ -20,6 +20,7 @@ defmodule Zenflows.VF.Proposal.Domain do
alias Ecto.Multi
alias Zenflows.DB.Repo
+alias Zenflows.GQL.Paging
alias Zenflows.VF.Proposal
@typep repo() :: Ecto.Repo.t()
@@ -27,20 +28,22 @@ alias Zenflows.VF.Proposal
@typep id() :: Zenflows.DB.Schema.id()
@typep params() :: Zenflows.DB.Schema.params()
-@spec one(repo(), id()) :: {:ok, Proposal.t()} | {:error, String.t()}
-def one(repo \\ Repo, id) do
- one_by(repo, id: id)
-end
-
-@spec one_by(repo(), map() | Keyword.t())
+@spec one(repo(), id() | map() | Keyword.t())
:: {:ok, Proposal.t()} | {:error, String.t()}
-def one_by(repo \\ Repo, clauses) do
+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(Proposal, clauses) do
nil -> {:error, "not found"}
found -> {:ok, found}
end
end
+@spec all(Paging.params()) :: Paging.result(Proposal.t())
+def all(params) do
+ Paging.page(Proposal, params)
+end
+
@spec create(params()) :: {:ok, Proposal.t()} | {:error, chgset()}
def create(params) do
Multi.new()
@@ -57,7 +60,7 @@ end
def update(id, params) do
Multi.new()
|> Multi.put(:id, id)
- |> Multi.run(:one, &one_by/2)
+ |> Multi.run(:one, &one/2)
|> Multi.update(:update, &Proposal.chgset(&1.one, params))
|> Repo.transaction()
|> case do
@@ -71,8 +74,8 @@ end
def delete(id) do
Multi.new()
|> Multi.put(:id, id)
- |> Multi.run(:one, &one_by/2)
- |> Multi.delete(:delete, &(&1.one))
+ |> Multi.run(:one, &one/2)
+ |> Multi.delete(:delete, & &1.one)
|> Repo.transaction()
|> case do
{:ok, %{delete: pi}} -> {:ok, pi}
diff --git a/src/zenflows/vf/proposal/resolv.ex b/src/zenflows/vf/proposal/resolv.ex
@@ -20,38 +20,12 @@ defmodule Zenflows.VF.Proposal.Resolv do
alias Zenflows.VF.Proposal.Domain
-def eligible_location(prop, _, _) do
- prop = Domain.preload(prop, :eligible_location)
- {:ok, prop.eligible_location}
-end
-
-def publishes(prop, _, _) do
- prop = Domain.preload(prop, :publishes)
- {:ok, prop.publishes}
-end
-
-def primary_intents(prop, _, _) do
- prop = Domain.preload(prop, :primary_intents)
- {:ok, prop.primary_intents}
-end
-
-def reciprocal_intents(prop, _, _) do
- prop = Domain.preload(prop, :reciprocal_intents)
- {:ok, prop.reciprocal_intents}
+def proposal(params, _) do
+ Domain.one(params)
end
-def proposal(%{id: id}, _) do
- Domain.one(id)
-end
-
-def proposals(_params, _) do
- {:ok, %{
- edges: [],
- page_info: %{
- has_previous_page: false,
- has_next_page: false,
- },
- }}
+def proposals(params, _) do
+ Domain.all(params)
end
def offers(_params, _) do
@@ -91,4 +65,24 @@ def delete_proposal(%{id: id}, _) do
{:ok, true}
end
end
+
+def eligible_location(prop, _, _) do
+ prop = Domain.preload(prop, :eligible_location)
+ {:ok, prop.eligible_location}
+end
+
+def publishes(prop, _, _) do
+ prop = Domain.preload(prop, :publishes)
+ {:ok, prop.publishes}
+end
+
+def primary_intents(prop, _, _) do
+ prop = Domain.preload(prop, :primary_intents)
+ {:ok, prop.primary_intents}
+end
+
+def reciprocal_intents(prop, _, _) do
+ prop = Domain.preload(prop, :reciprocal_intents)
+ {:ok, prop.reciprocal_intents}
+end
end
diff --git a/src/zenflows/vf/proposal/type.ex b/src/zenflows/vf/proposal/type.ex
@@ -74,20 +74,6 @@ object :proposal do
resolve: &Resolv.reciprocal_intents/3
end
-object :proposal_response do
- field :proposal, non_null(:proposal)
-end
-
-object :proposal_edge do
- field :cursor, non_null(:string)
- field :node, non_null(:proposal)
-end
-
-object :proposal_connection do
- field :page_info, non_null(:page_info)
- field :edges, non_null(list_of(non_null(:proposal_edge)))
-end
-
input_object :proposal_create_params do
@desc @name
field :name, :string
@@ -130,6 +116,20 @@ input_object :proposal_update_params do
field :eligible_location_id, :id, name: "eligible_location"
end
+object :proposal_response do
+ field :proposal, non_null(:proposal)
+end
+
+object :proposal_edge do
+ field :cursor, non_null(:id)
+ field :node, non_null(:proposal)
+end
+
+object :proposal_connection do
+ field :page_info, non_null(:page_info)
+ field :edges, non_null(list_of(non_null(:proposal_edge)))
+end
+
object :query_proposal do
field :proposal, :proposal do
arg :id, non_null(:id)
@@ -138,29 +138,27 @@ object :query_proposal do
field :proposals, non_null(:proposal_connection) do
arg :first, :integer
- arg :after, :string
+ arg :after, :id
arg :last, :integer
- arg :before, :string
+ arg :before, :id
resolve &Resolv.proposals/2
end
@desc "List all proposals that are being listed as offers."
field :offers, non_null(:proposal_connection) do
arg :first, :integer
- arg :first, :integer
- arg :after, :string
+ arg :after, :id
arg :last, :integer
- arg :before, :string
+ arg :before, :id
resolve &Resolv.offers/2
end
@desc "List all proposals that are being listed as requests."
field :requests, non_null(:proposal_connection) do
arg :first, :integer
- arg :first, :integer
- arg :after, :string
+ arg :after, :id
arg :last, :integer
- arg :before, :string
+ arg :before, :id
resolve &Resolv.offers/2
end
end
diff --git a/test/vf/proposal/domain.test.exs b/test/vf/proposal/domain.test.exs
@@ -35,7 +35,6 @@ setup do
eligible_location_id: Factory.insert!(:spatial_thing).id,
},
inserted: Factory.insert!(:proposal),
- id: Factory.id(),
}
end
@@ -44,37 +43,36 @@ describe "one/1" do
assert {:ok, %Proposal{}} = Domain.one(id)
end
- test "with bad id: doesn't find the Proposal", %{id: id} do
- assert {:error, "not found"} = Domain.one(id)
+ test "with bad id: doesn't find the Proposal" do
+ assert {:error, "not found"} = Domain.one(Factory.id())
end
end
describe "create/1" do
test "with good params: creates a Proposal", %{params: params} do
- assert {:ok, %Proposal{} = prop} = Domain.create(params)
- assert prop.name == params.name
- assert prop.note == params.note
- assert prop.has_beginning == params.has_beginning
- assert prop.has_end == params.has_end
- assert prop.unit_based == params.unit_based
- assert prop.eligible_location_id == params.eligible_location_id
+ assert {:ok, %Proposal{} = new} = Domain.create(params)
+ assert new.name == params.name
+ assert new.note == params.note
+ assert new.has_beginning == params.has_beginning
+ assert new.has_end == params.has_end
+ assert new.unit_based == params.unit_based
+ assert new.eligible_location_id == params.eligible_location_id
end
test "with empty params: creates a Proposal" do
- assert {:ok, %Proposal{} = prop} = Domain.create(%{})
- assert prop.name == nil
- assert prop.note == nil
- assert prop.has_beginning == nil
- assert prop.has_end == nil
- assert prop.unit_based == false # since it defaults
- assert prop.eligible_location_id == nil
+ assert {:ok, %Proposal{} = new} = Domain.create(%{})
+ assert new.name == nil
+ assert new.note == nil
+ assert new.has_beginning == nil
+ assert new.has_end == nil
+ assert new.unit_based == false # since it defaults
+ assert new.eligible_location_id == nil
end
end
describe "update/2" do
test "with good params: updates the Proposal", %{params: params, inserted: old} do
assert {:ok, %Proposal{} = new} = Domain.update(old.id, params)
-
assert new.name == params.name
assert new.note == params.note
assert new.has_beginning == params.has_beginning
@@ -85,7 +83,6 @@ describe "update/2" do
test "with bad params: doesn't update the Proposal", %{inserted: old} do
assert {:ok, %Proposal{} = new} = Domain.update(old.id, %{})
-
assert new.name == old.name
assert new.note == old.note
assert new.has_beginning == old.has_beginning
@@ -101,8 +98,8 @@ describe "delete/1" do
assert {:error, "not found"} = Domain.one(id)
end
- test "with bad id: doesn't delete the Proposal", %{id: id} do
- assert {:error, "not found"} = Domain.delete(id)
+ test "with bad id: doesn't delete the Proposal" do
+ assert {:error, "not found"} = Domain.delete(Factory.id())
end
end
diff --git a/test/vf/proposal/type.test.exs b/test/vf/proposal/type.test.exs
@@ -43,61 +43,28 @@ fragment proposal on Proposal {
eligibleLocation {id}
}
"""
+
describe "Query" do
- test "proposal", %{inserted: prop} do
+ test "proposal", %{inserted: new} do
assert %{data: %{"proposal" => data}} =
run!("""
#{@frag}
query ($id: ID!) {
proposal(id: $id) {...proposal}
}
- """, vars: %{"id" => prop.id})
+ """, vars: %{"id" => new.id})
- assert data["id"] == prop.id
- assert data["name"] == prop.name
- assert data["note"] == prop.note
- assert data["unitBased"] == prop.unit_based
- assert data["eligibleLocation"]["id"] == prop.eligible_location_id
+ assert data["id"] == new.id
+ assert data["name"] == new.name
+ assert data["note"] == new.note
+ assert data["unitBased"] == new.unit_based
+ assert data["eligibleLocation"]["id"] == new.eligible_location_id
assert {:ok, has_beginning, 0} = DateTime.from_iso8601(data["hasBeginning"])
assert DateTime.compare(DateTime.utc_now(), has_beginning) != :lt
assert {:ok, has_end, 0} = DateTime.from_iso8601(data["hasEnd"])
assert DateTime.compare(DateTime.utc_now(), has_end) != :lt
end
- test "proposals" do
- assert %{data: %{"proposals" => data}} =
- run!("""
- #{@frag}
- query {
- proposals {
- pageInfo {
- startCursor
- endCursor
- hasPreviousPage
- hasNextPage
- totalCount
- pageLimit
- }
- edges {
- cursor
- node {...proposal}
- }
- }
- }
- """)
- assert %{
- "pageInfo" => %{
- "startCursor" => nil,
- "endCursor" => nil,
- "hasPreviousPage" => false,
- "hasNextPage" => false,
- "totalCount" => nil,
- "pageLimit" => nil,
- },
- "edges" => [],
- } = data
- end
-
test "offers" do
assert %{data: %{"offers" => data}} =
run!("""
@@ -185,7 +152,7 @@ describe "Mutation" do
assert data["eligibleLocation"]["id"] == params["eligibleLocation"]
end
- test "updateProposal", %{params: params, inserted: prop} do
+ test "updateProposal", %{params: params, inserted: old} do
assert %{data: %{"updateProposal" => %{"proposal" => data}}} =
run!("""
#{@frag}
@@ -194,9 +161,9 @@ describe "Mutation" do
proposal {...proposal}
}
}
- """, vars: %{"proposal" => params |> Map.put("id", prop.id)})
+ """, vars: %{"proposal" => Map.put(params, "id", old.id)})
- assert data["id"] == prop.id
+ assert data["id"] == old.id
keys = ~w[name note unitBased hasBeginning hasEnd]
assert Map.take(data, keys) == Map.take(params, keys)
assert data["eligibleLocation"]["id"] == params["eligibleLocation"]