Browse Source

lk | posts to bike index in sidekiq job

master
Loos 9 years ago
parent
commit
356098b7a6
  1. 3
      .env.development
  2. 6
      Gemfile
  3. 16
      Gemfile.lock
  4. 4
      app/assets/javascripts/application.js
  5. 6
      app/assets/javascripts/bikes.coffee
  6. 2
      app/assets/javascripts/bikes.js
  7. 19
      app/models/bike.rb
  8. 13
      app/services/bike_index_bike_generator.rb
  9. 32
      app/workers/bike_index_logger.rb
  10. 0
      spec/factories/bike_factory.rb
  11. 0
      spec/factories/client_factory.rb
  12. 0
      spec/factories/user_factory.rb
  13. 21
      spec/models/bike_spec.rb
  14. 42
      spec/services/bike_index_bike_generator_spec.rb
  15. 63
      spec/workers/bike_index_logger_spec.rb

3
.env.development

@ -0,0 +1,3 @@
OWNER_EMAIL: 'coolemail@example.com'
BIKE_INDEX_URL: 'http://lvh.me:3000'
BIKE_INDEX_TOKEN: 'asdfklkjasfdljkd3asdfjkl2asdf'

6
Gemfile

@ -7,6 +7,7 @@ gem 'devise'
gem 'faraday', '0.9.1' gem 'faraday', '0.9.1'
gem 'oauth2', '1.0.0' gem 'oauth2', '1.0.0'
gem 'dotenv-rails' gem 'dotenv-rails'
gem 'sidekiq'
#SCSS & Bootstrap #SCSS & Bootstrap
gem 'bootstrap-sass', '2.3.2.0' gem 'bootstrap-sass', '2.3.2.0'
@ -27,12 +28,15 @@ group :test, :development do
gem 'better_errors' gem 'better_errors'
gem 'assert_difference' gem 'assert_difference'
gem 'binding_of_caller' gem 'binding_of_caller'
gem 'webmock', '1.21.0'
# Uncomment this line on OS X. # Uncomment this line on OS X.
gem 'growl', '1.0.3' gem 'growl', '1.0.3'
end end
group :test do
gem 'webmock', '1.21.0'
end
gem 'uglifier', '2.1.1' gem 'uglifier', '2.1.1'
gem 'jquery-rails', '3.0.4' gem 'jquery-rails', '3.0.4'
gem 'jquery-turbolinks' gem 'jquery-turbolinks'

16
Gemfile.lock

@ -46,6 +46,8 @@ GEM
rack (>= 1.0.0) rack (>= 1.0.0)
rack-test (>= 0.5.4) rack-test (>= 0.5.4)
xpath (~> 2.0) xpath (~> 2.0)
celluloid (0.16.0)
timers (~> 4.0.0)
childprocess (0.5.6) childprocess (0.5.6)
ffi (~> 1.0, >= 1.0.11) ffi (~> 1.0, >= 1.0.11)
coderay (1.1.0) coderay (1.1.0)
@ -56,6 +58,7 @@ GEM
coffee-script-source coffee-script-source
execjs execjs
coffee-script-source (1.9.1.1) coffee-script-source (1.9.1.1)
connection_pool (2.1.3)
crack (0.4.2) crack (0.4.2)
safe_yaml (~> 1.0.0) safe_yaml (~> 1.0.0)
debug_inspector (0.0.2) debug_inspector (0.0.2)
@ -87,6 +90,7 @@ GEM
haml (4.0.6) haml (4.0.6)
tilt tilt
hike (1.2.3) hike (1.2.3)
hitimes (1.2.2)
i18n (0.7.0) i18n (0.7.0)
jbuilder (1.0.2) jbuilder (1.0.2)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
@ -149,6 +153,9 @@ GEM
rake (10.4.2) rake (10.4.2)
rdoc (3.12.2) rdoc (3.12.2)
json (~> 1.4) json (~> 1.4)
redis (3.2.1)
redis-namespace (1.5.1)
redis (~> 3.0, >= 3.0.4)
responders (1.1.2) responders (1.1.2)
railties (>= 3.2, < 4.2) railties (>= 3.2, < 4.2)
rspec (3.2.0) rspec (3.2.0)
@ -188,6 +195,12 @@ GEM
multi_json (~> 1.0) multi_json (~> 1.0)
rubyzip (< 1.0.0) rubyzip (< 1.0.0)
websocket (~> 1.0.4) websocket (~> 1.0.4)
sidekiq (3.3.3)
celluloid (>= 0.16.0)
connection_pool (>= 2.1.1)
json
redis (>= 3.0.6)
redis-namespace (>= 1.3.1)
slop (3.6.0) slop (3.6.0)
sprockets (2.12.3) sprockets (2.12.3)
hike (~> 1.2) hike (~> 1.2)
@ -201,6 +214,8 @@ GEM
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.5) thread_safe (0.3.5)
tilt (1.4.1) tilt (1.4.1)
timers (4.0.1)
hitimes
treetop (1.4.15) treetop (1.4.15)
polyglot polyglot
polyglot (>= 0.3.1) polyglot (>= 0.3.1)
@ -252,6 +267,7 @@ DEPENDENCIES
sass-rails (~> 4.0.0) sass-rails (~> 4.0.0)
sdoc (= 0.3.20) sdoc (= 0.3.20)
selenium-webdriver (= 2.35.1) selenium-webdriver (= 2.35.1)
sidekiq
turbolinks (= 1.1.1) turbolinks (= 1.1.1)
uglifier (= 2.1.1) uglifier (= 2.1.1)
webmock (= 1.21.0) webmock (= 1.21.0)

4
app/assets/javascripts/application.js

@ -14,6 +14,6 @@
//= require jquery_ujs //= require jquery_ujs
//= require turbolinks //= require turbolinks
//= require_tree . //= require_tree .
//= require bootstrap //= require bootstrap
//= require bootstrap-datepicker //= require bootstrap-datepicker
//= require bootstrap-select //= require bootstrap-select

6
app/assets/javascripts/bikes.coffee

@ -0,0 +1,6 @@
seatTubeIn = $(".seat-tube-in")
seatTubeCm = $(".seat-tube-cm")
seatTubeIn.on("change", () ->
seatTubeCm.val(parseFloat(seatTubeIn.val())*2.54)
)

2
app/assets/javascripts/bikes.js

@ -1,2 +0,0 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

19
app/models/bike.rb

@ -12,7 +12,7 @@ class Bike < ActiveRecord::Base
end end
def client def client
client = Client.find_by bike_id: self.id Client.find_by bike_id: self.id
end end
def ready_for_pickup? def ready_for_pickup?
@ -35,22 +35,7 @@ class Bike < ActiveRecord::Base
def post_to_bike_index def post_to_bike_index
return true if self.bike_index_id.present? return true if self.bike_index_id.present?
BikeIndexLogger.perform_async(self.id)
conn = Faraday.new(:url => "#{ENV['BIKE_INDEX_URL']}") do |faraday|
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
response = conn.post do |req|
req.url "/api/v2/bikes?access_token=#{ENV['BIKE_INDEX_TOKEN']}"
req.headers['Content-Type'] = 'application/json'
req.body = BikeIndexBikeGenerator.create_bike_index_bike(self)
end
self.update_attribute :bike_index_id, JSON.parse(response.body)['bike']['id'] if response.status == 201
end end
end end

13
app/services/bike_index_bike_generator.rb

@ -1,13 +0,0 @@
class BikeIndexBikeGenerator
def self.create_bike_index_bike(bike)
{
serial: bike.serial_number,
manufacturer: bike.brand,
owner_email: ENV["OWNER_EMAIL"],
color: bike.color,
is_for_sale: bike.purpose != "freecyclery",
frame_model: bike.model,
no_notify: true
}.to_json
end
end

32
app/workers/bike_index_logger.rb

@ -0,0 +1,32 @@
class BikeIndexLogger
include Sidekiq::Worker
def perform(bike_id)
bike = Bike.find(bike_id)
conn = Faraday.new(:url => "#{ENV['BIKE_INDEX_URL']}") do |faraday|
faraday.request :url_encoded
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
response = conn.post do |req|
req.url "/api/v2/bikes?access_token=#{ENV['BIKE_INDEX_TOKEN']}"
req.headers['Content-Type'] = 'application/json'
req.body = BikeIndexLogger.create_bike_index_bike(bike)
end
bike.update_attribute :bike_index_id, JSON.parse(response.body)['bike']['id'] if response.status == 201
end
def self.create_bike_index_bike(bike)
{
serial: bike.serial_number,
manufacturer: bike.brand,
owner_email: ENV["OWNER_EMAIL"],
color: bike.color,
is_for_sale: bike.purpose != "freecyclery",
frame_model: bike.model,
no_notify: true
}.to_json
end
end

0
spec/factories/bikes.rb → spec/factories/bike_factory.rb

0
spec/factories/clients.rb → spec/factories/client_factory.rb

0
spec/factories/users.rb → spec/factories/user_factory.rb

21
spec/models/bike_spec.rb

@ -1,18 +1,15 @@
require 'spec_helper' require 'spec_helper'
describe Bike do describe Bike do
it "posts to bike index" do describe "#post_to_bike_index" do
it "calls BikeIndexLogger if no bike_index_id is present" do
expect(BikeIndexLogger).to receive(:perform_async)
create(:bike, bike_index_id: nil)
end
WebMock.stub_request(:post, "http://lvh.me:3000/api/v2/bikes?access_token=asdfklkjasfdljkd3asdfjkl2asdf") it "returns true if bike_index_id is present" do
.and_return(:status => 201, :body => {bike: {id: 1}}.to_json, :headers => {}) bike = create(:bike, bike_index_id: 1)
bike = create(:bike, bike_index_id: nil) expect(bike.post_to_bike_index).to be_truthy
expect(bike.bike_index_id).to eq(1) end
end
it "assigns bike_index_id after posting to bike index" do
WebMock.stub_request(:post, "http://lvh.me:3000/api/v2/bikes?access_token=asdfklkjasfdljkd3asdfjkl2asdf")
.and_return(:status => 400, :body => {error: "error"}.to_json, :headers => {})
bike = create(:bike, bike_index_id: nil)
expect(bike.bike_index_id).to_not be_present
end end
end end

42
spec/services/bike_index_bike_generator_spec.rb

@ -1,42 +0,0 @@
require 'spec_helper'
describe BikeIndexBikeGenerator do
it "creates a bike with required attributes" do
bike = create(:bike)
bikeIndexBikeJson = BikeIndexBikeGenerator.create_bike_index_bike(bike)
bikeIndexBike = JSON.parse(bikeIndexBikeJson)
expect(bikeIndexBike["serial"]).to eq(bike.serial_number)
expect(bikeIndexBike["manufacturer"]).to eq(bike.brand)
expect(bikeIndexBike["frame_model"]).to eq(bike.model)
expect(bikeIndexBike["owner_email"]).to eq(ENV["OWNER_EMAIL"])
expect(bikeIndexBike["no_notify"]).to be_truthy
expect(bikeIndexBike["color"]).to eq(bike.color)
end
describe "freecyclery bikes" do
it "is_for_sale is false" do
bike = create(:bike, purpose: "freecyclery")
bikeIndexBikeJson = BikeIndexBikeGenerator.create_bike_index_bike(bike)
bikeIndexBike = JSON.parse(bikeIndexBikeJson)
expect(bikeIndexBike["is_for_sale"]).to be_falsey
end
end
describe "sale bikes" do
it "is_for_sale is true" do
bike = create(:bike, purpose: "sale")
bikeIndexBikeJson = BikeIndexBikeGenerator.create_bike_index_bike(bike)
bikeIndexBike = JSON.parse(bikeIndexBikeJson)
expect(bikeIndexBike["is_for_sale"]).to be_truthy
end
end
end

63
spec/workers/bike_index_logger_spec.rb

@ -0,0 +1,63 @@
require 'spec_helper'
describe BikeIndexLogger do
context "#create_bike_index_bike" do
it "creates a bike with required attributes" do
bike = build(:bike)
allow(Bike).to receive(:find).and_return(bike)
bikeIndexBikeJson = BikeIndexLogger.create_bike_index_bike(bike)
bikeIndexBike = JSON.parse(bikeIndexBikeJson)
expect(bikeIndexBike["serial"]).to eq(bike.serial_number)
expect(bikeIndexBike["manufacturer"]).to eq(bike.brand)
expect(bikeIndexBike["frame_model"]).to eq(bike.model)
expect(bikeIndexBike["owner_email"]).to eq(ENV["OWNER_EMAIL"])
expect(bikeIndexBike["no_notify"]).to be_truthy
expect(bikeIndexBike["color"]).to eq(bike.color)
end
describe "freecyclery bikes" do
it "is_for_sale is false" do
bike = build(:bike, purpose: "freecyclery")
allow(Bike).to receive(:find).and_return(bike)
bikeIndexBikeJson = BikeIndexLogger.create_bike_index_bike(bike)
bikeIndexBike = JSON.parse(bikeIndexBikeJson)
expect(bikeIndexBike["is_for_sale"]).to be_falsey
end
end
describe "sale bikes" do
it "is_for_sale is true" do
bike = build(:bike, purpose: "sale")
allow(Bike).to receive(:find).and_return(bike)
bikeIndexBikeJson = BikeIndexLogger.create_bike_index_bike(bike)
bikeIndexBike = JSON.parse(bikeIndexBikeJson)
expect(bikeIndexBike["is_for_sale"]).to be_truthy
end
end
end
it "assigns bike_index_id on successful response from bike index" do
WebMock.stub_request(:post, "http://lvh.me:3000/api/v2/bikes?access_token=asdfklkjasfdljkd3asdfjkl2asdf")
.and_return(:status => 201, :body => {bike: {id: 1}}.to_json, :headers => {})
allow_any_instance_of(Bike).to receive(:post_to_bike_index)
bike = create(:bike, bike_index_id: nil)
allow(Bike).to receive(:find).and_return(bike)
BikeIndexLogger.new.perform(bike.id)
expect(bike.bike_index_id).to eq(1)
end
it "does not assign bike_index_id on unsuccessful response from bike index" do
WebMock.stub_request(:post, "http://lvh.me:3000/api/v2/bikes?access_token=asdfklkjasfdljkd3asdfjkl2asdf")
.and_return(:status => 400, :body => {error: "error"}.to_json, :headers => {})
allow_any_instance_of(Bike).to receive(:post_to_bike_index)
bike = create(:bike, bike_index_id: nil)
allow(Bike).to receive(:find).and_return(bike)
BikeIndexLogger.new.perform(bike.id)
expect(bike.bike_index_id).to_not be_present
end
end
Loading…
Cancel
Save