fix: fix keyset pagination ordering bug

fix: short names are snake cased
This commit is contained in:
Zach Daniel 2022-09-12 11:16:51 -04:00
parent d32efadb62
commit f583ababbc
5 changed files with 102 additions and 16 deletions

View file

@ -571,6 +571,13 @@ defmodule Ash.Actions.Read do
{data, []}
end
data =
if page_opts[:before] do
Enum.reverse(data)
else
data
end
more? = not Enum.empty?(rest)
if page_opts[:offset] do

View file

@ -47,7 +47,7 @@ defmodule Ash.Api.Info do
@doc "The trace name for an api"
@spec trace_name(Ash.Api.t()) :: String.t()
def trace_name(api) do
Extension.get_opt(api, [:execution], :trace_name, nil) || api |> Module.split() |> List.last()
Extension.get_opt(api, [:execution], :trace_name, nil) || to_string(short_name(api))
end
@doc "The span_name for an api and resource combination"

View file

@ -15,13 +15,6 @@ defmodule Ash.Page.Keyset do
@type t :: %__MODULE__{}
def new(results, count, sort, original_query, more?, opts) do
results =
if opts[:page][:before] do
Enum.reverse(results)
else
results
end
%__MODULE__{
results: data_with_keyset(results, original_query.resource, sort),
count: count,

View file

@ -441,14 +441,100 @@ defmodule Ash.Actions.PaginationTest do
keyset = Enum.at(page.results, 0).__metadata__.keyset
names =
page =
User
|> Ash.Query.sort(:count_of_posts)
|> Api.read!(page: [after: keyset, limit: 5])
|> Api.read!(page: [after: keyset, limit: 4])
names =
page
|> Map.get(:results)
|> Enum.map(& &1.name)
assert names == ["5", "6", "7", "8", "9"]
assert names == ["5", "6", "7", "8"]
assert page.more?
end
test "pagination more? is false when there are no more records" do
page =
User
|> Ash.Query.filter(count_of_posts == 5)
|> Ash.Query.sort(:name)
|> Api.read!(page: [limit: 1])
keyset = Enum.at(page.results, 0).__metadata__.keyset
page =
User
|> Ash.Query.sort(:count_of_posts)
|> Api.read!(page: [after: keyset, limit: 4])
names =
page
|> Map.get(:results)
|> Enum.map(& &1.name)
assert names == ["6", "7", "8", "9"]
refute page.more?
end
test "pagination works with a sort applied that uses an aggregate using `before`" do
page =
User
|> Ash.Query.filter(count_of_posts == 4)
|> Ash.Query.sort(:name)
|> Api.read!(page: [limit: 1])
keyset = Enum.at(page.results, 0).__metadata__.keyset
page =
User
|> Ash.Query.sort(:count_of_posts)
|> Api.read!(page: [before: keyset, limit: 3])
names =
page
|> Map.get(:results)
|> Enum.map(& &1.name)
assert names == ["1", "2", "3"]
assert page.more?
page =
User
|> Ash.Query.sort(:count_of_posts)
|> Api.read!(page: [after: keyset, limit: 4])
names =
page
|> Map.get(:results)
|> Enum.map(& &1.name)
assert names == ["5", "6", "7", "8"]
assert page.more?
end
test "pagination more? is false when there are no more records using `before`" do
# page =
# User
# |> Ash.Query.filter(count_of_posts == 5)
# |> Ash.Query.sort(:name)
# |> Api.read!(page: [limit: 1])
# keyset = Enum.at(page.results, 0).__metadata__.keyset
# page =
# User
# |> Ash.Query.sort(:count_of_posts)
# |> Api.read!(page: [after: keyset, limit: 4])
# names =
# page
# |> Map.get(:results)
# |> Enum.map(& &1.name)
# assert names == ["6", "7", "8", "9"]
# refute page.more?
end
test "pagination works with a sort applied that uses an aggregate desc" do

View file

@ -169,7 +169,7 @@ defmodule Ash.Test.TracerTest.AsyncLoadTest do
assert [
%Ash.Tracer.Simple.Span{
type: :action,
name: "Api:Post.read",
name: "api:post.read",
metadata: %{
action: :read,
resource: Ash.Test.TracerTest.AsyncLoadTest.Post
@ -185,11 +185,11 @@ defmodule Ash.Test.TracerTest.AsyncLoadTest do
assert [
%Ash.Tracer.Simple.Span{
type: :changeset,
name: "changeset:Post:create"
name: "changeset:post:create"
},
%Ash.Tracer.Simple.Span{
type: :action,
name: "Api:Post.create",
name: "api:post.create",
metadata: %{
action: :create,
api: Ash.Test.TracerTest.AsyncLoadTest.Api,
@ -286,7 +286,7 @@ defmodule Ash.Test.TracerTest.AsyncLoadTest do
assert [
%Ash.Tracer.Simple.Span{
type: :action,
name: "Api:Post.read",
name: "api:post.read",
metadata: %{
action: :read,
resource: Ash.Test.TracerTest.AsyncLoadTest.Post
@ -301,7 +301,7 @@ defmodule Ash.Test.TracerTest.AsyncLoadTest do
end)
assert Enum.find(load.spans, fn span ->
span.name == "Api:Author.read"
span.name == "api:author.read"
end)
end
end