I have a controller:
defmodule ParrotApi.MeetupController do
use ParrotApi.Web, :controller
alias ParrotApi.Meetup
def index(conn, _params) do
one_hour_ago = Timex.now
|> Timex.shift(hours: -1)
|> Timex.to_unix
meetups = from(m in Meetup, where: m.timestamp >= ^one_hour_ago)
|> Repo.all
|> Repo.preload(:topic)
render conn, meetups: meetups
end
end
and a view for this controller:
defmodule ParrotApi.MeetupView do
use ParrotApi.Web, :view
def render("index.json", %{ meetups: meetups }) do
render_many(meetups, ParrotApi.MeetupView, "meetup.json")
end
def render("meetup.json", %{ meetup: meetup }) do
%{
id: meetup.id,
timestamp: meetup.timestamp,
topic: meetup.topic.title,
}
end
end
I'm writing my first controller test:
defmodule ParrotApi.MeetupControllerTest do
use ParrotApi.ConnCase
alias ParrotApi.Meetup
alias ParrotApi.Topic
alias ParrotApi.Repo
require Logger
describe "#index" do
test "returns future meetups" do
topic_title = "Is Jesus your savior?"
future_time = Timex.now
|> Timex.shift(minutes: 1)
|> Timex.to_unix
{:ok, topic} = Topic.changeset(%Topic{}, %{title: topic_title}) |> Repo.insert
{:ok, meetup} = Meetup.changeset(%Meetup{}, %{timestamp: future_time, topic_id: topic.id}) |> Repo.insert
conn = build_conn()
conn = get conn, meetup_path(conn, :index)
assert json_response(conn, 200) == [
%{
"id" => meetup.id,
"timestamp" => future_time,
"topic" => topic_title,
}
]
end
It passes. However... it feels like a view test to me? It's testing the decorated/presented response that the view manipulates. So I don't really know what to do for my view test.
Is there a way to test the render conn, meetups: meetups
response only, and then extract the stuff currently in my controller test into a view test? Or is this the wrong way to test things?
200
status code when I expect the page to load,302
for a redirect when a user is not logged in, etc. Then in my view tests, I ensure that certain content is loaded and displayed. – Justin Wood