The ticket
Issue #1 in your copy of web-apps-2:
Post a taco
As a Tacostagram user, I want to post a photo of my tacos with a caption, so everyone can see what I'm eating.
Definition of done
- The new post page shows a form with fields for the author, the body and the image.
- Submitting the form creates a post with the author, body and image that were entered.
- After submitting, the user lands on the posts page and sees the new post there.
The ticket is the whole specification. Your agent read it, built it, and wrote one test per sentence. Yours will not match this line for line, and should not. What should match is the shape: two actions, one form, three tests, and a pull request that a classmate reviewed against the ticket.
What the agent built
The controller
new and create were already there as comments. The agent filled them in, keeping each step comment:
def new
# render posts/new view, the form for a new Post
render({ :template => "posts/new" })
end
def create
# start with a new Post
post = Post.new
# assign the form's values to the Post's columns
post["author"] = params["author"]
post["body"] = params["body"]
post["image"] = params["image"]
# save the Post row
post.save
# redirect the user
redirect_to("/posts")
end
new only renders the form. create has no view: it saves and sends the user to a page that already exists. The three keys in params are the three name attributes in the form below.
The form
app/views/posts/new.html.erb had a skeleton with a comment where the fields go:
<h1>New post</h1>
<form action="/posts" method="post">
<p>
<label for="author">Author</label>
<input type="text" name="author" id="author">
</p>
<p>
<label for="body">Body</label>
<input type="text" name="body" id="body">
</p>
<p>
<label for="image">Image</label>
<input type="text" name="image" id="image">
</p>
<button>Post it</button>
</form>
<p><a href="/posts">Back to all posts</a></p>
action="/posts" and method="post" are the create row of the pattern. No routes were added: resources("posts") in config/routes.rb already made all seven.
The tests
One per sentence, named with the sentence, in test/integration/posts_page_test.rb:
require "test_helper"
class PostsPageTest < ActionDispatch::IntegrationTest
test "The new post page shows a form with fields for the author, the body and the image." do
get("/posts/new")
assert_response(:success)
assert_select("form[action='/posts'][method='post']") do
assert_select("input[name='author']")
assert_select("input[name='body']")
assert_select("input[name='image']")
end
end
test "Submitting the form creates a post with the author, body and image that were entered." do
post("/posts", :params => {
"author" => "Ben",
"body" => "Al pastor on a Tuesday",
"image" => "https://images.unsplash.com/photo-tacos"
})
created = Post.find_by({ "author" => "Ben" })
assert_not_nil(created)
assert_equal("Al pastor on a Tuesday", created["body"])
assert_equal("https://images.unsplash.com/photo-tacos", created["image"])
end
test "After submitting, the user lands on the posts page and sees the new post there." do
post("/posts", :params => {
"author" => "Ben",
"body" => "Al pastor on a Tuesday",
"image" => "https://images.unsplash.com/photo-tacos"
})
assert_redirected_to("/posts")
follow_redirect!
assert_select("h3", "Ben")
assert_select("p", "Al pastor on a Tuesday")
assert_select("img[src='https://images.unsplash.com/photo-tacos']")
end
end
bin/rails test
3 runs, 21 assertions, 0 failures, 0 errors, 0 skips
Read each test against its sentence. The first fetches the form page and looks for the three inputs. The second submits the form and looks the row up in the table. The third submits, follows the redirect, and looks for the post on the page. Each one checks exactly what its sentence says, and nothing it doesn't.
Reviewing it
The five questions from class, answered for this change:
- Does it do what the issue says? The three sentences are the three tests, and they pass.
- Does the commit message tell you what changed? Yours to judge. "Add the new post form and create action, with tests" would.
- Does it follow the pattern?
newandcreateinPostsController, the form posts to/posts,createredirects. Yes. - A test per sentence, passing when you run them? Three sentences, three tests, green.
- Would you merge it? Yes. One thing you might ask for: the image is a text box the user has to paste an address into. That is what the ticket asked for; a file upload is week ten.
Issue #2, if you got to it
"Add a contact to a company" is the same loop with one new piece: the company's id has to travel from the company's page, through the form, to create, without the user typing it. That is a hidden field, and the "Handling relationships" section of Creating new records walks through it.