2019-12-07 09:54:30 +13:00
defmodule Ash.Test.Resource.Relationships.BelongsToTest do
2020-06-02 17:47:25 +12:00
@moduledoc false
2019-12-06 20:00:26 +13:00
use ExUnit.Case , async : true
2020-11-03 09:33:14 +13:00
alias Ash.Resource.Relationships.BelongsTo
2019-12-06 20:00:26 +13:00
defmacrop defposts ( do : body ) do
quote do
defmodule Post do
2020-06-02 17:47:25 +12:00
@moduledoc false
2021-01-13 09:05:56 +13:00
use Ash.Resource , data_layer : Ash.DataLayer.Ets
2019-12-06 20:00:26 +13:00
2020-06-30 16:31:07 +12:00
attributes do
2021-01-13 09:40:55 +13:00
uuid_primary_key :id
2020-06-30 16:31:07 +12:00
end
2019-12-06 20:00:26 +13:00
unquote ( body )
end
end
end
2022-10-31 10:40:10 +13:00
defmacrop defcomments ( do : body ) do
quote do
defmodule Comment do
@moduledoc false
use Ash.Resource , data_layer : Ash.DataLayer.Ets
attributes do
uuid_primary_key :id
end
unquote ( body )
end
end
end
2019-12-06 20:00:26 +13:00
describe " representation " do
test " it creates an attribute " do
defposts do
relationships do
2020-07-16 09:06:27 +12:00
belongs_to ( :foobar , FooBar )
2019-12-06 20:00:26 +13:00
end
end
assert [
2021-07-27 12:55:44 +12:00
_ ,
2020-06-14 18:39:11 +12:00
% Ash.Resource.Attribute {
2019-12-06 20:00:26 +13:00
name : :foobar_id ,
primary_key? : false ,
2020-11-03 09:33:14 +13:00
type : Ash.Type.UUID ,
private? : true
2021-07-27 12:55:44 +12:00
}
2021-02-23 14:29:31 +13:00
] = Ash.Resource.Info . attributes ( Post )
2020-11-03 09:33:14 +13:00
end
test " it creates an attribute that honors private? " do
defposts do
relationships do
belongs_to ( :foobar , FooBar , private? : true )
end
end
assert [
2021-07-27 12:55:44 +12:00
_ ,
2020-11-03 09:33:14 +13:00
% Ash.Resource.Attribute {
name : :foobar_id ,
primary_key? : false ,
type : Ash.Type.UUID ,
private? : true
2021-07-27 12:55:44 +12:00
}
2021-02-23 14:29:31 +13:00
] = Ash.Resource.Info . attributes ( Post )
2019-12-06 20:00:26 +13:00
end
2022-07-07 00:29:46 +12:00
test " it creates an attribute that honors attribute_writable? " do
defposts do
relationships do
belongs_to ( :foobar , FooBar , attribute_writable? : true )
end
end
assert [
_ ,
% Ash.Resource.Attribute {
name : :foobar_id ,
primary_key? : false ,
type : Ash.Type.UUID ,
writable? : true
}
] = Ash.Resource.Info . attributes ( Post )
end
2019-12-06 20:00:26 +13:00
test " it creates a relationship " do
defposts do
relationships do
2020-11-03 09:33:14 +13:00
belongs_to ( :foo , Foo )
2022-08-16 06:00:02 +12:00
belongs_to ( :bar , Bar , source_attribute : :bazz , private? : true )
2019-12-06 20:00:26 +13:00
end
end
assert [
2020-11-03 09:33:14 +13:00
% BelongsTo {
2019-12-06 20:00:26 +13:00
cardinality : :one ,
2022-08-16 06:00:02 +12:00
define_attribute? : true ,
2020-11-03 09:33:14 +13:00
destination : Foo ,
2022-08-16 06:00:02 +12:00
destination_attribute : :id ,
attribute_type : :uuid ,
2020-11-03 09:33:14 +13:00
name : :foo ,
2019-12-06 20:00:26 +13:00
primary_key? : false ,
2022-08-16 06:00:02 +12:00
source_attribute : :foo_id ,
2020-11-03 09:33:14 +13:00
type : :belongs_to ,
private? : false
} ,
% BelongsTo {
cardinality : :one ,
2022-08-16 06:00:02 +12:00
define_attribute? : true ,
2020-11-03 09:33:14 +13:00
destination : Bar ,
2022-08-16 06:00:02 +12:00
destination_attribute : :id ,
attribute_type : :uuid ,
2020-11-03 09:33:14 +13:00
name : :bar ,
primary_key? : false ,
2022-08-16 06:00:02 +12:00
source_attribute : :bazz ,
2020-11-03 09:33:14 +13:00
type : :belongs_to ,
private? : true
2019-12-06 20:00:26 +13:00
}
2021-02-23 14:29:31 +13:00
] = Ash.Resource.Info . relationships ( Post )
2020-11-03 09:33:14 +13:00
2021-02-23 14:29:31 +13:00
assert [ % BelongsTo { name : :foo } ] = Ash.Resource.Info . public_relationships ( Post )
2020-11-03 09:33:14 +13:00
2021-02-23 14:29:31 +13:00
assert % BelongsTo { name : :foo } = Ash.Resource.Info . public_relationship ( Post , :foo )
2020-11-03 09:33:14 +13:00
2021-02-23 14:29:31 +13:00
assert nil == Ash.Resource.Info . relationship ( Post , :definitely_legit_relationship )
2020-11-03 09:33:14 +13:00
2021-02-23 14:29:31 +13:00
assert nil == Ash.Resource.Info . public_relationship ( Post , :bar )
2019-12-06 20:00:26 +13:00
end
end
describe " validations " do
2022-08-16 06:00:02 +12:00
test " fails if destination_attribute is not an atom " do
2019-12-06 20:00:26 +13:00
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2022-08-16 06:00:02 +12:00
" [Ash.Test.Resource.Relationships.BelongsToTest.Post] \n relationships -> belongs_to -> foobar: \n expected :destination_attribute to be an atom, got: \" foo \" " ,
2019-12-06 20:00:26 +13:00
fn ->
defposts do
relationships do
2022-08-16 06:00:02 +12:00
belongs_to ( :foobar , FooBar , destination_attribute : " foo " )
2019-12-06 20:00:26 +13:00
end
end
end
)
end
2022-08-16 06:00:02 +12:00
test " fails if source_attribute is not an atom " do
2019-12-06 20:00:26 +13:00
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2022-08-16 06:00:02 +12:00
" [Ash.Test.Resource.Relationships.BelongsToTest.Post] \n relationships -> belongs_to -> foobar: \n expected :source_attribute to be an atom, got: \" foo \" " ,
2019-12-06 20:00:26 +13:00
fn ->
defposts do
relationships do
2022-08-16 06:00:02 +12:00
belongs_to ( :foobar , FooBar , source_attribute : " foo " )
2019-12-06 20:00:26 +13:00
end
end
end
)
end
test " fails if the destination is not an atom " do
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2022-03-16 10:41:25 +13:00
" [Ash.Test.Resource.Relationships.BelongsToTest.Post] \n relationships -> belongs_to -> foobar: \n expected :destination to be an atom, got: \" foobar \" " ,
2019-12-06 20:00:26 +13:00
fn ->
defposts do
relationships do
2020-07-16 09:06:27 +12:00
belongs_to ( :foobar , " foobar " )
2019-12-06 20:00:26 +13:00
end
end
end
)
end
test " fails if the relationship name is not an atom " do
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2022-03-16 10:41:25 +13:00
" [Ash.Test.Resource.Relationships.BelongsToTest.Post] \n relationships -> belongs_to -> foobar: \n expected :name to be an atom, got: \" foobar \" " ,
2019-12-06 20:00:26 +13:00
fn ->
defposts do
relationships do
2020-07-16 09:06:27 +12:00
belongs_to ( " foobar " , Foobar )
2019-12-06 20:00:26 +13:00
end
end
end
)
end
test " fails if `primary_key?` is not a boolean " do
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2022-03-16 10:41:25 +13:00
" [Ash.Test.Resource.Relationships.BelongsToTest.Post] \n relationships -> belongs_to -> foobar: \n expected :primary_key? to be a boolean, got: \" blah \" " ,
2019-12-06 20:00:26 +13:00
fn ->
defposts do
relationships do
2020-07-16 09:06:27 +12:00
belongs_to ( :foobar , Foobar , primary_key? : " blah " )
2019-12-06 20:00:26 +13:00
end
end
end
)
end
2020-11-03 09:33:14 +13:00
test " fails if `private?` is not a boolean " do
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2022-03-16 10:41:25 +13:00
" [Ash.Test.Resource.Relationships.BelongsToTest.Post] \n relationships -> belongs_to -> foobar: \n expected :private? to be a boolean, got: \" blah \" " ,
2020-11-03 09:33:14 +13:00
fn ->
defposts do
relationships do
belongs_to ( :foobar , Foobar , private? : " blah " )
end
end
end
)
end
2019-12-06 20:00:26 +13:00
end
2022-08-16 06:00:02 +12:00
test " fails if `define_attribute?` is not a boolean " do
2019-12-06 20:00:26 +13:00
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2022-08-16 06:00:02 +12:00
" [Ash.Test.Resource.Relationships.BelongsToTest.Post] \n relationships -> belongs_to -> foobar: \n expected :define_attribute? to be a boolean, got: \" blah \" " ,
2019-12-06 20:00:26 +13:00
fn ->
defposts do
relationships do
2022-08-16 06:00:02 +12:00
belongs_to ( :foobar , Foobar , define_attribute? : " blah " )
2019-12-06 20:00:26 +13:00
end
end
end
)
end
2020-07-12 18:25:53 +12:00
test " fails in api initialization if the destination resource doesn't have the correct field " do
2020-07-09 16:20:32 +12:00
assert_raise (
2022-08-15 06:06:58 +12:00
Spark.Error.DslError ,
2020-07-09 16:20:32 +12:00
~r/ Relationship `post` expects source field `post_id` to be defined / ,
fn ->
defposts do
relationships do
2022-08-16 06:00:02 +12:00
belongs_to ( :post , __MODULE__ , define_attribute? : false )
2020-07-09 16:20:32 +12:00
end
end
2020-07-12 18:25:53 +12:00
2021-10-07 19:41:02 +13:00
defmodule Registry do
@moduledoc false
use Ash.Registry
entries do
entry Post
end
end
2020-07-12 18:25:53 +12:00
defmodule Api do
use Ash.Api
resources do
2021-10-07 19:41:02 +13:00
registry Registry
2020-07-12 18:25:53 +12:00
end
end
2020-07-09 16:20:32 +12:00
end
)
end
2022-10-31 10:40:10 +13:00
test " don't add required error for belongs_to if other errors are present " do
defposts do
relationships do
has_many ( :comments , Comment )
end
end
defcomments do
actions do
defaults [ :create ]
end
relationships do
belongs_to ( :post , Post , allow_nil? : false )
end
end
defmodule Registry do
@moduledoc false
use Ash.Registry
entries do
entry ( Post )
entry ( Comment )
end
end
defmodule Api do
@moduledoc false
use Ash.Api
resources do
registry Registry
end
end
assert { :error ,
% Ash.Error.Invalid {
changeset : %{
errors : [
# there should not be a Ash.Error.Changes.Required error in this list
% Ash.Error.Invalid { path : [ :post ] }
]
}
} } =
Comment
|> Ash.Changeset . new ( )
|> Ash.Changeset . manage_relationship ( :post , Ecto.UUID . generate ( ) ,
type : :append_and_remove
)
|> Api . create ( )
end
2019-12-06 20:00:26 +13:00
end