Skip to content

Commit

Permalink
perspectives
Browse files Browse the repository at this point in the history
  • Loading branch information
balexand committed May 11, 2024
1 parent 38a5be3 commit b671f4e
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 78 deletions.
16 changes: 6 additions & 10 deletions lib/sanity.ex
Original file line number Diff line number Diff line change
Expand Up @@ -281,11 +281,11 @@ defmodule Sanity do
doc:
~S'Number of results to fetch per request. The Sanity docs say: "In the general case, we recommend a batch size of no more than 5,000. If your documents are very large, a smaller batch size is better."'
],
drafts: [
type: {:in, [:exclude, :include, :only]},
default: :exclude,
perspective: [
type: :string,
default: "published",
doc:
"Use `:exclude` to exclude drafts, `:include` to include drafts along with published docs, or `:only` to fetch drafts and not published documents."
~S'Perspective to use. Common values are `"published"`, `"previewDrafts"`, and `"raw"`. See the [docs](https://www.sanity.io/docs/perspectives) for details.'
],
projection: [
type: :string,
Expand Down Expand Up @@ -355,14 +355,14 @@ defmodule Sanity do

defp stream_page(opts, page_query) do
query =
[opts[:query], drafts_query(opts[:drafts]), page_query]
[opts[:query], page_query]
|> Enum.filter(& &1)
|> Enum.map(&"(#{&1})")
|> Enum.join(" && ")

results =
"*[#{query}] | order(_id) [0..#{opts[:batch_size] - 1}] #{opts[:projection]}"
|> query(opts[:variables])
|> query(opts[:variables], perspective: opts[:perspective])
|> opts[:request_module].request!(opts[:request_opts])
|> result!()

Expand All @@ -373,10 +373,6 @@ defmodule Sanity do
end
end

defp drafts_query(:exclude), do: "!(_id in path('drafts.**'))"
defp drafts_query(:include), do: nil
defp drafts_query(:only), do: "_id in path('drafts.**')"

@doc """
Generates a request for the [asset endpoint](https://www.sanity.io/docs/http-api-assets).
Expand Down
100 changes: 62 additions & 38 deletions test/integration_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -127,45 +127,69 @@ defmodule Sanity.MutateIntegrationTest do
|> Sanity.request(Keyword.put(config, :cdn, true))
end

test "stream", %{config: config} do
type = "streamItem#{:rand.uniform(1_000_000)}"

Sanity.mutate(Enum.map(1..5, &%{create: %{_type: type, title: "item #{&1}"}}))
|> Sanity.request!(config)

Sanity.mutate([
%{create: %{_id: "drafts.a-#{:rand.uniform(1_000_000)}", _type: type, title: "my draft"}}
])
|> Sanity.request!(config)
describe "stream" do
test "with multiple batches", %{config: config} do
type = "streamItem#{:rand.uniform(1_000_000)}"

Sanity.mutate(Enum.map(1..5, &%{create: %{_type: type, title: "item #{&1}"}}))
|> Sanity.request!(config)

Sanity.mutate([
%{create: %{_id: "drafts.a-#{:rand.uniform(1_000_000)}", _type: type, title: "my draft"}}
])
|> Sanity.request!(config)

assert [
%{"title" => "item 1"},
%{"title" => "item 2"},
%{"title" => "item 3"},
%{"title" => "item 4"},
%{"title" => "item 5"}
] =
Sanity.stream(query: "_type == '#{type}'", batch_size: 2, request_opts: config)
|> Enum.to_list()
|> Enum.sort_by(& &1["title"])
end

assert [
%{"title" => "item 1"},
%{"title" => "item 2"},
%{"title" => "item 3"},
%{"title" => "item 4"},
%{"title" => "item 5"}
] =
Sanity.stream(query: "_type == '#{type}'", batch_size: 2, request_opts: config)
|> Enum.to_list()
|> Enum.sort_by(& &1["title"])

# Only draft documents
assert [%{"title" => "my draft"}] =
Sanity.stream(query: "_type == '#{type}'", drafts: :only, request_opts: config)
|> Enum.to_list()

# Include both drafts and published documents
assert [
%{"title" => "item 1"},
%{"title" => "item 2"},
%{"title" => "item 3"},
%{"title" => "item 4"},
%{"title" => "item 5"},
%{"title" => "my draft"}
] =
Sanity.stream(query: "_type == '#{type}'", drafts: :include, request_opts: config)
|> Enum.to_list()
|> Enum.sort_by(& &1["title"])
test "with perspectives", %{config: config} do
type = "streamItem#{:rand.uniform(1_000_000)}"
id = "my-id-#{:rand.uniform(1_000_000)}"

Sanity.mutate([
%{create: %{_id: id, _type: type, title: "published item"}},
%{create: %{_id: "drafts.#{id}", _type: type, title: "draft item"}}
])
|> Sanity.request!(config)

# Published (default)
assert [%{"_id" => ^id, "title" => "published item"}] =
Sanity.stream(
query: "_type == '#{type}'",
request_opts: config
)
|> Enum.to_list()

# Preview drafts
assert [%{"_id" => ^id, "title" => "draft item"}] =
Sanity.stream(
query: "_type == '#{type}'",
perspective: "previewDrafts",
request_opts: config
)
|> Enum.to_list()

# Raw
assert [
%{"_id" => "drafts." <> ^id, "title" => "draft item"},
%{"_id" => ^id, "title" => "published item"}
] =
Sanity.stream(
query: "_type == '#{type}'",
perspective: "raw",
request_opts: config
)
|> Enum.to_list()
end
end

test "timeout error", %{config: config} do
Expand Down
46 changes: 16 additions & 30 deletions test/sanity_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,8 @@ defmodule SanityTest do
test "opts[:drafts] == :exclude (default)" do
Mox.expect(MockSanity, :request!, fn %Request{query_params: query_params}, _ ->
assert query_params == %{
"query" => "*[(!(_id in path('drafts.**')))] | order(_id) [0..999] { ... }"
"query" => "*[] | order(_id) [0..999] { ... }",
"perspective" => "published"
}

%Response{body: %{"result" => [%{"_id" => "a"}]}}
Expand All @@ -267,40 +268,24 @@ defmodule SanityTest do
Sanity.stream(request_module: MockSanity, request_opts: @request_config) |> Enum.to_list()
end

test "opts[:drafts] == :include" do
test "opts[:perspective]" do
Mox.expect(MockSanity, :request!, fn %Request{query_params: query_params}, _ ->
assert query_params == %{
"query" => "*[] | order(_id) [0..999] { ... }"
"query" => "*[] | order(_id) [0..999] { ... }",
"perspective" => "previewDrafts"
}

%Response{body: %{"result" => [%{"_id" => "a"}]}}
end)

Sanity.stream(drafts: :include, request_module: MockSanity, request_opts: @request_config)
Sanity.stream(
perspective: "previewDrafts",
request_module: MockSanity,
request_opts: @request_config
)
|> Enum.to_list()
end

test "opts[:drafts] == :only" do
Mox.expect(MockSanity, :request!, fn %Request{query_params: query_params}, _ ->
assert query_params == %{
"query" => "*[(_id in path('drafts.**'))] | order(_id) [0..999] { ... }"
}

%Response{body: %{"result" => [%{"_id" => "a"}]}}
end)

Sanity.stream(drafts: :only, request_module: MockSanity, request_opts: @request_config)
|> Enum.to_list()
end

test "opts[:drafts] == :invalid" do
assert_raise NimbleOptions.ValidationError,
"invalid value for :drafts option: expected one of [:exclude, :include, :only], got: :invalid",
fn ->
Sanity.stream(drafts: :invalid, request_opts: @request_config)
end
end

test "opts[:variables] invalid" do
assert_raise NimbleOptions.ValidationError,
"invalid value for :variables option: expected map, got: []",
Expand All @@ -318,7 +303,8 @@ defmodule SanityTest do
test "pagination" do
Mox.expect(MockSanity, :request!, fn %Request{query_params: query_params}, _ ->
assert query_params == %{
"query" => "*[(!(_id in path('drafts.**')))] | order(_id) [0..4] { ... }"
"query" => "*[] | order(_id) [0..4] { ... }",
"perspective" => "published"
}

results = Enum.map(1..5, &%{"_id" => "doc-#{&1}"})
Expand All @@ -327,8 +313,8 @@ defmodule SanityTest do

Mox.expect(MockSanity, :request!, fn %Request{query_params: query_params}, _ ->
assert query_params == %{
"query" =>
"*[(!(_id in path('drafts.**'))) && (_id > $pagination_last_id)] | order(_id) [0..4] { ... }",
"query" => "*[(_id > $pagination_last_id)] | order(_id) [0..4] { ... }",
"perspective" => "published",
"$pagination_last_id" => "\"doc-5\""
}

Expand Down Expand Up @@ -357,8 +343,8 @@ defmodule SanityTest do
Mox.expect(MockSanity, :request!, fn %Request{query_params: query_params}, _request_opts ->
assert query_params == %{
"$type" => "\"page\"",
"query" =>
"*[(_type == $type) && (!(_id in path('drafts.**')))] | order(_id) [0..999] { _id, title }"
"query" => "*[(_type == $type)] | order(_id) [0..999] { _id, title }",
"perspective" => "published"
}

%Response{body: %{"result" => [%{"_id" => "a", "title" => "home"}]}}
Expand Down

0 comments on commit b671f4e

Please sign in to comment.