mirror of
https://github.com/ash-project/ash.git
synced 2024-09-19 21:13:10 +12:00
WIP
This commit is contained in:
parent
dd081977a0
commit
af40b830fc
6 changed files with 120 additions and 45 deletions
|
@ -5,11 +5,11 @@ defmodule Ash.Api.Interface do
|
|||
Ash.Api.Interface.get(__MODULE__, resource, id, params)
|
||||
end
|
||||
|
||||
def read(resource, params) do
|
||||
def read(resource, params \\ %{}) do
|
||||
Ash.Api.Interface.read(__MODULE__, resource, params)
|
||||
end
|
||||
|
||||
def create(resource, params) do
|
||||
def create(resource, params \\ %{}) do
|
||||
Ash.Api.Interface.create(__MODULE__, resource, params)
|
||||
end
|
||||
end
|
||||
|
@ -65,11 +65,17 @@ defmodule Ash.Api.Interface do
|
|||
end
|
||||
|
||||
defp add_default_page_size(api, params) do
|
||||
params
|
||||
|> Map.update(
|
||||
:page,
|
||||
%{limit: api.default_page_size},
|
||||
&Map.put(&1, :limit, api.default_page_size)
|
||||
)
|
||||
case api.default_page_size() do
|
||||
nil ->
|
||||
params
|
||||
|
||||
page_size ->
|
||||
Map.update(
|
||||
params,
|
||||
:page,
|
||||
%{limit: api.default_page_size},
|
||||
&Map.put(&1, :limit, page_size)
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -84,7 +84,7 @@ defmodule Ash.DataLayer.Actions do
|
|||
end
|
||||
end
|
||||
|
||||
def run_create_action(resource, action, params, api) do
|
||||
def run_create_action(resource, action, api, params) do
|
||||
auth_context = %{
|
||||
resource: resource,
|
||||
action: action,
|
||||
|
|
61
lib/test.ex
Normal file
61
lib/test.ex
Normal file
|
@ -0,0 +1,61 @@
|
|||
defmodule Ash.Test do
|
||||
defmacro test_resource(name, type, opts \\ [], do: block) do
|
||||
quote do
|
||||
module_name = Module.concat(__MODULE__, String.capitalize(unquote(name)))
|
||||
|
||||
Module.put_attribute(
|
||||
__MODULE__,
|
||||
unquote(opts[:attr]) || String.to_atom(unquote(name)),
|
||||
module_name
|
||||
)
|
||||
|
||||
defmodule module_name do
|
||||
use Ash.Resource, name: unquote(name), type: unquote(type)
|
||||
use Ash.DataLayer.Ets, private?: true
|
||||
unquote(block)
|
||||
end
|
||||
|
||||
module_name
|
||||
end
|
||||
end
|
||||
|
||||
defmacro test_api(opts, do: block) do
|
||||
quote do
|
||||
opts = unquote(opts)
|
||||
module_name = Module.concat(__MODULE__, Api)
|
||||
Module.put_attribute(__MODULE__, opts[:attr] || :api, module_name)
|
||||
|
||||
resources =
|
||||
Enum.map(
|
||||
opts[:resources],
|
||||
fn
|
||||
{:@, _, [{attr, _, nil}]} ->
|
||||
Module.get_attribute(__MODULE__, attr)
|
||||
|
||||
resource when is_atom(resource) ->
|
||||
Module.get_attribute(__MODULE__, resource) || resource
|
||||
end
|
||||
)
|
||||
|
||||
defmodule module_name do
|
||||
use Ash.Api
|
||||
|
||||
api do
|
||||
resources resources
|
||||
end
|
||||
|
||||
unquote(block)
|
||||
end
|
||||
|
||||
module_name
|
||||
end
|
||||
end
|
||||
|
||||
defmacro test_api(opts) do
|
||||
quote do
|
||||
test_api(unquote(opts)) do
|
||||
:ok
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,70 +1,91 @@
|
|||
defmodule Ash.Test.Actions.Read do
|
||||
defmodule Ash.Test.Actions.ReadTest do
|
||||
use ExUnit.Case, async: true
|
||||
# import Ash.Test
|
||||
|
||||
alias Ash.Test.Post
|
||||
defmodule Post do
|
||||
use Ash.Resource, name: "posts", type: "post"
|
||||
use Ash.DataLayer.Ets, private?: true
|
||||
|
||||
describe "Ash.get/3" do
|
||||
actions do
|
||||
defaults [:read, :create]
|
||||
end
|
||||
|
||||
attributes do
|
||||
attribute :title, :string
|
||||
attribute :contents, :string
|
||||
end
|
||||
end
|
||||
|
||||
defmodule Api do
|
||||
use Ash.Api
|
||||
|
||||
api do
|
||||
resources [Post]
|
||||
end
|
||||
end
|
||||
|
||||
describe "api.get/3" do
|
||||
setup do
|
||||
{:ok, post} = Ash.create(Post, %{attributes: %{title: "test", contents: "yeet"}})
|
||||
{:ok, post} = Api.create(Post, %{attributes: %{title: "test", contents: "yeet"}})
|
||||
%{post: post}
|
||||
end
|
||||
|
||||
test "it returns a matching record", %{post: post} do
|
||||
assert {:ok, fetched_post} = Ash.get(Post, post.id)
|
||||
assert {:ok, fetched_post} = Api.get(Post, post.id)
|
||||
|
||||
assert fetched_post == post
|
||||
end
|
||||
|
||||
test "it returns nil when there is no matching record" do
|
||||
assert {:ok, nil} = Ash.get(Post, Ash.UUID.generate())
|
||||
assert {:ok, nil} = Api.get(Post, Ash.UUID.generate())
|
||||
end
|
||||
end
|
||||
|
||||
describe "Ash.read/2 with no records" do
|
||||
test "returns an empty result" do
|
||||
assert {:ok, %{results: []}} = Ash.read(Post)
|
||||
assert {:ok, %{results: []}} = Api.read(Post)
|
||||
end
|
||||
end
|
||||
|
||||
describe "Ash.read/2" do
|
||||
setup do
|
||||
{:ok, post1} = Ash.create(Post, %{attributes: %{title: "test", contents: "yeet"}})
|
||||
{:ok, post2} = Ash.create(Post, %{attributes: %{title: "test1", contents: "yeet2"}})
|
||||
{:ok, post1} = Api.create(Post, %{attributes: %{title: "test", contents: "yeet"}})
|
||||
{:ok, post2} = Api.create(Post, %{attributes: %{title: "test1", contents: "yeet2"}})
|
||||
|
||||
%{post1: post1, post2: post2}
|
||||
end
|
||||
|
||||
test "with page size of 1, returns only 1 record" do
|
||||
assert {:ok, %{results: [_post]}} = Ash.read(Post, %{page: %{limit: 1}})
|
||||
assert {:ok, %{results: [_post]}} = Api.read(Post, %{page: %{limit: 1}})
|
||||
end
|
||||
|
||||
test "with page size of 2, returns 2 records" do
|
||||
assert {:ok, %{results: [_, _]}} = Ash.read(Post, %{page: %{limit: 2}})
|
||||
assert {:ok, %{results: [_, _]}} = Api.read(Post, %{page: %{limit: 2}})
|
||||
end
|
||||
|
||||
test "with page size of 1 and an offset of 1, it returns 1 record" do
|
||||
assert {:ok, %{results: [_]}} = Ash.read(Post, %{page: %{limit: 1, offset: 1}})
|
||||
assert {:ok, %{results: [_]}} = Api.read(Post, %{page: %{limit: 1, offset: 1}})
|
||||
end
|
||||
end
|
||||
|
||||
describe "filters" do
|
||||
setup do
|
||||
{:ok, post1} = Ash.create(Post, %{attributes: %{title: "test", contents: "yeet"}})
|
||||
{:ok, post2} = Ash.create(Post, %{attributes: %{title: "test1", contents: "yeet"}})
|
||||
{:ok, post1} = Api.create(Post, %{attributes: %{title: "test", contents: "yeet"}})
|
||||
{:ok, post2} = Api.create(Post, %{attributes: %{title: "test1", contents: "yeet"}})
|
||||
|
||||
%{post1: post1, post2: post2}
|
||||
end
|
||||
|
||||
test "a filter that matches nothing returns no results" do
|
||||
assert {:ok, %{results: []}} = Ash.read(Post, %{filter: %{contents: "not_yeet"}})
|
||||
assert {:ok, %{results: []}} = Api.read(Post, %{filter: %{contents: "not_yeet"}})
|
||||
end
|
||||
|
||||
test "a filter returns only matching records", %{post1: post1} do
|
||||
assert {:ok, %{results: [^post1]}} = Ash.read(Post, %{filter: %{title: post1.title}})
|
||||
assert {:ok, %{results: [^post1]}} = Api.read(Post, %{filter: %{title: post1.title}})
|
||||
end
|
||||
|
||||
test "a filter returns multiple records if they match", %{post1: post1, post2: post2} do
|
||||
assert {:ok, %{results: [_, _] = results}} = Ash.read(Post, %{filter: %{contents: "yeet"}})
|
||||
assert {:ok, %{results: [_, _] = results}} = Api.read(Post, %{filter: %{contents: "yeet"}})
|
||||
|
||||
assert post1 in results
|
||||
assert post2 in results
|
||||
|
@ -73,8 +94,8 @@ defmodule Ash.Test.Actions.Read do
|
|||
|
||||
describe "sort" do
|
||||
setup do
|
||||
{:ok, post1} = Ash.create(Post, %{attributes: %{title: "abc", contents: "abc"}})
|
||||
{:ok, post2} = Ash.create(Post, %{attributes: %{title: "xyz", contents: "abc"}})
|
||||
{:ok, post1} = Api.create(Post, %{attributes: %{title: "abc", contents: "abc"}})
|
||||
{:ok, post2} = Api.create(Post, %{attributes: %{title: "xyz", contents: "abc"}})
|
||||
|
||||
%{post1: post1, post2: post2}
|
||||
end
|
||||
|
@ -83,21 +104,21 @@ defmodule Ash.Test.Actions.Read do
|
|||
post1: post1,
|
||||
post2: post2
|
||||
} do
|
||||
assert {:ok, %{results: [^post1, ^post2]}} = Ash.read(Post, %{sort: [asc: :title]})
|
||||
assert {:ok, %{results: [^post1, ^post2]}} = Api.read(Post, %{sort: [asc: :title]})
|
||||
end
|
||||
|
||||
test "a sort will sor rows accordingly when descending", %{
|
||||
post1: post1,
|
||||
post2: post2
|
||||
} do
|
||||
assert {:ok, %{results: [^post2, ^post1]}} = Ash.read(Post, %{sort: [desc: :title]})
|
||||
assert {:ok, %{results: [^post2, ^post1]}} = Api.read(Post, %{sort: [desc: :title]})
|
||||
end
|
||||
|
||||
test "a nested sort sorts accordingly", %{post1: post1, post2: post2} do
|
||||
{:ok, middle_post} = Ash.create(Post, %{attributes: %{title: "abc", contents: "xyz"}})
|
||||
{:ok, middle_post} = Api.create(Post, %{attributes: %{title: "abc", contents: "xyz"}})
|
||||
|
||||
assert {:ok, %{results: [^post1, ^middle_post, ^post2]}} =
|
||||
Ash.read(Post, %{sort: [asc: :title, asc: :contents]})
|
||||
Api.read(Post, %{sort: [asc: :title, asc: :contents]})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
0
test/support/.gitkeep
Normal file
0
test/support/.gitkeep
Normal file
|
@ -1,13 +0,0 @@
|
|||
defmodule Ash.Test.Post do
|
||||
use Ash.Resource, name: "posts", type: "post"
|
||||
use Ash.DataLayer.Ets, private?: true
|
||||
|
||||
actions do
|
||||
defaults [:read, :create]
|
||||
end
|
||||
|
||||
attributes do
|
||||
attribute :title, :string
|
||||
attribute :contents, :string
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue