2019-12-16 13:20:44 +13:00
|
|
|
defmodule Ash.Test.Filter.FilterTest do
|
|
|
|
use ExUnit.Case, async: true
|
|
|
|
|
2019-12-20 18:30:27 +13:00
|
|
|
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
|
2019-12-24 17:22:31 +13:00
|
|
|
belongs_to :user, Ash.Test.Filter.FilterTest.User
|
2019-12-20 18:30:27 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-12-16 13:20:44 +13:00
|
|
|
defmodule User do
|
|
|
|
use Ash.Resource, name: "users", type: "user"
|
|
|
|
use Ash.DataLayer.Ets, private?: true
|
|
|
|
|
|
|
|
actions do
|
|
|
|
read :default
|
|
|
|
create :default
|
2019-12-20 18:30:27 +13:00
|
|
|
update :default
|
2019-12-16 13:20:44 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
attributes do
|
|
|
|
attribute :name, :string
|
|
|
|
attribute :allow_second_author, :boolean
|
|
|
|
end
|
|
|
|
|
|
|
|
relationships do
|
2019-12-24 17:22:31 +13:00
|
|
|
has_many :posts, Ash.Test.Filter.FilterTest.Post,
|
|
|
|
reverse_relationship: :author1,
|
|
|
|
destination_field: :author1_id
|
2019-12-20 18:30:27 +13:00
|
|
|
|
2019-12-24 17:22:31 +13:00
|
|
|
has_many :second_posts, Ash.Test.Filter.FilterTest.Post,
|
|
|
|
reverse_relationship: :author2,
|
|
|
|
destination_field: :author1_id
|
|
|
|
|
|
|
|
has_one :profile, Profile
|
2019-12-20 18:30:27 +13:00
|
|
|
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
|
2019-12-16 13:20:44 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Post do
|
|
|
|
use Ash.Resource, name: "posts", type: "post"
|
|
|
|
use Ash.DataLayer.Ets, private?: true
|
|
|
|
|
|
|
|
actions do
|
|
|
|
read :default
|
|
|
|
|
|
|
|
create :default
|
2019-12-20 18:30:27 +13:00
|
|
|
|
|
|
|
update :default
|
2019-12-16 13:20:44 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
attributes do
|
|
|
|
attribute :title, :string
|
|
|
|
attribute :contents, :string
|
2019-12-20 18:30:27 +13:00
|
|
|
attribute :points, :integer
|
2019-12-16 13:20:44 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
relationships do
|
|
|
|
belongs_to :author1, User,
|
|
|
|
destination_field: :id,
|
|
|
|
source_field: :author1_id
|
|
|
|
|
|
|
|
belongs_to :author2, User,
|
|
|
|
destination_field: :id,
|
|
|
|
source_field: :author2_id
|
2019-12-20 18:30:27 +13:00
|
|
|
|
|
|
|
many_to_many :related_posts, __MODULE__,
|
|
|
|
through: PostLink,
|
|
|
|
source_field_on_join_table: :source_post_id,
|
2019-12-22 21:17:29 +13:00
|
|
|
destination_field_on_join_table: :destination_post_id,
|
|
|
|
reverse_relationship: :related_posts
|
2019-12-16 13:20:44 +13:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
defmodule Api do
|
|
|
|
use Ash.Api
|
|
|
|
|
2019-12-22 21:17:29 +13:00
|
|
|
resources [Post, User, Profile, PostLink]
|
2019-12-16 13:20:44 +13:00
|
|
|
end
|
|
|
|
|
2019-12-20 18:30:27 +13:00
|
|
|
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})
|
|
|
|
|
|
|
|
%{post1: post1, post2: post2}
|
|
|
|
end
|
|
|
|
|
|
|
|
test "single filter field", %{post1: post1} do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [^post1] =
|
2019-12-20 18:30:27 +13:00
|
|
|
Api.read!(Post,
|
|
|
|
filter: [
|
|
|
|
title: post1.title
|
|
|
|
]
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "multiple filter field matches", %{post1: post1} do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [^post1] =
|
2019-12-20 18:30:27 +13:00
|
|
|
Api.read!(Post,
|
|
|
|
filter: [
|
|
|
|
title: post1.title,
|
|
|
|
contents: post1.contents
|
|
|
|
]
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "no field matches" do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [] =
|
2019-12-20 18:30:27 +13:00
|
|
|
Api.read!(Post,
|
|
|
|
filter: [
|
|
|
|
title: "no match"
|
|
|
|
]
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
test "no field matches single record, but each matches one record", %{
|
|
|
|
post1: post1,
|
|
|
|
post2: post2
|
|
|
|
} do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [] =
|
2019-12-20 18:30:27 +13:00
|
|
|
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})
|
|
|
|
|
2019-12-22 21:17:29 +13:00
|
|
|
post3 =
|
|
|
|
Api.create!(Post,
|
|
|
|
attributes: %{title: "title3", contents: "contents3", points: 3},
|
|
|
|
relationships: %{related_posts: [post1, post2]}
|
|
|
|
)
|
2019-12-20 18:30:27 +13:00
|
|
|
|
2019-12-24 17:22:31 +13:00
|
|
|
post4 =
|
|
|
|
Api.create!(Post,
|
|
|
|
attributes: %{title: "title4", contents: "contents3", points: 4},
|
|
|
|
relationships: %{related_posts: [post3]}
|
|
|
|
)
|
|
|
|
|
2019-12-20 18:30:27 +13:00
|
|
|
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})
|
|
|
|
|
2019-12-22 22:06:33 +13:00
|
|
|
%{
|
2019-12-24 17:22:31 +13:00
|
|
|
post1: Api.reload!(post1),
|
|
|
|
post2: Api.reload!(post2),
|
|
|
|
post3: Api.reload!(post3),
|
|
|
|
post4: Api.reload!(post4),
|
|
|
|
profile1: Api.reload!(profile1),
|
|
|
|
user1: Api.reload!(user1),
|
|
|
|
user2: Api.reload!(user2),
|
|
|
|
profile2: Api.reload!(profile2)
|
2019-12-22 22:06:33 +13:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2019-12-24 17:22:31 +13:00
|
|
|
test "filtering on a has_one relationship", %{profile2: profile2, user2: user2} do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [^user2] = Api.read!(User, filter: [profile: profile2.id])
|
2019-12-24 17:22:31 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "filtering on a belongs_to relationship", %{profile1: profile1, user1: user1} do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [^profile1] = Api.read!(Profile, filter: [user: user1.id])
|
2019-12-24 17:22:31 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "filtering on a has_many relationship", %{user2: user2, post2: post2} do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [^user2] = Api.read!(User, filter: [posts: post2.id])
|
2019-12-24 17:22:31 +13:00
|
|
|
end
|
|
|
|
|
|
|
|
test "filtering on a many_to_many relationship", %{post4: post4, post3: post3} do
|
2020-05-10 14:23:23 +12:00
|
|
|
assert [^post4] = Api.read!(Post, filter: [related_posts: post3.id])
|
2019-12-24 17:22:31 +13:00
|
|
|
end
|
2019-12-16 13:20:44 +13:00
|
|
|
end
|
|
|
|
end
|