Commit 5375b55b authored by Antonis Kalou's avatar Antonis Kalou

Add the remainder of claims context + tests

parent 4dc23f7f
......@@ -63,14 +63,26 @@ defmodule ValueFlows.Claim do
receiver_id: receiver.id,
is_public: true
)
|> change_measures(attrs)
|> common_changeset()
|> common_changeset(attrs)
end
def update_changeset(%__MODULE__{} = claim, attrs) do
claim
|> Changeset.cast(attrs, @cast)
|> common_changeset(attrs)
end
def validate_required(changeset) do
Changeset.validate_required(changeset, @required)
end
defp common_changeset(changeset, attrs) do
changeset
|> change_measures(attrs)
|> change_public()
|> change_disabled()
end
def change_measures(changeset, %{} = attrs) do
measures = Map.take(attrs, measure_fields())
......@@ -79,11 +91,5 @@ defmodule ValueFlows.Claim do
end)
end
defp common_changeset(changeset) do
changeset
|> change_public()
|> change_disabled()
end
def measure_fields, do: [:resource_quantity, :effort_quantity]
end
......@@ -15,19 +15,11 @@ defmodule ValueFlows.Claim.Claims do
def many(filters \\ []), do: {:ok, Repo.all(Queries.query(Claim, filters))}
def preload_all(%Claim{} = claim) do
Repo.preload(claim, [
:creator,
:provider,
:receiver,
:context,
:resource_conforms_to,
:resource_quantity,
:effort_quantity,
:triggered_by,
])
# shouldn't fail
{:ok, claim} = one(id: claim.id, preload: :all)
claim
end
# TODO: change attributes and then pass to changeset, use preload for rest
def create(%User{} = creator, %{id: _} = provider, %{id: _} = receiver, %{} = attrs) do
Repo.transact_with(fn ->
attrs = prepare_attrs(attrs)
......@@ -42,12 +34,19 @@ defmodule ValueFlows.Claim.Claims do
end)
end
def update(%Claim{} = claim, %{} = _attrs) do
{:ok, claim}
def update(%Claim{} = claim, %{} = attrs) do
Repo.transact_with(fn ->
attrs = prepare_attrs(attrs)
claim
|> Claim.update_changeset(attrs)
|> Repo.update()
|> CommonsPub.Common.maybe_ok_error(&preload_all/1)
end)
end
def soft_delete(%Claim{} = claim) do
{:ok, claim}
CommonsPub.Common.Deletion.soft_delete(claim)
end
defp prepare_attrs(attrs) do
......
# SPDX-License-Identifier: AGPL-3.0-only
defmodule ValueFlows.Claim.Queries do
import CommonsPub.Common.Query, only: [match_admin: 0]
import Ecto.Query
alias CommonsPub.Follows.Follow
alias CommonsPub.Users.User
alias ValueFlows.Claim
def query(Claim) do
......@@ -27,6 +30,13 @@ defmodule ValueFlows.Claim.Queries do
join(q, jq, [claim: c], c2 in assoc(c, :context), as: :context)
end
def join_to(q, {:follow, follower_id}, jq) do
join(q, jq, [claim: c], f in Follow,
as: :follow,
on: c.id == f.context_id and f.creator_id == ^follower_id
)
end
def filter(q, filters) when is_list(filters) do
Enum.reduce(filters, q, &filter(&2, &1))
end
......@@ -34,6 +44,8 @@ defmodule ValueFlows.Claim.Queries do
def filter(q, {:join, {join, qual}}), do: join_to(q, join, qual)
def filter(q, {:join, join}), do: join_to(q, join)
## by status
def filter(q, :default) do
filter(q, [:deleted])
end
......@@ -42,6 +54,31 @@ defmodule ValueFlows.Claim.Queries do
where(q, [claim: c], is_nil(c.deleted_at))
end
def filter(q, :disabled) do
where(q, [claim: c], is_nil(c.disabled_at))
end
def filter(q, :private) do
where(q, [claim: c], not is_nil(c.published_at))
end
## by user
def filter(q, {:creator, match_admin()}), do: q
def filter(q, {:creator, nil}) do
filter(q, ~w(disabled private)a)
end
def filter(q, {:creator, %User{id: id}}) do
q
|> join_to(follow: id)
|> where([claim: c, follow: f], not is_nil(c.published_at) or not is_nil(f.id))
|> filter(~w(disabled)a)
end
## by field values
def filter(q, {:id, id}) when is_binary(id) do
where(q, [claim: c], c.id == ^id)
end
......@@ -49,4 +86,51 @@ defmodule ValueFlows.Claim.Queries do
def filter(q, {:id, ids}) when is_list(ids) do
where(q, [claim: c], c.id in ^ids)
end
def filter(q, {:provider_id, id}) when is_binary(id) do
where(q, [claim: c], c.provider_id == ^id)
end
def filter(q, {:provider_id, ids}) when is_list(ids) do
where(q, [claim: c], c.provider_id in ^ids)
end
def filter(q, {:receiver_id, id}) when is_binary(id) do
where(q, [claim: c], c.receiver_id == ^id)
end
def filter(q, {:receiver_id, ids}) when is_list(ids) do
where(q, [claim: c], c.receiver_id in ^ids)
end
def filter(q, {:context_id, id}) when is_binary(id) do
where(q, [claim: c], c.context_id == ^id)
end
def filter(q, {:context_id, ids}) when is_list(ids) do
where(q, [claim: c], c.context_id in ^ids)
end
def filter(q, {:action_id, ids}) when is_list(ids) do
where(q, [claim: c], c.action_id in ^ids)
end
def filter(q, {:action_id, id}) when is_binary(id) do
where(q, [claim: c], c.action_id == ^id)
end
## preloading
def filter(q, {:preload, :all}) do
preload(q, [
:creator,
:provider,
:receiver,
:resource_conforms_to,
:resource_quantity,
:effort_quantity,
:context,
:triggered_by,
])
end
end
......@@ -8,9 +8,9 @@ defmodule ValueFlows.Simulate do
import Measurement.Simulate
alias ValueFlows.Claim.Claims
alias ValueFlows.Planning.Intent.Intents
alias ValueFlows.Proposal.Proposals
# alias ValueFlows.Proposal.ProposedIntent
alias ValueFlows.Observation.EconomicEvent.EconomicEvents
alias ValueFlows.Observation.EconomicResource.EconomicResources
alias ValueFlows.Observation.Process.Processes
......@@ -223,6 +223,16 @@ defmodule ValueFlows.Simulate do
|> Map.put_new_lazy("effort_quantity", fn -> measure_input(unit) end)
end
@doc "Shorter version of fake_claim!/4, but instead generates a provider and receiver."
def fake_claim!(user, overrides \\ %{}) do
fake_claim!(user, fake_user!(), fake_user!(), overrides)
end
def fake_claim!(user, provider, receiver, overrides \\ %{}) do
{:ok, claim} = Claims.create(user, provider, receiver, claim(overrides))
claim
end
def fake_intent!(user, unit \\ nil, context \\ nil, overrides \\ %{})
def fake_intent!(user, unit, context, overrides) when is_nil(unit) do
......
......@@ -8,6 +8,81 @@ defmodule ValueFlows.Claim.ClaimsTest do
alias ValueFlows.Claim.Claims
describe "one" do
test "by id" do
claim = fake_claim!(fake_user!())
assert {:ok, fetched} = Claims.one(id: claim.id)
assert_claim(fetched)
assert claim.id == fetched.id
end
test "by action" do
action_id = action_id()
claim = fake_claim!(fake_user!(), %{action: action_id})
assert {:ok, fetched} = Claims.one(action_id: action_id)
assert_claim(fetched)
assert claim.action_id == fetched.action_id
end
test "by user" do
user = fake_user!()
claim = fake_claim!(user)
assert {:ok, fetched} = Claims.one(creator: user)
assert_claim(fetched)
assert claim.id == fetched.id
assert claim.creator_id == fetched.creator_id
end
test "by provider" do
user = fake_user!()
provider = fake_user!()
receiver = fake_user!()
claim = fake_claim!(user, provider, receiver)
assert {:ok, fetched} = Claims.one(provider_id: provider.id)
assert_claim(fetched)
assert claim.id == fetched.id
assert claim.provider_id == fetched.provider_id
end
test "by receiver" do
user = fake_user!()
provider = fake_user!()
receiver = fake_user!()
claim = fake_claim!(user, provider, receiver)
assert {:ok, fetched} = Claims.one(receiver_id: receiver.id)
assert_claim(fetched)
assert claim.id == fetched.id
assert claim.receiver_id == fetched.receiver_id
end
test "by context" do
user = fake_user!()
context = fake_community!(user)
claim = fake_claim!(user, %{in_scope_of: [context.id]})
assert {:ok, fetched} = Claims.one(context_id: context.id)
assert_claim(fetched)
assert claim.id == fetched.id
assert claim.context_id == fetched.context_id
end
test "default filter handles deleted items" do
claim = fake_claim!(fake_user!())
assert {:ok, claim} = Claims.soft_delete(claim)
assert {:error, %CommonsPub.Common.NotFoundError{}} = Claims.one([:default, id: claim.id])
end
end
describe "many" do
end
describe "create" do
test "with only required parameters" do
user = fake_user!()
......@@ -80,4 +155,85 @@ defmodule ValueFlows.Claim.ClaimsTest do
assert claim.triggered_by.id == attrs.triggered_by
end
end
describe "update" do
test "can update an existing claim" do
user = fake_user!()
claim = fake_claim!(user)
assert {:ok, updated} = Claims.update(claim, claim())
assert_claim(updated)
assert updated.id == claim.id
assert updated != claim
end
test "with a context" do
user = fake_user!()
claim = fake_claim!(user)
context = fake_community!(user)
assert {:ok, updated} = Claims.update(claim, %{in_scope_of: [context.id]})
assert_claim(updated)
assert updated.context.id == context.id
end
test "with measure quantities" do
user = fake_user!()
claim = fake_claim!(user)
unit = fake_unit!(user)
attrs = %{
resource_quantity: measure(%{unit_id: unit.id}),
effort_quantity: measure(%{unit_id: unit.id}),
}
assert {:ok, updated} = Claims.update(claim, attrs)
assert_claim(updated)
assert updated.resource_quantity.id
assert updated.effort_quantity.id
end
test "with a resource specification" do
user = fake_user!()
claim = fake_claim!(user)
attrs = %{
resource_conforms_to: fake_resource_specification!(user).id
}
assert {:ok, updated} = Claims.update(claim, attrs)
assert_claim(updated)
assert attrs.resource_conforms_to == updated.resource_conforms_to.id
end
test "with a triggered by event" do
user = fake_user!()
claim = fake_claim!(user)
attrs = %{
triggered_by: fake_economic_event!(user).id
}
assert {:ok, updated} = Claims.update(claim, attrs)
assert_claim(updated)
assert attrs.triggered_by == updated.triggered_by.id
end
end
describe "soft_delete" do
test "can delete an existing claim" do
claim = fake_claim!(fake_user!())
refute claim.deleted_at
assert {:ok, claim} = Claims.soft_delete(claim)
assert claim.deleted_at
end
test "fails if the claim doesn't exist" do
claim = fake_claim!(fake_user!())
assert {:ok, claim} = Claims.soft_delete(claim)
assert {:error, %CommonsPub.Common.DeletionError{}} = Claims.soft_delete(claim)
end
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment