ERROR - Could not load 'guard/sass' or find class Guard::Sass - guard

I'm not sure how I've done it, but upon running guard on my project, I'm getting the following error:
WARN: Unresolved specs during Gem::Specification.reset:
thor (>= 0.14.6)
WARN: Clearing out unresolved specs.
Please report a bug if this causes problems.
11:25:16 - ERROR - Could not load 'guard/sass' or find class Guard::Sass
11:25:16 - ERROR - Unable to activate sass-3.3.0.alpha.229, because listen-1.3.0 conflicts with listen (~> 1.1.0)
11:25:16 - ERROR - Invalid Guardfile, original error is:
> [#] undefined method `new' for nil:NilClass
11:25:16 - INFO - Guard is using TerminalTitle to send notifications.
11:25:16 - INFO - Guard is now watching at '/srv/www/unknowntales.net'
11:25:16 - INFO - LiveReload is waiting for a browser to connect.
My Guardfile looks like this (and was generated by Laravel Guard):
guard :concat, :type => "css", :files => %w[foundation normalize], :input_dir => "public/css", :output => "public/css/styles.min"
guard :concat, :type => "js", :files => %w[vendor/jquery vendor/custom.modernizr vendor/zepto foundation/foundation.joyride foundation/foundation.topbar foundation/foundation.placeholder foundation/foundation.tooltips foundation/foundation.magellan foundation/foundation.clearing foundation/foundation.abide foundation/foundation.interchange foundation/foundation.alerts foundation/index foundation/foundation foundation/foundation.cookie foundation/foundation.forms foundation/foundation.dropdown foundation/foundation.orbit foundation/foundation.section foundation/foundation.reveal], :input_dir => "public/js", :output => "public/js/scripts.min"
# Refresh the browser on save
guard 'livereload' do
watch(%r{.+(?<!\.min)\.(css|html|js|blade\.php)$})
end
guard :phpunit, :all_on_start => false, :tests_path => 'app/tests/', :cli => '--colors -c phpunit.xml' do
# Run any test in app/tests upon save.
watch(%r{^.+Test\.php$})
# When a view file is updated, run tests.
# Tip: you probably only want to run your integration tests.
watch(%r{app/views/.+\.php}) { Dir.glob('app/tests/**/*.php') }
# When a file is edited, try to run its associated test.
# Save app/models/User.php, and it will run app/tests/models/UserTest.php
watch(%r{^app/(.+)/(.+)\.php$}) { |m| "app/tests/#{m[1]}/#{m[2]}Test.php"}
end
module ::Guard
class Refresher < Guard
def run_all
# refresh
end
def run_on_additions(paths)
refresh
end
def run_on_removals(paths)
refresh
end
def refresh
`php artisan guard:refresh`
end
end
end
require 'cssmin'
require 'jsmin'
guard :refresher do
watch(%r[public/js/.+])
watch(%r[public/css/.+])
watch(%r{app/config/packages/way/guard-laravel/guard.php}) do |m|
`php artisan guard:refresh`
end
watch('public/css/styles.min.css') do |m|
css = File.read(m[0])
File.open(m[0], 'w') { |file| file.write(CSSMin.minify(css)) }
end
watch('public/js/scripts.min.js') do |m|
js = File.read(m[0])
File.open(m[0], 'w') { |file| file.write(JSMin.minify(js)) }
end
end
guard :sass, :input => 'app/assets/sass', :output => 'public/css'

Related

Airbrake not catching errors for Sidekiq in Rails app on an environment other than development

I'm using Sidekiq and Airbrake in my Rails application. I would like Airbrake to catch any errors that occur during Sidekiq jobs. As per instructions I found online, I've added the following to sidekiq.rb:
config.error_handlers << Proc.new { |ex,context| Airbrake.notify_or_ignore(ex, parameters: context) }
Airbrake then was able to catch errors when they occurred in my development environment. However, once I deployed to a higher environment, Airbrake stopped being able to catch Sidekiq errors. Is there any reason this would happen? Is there anything else I need to configure inside my app?
I'm using sidekiq gem version ~>3.0.2, airbrake gem version ~>4.0.0, and rails 3.2.18
Here is my full sidekiq.rb:
require 'sidekiq'
require 'sidekiq-status'
redis_connection = "redis://127.0.0.1:6379/0"
Sidekiq.configure_server do |config|
config.redis = { :url => redis_connection, :namespace => 'sidekiq' }
config.server_middleware do |chain|
chain.add Sidekiq::Status::ServerMiddleware, expiration: 30.minutes
end
config.client_middleware do |chain|
chain.add Sidekiq::Status::ClientMiddleware
end
config.error_handlers << Proc.new { |ex,context| Airbrake.notify_or_ignore(ex, parameters: context) }
end
Sidekiq.configure_client do |config|
config.redis = { :url => redis_connection, :namespace => 'sidekiq' }
config.client_middleware do |chain|
chain.add Sidekiq::Status::ClientMiddleware
end
end
And here is my full airbrake.rb:
Airbrake.configure do |config|
config.user_attributes = [:id, :email]
config.api_key = '*my_api_key*'
end
It turns out that if your app is also using rubber, then you also have to change your rubber sidekiq initializer (config/rubber/common/initializers/sidekiq) to include the line:
config.error_handlers << Proc.new { |ex,context| Airbrake.notify_or_ignore(ex, parameters: context) }
The rubber sidekiq initializer is used for all non-development environments, whereas the sidekiq.rb file is used for development environment.

Rspec testing API with rack protection

I am trying to test my API with an rspec integration(request) test.
I go to my api endpoint at 0.0.0.0:3000/api/regions in a browser and it returns my data, I get a session id and looks like everything is working.
I am using rack protection in my API:
module Api
class Root < Grape::API
use Rack::Protection, instrumenter: ActiveSupport::Notifications
use Rack::Protection::AuthenticityToken
prefix 'api'
helpers do
def warden
request.env['warden']
end
end
version 'v1', using: :header, vendor: 'vendor', strict: false do
mount Resources::V1::Search => '/'
mount Resources::V1::Regions => '/'
end
end
end
The api resource:
module Resources
module V1
class Regions < Grape::API
resource :regions do
get do
# Some code...
end
end
end
end
end
spec_helper.rb
[...]
RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods
config.include Rack::Test::Methods, type: :request
config.include Module.new { def app; Api::Root; end }, type: :request
config.include Warden::Test::Helpers
# ## Mock Framework
#
# If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
#
# config.mock_with :mocha
# config.mock_with :flexmock
# config.mock_with :rr
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
# If true, the base class of anonymous controllers will be inferred
# automatically. This will be the default behavior in future versions of
# rspec-rails.
config.infer_base_class_for_anonymous_controllers = false
# Run specs in random order to surface order dependencies. If you find an
# order dependency and want to debug it, you can fix the order by providing
# the seed, which is printed after each run.
# --seed 1234
config.order = "random"
end
Here is a test:
describe Resources::V1::Regions do
describe 'GET /regions' do
it 'returns some data' do
get '/api/regions'
[... expectations - doesn't get here...]
end
end
end
Here is the error:
RuntimeError:
you need to set up a session middleware *before* Rack::Protection::RemoteToken
# ./spec/requests/api/region_spec.rb:6:in `block (3 levels) in <top (required)>'
Which comes from here: https://github.com/rkh/rack-protection/blob/master/lib/rack/protection/base.rb#L85
So I need to add rack session middleware, right?
I add use Rack::Session::Cookie, secret: '...' to my api which gets me to request.env['warden'] being nil (another question another time).
Now, however, when I load the endpoint with the browser I get:
undefined method `each' for #<ActionDispatch::Request::Session:0x7f7bf9e521e0 not yet loaded>
which raises over here: https://github.com/rack/rack/blob/master/lib/rack/session/abstract/id.rb#L158
I suspect I don't need to use Rack::Session::Cookie, as something else is doing it when loaded by the server, but I need to add something for the tests to work. No idea what that something is.
Please let me know if you need any other info.
Versions:
grape (0.6.1)
rails (4.0.2)
rack-protection (1.5.2)
rspec (2.14.1)
I was solving this by adding a 'rack.session' hash to the 3rd argument of my request i.e get '/api/regions', {}, {'rack.session' => {}}
But I found a better way: https://github.com/heavysixer/grape-on-rack/pull/1
which adds sessions and solves the warden issue at the same time.
RSpec.configure do |config|
[...]
rack_app = Module.new do
def app
#app ||= Rack::Builder.new do
use Rack::Session::Cookie
Warden::Manager.serialize_into_session { |user| user.id }
Warden::Manager.serialize_from_session { |id| User.get(id) }
use Warden::Manager do |manager|
manager.default_strategies :password, :basic
# manager.failure_app = Acme::BadAuthentication
end
run Api::Root
end
end
end
config.include rack_app, type: :request
end
Marking as answer unless anyone has anything better.

Can't test engine routes under Rails 3.2 + Rspec 2.13

In my engine 'Utilizer', I'm trying to test routes with Rspec 3.2.
Namespace are isolated
# lib/utilizer/engine.rb
module Utilizer
class Engine < ::Rails::Engine
isolate_namespace Utilizer
...
end
end
The engine is mounted to the dummy app:
# spec/dummy/config/routes.rb
Rails.application.routes.draw do
mount Utilizer::Engine => "/utilizer", as: 'utilizer'
end
To the spec_helper.rb I've added a couple of configures as below (from here):
# spec/spec_helper.rb
RSpec.configure do |config|
...
config.before(:each, type: :routing) { #routes = Utilizer::Engine.routes }
...
end
When I defined a route:
# config/routes.rb
Utilizer::Engine.routes.draw do
resources :auths, id: /\d+/, only: [:destroy]
end
Rake shows it properly for the dummy app:
$ spec/dummy > bundle exec rake routes
$ utilizer /utilizer Utilizer::Engine
$ Routes for Utilizer::Engine:
$ auth DELETE /auths/:id(.:format) utilizer/auths#destroy {:id=>/\d+/}
BUT both Rspec tests
# spec/routing/auths_routing_spec.rb
require 'spec_helper'
describe "Auths page routing" do
let!(:auth) { create(:utilizer_auth) } # factory is working properly by itself
describe "#destroy" do
let!(:action) { { controller: "utilizer/auths", action: "destroy", id: auth.id } }
specify { { delete: "/auths/#{ auth.id }" }.should route_to(action) }
specify { { delete: auth_path(auth) }.should route_to(action) }
end
end
fail with errors (for the first and second tests correspondingly):
No route matches "/auths/1"
No route matches "/utilizer/auths/1"
But, Holmes, why?
Since RSpec 2.14 you can use the following:
describe "Auths page routing" do
routes { Utilizer::Engine.routes }
# ...
end
Source: https://github.com/rspec/rspec-rails/pull/668
I've fount a solution in Exoth's comment at the end of this discussion on Github (thanks to Brandan).
In my spec_helper instead of
config.before(:each, type: :routing) { #routes = Utilizer::Engine.routes }
I use
config.before(:each, type: :routing) do
#routes = Utilizer::Engine.routes
assertion_instance.instance_variable_set(:#routes, Utilizer::Engine.routes)
end
and it works.

How to determine ActiveModel::Errors validation type

With the migration from Rails 2 to Rails 3 validation errors were moved from ActiveRecord::Error to ActiveModel::Errors.
In rails 2 the validation error had a type and a message (among other things) and you could check the type of the validation error by doing something like the following:
rescue ActiveRecord::RecordInvalid => e
e.record.errors.each do |attr, error|
if error.type == :foo
do_something
end
end
end
But with Rails 3 it seems everything but the invalid attribute and message has been lost. As a result the only way to determine the type is to compare the error message:
rescue ActiveRecord::RecordInvalid => e
e.record.errors.each do |attr, error|
if error == "foobar"
do_something
end
end
end
Which is not at all ideal (eg. what if you have several validations which use the same message?).
Question:
Is there a better way in rails 3.0 to determine the type of validation error?
Check for added? on ActiveModel::Errors:
https://github.com/rails/rails/blob/master/activemodel/lib/active_model/errors.rb#L331
That allows you to do this:
record.errors.added?(:field, :error)
I needed it not only for test purposes, but also for API. I've ended up with monkey patch:
module CoreExt
module ActiveModel
module Errors
# When validation on model fails, ActiveModel sets only human readable
# messages. This does not allow programmatically identify which
# validation rule exactly was violated.
#
# This module patches {ActiveModel::Errors} to have +details+ property,
# that keeps name of violated validators.
#
# #example
# customer.valid? # => false
# customer.errors.messages # => { email: ["must be present"] }
# customer.errors.details # => { email: { blank: ["must be present"] } }
module Details
extend ActiveSupport::Concern
included do
if instance_methods.include?(:details)
fail("Can't monkey patch. ActiveModel::Errors already has method #details")
end
def details
#__details ||= Hash.new do |attr_hash, attr_key|
attr_hash[attr_key] = Hash.new { |h, k| h[k] = [] }
end
end
def add_with_details(attribute, message = nil, options = {})
error_type = message.is_a?(Symbol) ? message : :invalid
normalized_message = normalize_message(attribute, message, options)
details[attribute][error_type] << normalized_message
add_without_details(attribute, message, options)
end
alias_method_chain :add, :details
def clear_with_details
details.clear
clear_without_details
end
alias_method_chain :clear, :details
end
end
end
end
end
# Apply monkey patches
::ActiveModel::Errors.send(:include, ::CoreExt::ActiveModel::Errors::Details)

assert_routing with method is giving an error instead of failing

In my rails 3.2.3 app, I have a topics controller, which is modeled as a resource. I want to write a functional test to verify that post on /topics is a valid route. This should fail first, and then I will add the code to fix it. However, I am getting an error in the routing test, instead of a failure. What am I doing wrong?(Note: If I fix the route in routes.rb, the test passes - just not sure why I am getting an error instead of a failure in the test):
# topics_controller_test.rb
test 'route exists to create topic' do
assert_routing({:path => '/topics', :method => 'post'} , { :controller => "topics", :action => "create"}, {}, {}, 'could not route to create topic')
end
# routes.rb
resources :topics, :only => [:new]
# terminal output
$ rake test:functionals
Run options:
# Running tests:
.....E.
Finished tests in 0.373543s, 18.7395 tests/s, 53.5414 assertions/s.
1) Error:
test_route_exists_to_create_topic(TopicsControllerTest):
ActionController::RoutingError: No route matches "/topics"
.../gems/ruby-1.9.3-p0/gems/actionpack-3.2.3/lib/action_dispatch/routing/route_set.rb:633:in `recognize_path'
.../gems/ruby-1.9.3-p0/gems/actionpack-3.2.3/lib/action_dispatch/testing/assertions/routing.rb:210:in `recognized_request_for'
.../gems/ruby-1.9.3-p0/gems/actionpack-3.2.3/lib/action_dispatch/testing/assertions/routing.rb:42:in `assert_recognizes'
.../gems/ruby-1.9.3-p0/gems/actionpack-3.2.3/lib/action_dispatch/testing/assertions/routing.rb:118:in `assert_routing'
`.../myapp/test/functional/topics_controller_test.rb:25:in block in <class:TopicsControllerTest>'`
>> 7 tests, 20 assertions, 0 failures, 1 errors, 0 skips
The created route in routes.rb is different from the route your testing. If you want to route to the :create action in the controller, in your routes.rb you should use:
resources :topics, :only => [:create]
See the routing topic in the RailsGuides.