Skip to content

Commit

Permalink
Merge pull request #243 from binaryseed/complexity-via-put_options
Browse files Browse the repository at this point in the history
Set all plug options via put_options
  • Loading branch information
binaryseed authored Jan 21, 2021
2 parents a3792a3 + cd56b64 commit 2525d4c
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v1.5.4

- Feature: [Set all plug options via put_options](https://github.com/absinthe-graphql/absinthe_plug/pull/243)

## v1.5.3

- Chore: [Loosen Absinthe version](https://github.com/absinthe-graphql/absinthe_plug/pull/242)
Expand Down
44 changes: 43 additions & 1 deletion lib/absinthe/plug.ex
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,27 @@ defmodule Absinthe.Plug do

alias __MODULE__.Request

@raw_options [:analyze_complexity, :max_complexity]
@init_options [
:adapter,
:context,
:no_query_message,
:json_codec,
:pipeline,
:document_providers,
:schema,
:serializer,
:content_type,
:before_send,
:log_level,
:pubsub,
:analyze_complexity,
:max_complexity,
:transport_batch_payload_key
]
@raw_options [
:analyze_complexity,
:max_complexity
]

@type function_name :: atom

Expand All @@ -140,6 +160,7 @@ defmodule Absinthe.Plug do
- `:content_type` -- (Optional) The content type of the response. Should probably be set if `:serializer` option is used. Defaults to `"application/json"`.
- `:before_send` -- (Optional) Set a value(s) on the connection after resolution but before values are sent to the client.
- `:log_level` -- (Optional) Set the logger level for Absinthe Logger. Defaults to `:debug`.
- `:pubsub` -- (Optional) Pub Sub module for Subscriptions.
- `:analyze_complexity` -- (Optional) Set whether to calculate the complexity of incoming GraphQL queries.
- `:max_complexity` -- (Optional) Set the maximum allowed complexity of the GraphQL query. If a document’s calculated complexity exceeds the maximum, resolution will be skipped and an error will be returned in the result detailing the calculated and maximum complexities.
- `:transport_batch_payload_key` -- (Optional) Set whether or not to nest Transport Batch request results in a `payload` key. Older clients expected this key to be present, but newer clients have dropped this pattern. (default: `true`)
Expand All @@ -162,6 +183,7 @@ defmodule Absinthe.Plug do
content_type: String.t(),
before_send: {module, atom},
log_level: Logger.level(),
pubsub: module | nil,
transport_batch_payload_key: boolean
]

Expand Down Expand Up @@ -299,6 +321,13 @@ defmodule Absinthe.Plug do
end

defp update_config(conn, config) do
config
|> update_config(:pubsub, conn)
|> update_config(:raw_options, conn)
|> update_config(:init_options, conn)
end

defp update_config(config, :pubsub, conn) do
pubsub = config[:pubsub] || config.context[:pubsub] || conn.private[:phoenix_endpoint]

if pubsub do
Expand All @@ -308,6 +337,19 @@ defmodule Absinthe.Plug do
end
end

defp update_config(config, :raw_options, %{private: %{absinthe: absinthe}}) do
raw_options = Map.take(absinthe, @raw_options) |> Map.to_list()
update_in(config.raw_options, &Keyword.merge(&1, raw_options))
end

defp update_config(config, :init_options, %{private: %{absinthe: absinthe}}) do
Map.merge(config, Map.take(absinthe, @init_options -- @raw_options))
end

defp update_config(config, _, _conn) do
config
end

def subscribe(conn, topic, %{context: %{pubsub: pubsub}} = config) do
pubsub.subscribe(topic)

Expand Down
47 changes: 47 additions & 0 deletions test/lib/absinthe/plug_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,53 @@ defmodule Absinthe.PlugTest do
assert conn.private.absinthe.context.current_user.id == 1
assert conn.private.absinthe.root_value.field_on_root_value == "foo"
end

test "sets complexity" do
opts = Absinthe.Plug.init(schema: TestSchema)

query = "{expensive}"

assert %{status: 200, resp_body: resp_body} =
conn(:post, "/", Jason.encode!(%{"query" => query}))
|> Absinthe.Plug.put_options(
analyze_complexity: true,
max_complexity: 100
)
|> put_req_header("content-type", "application/json")
|> call(opts)

expected = %{
"errors" => [
%{
"locations" => [%{"column" => 2, "line" => 1}],
"message" => "Field expensive is too complex: complexity is 1000 and maximum is 100"
},
%{
"locations" => [%{"column" => 1, "line" => 1}],
"message" => "Operation is too complex: complexity is 1000 and maximum is 100"
}
]
}

assert expected == resp_body
end

test "sets all init options" do
opts = Absinthe.Plug.init(schema: TestSchema)
query = ""

assert %{resp_body: resp_body, resp_headers: resp_headers} =
conn(:post, "/", Jason.encode!(%{"query" => query}))
|> Absinthe.Plug.put_options(
no_query_message: "No query!!",
content_type: "text/who-knows"
)
|> put_req_header("content-type", "application/json")
|> call(opts)

assert %{"errors" => [%{"message" => "No query!!"}]} = resp_body
assert {"content-type", "text/who-knows; charset=utf-8"} in resp_headers
end
end

describe "assign_context/2" do
Expand Down

0 comments on commit 2525d4c

Please sign in to comment.