Routes not matching in Rspec tests - ruby

I can't seem to get a matching route in my rspec tests and I am not quite sure why.
routes.rb
resources :admins, only: [:index] do
get 'configs', on: :collection, to: 'admins#configs'
end
Rspec response
Failure/Error: get '/admins/config'
ActionController::RoutingError:
No route matches [GET] "/admins/config"
I run rails routes | grep config and this is the response so I think I am using the correct route
configs_admins GET /admins/configs(.:format) admins#configs

You defined '/admins/configs' (plural) but you're trying to access '/admins/config' (singular).

Related

No route matches [GET] "/" when trying to add the gem devise

The error comes with
Please add some routes in config/routes.rb.
routes.rb already has
devise_for :users
I am not sure how to fix this error. I have tried rake routes in the GIT terminal with the result:
rake aborted!
Don't know how to build task 'routes' (See the list of available tasks with `rake --tasks`)
Running in development mode on local server.
So few things:
Firstly, rake routes has been removed - I have no idea why tbh, but it is rails routes now instead.
Secondly, devise is adding its routes, but you still need to have some ohter content that devise is to guard access to. You can create a simple HomeController:
class HomeController < ApplicationController
def show
render html: "home"
end
end
and use this as your root route:
# routes.rb
devise_for ...
root to: "home#show"

Bypass not_found filter in Sinatra

I am trying to configure Sinatra to
Show a simple 404 string in all requests that are not found.
Send a custom 404 video file in one route, when the route fails to fulfill the request.
The minimal code to show the issue:
# somefile.txt
some content
# server.rb
require 'sinatra'
require 'sinatra/reloader'
set :bind, '0.0.0.0'
set :port, 3000
not_found do
content_type :text
"404 Not Found"
end
get '/test' do
# in reality this is a video file, not a text file.
# .. do some work here, and if failed, send 404 file ...
# this does not work, since it triggers the not_found filter above
send_file "somefile.txt", type: :text, status: 404
# this works, but with 200 instead of 404
# send_file "somefile.txt", type: :text
end
The not_found filter captures everything, even the send_file ... status: 404
To me, this seems a little like a bug in send_file, but perhaps I am wrong.
Is there a way to state "skip the not_found filter", or any other more appropriate way to achieve this?
Keep in mind, in reality, this server should return a not found video file, not a text file. I used text here just for simplicity.
That is not a bug, as documentation states,
When a Sinatra::NotFound exception is raised, or the response’s status code is 404, the not_found handler is invoked:
I suppose that you can solve problem by replacing not_found override with error handling like this:
error Sinatra::NotFound do
content_type :text
"404 Not Found"
end
This should trigger only on error, not on response code.

URL Map an entire namespace using rack mount?

I have two modular Sinatra rack based applications: core.rb & project.rb:
# core.rb
class Core < Sinatra::Base
get "/" do
"Hello, world!"
end
end
# project.rb
class Project < Sinatra::Base
get "/" do
"A snazzy little Sinatra project I wish to showcase."
end
get "/foo" do
"If you see this, congratulations."
end
end
My goal is simply to map the entire /projects namespace to the Project class, wheras everything else is handled by the Core class. I found that you can do this to a limited extent in 2 ways:
# config.ru
require "./core.rb"
require "./projects.rb"
map "/projects" do
# Method #1: Using Sinatra's built-in Middleware
use Project
# Method #2: Using Rack::Cascade
run Rack::Cascade.new( [Project, Core] )
end
run Core
Both of the methods I tried above have the same effect. The routes / and /projects show up correctly, however when going to /projects/foo it throws an error which states it can't find the /foo route in my main core.rb file - which is NOT what I want. In other words it's looking for my /foo route in the wrong file :(
So, is it possible to map across the entire /projects namespace using rack-mount? And no, adding "/projects/" to all my routes in project.rb is not an option here I'm afraid.
Your config.ru file seems to work okay when I test it, but it looks a little confused. Here’s a simpler example that achieves the same thing:
map "/projects" do
run Project # note run, not use
end
run Core
Now any request where the path starts with /projects will be routed to the Project app, and all other will go to Core, which is associated with the root path automatically.

Rails routing error after scaffolding?

So I'm receiving a routing error No route matches [GET] "/"
my routes.rb:
Webapp::Application.routes.draw do
resources :ideas
end
I scaffolded this ideas controller together by running this in my projects folder:
$ rails generate scaffold idea name:string description:text picture:string
$ rake db:migrate
$ rails s
& thats when I received the routing error.
What do you have for root :to => in routes.rb?
This determines [GET] "/"

How do I configure RSpec with Sinatra to dynamically determine which Sinatra app is running before my test suite runs?

Ok so. I'm wanting to do request specs with RSpec for my Sinatra app.
I have a config.ru
# config.ru
require File.dirname(__FILE__) + '/config/boot.rb'
map 'this_route' do
run ThisApp
end
map 'that_route' do
run ThatApp
end
The boot.rb just uses Bundler and does additional requires for the rest of the app:
ThisApp looks like:
# lib/this_app.rb
class ThisApp < Sinatra::Base
get '/hello' do
'hello'
end
end
So I'm using RSpec and I want to write request specs like:
# spec/requests/this_spec.rb
require_relative '../spec_helper'
describe "This" do
describe "GET /this_route/hello" do
it "should reach a page" do
get "/hello"
last_response.status.should be(200)
end
end
it "should reach a page that says hello" do
get "/hello"
last_response.body.should have_content('hello')
end
end
end
end
This works fine because my spec_helper.rb is setup as follows:
# spec/spec_helper.rb
ENV['RACK_ENV'] = "test"
require File.expand_path(File.dirname(__FILE__) + "/../config/boot")
require 'capybara/rspec'
RSpec.configure do |config|
config.include Rack::Test::Methods
end
def app
ThisApp
end
But my problem is that I want to test "ThatApp" from my rackup file along with any amount more apps I might add later along with "ThisApp". For example if I had a second request spec file:
# spec/requests/that_spec.rb
require_relative '../spec_helper'
describe "That" do
describe "GET /that_route/hello" do
it "should reach a page" do
get "/hello"
last_response.status.should be(200)
end
end
it "should reach a page that says hello" do
get "/hello"
last_response.body.should have_content('hello')
end
end
end
end
RackTest requires the rack app I'm testing be defined in the spec_helper file with that 'app' method, and I think eventually I'm going to have to feed Capybara.app the same thing as well when doing further request specs with it.
I feel like I'm missing something and maybe there's an easy way to setup 'app' for RackTest and Capybara at runtime depending on what route and consequent rack app I'm testing in my request specs. Like a before filter in RSpec.configure maybe, but I can't think of or find how I'd access what rack app is currently loaded and try and set it there before the test suite runs.
Anyone get what I'm trying to do and can think of something? Thanks for any help.
Define a different helper module for each sinatra app you want to test, each of which should define its own app method that returns the corresponding app. Then you can simply include MySinatraAppHelper in the appropriate example groups where you want to test the the given app.
You can also use rspec metadata to have the module included in example groups automatically.
Have a look at my sinatra-rspec-bundler-template. Especially at the spec files. I think that's what you are trying to achieve.
It combines two separate Sinatra apps each with it's own specs.

Resources