Trying to write what should be a straightforward RSpec test and have set up my create action to render JSON like the following:
require 'spec_helper'
describe CommentsController do
let(:valid_attributes) do
{
title: 'First Comment', comment_text: 'LoremIpsum', commentable_id: 1,
user_id: 1, entered_by: 'john', last_updated_by: 'doe'
}
end
context 'JSON' do
describe 'POST create' do
describe 'with valid params' do
it 'creates a new Comment' do
json = {:format => 'json', :comment => valid_attributes}
post :create, json
end
it 'assigns a newly created comment as #comment' do
json = {:format => 'json', :comment => valid_attributes}
post :create, json
assigns(:comment).should be_a(Comment)
assigns(:comment).should be_persisted
end
end
end
end
end
However I am getting the following output:
ActionView::MissingTemplate: Missing template comments/create, application/create with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee, :haml]}. Searched in:
you missed the else part when #commentable is nil. this will try rendering the default template!
to clarify:
this is what was posted initially:
def create
if #commentable
#comment = #commentable.comments.new(comment_params)
if #comment.save
render json: #comment, status: :created
else
render json: #comment.errors, status: :unprocessable_entity
end
end
end
in the case where #commentable is nil there is nothing that tells rails what to render, so it will try to render the default template for the create action. this is where Missing template comments/create comes from.
what i mean with the else part is this:
def create
if #commentable
[...]
else
head 404
end
end
Related
I'm using render_to_string as a json response. It works fine in my app, but rspec can't find the partial.
controller:
# controllers/admin_controller.rb
class AdminController < ApplicationController
def retrieve_edit_form
user = User.find(params[:id])
form = render_to_string('_user_form', layout: false)
respond_to do |format|
format.json { render json: { form: form } }
end
end
end
spec:
# spec/app/controllers/admin_controller_spec.rb
require 'rails_helper'
RSpec.describe AdminController, type: :controller do
render_views
describe 'GET retrieve_edit_form' do
it 'returns http success' do
get :retrieve_edit_form, id: 100, format: :json
expect(response).to be_success
end
end
end
I get the error:
Missing template admin/_user_form, application/_user_form with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee]}. Searched in:
* "/Users/.../app/views"
How can I get rspec to recognize the partial?
Ok, I figured it out. Turns out I needed to add the extension to the partial and it all works fine.
The controller needed to be
form = render_to_string('_user_form.html.erb', layout: false)
An integration test is returning a 'Missing Template' error. The microposts_interface_test.rb errors on /members. It may be because the /members view uses the MicropostsController but I'm unsure how to fix the test.
ERROR["test_micropost_interface", MicropostsInterfaceTest, 2015-06-19 06:40:32 +0800]
test_micropost_interface#MicropostsInterfaceTest (1434667232.75s)
ActionView::MissingTemplate: ActionView::MissingTemplate: Missing template /members with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :haml, :jbuilder]}. Searched in:
* "/home/me/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/web-console-2.0.0.beta3/lib/action_dispatch/templates"
* "/home/me/Development/my_app/app/views"
* "/home/me/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/web-console-2.0.0.beta3/app/views"
* "/home/me/.rbenv/versions/2.2.1/lib/ruby/gems/2.2.0/gems/phrasing-4.0.0rc9/app/views"
app/controllers/microposts_controller.rb:14:in `create'
test/integration/microposts_interface_test.rb:16:in `block (2 levels) in <class:MicropostsInterfaceTest>'
test/integration/microposts_interface_test.rb:15:in `block in <class:MicropostsInterfaceTest>'
app/controllers/microposts_controller.rb:14:in `create'
test/integration/microposts_interface_test.rb:16:in `block (2 levels) in <class:MicropostsInterfaceTest>'
test/integration/microposts_interface_test.rb:15:in `block in <class:MicropostsInterfaceTest>'
MicropostsInterfaceTest:
require 'test_helper'
class MicropostsInterfaceTest < ActionDispatch::IntegrationTest
def setup
#user = users(:michael)
end
test "micropost interface" do
log_in_as(#user)
get members_path
assert_select 'div.pagination'
assert_select 'input[type=file]'
# Invalid submission
assert_no_difference 'Micropost.count' do
post microposts_path, micropost: { content: "" }
end
assert_select 'div#error_explanation'
# Valid submission
content = "This micropost really ties the room together"
picture = fixture_file_upload('test/fixtures/rails.png', 'image/png')
assert_difference 'Micropost.count', 1 do
post microposts_path, micropost: { content: content, picture: picture }
end
assert assigns(:micropost).picture?
assert_redirected_to root_url
follow_redirect!
assert_match content, response.body
# Delete a post.
assert_select 'a', text: 'delete'
first_micropost = #user.microposts.paginate(page: 1).first
assert_difference 'Micropost.count', -1 do
delete micropost_path(first_micropost)
end
# Visit a different user.
get user_path(users(:archer))
assert_select 'a', text: 'delete', count: 0
end
test "micropost sidebar count" do
log_in_as(#user)
get members_path
assert_match "#{#user.microposts.count} microposts", response.body
# User with zero microposts
other_user = users(:mallory)
log_in_as(other_user)
get members_path
assert_match "0 microposts", response.body
# Create a micropost.
other_user.microposts.create!(content: "A micropost")
get members_path
assert_match "1 micropost", response.body
end
end
Update:
# controller/members_controller.rb
class MembersController < ApplicationController
before_filter :logged_in_user
def index
#micropost = current_user.microposts.build
#feed_items = current_user.feed.paginate(page: params[:page])
end
end
I confirm there is a specific index view at app/views/members/index.html.erb.
Update 2:
# controller/microposts_controller.rb
class MicropostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
before_action :correct_user, only: :destroy
def create
#micropost = current_user.microposts.build(micropost_params)
if #micropost.save
flash[:success] = "Micropost created!"
redirect_to members_path
else
#feed_items = []
render members_path
end
end
def destroy
#micropost.destroy
flash[:success] = "Micropost deleted"
redirect_to request.referrer || members_path
end
private
def micropost_params
params.require(:micropost).permit(:content, :picture)
end
def correct_user
#micropost = current_user.microposts.find_by(id: params[:id])
redirect_to members_path if #micropost.nil?
end
end
In the create action in the MicropostController use render "members/index" instead of render members_path. Note that render does not load the variables needed in members/index, it only loads the template so add #micropost = [] just like you did for #feed_items = [] so that if you are calling those variables from the view you don't get an error of can't find variable #microposts. Or you can simply redirect_to members_path.
It was useful for me:
render template: 'template', formats: [:html]
So I have an api under
#controllers/api/v4/...rb
this api render jbuilder json under:
#views/api/v4/....json.jbuilder
I have spec:
#spec/controllers/api/v4/..._spec.rb
require 'rails_helper'
RSpec.describe Api::V4::AlbumsController do
let(:user) { create(:user) }
before(:each) do
#request.env["devise.mapping"] = Devise.mappings[:user]
sign_in(user)
end
describe "GET index" do
it "returns correct types" do
get :index, {:format => :json, :user_id => user.id}
puts #request.body
puts response.body
user_response = json_response
puts user_response
end
end
end
Everything is right until rendering when I get this:
Failure/Error: get :index, {:format => :json, :user_id => user.id}
ActionView::MissingTemplate:
Missing template api/v4/albums/index, api/api/index with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee, :haml]}. Searched in:
* "#<RSpec::Rails::ViewRendering::EmptyTemplatePathSetDecorator:0x007ff4721d9f20>"
Does someone have an idea to solve this?
I needed to include jbuilder in my gemfile... so it can render the .json.jbuilder views.
I have the following ajax function
$.ajax({
url: '/sub_categories/sub_cat',
data: 'sub_cat=45',
success: function() {
alert('success');
}
})
Here is my controller
require 'json'
class SubCategoriesController < ApplicationController
def show
end
def sub_cat
#sub_categories = SubCategory.where(category_id: params[:cat_id])
html = render_to_string 'sub_categories/sub_cat'
response_html true,html
end
end
My application controller
def response_html status,html
respond_to do |format|
format.json {render json: {
status: status,
html: html,
}
}
format.html
end
end
I have json file in sub_categories/sub_cat.json.erb
When I run getting error as
ActionView::MissingTemplate at /sub_categories/sub_cat.json
Missing template sub_categories/show, application/show with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :raw, :ruby, :jbuilder, :coffee]}. Searched in:
* "/home/editmehere/Documents/site/name/app/views"
My route.rb has
resources :sub_categories do
get 'sub_cat', on: :collection
end
Why I am getting error like this and how can I solve it. Can anyone help me to solve it.
I'm guessing you're trying to keep your application dry, but why don't you just use this in your SubCategoriesController:
class SubCategoriesController < ApplicationController
def sub_cat
#sub_categories = SubCategory.where(category_id: params[:cat_id])
respond_to do |format|
format.json
format.html
end
end
end
This will allow you to call sub_cat.json.erb without having to pass the status var, or pre-render the HTML. This is just convention, so apologies if it's not what you need. I see a lot of people on here overcomplicate things, when simplicity would work much better
Ajax
Also, I believe you've got a problem with your ajax data var:
data: 'sub_cat=45',
should be
data: {sub_cat: "45"},
After migrate on Rails 3 some RSpec test broken
Example:
Controller:
class ProfilesController < ApplicationController
def create
#profile = Profile.new(params[:note])
respond_to do |format|
if #profile.save
format.html { redirect_to :back }
else
format.html { render :new }
format.js do
render(:update) do |page|
page.flash.show #profile.errors.full_messages.join(', ')
end
end
end
end
end
end
Spec:
require 'spec_helper'
describe ProfilesController do
before(:each) { sign_in mock_model(Account).as_null_object }
context 'POST create' do
it 'is accessible for logged in user' do
controller.should_receive(:create)
post :create
end
end
end
Got failure:
19) ProfilesController POST create is accessible for logged in user
Failure/Error: post :create
ActionView::MissingTemplate:
Missing template profiles/create with {:locale=>[:en, :en], :formats=>[:html], :handlers=>[:rjs, :rhtml, :rxml, :builder, :erb]} in view paths "#<RSpec::Rails::ViewRendering::EmptyTemplatePathSetDecorator:0x1059d48f0>"
# ./spec/controllers/profiles_controller_spec.rb:48
Can you show your controller code?
May be you are really haven't any redirection actions in profiles_controller#create.
something like this:
def create
...
redirect_to '/'
end