Skip to content

Instantly share code, notes, and snippets.

@gravis
Created March 5, 2009 10:28
Show Gist options
  • Save gravis/74287 to your computer and use it in GitHub Desktop.
Save gravis/74287 to your computer and use it in GitHub Desktop.
# Taken from Thoughtbot-shoulda
# Put me in RAILS_ROOT/test/shoulda_macros/xml.rb
# Macro that creates a test asserting that the controller responded with an XML content-type
# and that the XML contains +<name/>+ as the root element.
def should_respond_with_xml_for(name = nil)
should "have ContentType set to 'application/xml'" do
assert_xml_response
end
if name
should "return <#{name}/> as the root element" do
body = @response.body.first(100).map {|l| " #{l}"}
assert_select name.to_s.dasherize, 1, "Body:\n#{body}...\nDoes not have <#{name}/> as the root element."
end
end
end
alias should_respond_with_xml should_respond_with_xml_for
def make_show_xml_tests(res) # :nodoc:
context "on GET to #{controller_name_from_class}#show as xml" do
setup do
request_xml
record = get_existing_record(res)
parent_params = make_parent_params(res, record)
get :show, parent_params.merge({ res.identifier => record.to_param })
end
if res.denied.actions.include?(:show)
should_not_assign_to res.object
should_respond_with 401
else
should_assign_to res.object
should_respond_with :success
should_respond_with_xml_for res.object
end
end
end
def make_edit_xml_tests(res) # :nodoc:
# XML doesn't need an :edit action
end
def make_new_xml_tests(res) # :nodoc:
# XML doesn't need a :new action
end
def make_index_xml_tests(res) # :nodoc:
context "on GET to #{controller_name_from_class}#index as xml" do
setup do
request_xml
parent_params = make_parent_params(res)
get(:index, parent_params)
end
if res.denied.actions.include?(:index)
should_not_assign_to res.object.to_s.pluralize
should_respond_with 401
else
should_respond_with :success
should_respond_with_xml_for res.object.to_s.pluralize
should_assign_to res.object.to_s.pluralize
end
end
end
def make_destroy_xml_tests(res) # :nodoc:
context "on DELETE to #{controller_name_from_class}#destroy as xml" do
setup do
request_xml
@record = get_existing_record(res)
parent_params = make_parent_params(res, @record)
delete :destroy, parent_params.merge({ res.identifier => @record.to_param })
end
if res.denied.actions.include?(:destroy)
should_respond_with 401
should "not destroy record" do
assert @record.reload
end
else
should "destroy record" do
assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
@record.reload
end
end
end
end
end
def make_create_xml_tests(res) # :nodoc:
context "on POST to #{controller_name_from_class}#create as xml" do
setup do
request_xml
parent_params = make_parent_params(res)
@count = res.klass.count
post :create, parent_params.merge(res.object => res.create.params)
end
if res.denied.actions.include?(:create)
should_respond_with 401
should_not_assign_to res.object
should "not create new record" do
assert_equal @count, res.klass.count
end
else
should_assign_to res.object
should "not have errors on @#{res.object}" do
assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
end
end
end
end
def make_update_xml_tests(res) # :nodoc:
context "on PUT to #{controller_name_from_class}#update as xml" do
setup do
request_xml
@record = get_existing_record(res)
parent_params = make_parent_params(res, @record)
put :update, parent_params.merge(res.identifier => @record.to_param, res.object => res.update.params)
end
if res.denied.actions.include?(:update)
should_not_assign_to res.object
should_respond_with 401
else
should_assign_to res.object
should "not have errors on @#{res.object}" do
assert_equal [], assigns(res.object).errors.full_messages, "@#{res.object} has errors:"
end
end
end
end
# Sets the next request's format to 'application/xml'
def request_xml
@request.accept = "application/xml"
end
# Asserts that the controller's response was 'application/xml'
def assert_xml_response
content_type = (@response.headers["Content-Type"] || @response.headers["type"]).to_s
regex = %r{\bapplication/xml\b}
msg = "Content Type '#{content_type.inspect}' doesn't match '#{regex.inspect}'\n"
msg += "Body: #{@response.body.first(100).chomp} ..."
assert_match regex, content_type, msg
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment