diff --git a/lib/httparrot.ex b/lib/httparrot.ex index dc85904..ba9f750 100644 --- a/lib/httparrot.ex +++ b/lib/httparrot.ex @@ -15,6 +15,7 @@ defmodule HTTParrot do {'/status/:code', HTTParrot.StatusCodeHandler, []}, {'/redirect/:n', HTTParrot.RedirectHandler, []}, {'/redirect-to', HTTParrot.RedirectToHandler, []}, + {'/relative-redirect/:n', HTTParrot.RelativeRedirectHandler, []}, {'/cookies', HTTParrot.CookiesHandler, []}, {'/cookies/set', HTTParrot.SetCookiesHandler, []}, {'/cookies/delete', HTTParrot.DeleteCookiesHandler, []}, diff --git a/lib/httparrot/relative_redirect_handler.ex b/lib/httparrot/relative_redirect_handler.ex new file mode 100644 index 0000000..6df0c6f --- /dev/null +++ b/lib/httparrot/relative_redirect_handler.ex @@ -0,0 +1,27 @@ +defmodule HTTParrot.RelativeRedirectHandler do + @moduledoc """ + Redirects to the relative foo URL. + """ + + def init(_transport, _req, _opts) do + {:upgrade, :protocol, :cowboy_rest} + end + + def allowed_methods(req, state) do + {["GET", "HEAD", "OPTIONS"], req, state} + end + + def malformed_request(req, state) do + HTTParrot.RedirectHandler.malformed_request(req, state) + end + + def resource_exists(req, state), do: {false, req, state} + def previously_existed(req, state), do: {true, req, state} + + def moved_permanently(req, n) do + url = if n > 1, do: "/redirect/#{n-1}", else: "/get" + {{true, url}, req, nil} + end + + def terminate(_, _, _), do: :ok +end diff --git a/test/relative_redirect_handler_test.exs b/test/relative_redirect_handler_test.exs new file mode 100644 index 0000000..628de58 --- /dev/null +++ b/test/relative_redirect_handler_test.exs @@ -0,0 +1,46 @@ +defmodule HTTParrot.RelativeRedirectHandlerTest do + use ExUnit.Case + import :meck + import HTTParrot.RelativeRedirectHandler + + setup do + new :cowboy_req + end + + teardown do + unload :cowboy_req + end + + test "malformed_request returns false if it's not an integer" do + expect(:cowboy_req, :binding, [{[:n, :req1], {"a2B=", :req2}}]) + + assert malformed_request(:req1, :state) == {true, :req2, :state} + + assert validate :cowboy_req + end + + test "malformed_request returns false if it's an integer" do + expect(:cowboy_req, :binding, [{[:n, :req1], {"2", :req2}}]) + + assert malformed_request(:req1, :state) == {false, :req2, 2} + + assert validate :cowboy_req + end + + test "malformed_request returns 1 if 'n' is less than 1" do + expect(:cowboy_req, :binding, [{[:n, :req1], {"0", :req2}}]) + + assert malformed_request(:req1, :state) == {false, :req2, 1} + + assert validate :cowboy_req + end + + test "moved_permanently returns 'redirect/n-1' if n > 1" do + assert moved_permanently(:req1, 4) == {{true, "/redirect/3"}, :req1, nil} + end + + test "moved_permanently returns '/get' if n = 1" do + assert moved_permanently(:req1, 1) == {{true, "/get"}, :req1, nil} + end + +end