Unable to make a rake-tasks file and make it work properly - ruby

I decided to create a rake tasks for my Sinatra project and not to use the ready ones.
#Rakefile
require 'rake/testtask'
require 'rake/clean'
Dir.glob("tasks/*.rake").each { |r| import r }
#/tasks/seed.rake
require 'rubygems'
require 'bundler'
Bundler.require
require 'mongoid'
require_relative '../models/user'
namespace :db do
task :seed do
puts 'Creating a user....'
user1 = User.new email: "email1#gmail.com", password: "test123"
user1.save!
puts 'User has been created.'
end
end
#user.rb
require 'bcrypt'
require 'digest/md5'
require 'openssl'
class User
include Mongoid::Document
include Mongoid::Timestamps
#.........
#gemfile (partly)
source 'http://rubygems.org'
gem 'bcrypt-ruby', require: 'bcrypt'
And I've got the error of "Creating a user....
rake aborted!
undefined method `create!' for BCrypt::Password:Class
/home/alex/ruby_projects/service/models/user.rb:47:in `password='"
where #47 looks like
def password= pass
self.hashed_password = BCrypt::Password.create! pass, cost: 10
end
Note that in normal development everything works just fine. So I missed to require a file I think.
Your thoughts?
p.s. Even if I put
require 'bcrypt'
require 'digest/md5'
require 'openssl
to /tasks/seed.rake the error remains.

It appears you are using a non-existant method from BCrypt::Password. According to the docs, there is only a .create method and no .create! method. Switch to BCrypt::Password.create and it should work.
def password= pass
self.hashed_password = BCrypt::Password.create pass, cost: 10
end

Related

Rspec for ssh connection

I am trying to write rspec to test ssh connection. In my spec file even though I have enetered incorrect server password it still says 0 examples, 0 failures. Can someone exmplain me why am I seeing that whereas I am expected to see at least one failure message.
Below is the piece of code of my ssh_host.rb and ssh_host_spec.rb files.
require "java"
require "highline/import"
require 'open-uri'
require 'socket'
require 'rubygems'
require 'net/ssh'
require 'stringio'
require 'net/scp'
require 'colorize'
module SshMod
class SshHost
attr_accessor :hostname, :username, :password
def initialize(host, user, password)
#hostname = host
#username = user
#password = password
#ssh = Net::SSH.start(#hostname, #username, :password => #password)
puts "\t Connection established for #{#hostname}...".blue
end
end
end
Rspec Class:
#!/usr/bin/env rspec
require 'spec_helper'
require 'ssh_host.rb'
describe SshMod::SshHost do
before :each do
#ssh = SshMod::SshHost.new "servername", "user", "wrong_password"
end
end
describe "#new" do
it "takes three parameters and returns sshhostobject" do
#ssh.should_be_an_instance_of SshHost
end
end
ssh_mock = double()
expect(SSH).to receive(:start).and_return(ssh_mock)
There are a number of things wrong with your spec file. your test for new should be within the context of your SshMod::SshHost describe otherwise it doesn't have access to the ssh instance variable. Also, your code should throw some errors because except isn't defined in Kernel it's within the context of an Rspec object. You most likely want to put it in your before.
Regarding your requires in your ruby class, I'd get rid of everything that you don't need (for example, why the explicit inclusion of socket when using net-ssh?).
I believe however, that you're running into the issue where no tests are running most likely due to your project structure (but that's only a guess since you haven't listed it). Rspec by default looks for spec files listed under spec/**/*_spec.rb which you can override with the --pattern flag. See rspec --help for more info.
Here's a working example of your code with a bunch of things cleaned up. I put the source of your code in lib assuming you're making something like a gem.
Gemfile:
source "https://rubygems.org"
gem "colorize"
gem "rspec"
gem "net-ssh"
lib/ssh_host.rb
require 'net/ssh'
require 'colorize'
module SshMod
class SshHost
attr_accessor :hostname, :username, :password
def initialize(host, user, password)
#hostname = host
#username = user
#password = password
#ssh = Net::SSH.start(#hostname, #username, password: #password)
puts "\t Connection established for #{#hostname}...".blue
end
end
end
spec/spec_helper.rb
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
require 'rspec'
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end
spec/ssh_host_spec.rb
require 'spec_helper'
require 'ssh_host'
describe SshMod::SshHost do
let (:ssh) { SshMod::SshHost.new "servername", "user", "wrong_password" }
before :each do
allow(Net::SSH).to receive(:start).and_return(double("connection"))
end
describe "#new" do
it "takes three parameters and returns sshhostobject" do
expect(ssh).to be_a SshMod::SshHost
end
end
end

Adapter not set: default. Did you forget to setup?

I'm getting the same error when I execute my test in Rspec. DataMapper::RepositoryNotSetupError: Adapter not set: default. Did you forget to setup? I don't understand this error because I've set up Datamapper as it says in Datamapper webpage. I show you my code
vip_client-spec.rb
require 'spec_helper'
require 'data_mapper'
require 'dm-postgres-adapter'
require File.join(File.dirname(__FILE__), '..', '..', 'models', 'vip_client.rb')
describe VipClient do
before {
DataMapper.finalize.auto_upgrade!
}
describe "#insert_into_database" do
it "inserts clients into database from an array of hashes" do
list_clients = [
{name: "David", birthday: "13-12-1985", email: "daviddsrperiodismo#gmail.com"},
{name: "Javier", birthday: "05-05-1985", email: "javier#gmail.com"}
]
VipClient.insert_into_database(list_clients)
expect(VipClient.all.count).to eq(2)
end
end
end
vip_client.rb
class VipClient
include ::DataMapper::Resource
property :id, Serial
property :name, Text
property :birthday, Date
property :email, Text
def self.insert_into_database(list_clients)
end
end
app.rb
require 'sinatra'
require 'data_mapper'
require 'roo'
require 'pony'
# HELPERS
require './helpers/code'
require './helpers/check_birthday_users'
require './helpers/excel_parser'
# MODELS
require './models/vip_client.rb'
require './models/invitations.rb'
include Code
include CheckUsers
DataMapper.setup(:default, 'postgres://david:123456#localhost/usersmareta')
DataMapper.finalize.auto_upgrade!
And my gemfile is this
source "https://rubygems.org"
gem 'sinatra'
gem 'pg'
gem 'roo'
gem 'data_mapper'
gem 'dm-postgres-adapter'
gem 'pony'
group :development, :test do
gem 'rack-test'
gem 'rspec'
end
As I've said. when I do rspec the console gives me this:
Failure/Error: DataMapper.finalize.auto_upgrade!
DataMapper::RepositoryNotSetupError:
Adapter not set: default. Did you forget to setup?

Sinatra tests always 404'ing

I have a very simple Sinatra app which I'm having trouble testing.
Basically, every single request test returns a 404 when I know from testing in the browser that the request works fine. Any ideas as to what the problem might be?
test_helper.rb:
ENV["RACK_ENV"] = 'test'
$: << File.expand_path(File.dirname(__FILE__) + '/../lib')
require 'app'
Sinatra::Synchrony.patch_tests!
class Test::Unit::TestCase
include Rack::Test::Methods
end
app_test.rb
require 'test_helper'
class AppTest < Test::Unit::TestCase
def app
#app ||= Sinatra::Application
end
def test_it_says_hello
get "/"
assert_equal 200, last_response.status
end
end
app.rb
$: << 'config'
require "rubygems" require "bundler"
ENV["RACK_ENV"] ||= "development"
Bundler.require(:default, ENV["RACK_ENV"].to_sym)
require ENV["RACK_ENV"]
class App < Sinatra::Base register Sinatra::Synchrony
get '/' do
status 200
'hello, I\'m bat shit crazy and ready to rock'
end
end
Gemfile
source :rubygems
gem 'daemons'
gem 'sinatra'
gem 'sinatra-synchrony', :require => 'sinatra/synchrony'
gem 'resque'
gem 'thin'
group :test do
gem 'rack-test', :require => "rack/test"
gem 'test-unit', :require => "test/unit"
end
Why can I not get this normally very simple thing working?
I had quite the same problem with only HTTP-404 coming in return.
I solved it with giving another return in the "app" function.
class IndexClassTest < Test::Unit::TestCase
def app
#app = Foxydeal #appname NOT Sinatra::Application
end
...
Also
Sinatra::Synchrony.patch_tests!
seems to be obsolete.
Under your app_test.rb do this instead of what you have now:
def app
#app ||= App.new
end
This will work with your your class style like you had it in the beginning, no need to switch to the non-class/modular style.
It may seem logical, but are your routes configured correctly? If a route isn't correctly configured, it'll throw 404 errors left and right.
Figured it out.
app.rb
$: << 'config'
require "rubygems" require "bundler"
ENV["RACK_ENV"] ||= "development" Bundler.require(:default,
ENV["RACK_ENV"].to_sym) require ENV["RACK_ENV"]
class App < Sinatra::Base
register Sinatra::Synchrony
end
get '/' do
status 200
'hello, I\'m bat shit crazy and ready to rock'
end
You may simply do this:
class AppTest < Test::Unit::TestCase
def app
Sinatra::Application
end
You can get a solid understanding of sinatra tests by reading Learning From the Masters: Sinatra Internals and Rack::Test

Load error when trying to include custom module

Same app, different problem. I'm working on an app using the Dan Benjamin "Meet Sinatra" screencast as a reference. I'm trying to include a custom authentication module, which is housed in a lib folder (lib/authentication.rb). I am requiring that line at the top of my code, but when I try to load the page, it claims there is no such file to load.
Any thoughts?
Here's the top of my main Sinatra file:
require 'sinatra'
require 'rubygems'
require 'datamapper'
require 'dm-core'
require 'lib/authorization'
DataMapper::setup(:default, "sqlite3://#{Dir.pwd}/entries.db")
class Entry
include DataMapper::Resource
property :id, Serial
property :first_name, String
property :last_name, String
property :email, String
property :created_at, DateTime
end
# create, upgrade, or migrate tables automatically
DataMapper.auto_upgrade!
helpers do
include Sinatra::Authorization
end
And the actual Module:
module Sinatra
module Authorization
def auth
#auth ||= Rack::Auth::Basic::Request.new(request.env)
end
def unauthorized!(realm="Short URL Generator")
headers 'WWW-Authenticate' => %(Basic realm="#{realm}")
throw :halt, [ 401, 'Authorization Required' ]
end
def bad_request!
throw :halt, [ 400, 'Bad Request' ]
end
def authorized?
request.env['REMOTE_USER']
end
def authorize(username, password)
if (username=='topfunky' && password=='peepcode') then
true
else
false
end
end
def require_admin
return if authorized?
unauthorized! unless auth.provided?
bad_request! unless auth.basic?
unauthorized! unless authorize(*auth.credentials)
request.env['REMOTE_USER'] = auth.username
end
def admin?
authorized?
end
end
end
Then, on any of the handlers I want to protect, I put "require_admin."
Assuming you're using Ruby 1.9, the default $LOAD_PATH no longer includes the current directory. So while statements like require 'sinatra' work just fine (because those gems are in $LOAD_PATH), Ruby doesn't know that your lib/authorization file is located relative to your main Sinatra file.
You can add the Sinatra file's directory to the load path, and then your require statements should work fine:
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'sinatra'
require 'rubygems' # Not actually needed on Ruby 1.9
require 'datamapper'
require 'dm-core'
require 'lib/authorization'
Personnaly, I use a "relative" path since I work with Ruby 1.9.2 :
require 'sinatra'
require 'rubygems' # Not actually needed on Ruby 1.9
require 'datamapper'
require 'dm-core'
require './lib/authorization'
But I never check what would happen if my code should work on Ruby 1.8.6 again.

Sinatra/CouchDB error?

I'm working on my first Sinatra/CouchDB project and I'm getting an error I can't explain.
Here's my rackup (config.ru) file:
require 'rubygems'
require 'couchrest'
require 'patina'
set :environment, :development
set :root, File.dirname(__FILE__)
set :run, false
FileUtils.mkdir_p 'log' unless File.exists?('log')
log = File.new("log/sinatra.log", "a")
$stdout.reopen(log)
$stderr.reopen(log)
set :db, CouchRest.database!("http://127.0.0.1:5984/test")
run Sinatra::Application
And here's the app file (patina.rb):
require 'rubygems'
require 'sinatra'
require 'couchrest'
require 'haml'
class Article < CouchRest::ExtendedDocument
use_database settings.db
property :title
timestamps!
view_by :title
end
get '/' do
#db = settings.db
haml :index
end
Without the class definition in patina.rb, the route returns a page that displays the #db property as I was expecting. However, when I add the class definition to patina.rb I get "Ruby (Rack) application could not be started" error message.
Obviously this has something to do with my class definition, but I can't figure out what the problem is and the error message doesn't seem that helpful to me.
Also, I'd actually prefer to have the class definition in a separate file (Article.rb), but I can't figure out how to do that in the context of my Sinatra app.
Any help would be greatly appreciated!
EDIT:
See my answer below.
After a lot of googling, I discovered that the 1.4 series of json.gem are known to cause a lot of problems. I uninstalled all the json gems I had and installed json-1.2.4.gem instead. I have everything working correctly now. Here's the setup I'm using:
config.ru (Rackup file):
require 'application'
set :environment, :production
set :root, File.dirname(__FILE__)
set :run, false
FileUtils.mkmdir_p 'log' unless File.exists?('log')
log = File.new('log/sinatra.log', 'a+')
$stdout.reopen(log)
$stderr.reopen(log)
run Sinatra::Application
environment.rb:
require 'rubygems'
require 'couchrest'
require 'haml'
require 'ostruct'
require 'sinatra' unless defined?(Sinatra)
configure do
SiteConfig = OpenStruct.new(
:title => 'Application Title',
:author => 'Your Name',
:url_base => 'Your URL',
:url_base_db => 'Your CouchDB Server',
:db_name => "Your DB Name"
)
# load models
$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib")
Dir.glob("#{File.dirname(__FILE__)}/lib/*.rb") { |lib| require File.basename(lib, '.*') }
end
lib/contact.rb (Model example, models auto-loaded in environment.rb):
class Contact < CouchRest::ExtendedDocument
include CouchRest::Validation
use_database CouchRest.database!((SiteConfig.url_base_db || '') + SiteConfig.db_name)
property :name
timestamps!
view_by :name
end
application.rb:
require 'rubygems'
require 'sinatra'
require 'environment'
configure do
set :views, "./views"
end
error do
e = request.env['sinatra.error']
Kernel.puts e.backtrace.join("\n")
'Application error'
end
helpers do
end
get '/new/?' do
haml :new
end
post '/save/?' do
#contact_name = params[:contact_name]
#contact = Contact.new
#contact.name = #contact_name
#contact.save
haml :save
end
get '/' do
haml :index
end
Hope this helps someone in the future!
try requiring 'patina' after setting :db. I think the class body of Article is executing the use_database method before the setting exists.
you should be able to put Article in article.rb (ruby naming convention is UpperCamel for classes, but under_scores for the files in which classes are defined) and then require 'article' in patina.rb.
thats the only thing that stood out for me, so let me know if that works.

Resources