0

Currently the documentation is clear and vibrant with the common HTTP verbs, but we started implementing some HEAD routes today and it is not tested the same way as the others.

To test say a GET method:

conn = get conn, controller_path(conn, :controller_method, params)

So I would assume you would just change get to head, but this is not the case.

Here is my route:

template_journeys_count_path HEAD /v1/templates/:template_id/journeys GondorWeb.V1.JourneyController :count

and my controller method:

def count(conn, %{"template_id" => template_id}) do count = Templates.get_journey_count(template_id) conn |> put_resp_header("x-total-count", count) |> send_resp(204, "") end

and my test:

conn = head conn, template_journeys_count_path(conn, :count, template.id) assert response(conn, 204)

But I am getting an error saying no response received and the resp_header that I added what not in conn.resp_headers

Am I missing something? I also tried to set up a connection build using Plug.ConnTest's method build_conn passing the HEAD method into it but still no luck.

Eric Stermer
  • 959
  • 1
  • 12
  • 23

1 Answers1

1

OK after more reading and testing using postman. Phoenix will automatically change HEAD requests into GET requests, there for when phoenix was looking for my route in the router, it was hitting the get route that matched the path with was my :index method.

For HEAD routes:

  • the verb in the router must be a get, ex: get '/items', :index
  • if you want to share a path, just add the put_resp_header on your returned connection in the controller method, only the header will be sent in the response
  • It is ok that the response code is not a 204, as per the w3c doc's HEAD requests can have a 200 response
  • testing a HEAD request, you can just change a the get to a head and test the response_headers and that no body was sent.

To show my changes... here is my router:

get "/journeys", JourneyController, :index

my controller method:

def index(conn, %{"template_id" => template_id}) do
    journeys = Templates.list_journeys(template_id)
    conn
    |> put_resp_header("x-total-count", "#{Enum.count(journeys)}")
    |> render("index.json", journeys: journeys)
end

and my test:

test "gets count", %{conn: conn, template: template} do
  conn = head conn, template_journey_path(conn, :index, template.id)
  assert conn.resp_body == ""
  assert Enum.at(get_resp_header(conn, "x-total-count"), 0) == "1"
end
Eric Stermer
  • 959
  • 1
  • 12
  • 23