diff --git a/CHANGELOG.md b/CHANGELOG.md index 2cc1827..2aaef7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,19 @@ # Changelog +## v1.4.0 (2024-04-04) + +* **Breaking Changes:** + + Replace the key `http_opts` by `req_opts` + +* **Changes:** + * Replaced `:any_http` by `:req`, `Req` offers the ability to provide custom `:adapter` + * Removed the dependency `bypass` + +* **Bug fixes:** + * Fixed a bug on `ElasticsearchEx.Api.Search.create_pid/2` with empty body + ## v1.3.0 (2024-04-04) * **New features:** diff --git a/README.md b/README.md index 73fb62e..53ec074 100644 --- a/README.md +++ b/README.md @@ -19,16 +19,13 @@ Documentation can be found at https://hexdocs.pm/elasticsearch_ex. ### Configure your cluster ```elixir -# Define the `any_http` client adapter -config :any_http, client_adapter: AnyHttp.Adapters.Httpc - # Configure ElasticsearchEx config :elasticsearch_ex, clusters: %{ default: %{ endpoint: "https://elastic:elastic@localhost:9200", # For development only, if not specified, SSL is configured for you. - http_opts: [ssl: [verify: :verify_none]] + req_opts: [ssl: [verify: :verify_none]] } } ``` diff --git a/config/dev.exs b/config/dev.exs index c3f43bb..d372c59 100644 --- a/config/dev.exs +++ b/config/dev.exs @@ -3,14 +3,11 @@ import Config # Clear the terminal when running mix test.watch config :mix_test_watch, clear: true -# Define default any_http client adapter -config :any_http, client_adapter: AnyHttp.Adapters.Httpc - # Configure ElasticsearchEx config :elasticsearch_ex, clusters: %{ default: %{ endpoint: "https://elastic:elastic@localhost:9200", - http_opts: [ssl: [verify: :verify_none]] + req_opts: [connect_options: [transport_opts: [verify: :verify_none]]] } } diff --git a/config/test.exs b/config/test.exs index 1c1b5ec..fe18598 100644 --- a/config/test.exs +++ b/config/test.exs @@ -1,13 +1,10 @@ import Config -# Define default any_http client adapter -config :any_http, client_adapter: AnyHttp.Adapters.Httpc - # Configure ElasticsearchEx config :elasticsearch_ex, clusters: %{ default: %{ endpoint: "https://elastic:elastic@localhost:9200", - http_opts: [ssl: [verify: :verify_none]] + req_opts: [connect_options: [transport_opts: [verify: :verify_none]]] } } diff --git a/lib/elasticsearch_ex/api/search.ex b/lib/elasticsearch_ex/api/search.ex index 0ee63d3..f11fd20 100644 --- a/lib/elasticsearch_ex/api/search.ex +++ b/lib/elasticsearch_ex/api/search.ex @@ -344,7 +344,7 @@ defmodule ElasticsearchEx.Api.Search do def create_pit(index, opts \\ []) when is_index(index) do index |> format_path(:_pit) - |> Client.post(nil, "", opts) + |> Client.post(nil, nil, opts) end @doc """ diff --git a/lib/elasticsearch_ex/client.ex b/lib/elasticsearch_ex/client.ex index ea502a2..5fe3094 100644 --- a/lib/elasticsearch_ex/client.ex +++ b/lib/elasticsearch_ex/client.ex @@ -5,6 +5,8 @@ defmodule ElasticsearchEx.Client do ## Module attributes + @redact_auth Mix.env() == :prod + @content_type_key "content-type" @application_json "application/json" @@ -17,18 +19,19 @@ defmodule ElasticsearchEx.Client do def request(method, path, headers, body, opts \\ []) when is_list(opts) do {cluster, opts} = get_cluster_configuration(opts) - {http_opts, query} = prepare_options(cluster, opts) - uri = prepare_uri(cluster, path, query) - {headers, uri} = prepare_headers(cluster, uri, headers || @default_headers) - body = prepare_body!(headers, body) - - # URI.to_string(uri) |> IO.inspect(label: "URL") - AnyHttp.request(method, uri, headers, body, http_opts) - |> maybe_decode_json_body!() + Req.new(method: method, redact_auth: @redact_auth, compressed: true) + |> set_uri_and_userinfo(cluster, path) + |> set_headers(cluster, headers) + |> set_body(body) + |> set_query_params(cluster, opts) + |> Req.Request.append_response_steps(nilify_empty_body: &nilify_empty_body/1) + # |> Req.Request.append_request_steps(inspect: &IO.inspect/1) + |> Req.request() |> parse_result() end + @spec head(binary(), nil | map(), keyword()) :: :ok | :error def head(path, headers \\ nil, opts \\ []) do case request(:head, path, headers, nil, opts) do {:ok, nil} -> @@ -43,7 +46,7 @@ defmodule ElasticsearchEx.Client do request(:get, path, headers, body, opts) end - def post(path, headers \\ nil, body \\ "", opts \\ []) do + def post(path, headers \\ nil, body \\ nil, opts \\ []) do request(:post, path, headers, body, opts) end @@ -63,11 +66,11 @@ defmodule ElasticsearchEx.Client do ## Private functions - defp parse_result({:ok, %{status: status, body: body}}) when status in 200..299 do + defp parse_result({:ok, %Req.Response{status: status, body: body}}) when status in 200..299 do {:ok, body} end - defp parse_result({:ok, %{status: status} = response}) when status in 300..599 do + defp parse_result({:ok, %Req.Response{status: status} = response}) when status in 300..599 do {:error, ElasticsearchEx.Error.exception(response)} end @@ -75,18 +78,6 @@ defmodule ElasticsearchEx.Client do raise "Unknown error: #{inspect(error)}" end - defp maybe_decode_json_body!({:ok, %{headers: headers, body: body} = response} = result) do - content_type = Map.get(headers, @content_type_key) - - if content_type == [@application_json] and is_binary(body) and body != "" do - {:ok, %{response | body: Jason.decode!(body)}} - else - result - end - end - - defp maybe_decode_json_body!(any), do: any - defp get_cluster_configuration(opts) do {cluster, opts} = Keyword.pop(opts, :cluster, :default) @@ -100,50 +91,48 @@ defmodule ElasticsearchEx.Client do end end - defp prepare_uri(cluster, path, []) do - cluster |> Map.fetch!(:endpoint) |> URI.new!() |> URI.merge(path) - end - - defp prepare_uri(cluster, path, query) do - uri_query = URI.encode_query(query) - uri = prepare_uri(cluster, path, []) + defp set_uri_and_userinfo(%Req.Request{} = req, cluster, path) do + uri = cluster |> Map.fetch!(:endpoint) |> URI.new!() |> URI.merge(path) + auth = uri.userinfo && {:basic, uri.userinfo} + uri = %{uri | userinfo: nil} - %{uri | query: uri_query} + Req.merge(req, url: uri, auth: auth) end - defp prepare_options(cluster, opts) do - global_http_opts = Map.get(cluster, :http_opts, []) - {http_opts, query} = Keyword.pop(opts, :http_opts, []) - http_opts = Keyword.merge(global_http_opts, http_opts) + defp set_query_params(%Req.Request{} = req, cluster, opts) do + global_req_opts = Map.get(cluster, :req_opts, []) + {req_opts, query} = Keyword.pop(opts, :req_opts, []) + req_opts = Keyword.merge(global_req_opts, req_opts) - {http_opts, query} + req |> Req.merge(params: query) |> Req.merge(req_opts) end - defp prepare_headers(cluster, uri, headers) when is_map(headers) do + defp set_headers(%Req.Request{} = req, cluster, headers) do headers = (Map.get(cluster, :headers) || %{}) - |> Map.merge(headers) + |> Map.merge(headers || @default_headers) |> Map.reject(fn {_key, value} -> is_nil(value) end) - if is_binary(uri.userinfo) do - headers = Map.put(headers, "authorization", "Basic #{Base.encode64(uri.userinfo)}") - uri = %{uri | userinfo: nil} + Req.merge(req, headers: headers) + end - {headers, uri} - else - {headers, uri} - end + defp set_body(%Req.Request{} = req, nil), do: Req.merge(req, body: "") + + defp set_body(%Req.Request{headers: %{@content_type_key => [@application_ndjson]}} = req, body) do + Req.merge(req, body: ElasticsearchEx.Ndjson.encode!(body), compress_body: true) end - defp prepare_body!(%{@content_type_key => @application_json}, body) - when not is_nil(body) and body != "" do - Jason.encode!(body) + defp set_body(%Req.Request{headers: %{@content_type_key => [@application_json]}} = req, body) do + Req.merge(req, json: body, compress_body: true) end - defp prepare_body!(%{@content_type_key => @application_ndjson}, body) - when not is_nil(body) and body != "" do - ElasticsearchEx.Ndjson.encode!(body) + defp set_body(%Req.Request{} = req, body), do: Req.merge(req, body: body, compress_body: true) + + defp nilify_empty_body({request, %Req.Response{body: ""} = response}) do + {request, %{response | body: nil}} end - defp prepare_body!(_headers, body), do: body + defp nilify_empty_body({request, response}) do + {request, response} + end end diff --git a/lib/elasticsearch_ex/error.ex b/lib/elasticsearch_ex/error.ex index 7e29367..b0329ba 100644 --- a/lib/elasticsearch_ex/error.ex +++ b/lib/elasticsearch_ex/error.ex @@ -19,13 +19,13 @@ defmodule ElasticsearchEx.Error do ## Public functions @impl true - @spec exception(AnyHttp.Response.t()) :: t() - def exception(%AnyHttp.Response{status: status, body: nil}) do + @spec exception(Req.Response.t()) :: t() + def exception(%Req.Response{status: status, body: nil}) do %__MODULE__{status: status, reason: "Response returned #{status} status code"} end @impl true - def exception(%AnyHttp.Response{status: status, body: %{"error" => error}}) do + def exception(%Req.Response{status: status, body: %{"error" => error}}) do %__MODULE__{ status: status, reason: error["reason"], @@ -36,7 +36,7 @@ defmodule ElasticsearchEx.Error do end @impl true - def exception(%AnyHttp.Response{ + def exception(%Req.Response{ status: 404, body: %{"_id" => doc_id, "result" => "not_found"} = body }) do diff --git a/mix.exs b/mix.exs index 907af94..2235684 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule ElasticsearchEx.MixProject do use Mix.Project @source_url "https://github.com/CoreCareinc/elasticsearch_ex" - @version "1.3.0" + @version "1.4.0" def project do [ @@ -77,7 +77,7 @@ defmodule ElasticsearchEx.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:any_http, "~> 0.6"}, + {:req, "~> 0.4"}, {:jason, "~> 1.4"}, ## Dev dependencies @@ -85,7 +85,7 @@ defmodule ElasticsearchEx.MixProject do {:ex_doc, "~> 0.30", only: :dev, runtime: false}, ## Test dependencies - {:bypass, "~> 2.1", only: :test}, + {:plug, "~> 1.15", only: :test}, ## Dev & Test dependencies {:credo, "~> 1.7", only: [:dev, :test], runtime: false}, diff --git a/mix.lock b/mix.lock index 8582bf9..36b34da 100644 --- a/mix.lock +++ b/mix.lock @@ -1,11 +1,7 @@ %{ - "any_http": {:hex, :any_http, "0.6.3", "acbe04b7a725f21ebae641664ac32cac6efcfa1007bfc32f35227206863c5e48", [:mix], [{:hackney, "~> 1.20", [hex: :hackney, repo: "hexpm", optional: true]}, {:req, "~> 0.3", [hex: :req, repo: "hexpm", optional: true]}, {:tls_certificate_check, "~> 1.21", [hex: :tls_certificate_check, repo: "hexpm", optional: false]}], "hexpm", "252b9069259f2a9dd0aea0d53b7764b1fa7f5bf3fc6d2a0ee623bb74bdd95998"}, "benchee": {:hex, :benchee, "1.3.0", "f64e3b64ad3563fa9838146ddefb2d2f94cf5b473bdfd63f5ca4d0657bf96694", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "34f4294068c11b2bd2ebf2c59aac9c7da26ffa0068afdf3419f1b176e16c5f81"}, "bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"}, - "bypass": {:hex, :bypass, "2.1.0", "909782781bf8e20ee86a9cabde36b259d44af8b9f38756173e8f5e2e1fabb9b1", [:mix], [{:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "d9b5df8fa5b7a6efa08384e9bbecfe4ce61c77d28a4282f79e02f1ef78d96b80"}, - "cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"}, - "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, - "cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"}, + "castore": {:hex, :castore, "1.0.6", "ffc42f110ebfdafab0ea159cd43d31365fa0af0ce4a02ecebf1707ae619ee727", [:mix], [], "hexpm", "374c6e7ca752296be3d6780a6d5b922854ffcc74123da90f2f328996b962d33a"}, "credo": {:hex, :credo, "1.7.5", "643213503b1c766ec0496d828c90c424471ea54da77c8a168c725686377b9545", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f799e9b5cd1891577d8c773d245668aa74a2fcd15eb277f51a0131690ebfb3fd"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "dialyxir": {:hex, :dialyxir, "1.4.3", "edd0124f358f0b9e95bfe53a9fcf806d615d8f838e2202a9f430d59566b6b53b", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "bf2cfb75cd5c5006bec30141b131663299c661a864ec7fbbc72dfa557487a986"}, @@ -13,19 +9,22 @@ "erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"}, "ex_doc": {:hex, :ex_doc, "0.31.2", "8b06d0a5ac69e1a54df35519c951f1f44a7b7ca9a5bb7a260cd8a174d6322ece", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "317346c14febaba9ca40fd97b5b5919f7751fb85d399cc8e7e8872049f37e0af"}, "file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"}, + "finch": {:hex, :finch, "0.18.0", "944ac7d34d0bd2ac8998f79f7a811b21d87d911e77a786bc5810adb75632ada4", [:mix], [{:castore, "~> 0.1 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: false]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.6 or ~> 1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "69f5045b042e531e53edc2574f15e25e735b522c37e2ddb766e15b979e03aa65"}, + "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"}, "makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"}, "makeup_elixir": {:hex, :makeup_elixir, "0.16.2", "627e84b8e8bf22e60a2579dad15067c755531fea049ae26ef1020cad58fe9578", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "41193978704763f6bbe6cc2758b84909e62984c7752b3784bd3c218bb341706b"}, "makeup_erlang": {:hex, :makeup_erlang, "0.1.5", "e0ff5a7c708dda34311f7522a8758e23bfcd7d8d8068dc312b5eb41c6fd76eba", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "94d2e986428585a21516d7d7149781480013c56e30c6a233534bedf38867a59a"}, "mime": {:hex, :mime, "2.0.5", "dc34c8efd439abe6ae0343edbb8556f4d63f178594894720607772a041b04b02", [:mix], [], "hexpm", "da0d64a365c45bc9935cc5c8a7fc5e49a0e0f9932a761c55d6c52b142780a05c"}, + "mint": {:hex, :mint, "1.5.2", "4805e059f96028948870d23d7783613b7e6b0e2fb4e98d720383852a760067fd", [:mix], [{:castore, "~> 0.1.0 or ~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "d77d9e9ce4eb35941907f1d3df38d8f750c357865353e21d335bdcdf6d892a02"}, "mix_test_watch": {:hex, :mix_test_watch, "1.2.0", "1f9acd9e1104f62f280e30fc2243ae5e6d8ddc2f7f4dc9bceb454b9a41c82b42", [:mix], [{:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "278dc955c20b3fb9a3168b5c2493c2e5cffad133548d307e0a50c7f2cfbf34f6"}, + "nimble_options": {:hex, :nimble_options, "1.1.0", "3b31a57ede9cb1502071fade751ab0c7b8dbe75a9a4c2b5bbb0943a690b63172", [:mix], [], "hexpm", "8bbbb3941af3ca9acc7835f5655ea062111c9c27bcac53e004460dfd19008a99"}, + "nimble_ownership": {:hex, :nimble_ownership, "0.3.1", "99d5244672fafdfac89bfad3d3ab8f0d367603ce1dc4855f86a1c75008bce56f", [:mix], [], "hexpm", "4bf510adedff0449a1d6e200e43e57a814794c8b5b6439071274d248d272a549"}, "nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"}, + "nimble_pool": {:hex, :nimble_pool, "1.1.0", "bf9c29fbdcba3564a8b800d1eeb5a3c58f36e1e11d7b7fb2e084a643f645f06b", [:mix], [], "hexpm", "af2e4e6b34197db81f7aad230c1118eac993acc0dae6bc83bac0126d4ae0813a"}, "plug": {:hex, :plug, "1.15.3", "712976f504418f6dff0a3e554c40d705a9bcf89a7ccef92fc6a5ef8f16a30a97", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cc4365a3c010a56af402e0809208873d113e9c38c401cabd88027ef4f5c01fd2"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.7.0", "3ae9369c60641084363b08fe90267cbdd316df57e3557ea522114b30b63256ea", [:mix], [{:cowboy, "~> 2.7.0 or ~> 2.8.0 or ~> 2.9.0 or ~> 2.10.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "d85444fb8aa1f2fc62eabe83bbe387d81510d773886774ebdcb429b3da3c1a4a"}, "plug_crypto": {:hex, :plug_crypto, "2.0.0", "77515cc10af06645abbfb5e6ad7a3e9714f805ae118fa1a70205f80d2d70fe73", [:mix], [], "hexpm", "53695bae57cc4e54566d993eb01074e4d894b65a3766f1c43e2c61a1b0f45ea9"}, - "ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"}, - "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.7", "354c321cf377240c7b8716899e182ce4890c5938111a1296add3ec74cf1715df", [:make, :mix, :rebar3], [], "hexpm", "fe4c190e8f37401d30167c8c405eda19469f34577987c76dde613e838bbc67f8"}, + "req": {:hex, :req, "0.4.14", "103de133a076a31044e5458e0f850d5681eef23dfabf3ea34af63212e3b902e2", [:mix], [{:aws_signature, "~> 0.3.2", [hex: :aws_signature, repo: "hexpm", optional: true]}, {:brotli, "~> 0.3.1", [hex: :brotli, repo: "hexpm", optional: true]}, {:ezstd, "~> 1.0", [hex: :ezstd, repo: "hexpm", optional: true]}, {:finch, "~> 0.17", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_csv, "~> 1.0", [hex: :nimble_csv, repo: "hexpm", optional: true]}, {:nimble_ownership, "~> 0.2.0 or ~> 0.3.0", [hex: :nimble_ownership, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "2ddd3d33f9ab714ced8d3c15fd03db40c14dbf129003c4a3eb80fac2cc0b1b08"}, "statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"}, "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, - "tls_certificate_check": {:hex, :tls_certificate_check, "1.22.1", "0f450cc1568a67a65ce5e15df53c53f9a098c3da081c5f126199a72505858dc1", [:rebar3], [{:ssl_verify_fun, "~> 1.1", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3092be0babdc0e14c2e900542351e066c0fa5a9cf4b3597559ad1e67f07938c0"}, } diff --git a/test/elasticsearch_ex/client_test.exs b/test/elasticsearch_ex/client_test.exs index 4f9aa2a..3ef58ef 100644 --- a/test/elasticsearch_ex/client_test.exs +++ b/test/elasticsearch_ex/client_test.exs @@ -8,6 +8,8 @@ defmodule ElasticsearchEx.ClientTest do @my_headers %{"x-custom-header" => "Hello World!"} @my_body %{query: %{match_all: %{}}} + @compressed_body @my_body |> Jason.encode!() |> :zlib.gzip() + @resp_success %{ "_shards" => %{"failed" => 0, "skipped" => 0, "successful" => 1, "total" => 1}, "hits" => %{ @@ -41,23 +43,21 @@ defmodule ElasticsearchEx.ClientTest do "status" => 404 } - setup_all :setup_bypass - describe "head/1" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "HEAD", "/my-index", fn conn -> + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "HEAD", request_path: "/my-index"} = conn -> Plug.Conn.resp(conn, 200, "") - end) + end - assert :ok = Client.head("/my-index") + assert :ok = Client.head("/my-index", nil, req_opts: [plug: plug_fun]) end - test "returns an error when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "HEAD", "/my-index", fn conn -> + test "returns an error when unsucessful" do + plug_fun = fn %Plug.Conn{method: "HEAD", request_path: "/my-index"} = conn -> Plug.Conn.resp(conn, 400, "") - end) + end - assert :error = Client.head("/my-index") + assert :error = Client.head("/my-index", nil, req_opts: [plug: plug_fun]) end end @@ -68,14 +68,14 @@ defmodule ElasticsearchEx.ClientTest do {:ok, response: response, status: status} end - test "returns okay when sucessful", %{bypass: bypass, response: response, status: status} do - Bypass.expect_once(bypass, "HEAD", "/my-index", fn conn -> + test "returns okay when sucessful", %{response: response, status: status} do + plug_fun = fn %Plug.Conn{method: "HEAD", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") Plug.Conn.resp(conn, status, "") - end) + end - assert ^response = Client.head("/my-index", @my_headers) + assert ^response = Client.head("/my-index", @my_headers, req_opts: [plug: plug_fun]) end end @@ -86,39 +86,33 @@ defmodule ElasticsearchEx.ClientTest do {:ok, response: response, status: status} end - @tag :capture_log - test "returns okay when sucessful", %{bypass: bypass, response: response, status: status} do - Bypass.expect_once(bypass, "HEAD", "/my-index", fn conn -> - # Ensure the http_opts are not passed to the URL query params - "a=b" = conn.query_string + test "returns okay when sucessful", %{response: response, status: status} do + plug_fun = fn %Plug.Conn{method: "HEAD", request_path: "/my-index", query_string: "a=b"} = + conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") Plug.Conn.resp(conn, status, "") - end) + end - assert ^response = - Client.head("/my-index", @my_headers, - a: :b, - http_opts: [c: :d] - ) + assert ^response = Client.head("/my-index", @my_headers, a: :b, req_opts: [plug: plug_fun]) end end describe "get/1" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> Plug.Conn.resp(conn, 200, "") - end) + end - assert {:ok, nil} = Client.get("/my-index") + assert {:ok, nil} = Client.get("/my-index", nil, nil, req_opts: [plug: plug_fun]) end - test "returns an error when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> + test "returns an error when unsucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -131,33 +125,34 @@ defmodule ElasticsearchEx.ClientTest do type: error["type"], original: error } - } == Client.get("/my-index") + } == Client.get("/my-index", nil, nil, req_opts: [plug: plug_fun]) end end describe "get/2 with headers" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") {:ok, "", conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.get("/my-index", @my_headers) + assert {:ok, @resp_success} = + Client.get("/my-index", @my_headers, nil, req_opts: [plug: plug_fun]) end - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") {:ok, "", conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -168,69 +163,68 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.get("/my-index", @my_headers) + }} == Client.get("/my-index", @my_headers, nil, req_opts: [plug: plug_fun]) end end - # Unsure what to do as :httpc doesn't support providing a body with a GET request - # describe "get/3 with body" do - # test "returns okay when sucessful", %{bypass: bypass} do - # Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> - # {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) - - # conn - # |> Plug.Conn.put_resp_header("content-type", "application/json") - # |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - # end) - - # assert {:ok, @resp_success} = Client.get("/my-index", nil, @my_body) - # end - - # test "returns okay when unsucessful", %{bypass: bypass} do - # Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> - # {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) - - # conn - # |> Plug.Conn.put_resp_header("content-type", "application/json") - # |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - # end) - - # error = @resp_error["error"] - - # assert {:error, - # %ElasticsearchEx.Error{ - # reason: error["reason"], - # root_cause: error["root_cause"], - # status: @resp_error["status"], - # type: error["type"], - # original: error - # }} == Client.get("/my-index", nil, @my_body) - # end - # end + describe "get/3 with body" do + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) + + conn + |> Plug.Conn.put_resp_header("content-type", "application/json") + |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) + end + + assert {:ok, @resp_success} = + Client.get("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) + end + + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) + + conn + |> Plug.Conn.put_resp_header("content-type", "application/json") + |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) + end + + error = @resp_error["error"] + + assert {:error, + %ElasticsearchEx.Error{ + reason: error["reason"], + root_cause: error["root_cause"], + status: @resp_error["status"], + type: error["type"], + original: error + }} == Client.get("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) + end + end describe "get/4 with options" do - @tag :capture_log - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.get("/my-index", nil, nil, a: :b, http_opts: [c: :d]) + assert {:ok, @resp_success} = + Client.get("/my-index", nil, nil, a: :b, req_opts: [plug: plug_fun]) end - @tag :capture_log - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "GET", "/my-index", fn conn -> + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "GET", request_path: "/my-index"} = conn -> "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -241,29 +235,29 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.get("/my-index", nil, nil, a: :b, http_opts: [c: :d]) + }} == Client.get("/my-index", nil, nil, a: :b, req_opts: [plug: plug_fun]) end end describe "post/1" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) Plug.Conn.resp(conn, 200, "") - end) + end - assert {:ok, nil} = Client.post("/my-index", nil, @my_body) + assert {:ok, nil} = Client.post("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end - test "returns an error when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns an error when unsucessful" do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -276,7 +270,7 @@ defmodule ElasticsearchEx.ClientTest do type: error["type"], original: error } - } == Client.post("/my-index", nil, @my_body) + } == Client.post("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end end @@ -285,28 +279,29 @@ defmodule ElasticsearchEx.ClientTest do {:ok, my_headers: Map.merge(@my_headers, %{"content-type" => "application/json"})} end - test "returns okay when sucessful", %{bypass: bypass, my_headers: my_headers} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> + test "returns okay when sucessful", %{my_headers: my_headers} do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.post("/my-index", my_headers, @my_body) + assert {:ok, @resp_success} = + Client.post("/my-index", my_headers, @my_body, req_opts: [plug: plug_fun]) end - test "returns okay when unsucessful", %{bypass: bypass, my_headers: my_headers} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> + test "returns okay when unsucessful", %{my_headers: my_headers} do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -317,31 +312,32 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.post("/my-index", my_headers, @my_body) + }} == Client.post("/my-index", my_headers, @my_body, req_opts: [plug: plug_fun]) end end describe "post/3 with body" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.post("/my-index", nil, @my_body) + assert {:ok, @resp_success} = + Client.post("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -352,36 +348,34 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.post("/my-index", nil, @my_body) + }} == Client.post("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end end describe "post/4 with options" do - @tag :capture_log - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end assert {:ok, @resp_success} = - Client.post("/my-index", nil, @my_body, a: :b, http_opts: [c: :d]) + Client.post("/my-index", nil, @my_body, a: :b, req_opts: [plug: plug_fun]) end - @tag :capture_log - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "POST", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "POST", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -392,29 +386,29 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.post("/my-index", nil, @my_body, a: :b, http_opts: [c: :d]) + }} == Client.post("/my-index", nil, @my_body, a: :b, req_opts: [plug: plug_fun]) end end describe "put/1" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) Plug.Conn.resp(conn, 200, "") - end) + end - assert {:ok, nil} = Client.put("/my-index", nil, @my_body) + assert {:ok, nil} = Client.put("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end - test "returns an error when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns an error when unsucessful" do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -427,7 +421,7 @@ defmodule ElasticsearchEx.ClientTest do type: error["type"], original: error } - } == Client.put("/my-index", nil, @my_body) + } == Client.put("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end end @@ -436,28 +430,29 @@ defmodule ElasticsearchEx.ClientTest do {:ok, my_headers: Map.merge(@my_headers, %{"content-type" => "application/json"})} end - test "returns okay when sucessful", %{bypass: bypass, my_headers: my_headers} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> + test "returns okay when sucessful", %{my_headers: my_headers} do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.put("/my-index", my_headers, @my_body) + assert {:ok, @resp_success} = + Client.put("/my-index", my_headers, @my_body, req_opts: [plug: plug_fun]) end - test "returns okay when unsucessful", %{bypass: bypass, my_headers: my_headers} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> + test "returns okay when unsucessful", %{my_headers: my_headers} do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -468,31 +463,32 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.put("/my-index", my_headers, @my_body) + }} == Client.put("/my-index", my_headers, @my_body, req_opts: [plug: plug_fun]) end end describe "put/3 with body" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.put("/my-index", nil, @my_body) + assert {:ok, @resp_success} = + Client.put("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -503,36 +499,34 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.put("/my-index", nil, @my_body) + }} == Client.put("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end end describe "put/4 with options" do - @tag :capture_log - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end assert {:ok, @resp_success} = - Client.put("/my-index", nil, @my_body, a: :b, http_opts: [c: :d]) + Client.put("/my-index", nil, @my_body, a: :b, req_opts: [plug: plug_fun]) end - @tag :capture_log - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "PUT", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "PUT", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -543,29 +537,29 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.put("/my-index", nil, @my_body, a: :b, http_opts: [c: :d]) + }} == Client.put("/my-index", nil, @my_body, a: :b, req_opts: [plug: plug_fun]) end end describe "delete/1" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) Plug.Conn.resp(conn, 200, "") - end) + end - assert {:ok, nil} = Client.delete("/my-index", nil, @my_body) + assert {:ok, nil} = Client.delete("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end - test "returns an error when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns an error when unsucessful" do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -578,7 +572,7 @@ defmodule ElasticsearchEx.ClientTest do type: error["type"], original: error } - } == Client.delete("/my-index", nil, @my_body) + } == Client.delete("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end end @@ -587,28 +581,29 @@ defmodule ElasticsearchEx.ClientTest do {:ok, my_headers: Map.merge(@my_headers, %{"content-type" => "application/json"})} end - test "returns okay when sucessful", %{bypass: bypass, my_headers: my_headers} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> + test "returns okay when sucessful", %{my_headers: my_headers} do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.delete("/my-index", my_headers, @my_body) + assert {:ok, @resp_success} = + Client.delete("/my-index", my_headers, @my_body, req_opts: [plug: plug_fun]) end - test "returns okay when unsucessful", %{bypass: bypass, my_headers: my_headers} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> + test "returns okay when unsucessful", %{my_headers: my_headers} do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> ["Hello World!"] = Plug.Conn.get_req_header(conn, "x-custom-header") - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -619,31 +614,32 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.delete("/my-index", my_headers, @my_body) + }} == Client.delete("/my-index", my_headers, @my_body, req_opts: [plug: plug_fun]) end end describe "delete/3 with body" do - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end - assert {:ok, @resp_success} = Client.delete("/my-index", nil, @my_body) + assert {:ok, @resp_success} = + Client.delete("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -654,36 +650,34 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.delete("/my-index", nil, @my_body) + }} == Client.delete("/my-index", nil, @my_body, req_opts: [plug: plug_fun]) end end describe "delete/4 with options" do - @tag :capture_log - test "returns okay when sucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when sucessful" do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(200, Jason.encode!(@resp_success)) - end) + end assert {:ok, @resp_success} = - Client.delete("/my-index", nil, @my_body, a: :b, http_opts: [c: :d]) + Client.delete("/my-index", nil, @my_body, a: :b, req_opts: [plug: plug_fun]) end - @tag :capture_log - test "returns okay when unsucessful", %{bypass: bypass} do - Bypass.expect_once(bypass, "DELETE", "/my-index", fn conn -> - {:ok, ~s<{"query":{"match_all":{}}}>, conn} = Plug.Conn.read_body(conn) + test "returns okay when unsucessful" do + plug_fun = fn %Plug.Conn{method: "DELETE", request_path: "/my-index"} = conn -> + {:ok, @compressed_body, conn} = Plug.Conn.read_body(conn) "a=b" = conn.query_string conn |> Plug.Conn.put_resp_header("content-type", "application/json") |> Plug.Conn.resp(@resp_error["status"], Jason.encode!(@resp_error)) - end) + end error = @resp_error["error"] @@ -694,7 +688,7 @@ defmodule ElasticsearchEx.ClientTest do status: @resp_error["status"], type: error["type"], original: error - }} == Client.delete("/my-index", nil, @my_body, a: :b, http_opts: [c: :d]) + }} == Client.delete("/my-index", nil, @my_body, a: :b, req_opts: [plug: plug_fun]) end end end diff --git a/test/elasticsearch_ex/error_test.exs b/test/elasticsearch_ex/error_test.exs index 17f4584..b5acc45 100644 --- a/test/elasticsearch_ex/error_test.exs +++ b/test/elasticsearch_ex/error_test.exs @@ -10,7 +10,7 @@ defmodule ElasticsearchEx.ErrorTest do @error %{"reason" => @reason, "type" => @error_type, "root_cause" => @root_cause} setup_all do - response = %AnyHttp.Response{status: 400, body: %{"error" => @error}} + response = %Req.Response{status: 400, body: %{"error" => @error}} {:ok, response: response} end @@ -22,7 +22,7 @@ defmodule ElasticsearchEx.ErrorTest do end describe "callback exception/1" do - test "accepts a AnyHttp.Response argument and returns an error", %{response: response} do + test "accepts a Req.Response argument and returns an error", %{response: response} do assert %Error{ status: 400, reason: @reason, @@ -34,7 +34,7 @@ defmodule ElasticsearchEx.ErrorTest do end describe "callback message/1" do - test "accepts a AnyHttp.Response argument and returns an error", %{response: response} do + test "accepts a Req.Response argument and returns an error", %{response: response} do error = Error.exception(response) assert @reason = Error.message(error) diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 1cfa729..7b47f71 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -13,18 +13,6 @@ defmodule ElasticsearchEx.ConnCase do ## Private functions - def setup_bypass(_tags) do - bypass = Bypass.open() - original = Application.get_env(:elasticsearch_ex, :clusters) - on_exit(fn -> Application.put_env(:elasticsearch_ex, :clusters, original) end) - - Application.put_env(:elasticsearch_ex, :clusters, %{ - default: %{endpoint: "http://@localhost:#{bypass.port}"} - }) - - {:ok, bypass: bypass} - end - def create_index(index_name, properties) do ElasticsearchEx.Client.delete("/#{index_name}", nil, nil)