mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 05:23:03 +12:00
adding some tests, working on relationship stateful changes
This commit is contained in:
parent
fc259c9012
commit
4e2e013f96
6 changed files with 154 additions and 52 deletions
|
@ -90,7 +90,7 @@ defmodule Ash.Api.Interface do
|
|||
end
|
||||
|
||||
:error ->
|
||||
{:error, "no such resource"}
|
||||
{:error, "no such resource #{resource}"}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -114,7 +114,7 @@ defmodule Ash.Api.Interface do
|
|||
end
|
||||
|
||||
:error ->
|
||||
{:error, "no such resource"}
|
||||
{:error, "no such resource #{resource}"}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -136,7 +136,7 @@ defmodule Ash.Api.Interface do
|
|||
end
|
||||
|
||||
:error ->
|
||||
{:error, "no such resource"}
|
||||
{:error, "no such resource #{resource}"}
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -158,7 +158,7 @@ defmodule Ash.Api.Interface do
|
|||
end
|
||||
|
||||
:error ->
|
||||
{:error, "no such resource"}
|
||||
{:error, "no such resource #{resource}"}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ defmodule Ash.DataLayer.Ets do
|
|||
|> Enum.reduce({:ok, []}, fn query, {:ok, records} ->
|
||||
case do_run_query(resource, query, limit + offset) do
|
||||
{:ok, results} -> {:ok, records ++ results}
|
||||
{:error, error} -> {:eror, error}
|
||||
{:error, error} -> {:error, error}
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -109,7 +109,7 @@ defmodule Ash.DataLayer.Ets do
|
|||
{:ok, match_spec} <- filter_to_matchspec(resource, filter),
|
||||
{:ok, table} <- wrap_or_create_table(resource),
|
||||
{:ok, results} <- match_limit(table, match_spec, limit) do
|
||||
{:ok, results}
|
||||
{:ok, Enum.map(results, &elem(&1, 1))}
|
||||
else
|
||||
%{errors: errors} ->
|
||||
{:error, errors}
|
||||
|
|
|
@ -45,10 +45,7 @@ defmodule Ash.Filter.Merge do
|
|||
# end
|
||||
|
||||
defp do_merge(left, right) do
|
||||
# There is no way this can reasonably fail
|
||||
{:ok, predicate} = And.prebuilt_new(left, right)
|
||||
|
||||
predicate
|
||||
And.prebuilt_new(left, right)
|
||||
end
|
||||
|
||||
## Equals + In filters
|
||||
|
|
|
@ -19,6 +19,8 @@ defmodule Ash.Type do
|
|||
|
||||
@builtins [
|
||||
string: [ecto_type: :string, filters: [:equal, :in], sortable?: true],
|
||||
integer: [ecto_type: :integer, filters: [:equal, :in], sortable?: true],
|
||||
int: [ecto_type: :integer, filters: [:equal, :in], sortable?: true],
|
||||
boolean: [ecto_type: :boolean, filters: [:equal], sortable?: true],
|
||||
uuid: [ecto_type: :binary_id, filters: [:equal, :in], sortable?: true],
|
||||
utc_datetime: [ecto_type: :utc_datetime, filters: [:equal, :in], sortable?: true]
|
||||
|
|
|
@ -45,36 +45,28 @@ defmodule Ash.Test.Actions.SideLoadTest do
|
|||
end
|
||||
|
||||
describe "side_loads" do
|
||||
# setup do
|
||||
# author = Api.create!(Author, attributes: %{name: "zerg"})
|
||||
setup do
|
||||
author = Api.create!(Author, attributes: %{name: "zerg"})
|
||||
|
||||
# post1 =
|
||||
# Api.create!(Post, attributes: %{title: "post1"}, relationships: %{author: author.id})
|
||||
post1 =
|
||||
Api.create!(Post, attributes: %{title: "post1"}, relationships: %{author: author.id})
|
||||
|
||||
# post2 =
|
||||
# Api.create!(Post, attributes: %{title: "post2"}, relationships: %{author: author.id})
|
||||
post2 =
|
||||
Api.create!(Post, attributes: %{title: "post2"}, relationships: %{author: author.id})
|
||||
|
||||
# %{post1: post1, post2: post2}
|
||||
# end
|
||||
|
||||
test "mything" do
|
||||
Api.read!(Author, filter: [or: [[name: "zach"], [posts: [id: Ecto.UUID.generate()]]]])
|
||||
%{post1: post1, post2: post2}
|
||||
end
|
||||
|
||||
# test "it allows sideloading related data", %{post1: post1, post2: post2} do
|
||||
# %{results: [author]} =
|
||||
# Api.read!(Author, side_load: [posts: [:author]], filter: [posts: [id: post1.id]])
|
||||
test "it allows sideloading related data", %{post1: post1, post2: post2} do
|
||||
%{results: [author]} =
|
||||
Api.read!(Author, side_load: [posts: [:author]], filter: [posts: [id: post1.id]])
|
||||
|
||||
# Api.read!(Author,
|
||||
# filter: [name: "zach", posts: [id: post1.id, title: "foo", contents: "bar"]]
|
||||
# )
|
||||
assert Enum.sort(Enum.map(author.posts, &Map.get(&1, :id))) ==
|
||||
Enum.sort([post1.id, post2.id])
|
||||
|
||||
# assert Enum.sort(Enum.map(author.posts, &Map.get(&1, :id))) ==
|
||||
# Enum.sort([post1.id, post2.id])
|
||||
|
||||
# for post <- author.posts do
|
||||
# assert post.author.id == author.id
|
||||
# end
|
||||
# end
|
||||
for post <- author.posts do
|
||||
assert post.author.id == author.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,6 +1,27 @@
|
|||
defmodule Ash.Test.Filter.FilterTest do
|
||||
use ExUnit.Case, async: true
|
||||
|
||||
defmodule Profile do
|
||||
use Ash.Resource, name: "profiles", type: "profile"
|
||||
use Ash.DataLayer.Ets, private?: true
|
||||
|
||||
actions do
|
||||
read :default
|
||||
create :default
|
||||
update :default
|
||||
end
|
||||
|
||||
attributes do
|
||||
attribute :bio, :string
|
||||
end
|
||||
|
||||
relationships do
|
||||
belongs_to :user, Ash.Test.Filter.FilterTest.User,
|
||||
source_field: :user_id,
|
||||
destination_field: :id
|
||||
end
|
||||
end
|
||||
|
||||
defmodule User do
|
||||
use Ash.Resource, name: "users", type: "user"
|
||||
use Ash.DataLayer.Ets, private?: true
|
||||
|
@ -8,6 +29,7 @@ defmodule Ash.Test.Filter.FilterTest do
|
|||
actions do
|
||||
read :default
|
||||
create :default
|
||||
update :default
|
||||
end
|
||||
|
||||
attributes do
|
||||
|
@ -17,6 +39,27 @@ defmodule Ash.Test.Filter.FilterTest do
|
|||
|
||||
relationships do
|
||||
has_many :posts, Ash.Test.Filter.FilterTest.Post
|
||||
|
||||
has_one :profile, Profile,
|
||||
destination_field: :user_id,
|
||||
source_field: :id
|
||||
end
|
||||
end
|
||||
|
||||
defmodule PostLink do
|
||||
use Ash.Resource, name: "post_links", type: "post_link", primary_key: false
|
||||
use Ash.DataLayer.Ets, private?: true
|
||||
|
||||
actions do
|
||||
read :default
|
||||
|
||||
create :default
|
||||
update :default
|
||||
end
|
||||
|
||||
relationships do
|
||||
belongs_to :source_post, Ash.Test.Filter.FilterTest.Post, primary_key?: true
|
||||
belongs_to :destination_post, Ash.Test.Filter.FilterTest.Post, primary_key?: true
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -28,11 +71,14 @@ defmodule Ash.Test.Filter.FilterTest do
|
|||
read :default
|
||||
|
||||
create :default
|
||||
|
||||
update :default
|
||||
end
|
||||
|
||||
attributes do
|
||||
attribute :title, :string
|
||||
attribute :contents, :string
|
||||
attribute :points, :integer
|
||||
end
|
||||
|
||||
relationships do
|
||||
|
@ -43,33 +89,98 @@ defmodule Ash.Test.Filter.FilterTest do
|
|||
belongs_to :author2, User,
|
||||
destination_field: :id,
|
||||
source_field: :author2_id
|
||||
|
||||
many_to_many :related_posts, __MODULE__,
|
||||
through: PostLink,
|
||||
source_field_on_join_table: :source_post_id,
|
||||
destination_field_on_join_table: :destination_post_id
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Api do
|
||||
use Ash.Api
|
||||
|
||||
resources [Post, Author]
|
||||
resources [Post, User, Profile]
|
||||
end
|
||||
|
||||
test "it works" do
|
||||
authorization_steps = [
|
||||
authorize_if: [author1: [id: 1]],
|
||||
forbid_if: [author1: [allow_second_author: false]],
|
||||
authorize_if: [author2: [id: 1]]
|
||||
]
|
||||
describe "simple attribute filters" do
|
||||
setup do
|
||||
post1 = Api.create!(Post, attributes: %{title: "title1", contents: "contents1", points: 1})
|
||||
post2 = Api.create!(Post, attributes: %{title: "title2", contents: "contents2", points: 2})
|
||||
|
||||
Ash.Filter.SatSolver.solve(Post, authorization_steps)
|
||||
%{post1: post1, post2: post2}
|
||||
end
|
||||
|
||||
# Api.read(Post,
|
||||
# filter: [
|
||||
# title: "foo",
|
||||
# title: "bar",
|
||||
# contents: [in: ["bar", "baz"]],
|
||||
# contents: [in: ["foo", "bar"]],
|
||||
# author1: [id: 1],
|
||||
# author2: [name: "bob"]
|
||||
# ]
|
||||
# )
|
||||
test "single filter field", %{post1: post1} do
|
||||
assert %{results: [^post1]} =
|
||||
Api.read!(Post,
|
||||
filter: [
|
||||
title: post1.title
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
test "multiple filter field matches", %{post1: post1} do
|
||||
assert %{results: [^post1]} =
|
||||
Api.read!(Post,
|
||||
filter: [
|
||||
title: post1.title,
|
||||
contents: post1.contents
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
test "no field matches" do
|
||||
assert %{results: []} =
|
||||
Api.read!(Post,
|
||||
filter: [
|
||||
title: "no match"
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
test "no field matches single record, but each matches one record", %{
|
||||
post1: post1,
|
||||
post2: post2
|
||||
} do
|
||||
assert %{results: []} =
|
||||
Api.read!(Post,
|
||||
filter: [
|
||||
title: post1.title,
|
||||
contents: post2.contents
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
describe "relationship filters" do
|
||||
setup do
|
||||
post1 = Api.create!(Post, attributes: %{title: "title1", contents: "contents1", points: 1})
|
||||
post2 = Api.create!(Post, attributes: %{title: "title2", contents: "contents2", points: 2})
|
||||
|
||||
# post3 =
|
||||
# Api.create!(Post,
|
||||
# attributes: %{title: "title3", contents: "contents3", points: 3},
|
||||
# relationships: %{related_posts: [post1, post2]}
|
||||
# )
|
||||
|
||||
profile1 = Api.create!(Profile, attributes: %{bio: "dope"})
|
||||
|
||||
user1 =
|
||||
Api.create!(User,
|
||||
attributes: %{name: "broseph"},
|
||||
relationships: %{posts: [post1, post2], profile: profile1}
|
||||
)
|
||||
|
||||
user2 = Api.create!(User, attributes: %{name: "broseph"}, relationships: %{posts: [post2]})
|
||||
|
||||
profile2 = Api.create!(Profile, attributes: %{bio: "dope2"}, relationships: %{user: user2})
|
||||
|
||||
%{post1: post1, post2: post2}
|
||||
end
|
||||
|
||||
test "it works" do
|
||||
assert true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue