Created
April 23, 2012 05:21
-
-
Save mainej/2468960 to your computer and use it in GitHub Desktop.
anemic controllers, thin models, fat domain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PostRepository | |
def self.update(id, post_updates, editor) | |
post = find(id) | |
raise SecurityTransgression unless can_edit?(post, editor) | |
post.update_attributes!(post_updates) | |
post | |
end | |
def self.find(id) | |
Post.find(id) | |
end | |
def self.can_edit?(post, editor) | |
editor.admin? || post.created_by?(editor) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'post_repository' | |
class Post | |
end | |
describe PostRepository do | |
describe ".update" do | |
let(:user) { stub! } | |
let(:post) { stub! } | |
before do | |
stub(user).admin { false } | |
stub(post).created_by?(user) { true } | |
stub(Post).find('1') { post } | |
end | |
it "returns the updated post" do | |
stub(post).update_attributes!(a: 'b') { true } | |
PostRepository.update('1', {a: 'b'}, user).should == post | |
end | |
context "permissions" do | |
it "allow admins to edit" do | |
stub(user).admin { true } | |
stub(post).created_by?(user) { false } | |
mock(post).update_attributes!(a: 'b') { true } | |
PostRepository.update('1', {a: 'b'}, user) | |
end | |
it "allow creator of post to edit" do | |
# default config | |
mock(post).update_attributes!(a: 'b') { true } | |
PostRepository.update('1', {a: 'b'}, user) | |
end | |
it "disallow others from editing" do | |
stub(user).admin { false } | |
stub(post).created_by?(user) { false } | |
dont_allow(post).update_attributes!(a: 'b') | |
expect { | |
PostRepository.update('1', {a: 'b'}, user) | |
}.to raise_error(SecurityTransgression) | |
end | |
end | |
it "raises error when post is missing" do | |
stub(Post).find(1) { raise ActiveRecord::RecordNotFound } | |
expect { | |
PostRepository.update('1', {a: 'b'}, user) | |
}.to raise_error(ActiveRecord::RecordNotFound) | |
end | |
it "raises error when post becomes invalid" do | |
stub(post).update_attributes!(a: 'b') { raise ActiveRecord::RecordInvalid } | |
expect { | |
PostRepository.update('1', {a: 'b'}, user) | |
}.to raise_error(ActiveRecord::RecordInvalid) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class PostsController < ApplicationController | |
# no before filters here, but heavy use of rescue_from, responds_to in ApplicationController | |
def update | |
post = PostRespository.update(params[:id], params[:post], current_user) | |
respond_with post | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'spec_helper' | |
describe PostsController do | |
before { log_in mock_user } | |
it "redirects to post's page" do | |
stub(PostRepository).update('1', {a: 'b'}, mock_user) { mock_post } | |
put :update, id: '1', post: {a: 'b'} | |
response.should redirect_to(post_url(mock_post)) | |
end | |
it "renders 404 when post repository can't find post" do | |
stub(PostRepository).update('1', {a: 'b'}, mock_user) { raise ActiveRecord::RecordNotFound } | |
put :update, id: '1', post: {a: 'b'} | |
response.code.should == "404" | |
end | |
it "renders 403 when user does not have permission to edit post" do | |
stub(PostRepository).update('1', {a: 'b'}, mock_user) { raise SecurityTransgression } | |
put :update, id: '1', post: {a: 'b'} | |
response.code.should == "403" | |
end | |
it "renders 422 when post becomes invalid" do | |
stub(PostRepository).update('1', {a: 'b'}, mock_user) { raise ActiveRecord::RecordInvalid } | |
put :update, id: '1', post: {a: 'b'} | |
response.code.should == "422" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment