Rails test controller - ruby

Trying to test my controller
static_pages_controller_spec.rb
require 'rails_helper'
RSpec.describe StatigPagesController, type: :controller do
it 'return home view' do
get '/'
expect(response).to render_template :home
end
it 'return about view' do
get :about
expect(response).to render_template :about
end
end
routes.rb
Rails.application.routes.draw do
devise_for :users
root 'static_pages#home'
get '/about', to: 'static_pages#about'
end
and i get errors
1) StatigPagesController return home view
Failure/Error: get '/'
ActionController::UrlGenerationError:
No route matches {:action=>"/", :controller=>"statig_pages"}
2) StatigPagesController return about view
Failure/Error: get :about
ActionController::UrlGenerationError:
No route matches {:action=>"about", :controller=>"statig_pages"}
I wrote routes, What i'm do wrong?

You have a typo in your static_pages_controller_spec.rb
RSpec.describe StatigPagesController
Try:
RSpec.describe StaticPagesController

Related

Can't determine why iteration not showing objects - Ruby / ActiveRecord / Sinatra

I have two tables created through ActiveRecord: Users and Paintings. I am able to create instances of both objects. Paintings have a belongs_to relationship to Users. Users have a has_many relationship to Paintings. When I attempt to iterate over a Users list of paintings nothing reflects. When I use a similiar convention for iterating over all paintings I don't run into any issues.
require './config/environment'
class ApplicationController < Sinatra::Base
configure do
set :public_folder, 'public'
set :views, 'app/views'
enable :sessions
set :session_secret, "extra_secret"
end
get '/' do
erb :index
end
helpers do
def logged_in?
!!current_user
end
def current_user
#current_user ||= User.find_by(id: session[:user_id]) if session[:user_id]
end
end
end
class UsersController < ApplicationController
get '/users/:slug' do
#user = User.find_by_slug(params[:slug])
erb :'users/user_homepage'
end
get '/signup' do
if !logged_in?
erb :'users/new_user'
else
redirect to '/'
end
end
post '/signup' do
if params[:username] == "" || params[:email] == "" || params[:password] == ""
redirect to '/new_user'
else
#user = User.new(:username => params[:username], :email => params[:email], :password => params[:password])
#user.save
session[:user_id] = #user.id
redirect to '/user_homepage'
end
end
get '/login' do
if !logged_in?
erb :'users/login'
else
redirect '/index'
end
end
post '/login' do
user = User.find_by(:username => params[:username])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect to '/index'
else
redirect to 'users/new_user'
end
end
get '/logout' do
if logged_in?
session.destroy
redirect to '/login'
else
redirect to '/'
end
end
end
class PaintingsController < ApplicationController
get '/index' do
if logged_in?
#paintings = Painting.all
erb :'paintings/index'
else
redirect to '/login'
end
end
get "/new" do #create get
erb :'paintings/new'
end
post "/new" do #create post
Painting.create(params)
redirect "/user_homepage"
end
post '/user_homepage' do #changed from /index to /user_homepage. Did not fix.
if logged_in?
if params[:name] == ""
redirect to "/new"
else
#painting = current_user.paintings.build(name: params[:name])
if #painting.save
redirect to "/index/#{#painting.id}"
else
redirect to "/new"
end
end
else
redirect to '/login'
end
end
get "/paintings/:id/edit" do #update get
if logged_in?
#painting = Painting.find_by_id(params[:id])
if #painting && #painting.user == current_user
erb :'paintings/edit_tweet'
else
redirect to '/user_homepage'
end
else
redirect to '/login'
end
end
post "/paintings/:id" do #update post
#painting = Painting.find(params[:id])
#painting.update(params.select{|p| p=="name" || p=="year" || p=="artist_id"})
redirect "/paintings/#{#painting.id}"
end
get "/paintings/:id" do #read get
#painting = Painting.find(params[:id])
erb :'paintings/show'
end
get '/user_homepage' do
if logged_in?
erb :'users/user_homepage'
else
redirect '/index'
end
end
#Need post /user_homepage to show users paintings?
end
#View that is not showing a Users paintings
<h1> User Homepage </h1>
<h2>Welcome <%= current_user.username %>!</h2>
<p> Below is a list of your favorite paintings: </p>
<% #current_user.paintings.each do |painting| %>
<div>
Name: <%= painting.painting_name %>
Year: <%= painting.year %>
</div>
<% end %>
<p> Add New Painting
<p> Click here to see today's popular paintings! </p>
ActiveRecord::Schema.define(version: 2021_03_03_151621) do
create_table "paintings", force: :cascade do |t|
t.string "painting_name"
t.string "year"
t.integer "artist_id"
t.integer "user_id"
end
create_table "users", force: :cascade do |t|
t.string "username"
t.string "email"
t.string "password_digest"
end
end
class Painting < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_secure_password
has_many :paintings
def slug
username.downcase.gsub(" ","-")
end
def self.find_by_slug(slug)
User.all.find{|user| user.slug == slug}
end
end
It seems that you might be using current_user where you intended to use #user.
This is your "user homepage" action:
#user = User.find_by_slug(params[:slug])
erb :'users/user_homepage'
but in the view you have
#current_user.paintings
Another option to check is that (I'm no Sinatra expert) the helpers are exposed to the view but not the underlying instance variables, so you need to use
current_user.paintings

No Route Matches DELETE Sessions Api

I've started to create an Api for my rails application. I am currently creating the Sessions Controller for Log in.
But for some reason I am getting this error
Started DELETE "/api/v1/sessions/?auth_token=6157d3673725013ebddbb5e26e8cd64756949110"
for 127.0.0.1 at 2014-08-29 18:54:18 -0700
ActionController::RoutingError (No route matches [DELETE] "/api/v1/sessions"):
I am not understanding why this is happening. Sign Out seems to work perfectly on the actual web application.
I know it may need an ID according to the rake routes but I'm not sure how to implement this.
API CONTROLLER
module Api
module V1
class SessionsController < ApplicationController
skip_before_filter :verify_authenticity_token,
:if => Proc.new { |c| c.request.format == 'application/json' }
respond_to :json
def destroy
sign_out
render :status => 200,
:json => { :success => true,
:info => "Logged Out",
:data => {} }
end
end
end
end
CONTROLLER
class SessionsController < ApplicationController
def destroy
sign_out
redirect_to root_path
end
end
SESSION HELPER
def sign_out
current_user = nil
cookies.delete(:remember_token)
end
ROUTES
### API Routes
namespace :api, defaults: {format: 'json'} do
scope module: :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resources :sessions, only: [:new, :create, :destroy]
end
end
RAKE ROUTES
api_v1_sessions POST /api/v1/sessions(.:format)
api/v1/sessions#create {:format=>"json"}
api_v1_session DELETE /api/v1/sessions/:id(.:format)
api/v1/sessions#destroy {:format=>"json"}
From the documentation
You can use resource instead of the resources routes helper. It's used to create routes for a singular resource that you don't access using IDs.
namespace :api, defaults: {format: 'json'} do
namespace :v1, constraints: ApiConstraints.new(version: 1, default: true) do
resource :session, only: [:new, :create, :destroy]
end
end
which will give you
GET /session/new
POST /session
DELETE /session

How can we test /user/show?id=xx with rspec?

The route in my system is:
user_show GET /user/show(.:format) user#show.
The controller code is:
def show
#user = User.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #user}
end
end
_spec.rb
describe 'GET #show' do
it 'should return success' do
get :show, id:#user.id
expect(response).to be_success
end
end
result is:
Failure/Error: expect(response).to be_success
expected success? to return true, got false
In the browser, when I type xxx/user/show, it get error.
ActiveRecord::RecordNotFound in UserController#show
But if I type xxx/user/show?id=31, it shows user with id=31!!
Thanks for #Alex Wayne, I add more information here: I check the routes.rb file:
get "user/show"
get "user/index"
get "user/delete"
get "user/edit"
post "user/update"
resource :users, :path => :user, :as => :user
I personal think my teammate should not write down "get user/show, get user/index...." based on Rails Routing. But I can't change their code. So,
anyone know how to test user/show?id=xxx ? Many thanks~!!!!

Testing custom routes in rails 3.0.1 does not work, or is it me?

For some reason when I run this functional test
require 'test_helper'
class ListControllerTest < ActionController::TestCase
test "should get mylist" do
post :mylist, :format => :json
assert_response :success
end
end
routes.rb
SomeApplication::Application.routes.draw do
match "/mylist" => "list#mylist", :method => "POST"
end
list_controller.rb
class ListController < ApplicationController
def mylist
respond_to do |format|
format.json { render :json => []}
end
end
end
Sourcecode as a gist
I get this error:
1) Error:
test_should_get_mylist(ListControllerTest):
ActionController::RoutingError: No route matches {:controller=>"list", :format=>:json, :action=>"mylist"}
/test/functional/list_controller_test.rb:6:in `test_should_get_mylist'
Any ideas?
Regards,
Michal
OK. I got it. Those stupid errors are the most difficult to spot. Sometimes I cry for ruby to have strong typing ;)
the problem is in the routes.rb. Instead of:
match "/mylist" => "list#mylist", :method => "POST"
it should have been
match "/mylist" => "list#mylist", :via => :post
Thanks everyone who tried to help me.

Fail at redirect expectation in a controller spec

I am using Devise 1.4.2, RSpec 2.6.0 and Rails 3.1.0.rc6. My routes.rb looks like this:
scope "(:locale)", :locale => /e(s|n)/ do
resources :demotivideos, :only => [:index, :show]
devise_for :users
namespace "admin" do
resources :demotivideos, :except => [:index, :show]
end
end
I am spec'ing that, when a not logged in user acces new, create or update, he should be redirected to new_user_session_path. For this, I am using the following code
context "when not logged in" do
before(:each) do
sign_out user
end
describe "GET new" do
it "should redirect to new user session" do
get :new
response.should redirect_to(new_user_session_path)
end
end
describe "POST create" do
it "should redirect to new user session" do
post :create, :demotivideo => valid_attributes
response.should redirect_to(new_user_session_path)
end
end
describe "PUT update" do
it "should redirect to new user session" do
put :update, :id => 1, :demotivideo => valid_attributes
response.should redirect_to(new_user_session_path)
end
end
end
All are failing because of the same reason: expected route includes the locale (by default en) but the actual redirect was to the same path without locale. My application controller was modified as told in Rails Guides:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :set_locale
def default_url_options(options={})
logger.debug "default_url_options is passed options: #{options.inspect}\n"
{ :locale => I18n.locale }
end
def set_locale
I18n.locale = params[:locale] || I18n.default_locale
end
end
What am I doing wrong?
Seems like though Rails Guides uses def default_url_options in Devise you need def self.default_url_options. Don't know the difference, though.

Resources