Did you finish the exercise?… Here is my answer =)
require "rspec"
require "active_model"
module Blog
def self.new_post_form
Form.new
end
def self.add_post(attrs, store)
form = Form.new(attrs)
if form.valid?
store.create(form.to_h)
SuccessStatus
else
ErrorStatus.new(form)
end
end
def self.list_all_posts(store)
store.all.sort_by(&:id).reverse
end
class Post
attr_reader :id, :title
def initialize(attrs)
@id = attrs[:id]
@title = attrs[:title]
end
end
class Form
include ActiveModel::Model
attr_accessor :title, :body
validates_presence_of :title
def to_h
{ title: title, body: body }
end
end
class ErrorStatus
attr_reader :form
def initialize(form)
@form = form
end
def success?
false
end
end
class SuccessStatus
def self.success?
true
end
end
end
module Blog
RSpec.describe "Add post" do
class DummyStore
def self.create(attrs)
end
end
def new_post_form
Blog.new_post_form
end
def add_post(params, store)
Blog.add_post(params, store)
end
def store
DummyStore
end
it "has a form" do
form = new_post_form
expect(form.title).to eq nil
expect(form.body).to eq nil
end
describe "with all attributes..." do
attr_reader :params
before do
@params = { "title" => "P1", "body" => "Super!" }
end
it "returns success" do
status = add_post(params, store)
expect(status).to be_success
end
it "creates a record" do
expect(store).to receive(:create).with(title: "P1", body: "Super!")
add_post(params, store)
end
end
describe "without title..." do
it "does not returns success" do
status = add_post({}, store)
expect(status).not_to be_success
end
it "does not creates the record" do
expect(store).not_to receive(:create)
add_post({}, store)
end
it "returns a blank error" do
status = add_post({}, store)
expect(status.form.errors[:title]).to eq ["can't be blank"]
end
end
end
RSpec.describe "List all posts" do
class FakeStore
attr_reader :all
def initialize(records)
@all = records
end
end
def post_with(attrs)
Post.new(attrs)
end
def store_with(records)
FakeStore.new(records)
end
def list_all_posts(store)
Blog.list_all_posts(store)
end
it "returns all the stored posts" do
store = store_with([
post_with(id: 1, title: "Post-1"),
post_with(id: 2, title: "Post-2")
])
posts = list_all_posts(store)
expect(posts.count).to eq 2
end
it "returns the posts sorted by id in descendent order" do
store = store_with([
post_with(id: 1, title: "Post-1"),
post_with(id: 2, title: "Post-2")
])
posts = list_all_posts(store)
expect(posts.map(&:id)).to eq [2, 1]
end
describe "each post..." do
it "has some attributes..." do
store = store_with([post_with(id: 1, title: "Post-1")])
post = list_all_posts(store).first
expect(post.id).to eq 1
expect(post.title).to eq "Post-1"
end
end
end
end
I send an email each week, trying to share knowledge and fixes to common problems and struggles for ruby on rails developers, like How to fetch the latest-N-of-each record or How to test that an specific mail was sent or a Capybara cheatsheet. You can see more examples on Most recent posts or All post by topic.