Geocoder DOCS explain how to fake a Geocoder lookup with Street addresses, but it doesn't seem to work with IP addresses.
This is my spec/support/geocoder.rb
Geocoder.configure(:lookup => :test)
Geocoder::Lookup::Test.add_stub(
"1.1.1.1", [
{
'latitude' => 10,
'longitude' => 10,
'address' => 'Test Address',
'state' => 'Test State',
'state_code' => 'TS',
'country' => 'Test Country',
'country_code' => 'TC'
}
]
)
Geocoder::Lookup::Test.set_default_stub(
[
{
'latitude' => 10,
'longitude' => 10,
'address' => 'Test Address',
'state' => 'Test State',
'state_code' => 'TS',
'country' => 'Test Country',
'country_code' => 'TC'
}
]
)
this is my service:
if params[:ip]
lat = Geocoder.search(params[:ip])[0].latitude
lng = Geocoder.search(params[:ip])[0].longitude
venues = venues.near([lat, lng], APP_CONFIG['geo_location_radius'], order: 'average_rating DESC')
end
And this is my service spec:
context "find featured venues by ip" do
let(:params) do
{
date: Date.today,
featured: true,
ip: '1.1.1.1',
}
end
it do
aggregate_failures do
expect(raw_venues.map { |v| v.id }.sort).to eq [venue1.id]
end
end
end
If I enter with pry in the it block and I try Geocoder.search('1.1.1.1') I get a "real" object response with a location in Australia instead of my stub, while I correctly get my stub if I enter something like Geocoder.search('Florence, Italy') ..
How can I setup stub responses to work with IP lookup?
Solution is simply:
Geocoder.configure(ip_lookup: :test)
Related
I have a huge array full of a bunch of hashes. What I need to do is single out one index hash from the array that meets a specific criteria. (doing this due to an rspec test, but having trouble singling out one of them)
My array is like this
[
{
"name" => "jon doe",
"team" => "team2",
"price" => 2000,
"eligibility_settings" => {}
},
{
"name" => "jonny doe",
"team" => "team1",
"value" => 2000,
"eligibility_settings" => {
"player_gender" => male,
"player_max_age" => 26,
"player_min_age" => 23,
"established_union_only" => true
}
},
{
"name" => "jonni doe",
"team" => "team3",
"price" => 2000,
"eligibility_settings" => {}
},
]
I need to single out the second one, based on its eligibility settings. I just took three of them from my array, have lots more, so simple active record methods like (hash.second) won't work in this instance.
I've tried things like
players.team.map(&:hash).find{ |x| x[ 'eligibility_settings?' ] == true}
However when I try this, I get a nil response. (which is odd)
I've also looked into using the ruby detect method, which hasn't gotten me anywhere either
Players.team.map(&:hash).['hash.seligibiltiy_settings'].detect { true }
Would anybody have any idea what to do with this one?
Notes
players.team.map(&:hash).find{ |x| x[ 'eligibility_settings?' ] == true}
Players.team.map(&:hash).['hash.seligibiltiy_settings'].detect { true }
Is is players or Players ?
Why is it plural?
If you can call map on team, it probably should be plural
Why do you convert to a hash?
eligibility_settings? isn't a key in your hash. eligibility_settings is
eligibility_settings can be a hash, but it cannot be true
If you want to check if it isn't empty, use !h['eligibility_settings'].empty?
Possible solution
You could use :
data = [
{
'name' => 'jon doe',
'team' => 'team2',
'price' => 2000,
'eligibility_settings' => {}
},
{
'name' => 'jonny doe',
'team' => 'team1',
'value' => 2000,
'eligibility_settings' => {
'player_gender' => 'male',
'player_max_age' => 26,
'player_min_age' => 23,
'established_union_only' => true
}
},
{
'name' => 'jonni doe',
'team' => 'team3',
'price' => 2000,
'eligibility_settings' => {}
}
]
p data.find { |h| !h['eligibility_settings'].empty? }
# {"name"=>"jonny doe", "team"=>"team1", "value"=>2000, "eligibility_settings"=>{"player_gender"=>"male", "player_max_age"=>26, "player_min_age"=>23, "established_union_only"=>true}}
If h['eligibility_settings'] can be nil, you can use :
data.find { |h| !h['eligibility_settings'].blank? }
or
data.find { |h| h['eligibility_settings'].present? }
I am trying to implement paypal payment gateway using activemerchet but getting error-A field was longer or shorter than the server allows
i am using credrntials of pro account. I saw other SO questions but it was not helpful
require 'rubygems'
require 'active_merchant'
ActiveMerchant::Billing::Base.mode = :test
gateway = ActiveMerchant::Billing::TrustCommerceGateway.new(
:login => 'XXX#gmail.com',
:password => 'my_password',
:signature => 'my_signature')
credit_card = ActiveMerchant::Billing::CreditCard.new(
:first_name => 'f_name',
:last_name => 'l_name',
:number => '4032034467080704',
:month => '9',
:year => '2021',
:verification_value => '123',
:brand => 'VISA'
)
AMOUNT = 1000
def purchase_options
{
ip: "127.0.0.1",
billing_address: {
name: "Flaying Cakes",
address1: "123 5th Av.",
city: "New York",
state: "NY",
country: "US",
zip: "10001"
}
}
end
if credit_card.validate.empty?
response = gateway.purchase(AMOUNT, credit_card, purchase_options)
if response.success?
puts "Successfully charged to the credit card #{credit_card.display_number}"
else
raise StandardError, response.message
end
else
puts "credit card is not valid #{credit_card.errors.full_messages.join(". ")}"
end
I changed
gateway = ActiveMerchant::Billing::TrustCommerceGateway.new
to
gateway = ActiveMerchant::Billing::PaypalGateway.new
and it worked fine.
I am trying to set up my RSpec tests to use stubs rather then using networking to do the geocoding.
I added this:
before(:each) do
Geocoder.configure(:lookup => :test)
Geocoder::Lookup::Test.add_stub(
"Los Angeles, CA", [{
:latitude => 34.052363,
:longitude => -118.256551,
:address => 'Los Angeles, CA, USA',
:state => 'California',
:state_code => 'CA',
:country => 'United States',
:country_code => 'US'
}],
)
end
I am using FactoryGirl to create the test data like so:
FactoryGirl.define do
factory :market do
city 'Los Angeles'
state 'CA'
radius 20.0
end
end
The latitude/longitude are correctly being geocoded and stored in latitude/longitude. However, when I try:
Market.near(params[:search])
it returns nil.. But, if I just use the lookup => :google it works just as I intend it to. Has anyone got this working before, specifically the near method of geocoder?
I ended up coming back to this on a new project and figured it out.
The docs on geocoder actually state that the hash has to have string keys and not symbols. geocoder docs - see notes
i.e.
before(:each) do
Geocoder.configure(:lookup => :test)
Geocoder::Lookup::Test.add_stub(
"Los Angeles, CA", [{
"latitude" => 34.052363,
"longitude" => -118.256551,
"address" => 'Los Angeles, CA, USA',
"state" => 'California',
"state_code" => 'CA',
"country" => 'United States',
"country_code" => 'US'
}],
)
end
and not how I did it in the original post:
i.e. :latitude => 34.052363
I ended up doing something a bit more dynamic:
# frozen_string_literal: true
module GeocoderStub
def self.stub_with(facility)
Geocoder.configure(lookup: :test)
results = [
{
'latitude' => Faker::Address.latitude.first(9),
'longitude' => Faker::Address.longitude.first(9)
}
]
queries = [facility.full_address, facility.zip]
queries.each { |q| Geocoder::Lookup::Test.add_stub(q, results) }
end
end
and in my factory:
require './spec/support/geocoder_stub'
FactoryGirl.define do
factory :facility do
name { Faker::Company.name }
rating { rand(1..5) }
street { Faker::Address.street_address }
city { Faker::Address.city }
state { Faker::Address.state }
zip { Faker::Address.zip_code }
after(:build) { |facility| GeocoderStub.stub_with(facility) }
end
end
This adds a geocoder stub for every Facility factory that is built for both full address (method defined in facility) and zip.
I found a simpler approach to be just stubbing everything with the same values by default:
# test/test_helper.rb
Geocoder.configure(lookup: :test)
Geocoder::Lookup::Test.set_default_stub([{ coordinates: [40.7143528, -74.0059731] }])
Also, to avoid unnecessary calls, it's also a good idea to restrict your callbacks:
class Account < ActiveRecord
after_validation :geocode, if: ->(obj) { obj.address.present? and obj.address_changed? }
end
Source: https://github.com/alexreisner/geocoder#testing
gem 'paypal-sdk-merchant'
#api = PayPal::SDK::Merchant::API.new
params = {:SetExpressCheckoutRequestDetails => payment_params.merge({
:ReturnURL => return_url,
:CancelURL => cancel_url,
})}
#set_express_checkout = #api.build_set_express_checkout(params)
i need send shipping address to paypal.
How to set shipping address in params?
When in doubt, take a look at the samples on the github SDK page.
I found this example:
set_express_checkout:
SetExpressCheckoutRequestDetails:
PaymentDetails:
PaymentAction: Sale
TaxTotal:
currencyID: USD
value: 0
ShippingMethod: UPSGround
ShippingTotal:
currencyID: USD
value: 3.0
PaymentDetailsItem:
Name: Item Name
Amount:
currencyID: USD
value: 5.27
Quantity: 1
ItemCategory: Physical
ShipToAddress:
Name: John Doe
Street1: "1 Main St"
CityName: San Jose
StateOrProvince: CA
Country: US
PostalCode: "95131"
Which leads me to believe the proper way to do it would be:
#api = PayPal::SDK::Merchant::API.new
params = {:SetExpressCheckoutRequestDetails => payment_params.merge({
:ReturnURL => return_url,
:CancelURL => cancel_url,
:PaymentDetails => {
:PaymentDetailsItem => {
:Name => "Item Name",
:Amount => {
:currencyId => "USD",
:value => "1.27"
}
},
:ShipToAddress => {
:Name => "John Doe",
:Street1 => "1 Main St",
:CityName => "San Jose",
:StateOrProvince => "CA",
:Country => "US",
:PostalCode => "95131"
}
}
}
)}
#set_express_checkout = #api.build_set_express_checkout(params)
Here is the example from the crack documentation:
json = '{"posts":[{"title":"Foobar"}, {"title":"Another"}]}'
Crack::JSON.parse(json)
=> {"posts"=>[{"title"=>"Foobar"}, {"title"=>"Another"}]}
But how do I actually access the data in the hash?
I've tried the following:
array = Crack::JSON.parse(json)
array["posts"]
array["posts"] shows all the values, but I tried array["posts"]["title"] and it didn't work.
Here is what I am trying to parse as an example:
{"companies"=>[{"city"=>"San Mateo", "name"=>"Jigsaw", "address"=>"777 Mariners Island Blvd Ste 400", "zip"=>"94404-5059", "country"=>"USA", "companyId"=>4427170, "activeContacts"=>168, "graveyarded"=>false, "state"=>"CA"}], "totalHits"=>1}
I want to access the individual elements under companies....like city and name.
Like this?
hash = {
"companies" => [
{
"city" => "San Mateo",
"name" => "Jigsaw",
"address" => "777 Mariners Island Blvd Ste 400",
"zip" => "94404-5059",
"country" => "USA",
"companyId" => 4427170,
"activeContacts" => 168,
"graveyarded" => false,
"state" => "CA"
}
],
"totalHits" => 1
}
hash['companies'].each{ |i|
puts "city => #{i['city']}"
puts "name => #{i['name']}"
}
# >> city => San Mateo
# >> name => Jigsaw
hash['companies'][0]['city'] # => "San Mateo"
hash['companies'][0]['name'] # => "Jigsaw"
The problem is you didn't account for the array that companies points to.