Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also .

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
...
  • 7 commits
  • 18 files changed
  • 0 commit comments
  • 2 contributors
View
7 Gemfile
@@ -7,10 +7,13 @@ gem 'hpricot'
gem 'goodreads', :git => 'git://github.com/thegreatape/goodreads.git', :ref => '762a1487556f'
gem 'oauth'
gem 'dynamic_form'
-gem 'resque', "~> 1.22.0"
-gem 'resque-scheduler'
+gem 'sidekiq'
+gem 'sinatra', require: false
+gem 'slim'
+gem 'autoscaler'
gem 'will_paginate'
gem 'thin'
+gem 'newrelic_rpm'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
View
45 Gemfile.lock
@@ -42,6 +42,9 @@ GEM
addressable (2.3.2)
ansi (1.4.3)
arel (3.0.2)
+ autoscaler (0.0.2)
+ heroku-api
+ sidekiq (~> 2.2)
builder (3.0.0)
capistrano (2.12.0)
highline
@@ -59,6 +62,9 @@ GEM
capybara-webkit (0.12.1)
capybara (>= 1.0.0, < 1.2)
json
+ celluloid (0.12.3)
+ facter (>= 1.6.12)
+ timers (>= 1.0.0)
childprocess (0.3.5)
ffi (~> 1.0, >= 1.0.6)
coffee-rails (3.2.2)
@@ -68,13 +74,16 @@ GEM
coffee-script-source
execjs
coffee-script-source (1.3.3)
+ connection_pool (0.9.2)
daemons (1.1.9)
database_cleaner (0.8.0)
dynamic_form (1.1.4)
erubis (2.7.0)
eventmachine (1.0.0)
+ excon (0.16.7)
execjs (1.4.0)
multi_json (~> 1.0)
+ facter (1.6.14)
factory_girl (2.3.2)
activesupport
factory_girl_rails (1.4.0)
@@ -84,6 +93,8 @@ GEM
ffi (1.1.5)
haml (3.1.6)
hashie (1.0.0)
+ heroku-api (0.3.6)
+ excon (~> 0.16.7)
highline (1.6.13)
hike (1.2.1)
hpricot (0.8.6)
@@ -112,6 +123,7 @@ GEM
net-ssh (2.5.2)
net-ssh-gateway (1.1.0)
net-ssh (>= 1.99.1)
+ newrelic_rpm (3.5.0.1)
nokogiri (1.5.5)
oauth (0.4.6)
pg (0.14.0)
@@ -143,23 +155,12 @@ GEM
rake (0.9.2.2)
rdoc (3.12)
json (~> 1.4)
- redis (3.0.1)
+ redis (3.0.2)
redis-namespace (1.2.1)
redis (~> 3.0.0)
- resque (1.22.0)
- multi_json (~> 1.0)
- redis-namespace (~> 1.0)
- sinatra (>= 0.9.2)
- vegas (~> 0.1.2)
- resque-scheduler (2.0.0)
- redis (>= 2.0.1)
- resque (>= 1.20.0)
- rufus-scheduler
rest-client (1.6.7)
mime-types (>= 1.16)
rubyzip (0.9.9)
- rufus-scheduler (2.0.17)
- tzinfo (>= 0.3.23)
rvm-capistrano (1.2.5)
capistrano (>= 2.0.0)
sass (3.1.20)
@@ -178,20 +179,31 @@ GEM
shoulda-context (1.0.0)
shoulda-matchers (1.2.0)
activesupport (>= 3.0.0)
+ sidekiq (2.5.2)
+ celluloid (~> 0.12.0)
+ connection_pool (~> 0.9.2)
+ multi_json (~> 1)
+ redis (~> 3)
+ redis-namespace
sinatra (1.3.3)
rack (~> 1.3, >= 1.3.6)
rack-protection (~> 1.2)
tilt (~> 1.3, >= 1.3.3)
+ slim (1.3.3)
+ temple (~> 0.5.5)
+ tilt (~> 1.3.3)
sprockets (2.1.3)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
+ temple (0.5.5)
thin (1.5.0)
daemons (>= 1.0.9)
eventmachine (>= 0.12.6)
rack (>= 1.0.0)
thor (0.15.4)
tilt (1.3.3)
+ timers (1.0.1)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
@@ -201,8 +213,6 @@ GEM
uglifier (1.2.7)
execjs (>= 0.3.0)
multi_json (~> 1.3)
- vegas (0.1.11)
- rack (>= 1.0.0)
will_paginate (3.0.3)
xpath (0.1.4)
nokogiri (~> 1.3)
@@ -211,6 +221,7 @@ PLATFORMS
ruby
DEPENDENCIES
+ autoscaler
capistrano
capybara-webkit
coffee-rails (~> 3.2.1)
@@ -226,14 +237,16 @@ DEPENDENCIES
json
minitest
mocha (= 0.11.4)
+ newrelic_rpm
oauth
pg
rails (= 3.2.8)
- resque (~> 1.22.0)
- resque-scheduler
rvm-capistrano
sass-rails (~> 3.2.3)
shoulda
+ sidekiq
+ sinatra
+ slim
thin
turn
uglifier (>= 1.0.3)
View
2 Procfile
@@ -1,2 +1,2 @@
web: bundle exec rails server thin -p $PORT -e $RACK_ENV
-resquework: env QUEUE=* TERM_CHILD=1 bundle exec rake resque:work
+worker: bundle exec sidekiq -c 3
View
2 app/controllers/users_controller.rb
@@ -11,7 +11,7 @@ def login
def oauth_callback
@user = get_authorized_user
@user.update_shelves
- Resque.enqueue(UpdateUser, @user.id)
+ UpdateUser.perform_async @user.id
session[:user_id] = @user.id
redirect_to :controller => :books, :action => :index
View
2 app/models/book.rb
@@ -3,7 +3,7 @@ class Book < ActiveRecord::Base
belongs_to :user
validates_presence_of :user
- has_many :copies
+ has_many :copies, dependent: :destroy
scope :with_copies_at, lambda {|locations|
where("books.id in (select distinct(copies.book_id) from copies where copies.location_id in (?))", Array(locations))
View
5 app/models/user.rb
@@ -29,8 +29,9 @@ def update!
results = []
library_systems.each do |system|
bot = system.search_bot(goodreads_id)
- results = bot.lookup
- sync_books results, system
+ system_results = bot.lookup
+ results += system_results
+ sync_books system_results, system
end
delete_books_not_on_list results
end
View
5 app/workers/queue_all_users.rb
@@ -1,10 +1,9 @@
class QueueAllUsers
- @queue = :lookup
- def self.perform
+ def perform
User.find_each do |user|
puts "enqueuing #{user.id} - goodreads id #{user.goodreads_id}"
- Resque.enqueue(UpdateUser, user.id)
+ UpdateUser.perform_asyn user.id
end
end
end
View
4 app/workers/update_user.rb
@@ -1,7 +1,7 @@
class UpdateUser
- @queue = :lookup
+ include Sidekiq::Worker
- def self.perform(user_id)
+ def perform(user_id)
User.find(user_id).update!
end
end
View
14 config.ru
@@ -1,4 +1,14 @@
# This file is used by Rack-based servers to start the application.
-
require ::File.expand_path('../config/environment', __FILE__)
-run Minuteman::Application
+require 'sidekiq/web'
+
+AUTH_PASSWORD = ENV['SIDEKIQ_PASSWORD']
+if AUTH_PASSWORD
+ Sidekiq::Web.use Rack::Auth::Basic do |username, password|
+ password == AUTH_PASSWORD
+ end
+end
+
+run Rack::URLMap.new \
+ "/" => Minuteman::Application,
+ "/sidekiq" => Sidekiq::Web
View
92 config/deploy.rb
@@ -1,92 +0,0 @@
-#---
-# Excerpted from "Agile Web Development with Rails",
-# published by The Pragmatic Bookshelf.
-# Copyrights apply to this code. It may not be used to create training material,
-# courses, books, articles, and the like. Contact us if you are in doubt.
-# We make no guarantees that this code is fit for any purpose.
-# Visit http://www.pragmaticprogrammer.com/titles/rails4 for more book information.
-#---
-# be sure to change these
-set :user, 'tmayfield'
-set :domain, 'zen-hacking.com'
-set :application, 'literate-minuteman'
-
-# adjust if you are using RVM, remove if you are not
-require "rvm/capistrano"
-set :rvm_ruby_string, '1.9.3'
-
-# file paths
-set :repository, "git@github.com:thegreatape/#{application}.git"
-set :deploy_to, "/var/www/#{application}"
-
-# distribute your applications across servers (the instructions below put them
-# all on the same server, defined above as 'domain', adjust as necessary)
-role :app, domain
-role :web, domain
-role :db, domain, :primary => true
-
-# you might need to set this if you aren't seeing password prompts
-# default_run_options[:pty] = true
-
-# As Capistrano executes in a non-interactive mode and therefore doesn't cause
-# any of your shell profile scripts to be run, the following might be needed
-# if (for example) you have locally installed gems or applications. Note:
-# this needs to contain the full values for the variables set, not simply
-# the deltas.
-# default_environment['PATH']='<your paths>:/usr/local/bin:/usr/bin:/bin'
-# default_environment['GEM_PATH']='<your paths>:/usr/lib/ruby/gems/1.8'
-
-# miscellaneous options
-set :deploy_via, :remote_cache
-set :scm, 'git'
-set :branch, 'master'
-set :scm_verbose, true
-set :use_sudo, false
-set :rails_env, :production
-set :normalize_asset_timestamps, false
-
-namespace :deploy do
- desc "cause Passenger to initiate a restart"
- task :restart do
- run "touch #{current_path}/tmp/restart.txt"
- end
-
- desc "reload the database with seed data"
- task :seed do
- run "cd #{current_path}; rake db:seed RAILS_ENV=#{rails_env}"
- end
-end
-
-after "deploy:update_code", :update_config
-desc "copy prod db config and goodreads keys to deployment"
-task :update_config, :roles => :app do
- run "cd #{release_path} && cp /var/www/literate-minuteman-database.yml #{release_path}/config/database.yml"
- run "cd #{release_path} && cp /var/www/goodreads.rb #{release_path}/config/initializers/goodreads.rb"
-end
-
-after "deploy:update_code", :bundle_install
-desc "install the necessary prerequisites"
-task :bundle_install, :roles => :app do
- run "cd #{release_path} && bundle install --without=test"
-end
-
-after "bundle_install", :precompile_assets
-desc "precompile assets"
-task :precompile_assets, :roles => :app do
- run "cd #{release_path} && bundle exec rake assets:precompile"
-end
-
-after "precompile_assets", :db_migrate
-desc "run migrations"
-task :db_migrate, :roles => :app do
- run "cd #{release_path} && RAILS_ENV=production bundle exec rake db:migrate"
-end
-
-after "deploy:restart", :restart_resque
-desc "restart resque"
-task :restart_resque, :roles => :app do
- run "sudo stop resque-worker"
- run "sudo start resque-worker"
- run "sudo stop resque-scheduler"
- run "sudo start resque-scheduler"
-end
View
1 config/environments/production.rb
@@ -58,5 +58,4 @@
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
- Resque.redis = ENV['REDISTOGO_URL']
end
View
14 config/initializers/sidekiq.rb
@@ -0,0 +1,14 @@
+require 'autoscaler/sidekiq'
+require 'autoscaler/heroku_scaler'
+
+Sidekiq.configure_client do |config|
+ config.client_middleware do |chain|
+ chain.add Autoscaler::Sidekiq::Client, 'default' => Autoscaler::HerokuScaler.new
+ end
+end
+
+Sidekiq.configure_server do |config|
+ config.server_middleware do |chain|
+ chain.add(Autoscaler::Sidekiq::Server, Autoscaler::HerokuScaler.new, 60)
+ end
+end
View
255 config/newrelic.yml
@@ -0,0 +1,255 @@
+# Here are the settings that are common to all environments
+common: &default_settings
+ # ============================== LICENSE KEY ===============================
+
+ # You must specify the license key associated with your New Relic
+ # account. This key binds your Agent's data to your account in the
+ # New Relic service.
+ license_key: '<%= ENV["NEW_RELIC_LICENSE_KEY"] %>'
+
+ # Agent Enabled (Rails Only)
+ # Use this setting to force the agent to run or not run.
+ # Default is 'auto' which means the agent will install and run only
+ # if a valid dispatcher such as Mongrel is running. This prevents
+ # it from running with Rake or the console. Set to false to
+ # completely turn the agent off regardless of the other settings.
+ # Valid values are true, false and auto.
+ #
+ # agent_enabled: auto
+
+ # Application Name Set this to be the name of your application as
+ # you'd like it show up in New Relic. The service will then auto-map
+ # instances of your application into an "application" on your
+ # dashboard page. If you want to map this instance into multiple
+ # apps, like "AJAX Requests" and "All UI" then specify a semicolon
+ # separated list of up to three distinct names, or a yaml list.
+ # Defaults to the capitalized RAILS_ENV or RACK_ENV (i.e.,
+ # Production, Staging, etc)
+ #
+ # Example:
+ #
+ # app_name:
+ # - Ajax Service
+ # - All Services
+ #
+ app_name: <%= ENV["NEW_RELIC_APP_NAME"] %>
+
+ # When "true", the agent collects performance data about your
+ # application and reports this data to the New Relic service at
+ # newrelic.com. This global switch is normally overridden for each
+ # environment below. (formerly called 'enabled')
+ monitor_mode: true
+
+ # Developer mode should be off in every environment but
+ # development as it has very high overhead in memory.
+ developer_mode: false
+
+ # The newrelic agent generates its own log file to keep its logging
+ # information separate from that of your application. Specify its
+ # log level here.
+ log_level: info
+
+ # Optionally set the path to the log file This is expanded from the
+ # root directory (may be relative or absolute, e.g. 'log/' or
+ # '/var/log/') The agent will attempt to create this directory if it
+ # does not exist.
+ # log_file_path: 'log'
+
+ # Optionally set the name of the log file, defaults to 'newrelic_agent.log'
+ # log_file_name: 'newrelic_agent.log'
+
+ # The newrelic agent communicates with the service via http by
+ # default. If you want to communicate via https to increase
+ # security, then turn on SSL by setting this value to true. Note,
+ # this will result in increased CPU overhead to perform the
+ # encryption involved in SSL communication, but this work is done
+ # asynchronously to the threads that process your application code,
+ # so it should not impact response times.
+ ssl: false
+
+ # EXPERIMENTAL: enable verification of the SSL certificate sent by
+ # the server. This setting has no effect unless SSL is enabled
+ # above. This may block your application. Only enable it if the data
+ # you send us needs end-to-end verified certificates.
+ #
+ # This means we cannot cache the DNS lookup, so each request to the
+ # service will perform a lookup. It also means that we cannot
+ # use a non-blocking lookup, so in a worst case, if you have DNS
+ # problems, your app may block indefinitely.
+ # verify_certificate: true
+
+ # Set your application's Apdex threshold value with the 'apdex_t'
+ # setting, in seconds. The apdex_t value determines the buckets used
+ # to compute your overall Apdex score.
+ # Requests that take less than apdex_t seconds to process will be
+ # classified as Satisfying transactions; more than apdex_t seconds
+ # as Tolerating transactions; and more than four times the apdex_t
+ # value as Frustrating transactions.
+ # For more about the Apdex standard, see
+ # http://newrelic.com/docs/general/apdex
+
+ apdex_t: 0.5
+
+ #============================== Browser Monitoring ===============================
+ # New Relic Real User Monitoring gives you insight into the performance real users are
+ # experiencing with your website. This is accomplished by measuring the time it takes for
+ # your users' browsers to download and render your web pages by injecting a small amount
+ # of JavaScript code into the header and footer of each page.
+ browser_monitoring:
+ # By default the agent automatically injects the monitoring JavaScript
+ # into web pages. Set this attribute to false to turn off this behavior.
+ auto_instrument: true
+
+ # Proxy settings for connecting to the service.
+ #
+ # If a proxy is used, the host setting is required. Other settings
+ # are optional. Default port is 8080.
+ #
+ # proxy_host: hostname
+ # proxy_port: 8080
+ # proxy_user:
+ # proxy_pass:
+
+
+ # Tells transaction tracer and error collector (when enabled)
+ # whether or not to capture HTTP params. When true, frameworks can
+ # exclude HTTP parameters from being captured.
+ # Rails: the RoR filter_parameter_logging excludes parameters
+ # Java: create a config setting called "ignored_params" and set it to
+ # a comma separated list of HTTP parameter names.
+ # ex: ignored_params: credit_card, ssn, password
+ capture_params: false
+
+
+ # Transaction tracer captures deep information about slow
+ # transactions and sends this to the service once a
+ # minute. Included in the transaction is the exact call sequence of
+ # the transactions including any SQL statements issued.
+ transaction_tracer:
+
+ # Transaction tracer is enabled by default. Set this to false to
+ # turn it off. This feature is only available at the Professional
+ # and above product levels.
+ enabled: true
+
+ # Threshold in seconds for when to collect a transaction
+ # trace. When the response time of a controller action exceeds
+ # this threshold, a transaction trace will be recorded and sent to
+ # the service. Valid values are any float value, or (default)
+ # "apdex_f", which will use the threshold for an dissatisfying
+ # Apdex controller action - four times the Apdex T value.
+ transaction_threshold: apdex_f
+
+ # When transaction tracer is on, SQL statements can optionally be
+ # recorded. The recorder has three modes, "off" which sends no
+ # SQL, "raw" which sends the SQL statement in its original form,
+ # and "obfuscated", which strips out numeric and string literals
+ record_sql: obfuscated
+
+ # Threshold in seconds for when to collect stack trace for a SQL
+ # call. In other words, when SQL statements exceed this threshold,
+ # then capture and send the current stack trace. This is
+ # helpful for pinpointing where long SQL calls originate from
+ stack_trace_threshold: 0.500
+
+ # Determines whether the agent will capture query plans for slow
+ # SQL queries. Only supported in mysql and postgres. Should be
+ # set to false when using other adapters.
+ # explain_enabled: true
+
+ # Threshold for query execution time below which query plans will not
+ # not be captured. Relevant only when `explain_enabled` is true.
+ # explain_threshold: 0.5
+
+ # Error collector captures information about uncaught exceptions and
+ # sends them to the service for viewing
+ error_collector:
+
+ # Error collector is enabled by default. Set this to false to turn
+ # it off. This feature is only available at the Professional and above
+ # product levels
+ enabled: true
+
+ # Rails Only - tells error collector whether or not to capture a
+ # source snippet around the place of the error when errors are View
+ # related.
+ capture_source: true
+
+ # To stop specific errors from reporting to New Relic, set this property
+ # to comma separated values. Default is to ignore routing errors
+ # which are how 404's get triggered.
+ #
+ ignore_errors: ActionController::RoutingError
+
+ # (Advanced) Uncomment this to ensure the cpu and memory samplers
+ # won't run. Useful when you are using the agent to monitor an
+ # external resource
+ # disable_samplers: true
+
+ # If you aren't interested in visibility in these areas, you can
+ # disable the instrumentation to reduce overhead.
+ #
+ # disable_view_instrumentation: true
+ # disable_activerecord_instrumentation: true
+ # disable_memcache_instrumentation: true
+ # disable_dj: true
+
+ # If you're interested in capturing memcache keys as though they
+ # were SQL uncomment this flag. Note that this does increase
+ # overhead slightly on every memcached call, and can have security
+ # implications if your memcached keys are sensitive
+ # capture_memcache_keys: true
+
+ # Certain types of instrumentation such as GC stats will not work if
+ # you are running multi-threaded. Please let us know.
+ # multi_threaded = false
+
+# Application Environments
+# ------------------------------------------
+# Environment specific settings are in this section.
+# For Rails applications, RAILS_ENV is used to determine the environment
+# For Java applications, pass -Dnewrelic.environment <environment> to set
+# the environment
+
+# NOTE if your application has other named environments, you should
+# provide newrelic configuration settings for these environments here.
+
+development:
+ <<: *default_settings
+ # Turn off communication to New Relic service in development mode (also
+ # 'enabled').
+ # NOTE: for initial evaluation purposes, you may want to temporarily
+ # turn the agent on in development mode.
+ monitor_mode: false
+
+ # Rails Only - when running in Developer Mode, the New Relic Agent will
+ # present performance information on the last 100 transactions you have
+ # executed since starting the mongrel.
+ # NOTE: There is substantial overhead when running in developer mode.
+ # Do not use for production or load testing.
+ developer_mode: true
+
+ # Enable textmate links
+ # textmate: true
+
+test:
+ <<: *default_settings
+ # It almost never makes sense to turn on the agent when running
+ # unit, functional or integration tests or the like.
+ monitor_mode: false
+
+# Turn on the agent in production for 24x7 monitoring. NewRelic
+# testing shows an average performance impact of < 5 ms per
+# transaction, you you can leave this on all the time without
+# incurring any user-visible performance degradation.
+production:
+ <<: *default_settings
+ monitor_mode: true
+
+# Many applications have a staging environment which behaves
+# identically to production. Support for that environment is provided
+# here. By default, the staging environment has the agent turned on.
+staging:
+ <<: *default_settings
+ monitor_mode: true
+ app_name: <%= ENV["NEW_RELIC_APP_NAME"] %> (Staging)
View
25 db/migrate/20121104182855_add_foreign_key_to_copies.rb
@@ -0,0 +1,25 @@
+class AddForeignKeyToCopies < ActiveRecord::Migration
+ def up
+ execute <<-SQL
+ delete from copies where copies.id in (
+ select copies.id from copies
+ left join books on copies.book_id = books.id
+ where books.id is null )
+ SQL
+
+ execute <<-SQL
+ alter table copies
+ add constraint fk_copies_books
+ foreign key (book_id)
+ references books (id)
+ SQL
+ end
+
+ def down
+
+ execute <<-SQL
+ alter table copies
+ drop constraint fk_copies_books
+ SQL
+ end
+end
View
22 db/schema.rb
@@ -11,14 +11,14 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20120812201045) do
+ActiveRecord::Schema.define(:version => 20121104182855) do
create_table "books", :force => true do |t|
t.string "title"
t.integer "user_id"
t.string "author"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
t.datetime "last_synced_at"
t.string "goodreads_link"
t.string "image_url"
@@ -31,17 +31,17 @@
t.string "call_number"
t.integer "book_id"
t.string "status"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
t.datetime "last_synced_at"
t.integer "location_id"
end
create_table "library_systems", :force => true do |t|
t.string "search_bot_class"
t.string "name"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
end
create_table "library_systems_users", :force => true do |t|
@@ -52,8 +52,8 @@
create_table "locations", :force => true do |t|
t.integer "library_system_id"
t.string "name"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
end
create_table "locations_users", :force => true do |t|
@@ -65,8 +65,8 @@
t.string "oauth_access_token"
t.string "oauth_access_secret"
t.string "goodreads_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at"
+ t.datetime "updated_at"
t.datetime "last_synced_at"
t.text "shelves"
t.text "active_shelves"
View
16 lib/tasks/resque.rake
@@ -1,16 +0,0 @@
-require 'resque/tasks'
-require 'resque_scheduler/tasks'
-
-
-namespace :resque do
- task :setup => :environment do
- ENV['QUEUE'] = '*'
- require 'resque'
- require 'resque_scheduler'
- require 'resque/scheduler'
- Resque.before_fork = Proc.new { ActiveRecord::Base.establish_connection }
- Resque.schedule = YAML.load_file("#{Rails.root}/config/resque-schedule.yml")
- end
-end
-
-
View
8 test/unit/book_test.rb
@@ -2,7 +2,7 @@
class BookTest < ActiveSupport::TestCase
context "book list syncing" do
- setup do
+ setup do
@list = [
{:title => "The Areas of My Expertise",
:status => 'In',
@@ -20,7 +20,7 @@ class BookTest < ActiveSupport::TestCase
should "produce Copies" do
assert_equal 2, @book.reload.copies.length
- @book.copies.each do |copy|
+ @book.copies.each do |copy|
assert_not_nil copy.location
assert_equal @library_system, copy.location.library_system
assert_not_nil copy.call_number
@@ -33,7 +33,9 @@ class BookTest < ActiveSupport::TestCase
end
should "delete copies no longer on the list" do
- @book.sync_copies [@list.first], @library_system
+ assert_difference "Copy.count", -1 do
+ @book.sync_copies [@list.first], @library_system
+ end
assert_equal 1, @book.reload.copies.length
assert_equal @list.first[:title], @book.copies.first.title
end
View
29 test/unit/user_test.rb
@@ -30,7 +30,6 @@ class UserTest < ActiveSupport::TestCase
@user.sync_books @list, Factory(:library_system)
assert_equal 2, @user.reload.books.length
end
-
end
test "goodreads_id should be unique" do
@@ -75,4 +74,32 @@ class UserTest < ActiveSupport::TestCase
end
+ context "with multiple library systems" do
+ setup do
+ @system_a = Factory(:library_system, search_bot_class: 'SearchBots::OrangeNCBot')
+ @system_b = Factory(:library_system, search_bot_class: 'SearchBots::MinutemanBot')
+
+ @system_a.search_bot_class.constantize.any_instance.stubs(:lookup).returns( book('Title 1', 'Copley') + book('Title 2', 'Copley') )
+ @system_b.search_bot_class.constantize.any_instance.stubs(:lookup).returns( book('Title 2', 'Alston') )
+ @user = Factory(:user, library_systems: [@system_a, @system_b])
+
+ @user.update!
+ @user.reload
+ end
+
+ should "have copies from both libraries" do
+ assert_equal 2, @user.books.count
+ end
+ end
+
+ def book(title, location)
+ [ {title: title,
+ author: "John Hodgeman",
+ copies: [{title: "The Areas of My Expertise",
+ status: "Out",
+ call_number: 'A325',
+ location: location }]
+ } ]
+ end
+
end

No commit comments for this range

Something went wrong with that request. Please try again.