module ThoughtBot::Shoulda::Controller::HTML::ClassMethods

def controller_name_from_class

def controller_name_from_class
  self.name.gsub(/Test/, '')
end

def make_create_html_tests(res)

def make_create_html_tests(res)
  context "on POST to #{controller_name_from_class}#create with #{res.create.params.inspect}" do
    setup do
      record = get_existing_record(res) rescue nil
      parent_params = make_parent_params(res, record)
      @count = res.klass.count
      post :create, parent_params.merge(res.object => res.create.params)
    end
    if res.denied.actions.include?(:create)
      should_redirect_to res.denied.redirect
      should_set_the_flash_to res.denied.flash
      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_set_the_flash_to res.create.flash
      if res.create.redirect.is_a? Symbol
        should_respond_with res.create.redirect
      else
        should_redirect_to res.create.redirect
      end
      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_destroy_html_tests(res)

def make_destroy_html_tests(res)
  context "on DELETE to #{controller_name_from_class}#destroy" do
    setup do
      @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_redirect_to res.denied.redirect
      should_set_the_flash_to res.denied.flash

      should "not destroy record" do
        assert_nothing_raised { assert @record.reload }
      end
    else
      should_set_the_flash_to res.destroy.flash
      if res.destroy.redirect.is_a? Symbol
        should_respond_with res.destroy.redirect
      else
        should_redirect_to res.destroy.redirect
      end
      should "destroy record" do
        assert_raises(::ActiveRecord::RecordNotFound, "@#{res.object} was not destroyed.") do
          @record.reload
        end
      end
    end
  end
end

def make_edit_html_tests(res)

def make_edit_html_tests(res)
  context "on GET to #{controller_name_from_class}#edit" do
    setup do
      @record = get_existing_record(res)
      parent_params = make_parent_params(res, @record)
      get :edit, parent_params.merge({ res.identifier => @record.to_param })          
    end
    if res.denied.actions.include?(:edit)
      should_not_assign_to res.object
      should_redirect_to res.denied.redirect
      should_set_the_flash_to res.denied.flash
    else
      should_assign_to res.object                    
      should_respond_with :success
      should_render_template :edit
      should_not_set_the_flash
      should_render_a_form
      should "set @#{res.object} to requested instance" do
        assert_equal @record, assigns(res.object)
      end
    end
  end
end

def make_index_html_tests(res)

def make_index_html_tests(res)
  context "on GET to #{controller_name_from_class}#index" do
    setup do
      record = get_existing_record(res) rescue nil
      parent_params = make_parent_params(res, record)
      get(:index, parent_params)          
    end
    if res.denied.actions.include?(:index)
      should_not_assign_to res.object.to_s.pluralize
      should_redirect_to res.denied.redirect
      should_set_the_flash_to res.denied.flash          
    else
      should_respond_with :success
      should_assign_to res.object.to_s.pluralize
      should_render_template :index
      should_not_set_the_flash
    end
  end
end

def make_new_html_tests(res)

def make_new_html_tests(res)
  context "on GET to #{controller_name_from_class}#new" do
    setup do
      record = get_existing_record(res) rescue nil
      parent_params = make_parent_params(res, record)
      get(:new, parent_params)          
    end
    if res.denied.actions.include?(:new)
      should_not_assign_to res.object
      should_redirect_to res.denied.redirect
      should_set_the_flash_to res.denied.flash
    else
      should_respond_with :success
      should_assign_to res.object
      should_not_set_the_flash
      should_render_template :new
      should_render_a_form
    end
  end
end

def make_show_html_tests(res)

def make_show_html_tests(res)
  context "on GET to #{controller_name_from_class}#show" do
    setup do
      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_redirect_to res.denied.redirect
      should_set_the_flash_to res.denied.flash
    else
      should_assign_to res.object          
      should_respond_with :success
      should_render_template :show
      should_not_set_the_flash
    end
  end
end

def make_update_html_tests(res)

def make_update_html_tests(res)
  context "on PUT to #{controller_name_from_class}#update with #{res.create.params.inspect}" do
    setup do
      @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_redirect_to res.denied.redirect
      should_set_the_flash_to res.denied.flash
    else
      should_assign_to res.object
      should_set_the_flash_to(res.update.flash)
      if res.update.redirect.is_a? Symbol
        should_respond_with res.update.redirect
      else
        should_redirect_to res.update.redirect
      end
      
      should "not have errors on @#{res.object}" do
        assert_equal [], pretty_error_messages(assigns(res.object)), "@#{res.object} has errors:"
      end
    end
  end
end