Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: provide a test for relationship filter by actor #234

Merged
merged 1 commit into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions test/custom_paginate_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,89 @@
}
end
end

test "loading relationships with filter by actor works" do

Check failure on line 168 in test/custom_paginate_test.exs

View workflow job for this annotation

GitHub Actions / ash-ci / mix test

test loading relationships with filter by actor works (AshGraphql.CustpmPaginateTest)
user_1 =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create)
|> Ash.create!(authorize?: false)

user_2 =
AshGraphql.Test.User
|> Ash.Changeset.for_create(:create)
|> Ash.create!(authorize?: false)

channel =
AshGraphql.Test.Channel
|> Ash.Changeset.for_create(:create, name: "test channel")
|> Ash.create!()

text_message =
AshGraphql.Test.TextMessage
|> Ash.Changeset.for_create(:create, text: "test text message")
|> Ash.Changeset.manage_relationship(:channel, channel, type: :append_and_remove)
|> Ash.create!()

AshGraphql.Test.MessageViewableUser
|> Ash.Changeset.for_create(:create, %{user_id: user_1.id, message_id: text_message.id})
|> Ash.create!()

image_message =
AshGraphql.Test.ImageMessage
|> Ash.Changeset.for_create(:create, text: "test image message")
|> Ash.Changeset.manage_relationship(:channel, channel, type: :append_and_remove)
|> Ash.create!()

AshGraphql.Test.MessageViewableUser
|> Ash.Changeset.for_create(:create, %{user_id: user_2.id, message_id: image_message.id})
|> Ash.create!()

resp =
"""
query ChannelWithUnionFilterByActorChannelMessages($id: ID!) {
channel(id: $id) {
id
filterByActorChannelMessages {
count
hasNextPage
results {
...on TextMessage {
__typename
id
text
type
}
...on ImageMessage {
__typename
id
text
type
}
}
}
}
}
"""
|> Absinthe.run(AshGraphql.Test.Schema,
variables: %{"id" => channel.id},
context: %{actor: user_1}
)

assert {:ok, result} = resp

refute Map.has_key?(result, :errors)

%{
"channel" => %{
"id" => _,
"filterByActorChannelMessages" => %{
"count" => count,
"hasNextPage" => _,
"results" => results
}
}
} = result.data

refute count != Enum.count(results)
end
end
1 change: 1 addition & 0 deletions test/support/domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ defmodule AshGraphql.Test.Domain do
resource(AshGraphql.Test.Channel)
resource(AshGraphql.Test.ChannelSimple)
resource(AshGraphql.Test.Message)
resource(AshGraphql.Test.MessageViewableUser)
resource(AshGraphql.Test.TextMessage)
resource(AshGraphql.Test.ImageMessage)
resource(AshGraphql.Test.Subscribable)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule AshGraphql.Test.PageOfFilterByActorChannelMessagesCalculation do
@moduledoc false
use Ash.Resource.Calculation

def load(_, _, context) do
limit = context.arguments.limit || 10
offset = context.arguments.offset || 0

[
:filter_by_user_channel_message_count,
filter_by_actor_messages:
AshGraphql.Test.Message
|> Ash.Query.limit(limit)
|> Ash.Query.offset(offset)
|> Ash.Query.select([:type, :text])
]
end

def calculate([channel], _, context) do
limit = context.arguments.limit || 10
offset = context.arguments.offset || 0

{:ok,
[
%{
count: channel.filter_by_user_channel_message_count,
has_next_page: channel.filter_by_user_channel_message_count > offset + limit,
results:
channel.filter_by_actor_messages
|> Enum.map(
&%Ash.Union{type: AshGraphql.Test.MessageUnion.struct_to_name(&1), value: &1}
)
}
]}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,17 @@ defmodule AshGraphql.Test.PageOfChannelMessagesCalculation do
]
end

def calculate([post], _, context) do
def calculate([channel], _, context) do
limit = context.arguments.limit || 100
offset = context.arguments.offset || 0

{:ok,
[
%{
count: post.channel_message_count,
has_next_page: post.channel_message_count > offset + limit,
count: channel.channel_message_count,
has_next_page: channel.channel_message_count > offset + limit,
results:
post.messages
channel.messages
|> Enum.map(
&%Ash.Union{type: AshGraphql.Test.MessageUnion.struct_to_name(&1), value: &1}
)
Expand Down
24 changes: 24 additions & 0 deletions test/support/resources/channel/changes/create_message_user.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
defmodule AshGraphql.Test.Changes.CreateMessageUser do
@moduledoc false
use Ash.Resource.Change

def change(changeset, _, context) do
IO.inspect(context: context)

Check warning on line 6 in test/support/resources/channel/changes/create_message_user.ex

View workflow job for this annotation

GitHub Actions / ash-ci / mix credo --strict

There should be no calls to `IO.inspect/1`.

changeset
|> Ash.Changeset.after_action(fn _, result ->
case AshGraphql.Test.MessageUser
|> Ash.Changeset.for_create(:create, %{
message_id: changeset.data.id,
user_id: context.actor.id
})
|> Ash.create() do
{:ok, _} ->
{:ok, result}

{:error, error} ->
{:error, error}
end
end)
end
end
21 changes: 21 additions & 0 deletions test/support/resources/channel/channel.ex
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,34 @@ defmodule AshGraphql.Test.Channel do
default(10)
end
end

calculate :filter_by_actor_channel_messages,
AshGraphql.Test.PageOfFilterByActorChannelMessages,
AshGraphql.Test.PageOfFilterByActorChannelMessagesCalculation do
public?(true)

argument :offset, :integer do
default(0)
end

argument :limit, :integer do
default(10)
end
end
end

aggregates do
count(:channel_message_count, :messages, public?: true)

count(:filter_by_user_channel_message_count, :filter_by_actor_messages, public?: true)
end

relationships do
has_many(:messages, AshGraphql.Test.Message, public?: true)

has_many(:filter_by_actor_messages, AshGraphql.Test.Message,
public?: true,
filter: expr(exists(message_users, user_id == ^actor(:id)))
)
end
end
10 changes: 4 additions & 6 deletions test/support/resources/channel/message.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ defmodule AshGraphql.Test.Message do
domain: AshGraphql.Test.Domain,
data_layer: Ash.DataLayer.Ets

# extensions: [AshGraphql.Resource]

ets do
table(:message)
end
Expand All @@ -30,9 +28,9 @@ defmodule AshGraphql.Test.Message do

relationships do
belongs_to(:channel, AshGraphql.Test.Channel, public?: true)
end

# graphql do
# type :message
# end
has_many(:message_users, AshGraphql.Test.MessageViewableUser,
destination_attribute: :message_id
)
end
end
36 changes: 36 additions & 0 deletions test/support/resources/channel/message_viewable_user.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
defmodule AshGraphql.Test.MessageViewableUser do
@moduledoc false

use Ash.Resource,
domain: AshGraphql.Test.Domain,
data_layer: Ash.DataLayer.Ets

ets do
table(:message_user)
end

actions do
default_accept(:*)
defaults([:read, :update, :destroy])

create :create do
primary?(true)
end
end

relationships do
belongs_to(:message, AshGraphql.Test.Message,
primary_key?: true,
allow_nil?: false,
attribute_writable?: true,
public?: true
)

belongs_to(:user, AshGraphql.Test.User,
primary_key?: true,
allow_nil?: false,
attribute_writable?: true,
public?: true
)
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
defmodule AshGraphql.Test.PageOfFilterByActorChannelMessages do
@moduledoc false

use AshGraphql.Type

use Ash.Type.NewType,
subtype_of: :map,
constraints: [
fields: [
count: [
type: :integer,
allow_nil?: false
],
has_next_page: [
type: :boolean,
allow_nil?: false
],
results: [
type: {:array, AshGraphql.Test.MessageUnion},
allow_nil?: false
]
]
]

@impl true
def graphql_type(_), do: :filter_by_actor_channel_messages

@impl true
def graphql_input_type(_), do: :filter_by_actor_channel_messages
end
Loading