insales_api 0.0.13 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +6 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile +1 -1
- data/README.md +57 -0
- data/Rakefile +8 -1
- data/insales_api.gemspec +12 -12
- data/lib/insales/controller/autologin.rb +45 -0
- data/lib/insales/controller/base_helpers.rb +52 -0
- data/lib/insales/controller/installer_actions.rb +19 -0
- data/lib/insales/controller/session_actions.rb +39 -0
- data/lib/insales/controller.rb +10 -0
- data/lib/insales.rb +7 -0
- data/lib/insales_api/account.rb +1 -9
- data/lib/insales_api/active_resource_proxy.rb +31 -0
- data/lib/insales_api/app.rb +57 -38
- data/lib/insales_api/application_charge.rb +3 -0
- data/lib/insales_api/asset.rb +3 -1
- data/lib/insales_api/base.rb +41 -5
- data/lib/insales_api/category.rb +8 -2
- data/lib/insales_api/client.rb +3 -1
- data/lib/insales_api/client_group.rb +3 -0
- data/lib/insales_api/collect.rb +8 -2
- data/lib/insales_api/discount_code.rb +3 -0
- data/lib/insales_api/helpers/has_insales_object.rb +34 -0
- data/lib/insales_api/helpers/init_api.rb +98 -0
- data/lib/insales_api/image.rb +5 -0
- data/lib/insales_api/order.rb +13 -5
- data/lib/insales_api/order_line.rb +2 -2
- data/lib/insales_api/product.rb +3 -1
- data/lib/insales_api/product_field.rb +3 -0
- data/lib/insales_api/product_field_value.rb +22 -0
- data/lib/insales_api/property.rb +3 -0
- data/lib/insales_api/resource/countable.rb +9 -0
- data/lib/insales_api/resource/paginated.rb +26 -0
- data/lib/insales_api/resource/with_updated_since.rb +28 -0
- data/lib/insales_api/theme.rb +7 -1
- data/lib/insales_api/variant.rb +18 -6
- data/lib/insales_api/version.rb +7 -1
- data/lib/insales_api.rb +74 -17
- data/spec/lib/insales_api/active_resource_proxy_spec.rb +59 -0
- data/spec/lib/insales_api/app_spec.rb +67 -0
- data/spec/lib/insales_api_spec.rb +110 -0
- data/spec/spec_helper.rb +3 -4
- metadata +54 -20
- data/README +0 -32
- data/spec/lib/insales_app_spec.rb +0 -63
@@ -0,0 +1,98 @@
|
|
1
|
+
module InsalesApi::Helpers
|
2
|
+
module InitApi
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class_attribute :insales_app_class
|
7
|
+
self.insales_app_class = InsalesApi::App
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
# Wraps methods into +init_api+ block. So you can be sure that method
|
12
|
+
# will run for certain account.
|
13
|
+
#
|
14
|
+
# class Account < ActiveRecord::Base
|
15
|
+
# include InsalesApi::Helpers
|
16
|
+
#
|
17
|
+
# def find_products_by_name(name)
|
18
|
+
# # ...
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# init_api_for :find_products_by_name
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# account1 = Account.find(1)
|
25
|
+
# account2 = Account.find(2)
|
26
|
+
#
|
27
|
+
# products1 = account1.find_products_by_name('smth')
|
28
|
+
# products2 = account2.find_products_by_name('smth_else')
|
29
|
+
#
|
30
|
+
# # instead of
|
31
|
+
# # products1 = account1.init_api { find_products_by_name('smth') }
|
32
|
+
# # products2 = account2.init_api { find_products_by_name('smth_else') }
|
33
|
+
#
|
34
|
+
# Can be used in nessted classes like this:
|
35
|
+
#
|
36
|
+
# class Order < ActiveRecord::Base
|
37
|
+
# extend InsalesApi::Helpers::ClassMethods
|
38
|
+
#
|
39
|
+
# belongs_to :account
|
40
|
+
#
|
41
|
+
# delegate :init_api, to: :account
|
42
|
+
#
|
43
|
+
# def insales_order
|
44
|
+
# InsalesApi::Order.find(insales_id)
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# init_api_for :insales_order
|
48
|
+
# end
|
49
|
+
#
|
50
|
+
# insales_order = Order.first.insales_order
|
51
|
+
#
|
52
|
+
def init_api_for(*methods)
|
53
|
+
file, line = caller.first.split(':', 2)
|
54
|
+
methods.each do |method|
|
55
|
+
alias_method_chain method, :init_api do |target, punct|
|
56
|
+
class_eval <<-RUBY, file, line.to_i - 1
|
57
|
+
def #{target}_with_init_api#{punct}(*args, &block) # def sell_with_init_api(*args, &block)
|
58
|
+
init_api { #{target}_without_init_api#{punct}(*args, &block) } # init_api { sell_without_init_api(*args, &block) }
|
59
|
+
end # end
|
60
|
+
RUBY
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# Configures api with credentials taken from +self.insales_domain+ and
|
67
|
+
# +self.insales_password+.
|
68
|
+
#
|
69
|
+
# If block is given, it is evaluated and its result is returned.
|
70
|
+
# After this old configuration is restored.
|
71
|
+
#
|
72
|
+
# account1 = Account.find(1)
|
73
|
+
# account2 = Account.find(2)
|
74
|
+
#
|
75
|
+
# account1.init_api
|
76
|
+
# # account1 credentials are used
|
77
|
+
# product1 = InsalesApi::Product.find(1)
|
78
|
+
# # will search within second account
|
79
|
+
# product2 = account2.init_api { InsalesApi::Product.find(2) }
|
80
|
+
# # configuration is restored
|
81
|
+
# variant1 = InsalesApi::Variants.find(1)
|
82
|
+
#
|
83
|
+
def init_api
|
84
|
+
if block_given?
|
85
|
+
old_config = insales_app_class.dump_config
|
86
|
+
begin
|
87
|
+
init_api
|
88
|
+
yield
|
89
|
+
ensure
|
90
|
+
insales_app_class.restore_config(old_config)
|
91
|
+
end
|
92
|
+
else
|
93
|
+
insales_app_class.configure_api(insales_domain, insales_password)
|
94
|
+
self
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/insales_api/order.rb
CHANGED
@@ -1,15 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
module InsalesApi
|
2
3
|
class Order < Base
|
4
|
+
extend Resource::WithUpdatedSince
|
5
|
+
|
3
6
|
def order_lines_attributes
|
4
|
-
@order_lines_attributes =
|
5
|
-
|
6
|
-
|
7
|
+
@order_lines_attributes = order_lines.map do |order_line|
|
8
|
+
ol = order_line.as_json
|
9
|
+
# при смене версии рельсов (видимо) изменилась сериализация
|
10
|
+
ol = ol['order_line'] if ol['order_line']
|
11
|
+
ol
|
7
12
|
end
|
8
|
-
@order_lines_attributes
|
9
13
|
end
|
10
14
|
|
11
15
|
def to_xml(options = {})
|
12
|
-
super(options.merge(
|
16
|
+
super(options.merge(methods: :order_lines_attributes))
|
17
|
+
end
|
18
|
+
|
19
|
+
def paid?
|
20
|
+
financial_status == 'paid'
|
13
21
|
end
|
14
22
|
end
|
15
23
|
end
|
data/lib/insales_api/product.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
module InsalesApi
|
2
|
+
class ProductFieldValue < Base
|
3
|
+
self.prefix = "#{prefix}products/:product_id/"
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def find_by_field_id(params)
|
7
|
+
field_id = params[:product_field_id]
|
8
|
+
all(params: {product_id: params[:product_id]}).
|
9
|
+
find { |x| x.product_field_id == field_id }
|
10
|
+
end
|
11
|
+
|
12
|
+
def create_or_update(params)
|
13
|
+
if value = find_by_field_id(params)
|
14
|
+
value.update_attribute(:value, params[:value])
|
15
|
+
value
|
16
|
+
else
|
17
|
+
create(params)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module InsalesApi
|
2
|
+
PER_PAGE_DEFAULT = 100
|
3
|
+
|
4
|
+
module Resource
|
5
|
+
module Paginated
|
6
|
+
def find_each(*args)
|
7
|
+
find_in_batches(*args) do |batch|
|
8
|
+
batch.each { |record| yield record }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def find_in_batches(options = {})
|
13
|
+
per_page = options[:per_page] || PER_PAGE_DEFAULT
|
14
|
+
params = {per_page: per_page}.merge(options[:params] || {})
|
15
|
+
page = 1
|
16
|
+
loop do
|
17
|
+
items = all(params: params.merge(page: page))
|
18
|
+
return unless items.any?
|
19
|
+
yield items
|
20
|
+
return if items.count < per_page
|
21
|
+
page += 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module InsalesApi
|
2
|
+
module Resource
|
3
|
+
module WithUpdatedSince
|
4
|
+
def find_in_batches(options = {}, &block)
|
5
|
+
return super unless updated_since = options.delete(:updated_since)
|
6
|
+
find_updated_since(updated_since, options, &block)
|
7
|
+
end
|
8
|
+
|
9
|
+
def find_updated_since(updated_since, options = {})
|
10
|
+
per_page = options[:per_page] || PER_PAGE_DEFAULT
|
11
|
+
params = { per_page: per_page }.merge(options[:params] || {})
|
12
|
+
last_id = nil
|
13
|
+
loop do
|
14
|
+
items = all(params: params.merge(
|
15
|
+
updated_since: updated_since,
|
16
|
+
from_id: last_id,
|
17
|
+
))
|
18
|
+
return unless items.any?
|
19
|
+
yield items
|
20
|
+
return if items.count < per_page
|
21
|
+
last_item = items.last
|
22
|
+
last_id = last_item.id
|
23
|
+
updated_since = last_item.updated_at
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/insales_api/theme.rb
CHANGED
data/lib/insales_api/variant.rb
CHANGED
@@ -1,11 +1,23 @@
|
|
1
1
|
module InsalesApi
|
2
2
|
class Variant < Base
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
class << self
|
4
|
+
# Updates all given variants. +variants+ should be array:
|
5
|
+
#
|
6
|
+
# [
|
7
|
+
# {
|
8
|
+
# id: 1,
|
9
|
+
# price: 340,
|
10
|
+
# quantity: 4,
|
11
|
+
# },
|
12
|
+
# {
|
13
|
+
# id: 2,
|
14
|
+
# price: 350,
|
15
|
+
# quantity: 5,
|
16
|
+
# },
|
17
|
+
# ]
|
18
|
+
def group_update(variants)
|
19
|
+
put(:group_update, {}, format.encode(variants, root: :variants))
|
20
|
+
end
|
8
21
|
end
|
9
|
-
|
10
22
|
end
|
11
23
|
end
|
data/lib/insales_api/version.rb
CHANGED
data/lib/insales_api.rb
CHANGED
@@ -1,40 +1,97 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'active_support'
|
1
3
|
require 'active_support/core_ext'
|
2
4
|
require 'active_resource'
|
3
5
|
# backport from 4.0
|
4
6
|
require 'active_resource/singleton' unless ActiveResource.const_defined?(:Singleton, false)
|
5
|
-
require 'digest/md5'
|
6
7
|
|
7
8
|
module InsalesApi
|
8
9
|
extend ActiveSupport::Autoload
|
9
10
|
|
11
|
+
Deprecator = ActiveSupport::Deprecation.new('1.0', name)
|
12
|
+
|
10
13
|
eager_autoload do
|
11
|
-
autoload :
|
12
|
-
autoload :
|
14
|
+
autoload :VERSION
|
15
|
+
autoload :Base
|
13
16
|
autoload :Password
|
17
|
+
autoload :App
|
14
18
|
|
15
|
-
autoload :Base
|
16
19
|
autoload :Account
|
20
|
+
autoload :ApplicationCharge
|
21
|
+
autoload :ApplicationWidget
|
22
|
+
autoload :Asset
|
17
23
|
autoload :Category
|
18
24
|
autoload :Client
|
19
|
-
autoload :
|
25
|
+
autoload :ClientGroup
|
20
26
|
autoload :Collect
|
27
|
+
autoload :Collection
|
28
|
+
autoload :DeliveryVariant
|
29
|
+
autoload :DiscountCode
|
30
|
+
autoload :Domain
|
31
|
+
autoload :Field
|
32
|
+
autoload :File
|
33
|
+
autoload :Image
|
34
|
+
autoload :JsTag
|
21
35
|
autoload :OptionName
|
22
36
|
autoload :OptionValue
|
23
|
-
autoload :Product
|
24
|
-
autoload :Variant
|
25
|
-
autoload :Webhook
|
26
37
|
autoload :Order
|
27
38
|
autoload :OrderLine
|
28
|
-
autoload :ApplicationWidget
|
29
|
-
autoload :Field
|
30
|
-
autoload :DeliveryVariant
|
31
|
-
autoload :PaymentGateway
|
32
|
-
autoload :JsTag
|
33
|
-
autoload :Domain
|
34
39
|
autoload :Page
|
35
|
-
autoload :
|
36
|
-
autoload :
|
40
|
+
autoload :PaymentGateway
|
41
|
+
autoload :Product
|
42
|
+
autoload :ProductField
|
43
|
+
autoload :ProductFieldValue
|
44
|
+
autoload :Property
|
37
45
|
autoload :RecurringApplicationCharge
|
38
|
-
autoload :
|
46
|
+
autoload :Theme
|
47
|
+
autoload :Variant
|
48
|
+
autoload :Webhook
|
39
49
|
end
|
50
|
+
|
51
|
+
class << self
|
52
|
+
# Calls the supplied block. If the block raises <tt>ActiveResource::ServerError</tt> with 503
|
53
|
+
# code which means Insales API request limit is reached, it will wait for the amount of seconds
|
54
|
+
# specified in 'Retry-After' response header. The called block will receive a parameter with
|
55
|
+
# current attempt number.
|
56
|
+
#
|
57
|
+
# ==== Params:
|
58
|
+
#
|
59
|
+
# +max_attempts+:: maximum number of attempts. Defaults to +nil+ (unlimited).
|
60
|
+
# +callback+:: +Proc+ or lambda to execute before waiting. Will receive four arguments: number
|
61
|
+
# of seconds we are going to wait, number of failed attempts, maximum number of
|
62
|
+
# attempts and the caught <tt>ActiveResource::ServerError</tt>. Defaults to +nil+
|
63
|
+
# (no callback).
|
64
|
+
#
|
65
|
+
# ==== Example
|
66
|
+
#
|
67
|
+
# notify_user = Proc.new do |wait_for, attempt, max_attempts, ex|
|
68
|
+
# puts "API limit reached. Waiting for #{wait_for} seconds. Attempt #{attempt}/#{max_attempts}"
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# InsalesApi.wait_retry(10, notify_user) do |x|
|
72
|
+
# puts "Attempt ##{x}."
|
73
|
+
# products = InsalesApi::Products.all
|
74
|
+
# end
|
75
|
+
def wait_retry(max_attempts = nil, callback = nil, &block)
|
76
|
+
attempts = 0
|
77
|
+
|
78
|
+
begin
|
79
|
+
attempts += 1
|
80
|
+
yield attempts
|
81
|
+
rescue ActiveResource::ServerError => ex
|
82
|
+
raise ex if '503' != ex.response.code.to_s
|
83
|
+
raise ex if max_attempts && attempts >= max_attempts
|
84
|
+
retry_after = (ex.response['Retry-After'] || 150).to_i
|
85
|
+
callback.call(retry_after, attempts, max_attempts, ex) if callback
|
86
|
+
sleep(retry_after)
|
87
|
+
retry
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
40
92
|
end
|
93
|
+
|
94
|
+
require 'insales_api/helpers/init_api'
|
95
|
+
require 'insales_api/helpers/has_insales_object'
|
96
|
+
|
97
|
+
ActiveSupport.run_load_hooks(:insales_api, InsalesApi)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe InsalesApi::ActiveResourceProxy do
|
4
|
+
let(:proxy) { described_class.new(configurer, object) }
|
5
|
+
let(:configurer) { Object.new.tap { |x| x.stub(:init_api).and_yield } }
|
6
|
+
|
7
|
+
describe '#method_missing' do
|
8
|
+
let(:object) { {} }
|
9
|
+
let(:method_name) { :some_method }
|
10
|
+
subject { proxy.send(method_name) }
|
11
|
+
|
12
|
+
it 'should proxy method to object & pass result through #proxy_for' do
|
13
|
+
result1 = {test: :resut1}
|
14
|
+
result2 = {test: :resut2}
|
15
|
+
object.should_receive(method_name).and_return(result1)
|
16
|
+
proxy.should_receive(:proxy_for).with(result1).and_return(result2)
|
17
|
+
subject.should eq(result2)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '::need_proxy?' do
|
22
|
+
subject { described_class.need_proxy?(object) }
|
23
|
+
|
24
|
+
context 'for scalar' do
|
25
|
+
let(:object) { true }
|
26
|
+
it { should be false }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'for array' do
|
30
|
+
let(:object) { [] }
|
31
|
+
it { should be true }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'for hash' do
|
35
|
+
let(:object) { {} }
|
36
|
+
it { should be true }
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'for InsalesApi::Base class' do
|
40
|
+
let(:object) { InsalesApi::Account }
|
41
|
+
it { should be true }
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'for InsalesApi::Base object' do
|
45
|
+
let(:object) { InsalesApi::Account.new }
|
46
|
+
it { should be true }
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'for ActiveResource::Collection object' do
|
50
|
+
let(:object) { ActiveResource::Collection.new }
|
51
|
+
it { should be true }
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'for ActiveResource::Base object' do
|
55
|
+
let(:object) { ActiveResource::Base.new }
|
56
|
+
it { should be false }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe InsalesApi::App do
|
4
|
+
let(:domain) { 'my.shop.com' }
|
5
|
+
let(:password) { 'password' }
|
6
|
+
let(:app) { InsalesApi::App.new(domain, password) }
|
7
|
+
|
8
|
+
subject { app }
|
9
|
+
|
10
|
+
describe '#initialize' do
|
11
|
+
its(:domain) { should eq(domain) }
|
12
|
+
its(:password) { should eq(password) }
|
13
|
+
its(:authorized?) { should be false }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#configure_api' do
|
17
|
+
it 'configures InsalesApi::Base' do
|
18
|
+
InsalesApi::Base.should_receive(:configure).with(described_class.api_key, domain, password)
|
19
|
+
app.configure_api
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#salt' do
|
24
|
+
its(:salt) { should be }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#auth_token' do
|
28
|
+
its(:auth_token) { should eq(InsalesApi::Password.create(app.password, app.salt)) }
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'authorization_url' do
|
32
|
+
subject { app.authorization_url }
|
33
|
+
let(:expected) do
|
34
|
+
URI::Generic.build(
|
35
|
+
scheme: 'http',
|
36
|
+
host: domain,
|
37
|
+
path: "/admin/applications/#{app.api_key}/login",
|
38
|
+
query: {
|
39
|
+
token: app.salt,
|
40
|
+
login: app.api_autologin_url,
|
41
|
+
}.to_query,
|
42
|
+
).to_s
|
43
|
+
end
|
44
|
+
it { should eq(expected) }
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#authorize' do
|
48
|
+
before { app.auth_token }
|
49
|
+
subject { app.authorize(token) }
|
50
|
+
|
51
|
+
context 'when valid token is given' do
|
52
|
+
let(:token) { app.auth_token }
|
53
|
+
it { should be true }
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'when invalid token is given' do
|
57
|
+
let(:token) { 'bad_token' }
|
58
|
+
it { should be false }
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe '::password_by_token' do
|
63
|
+
let(:token) { 'test' }
|
64
|
+
subject { InsalesApi::App.password_by_token(token) }
|
65
|
+
it { should eq(InsalesApi::Password.create(InsalesApi::App.api_secret, token)) }
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe InsalesApi do
|
4
|
+
|
5
|
+
describe '.wait_retry' do
|
6
|
+
|
7
|
+
response_stub = Struct.new(:code, :retry_after) do
|
8
|
+
def [](key)
|
9
|
+
{'Retry-After' => retry_after}[key]
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should not run without block' do
|
14
|
+
expect do
|
15
|
+
described_class.wait_retry(20, nil)
|
16
|
+
end.to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should handle succesfull request' do
|
20
|
+
counter = 0
|
21
|
+
described_class.wait_retry do
|
22
|
+
counter += 1
|
23
|
+
end
|
24
|
+
|
25
|
+
expect(counter).to eq(1)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should make specified amount of attempts' do
|
29
|
+
counter = 0
|
30
|
+
described_class.wait_retry(3) do
|
31
|
+
counter += 1
|
32
|
+
|
33
|
+
if counter < 3
|
34
|
+
raise ActiveResource::ServerError.new(response_stub.new("503", "0"))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
expect(counter).to eq(3)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should use callback proc' do
|
42
|
+
callback = Proc.new{}
|
43
|
+
counter = 0
|
44
|
+
callback.should_receive(:call).with(0, 1, 3, instance_of(ActiveResource::ServerError))
|
45
|
+
callback.should_receive(:call).with(0, 2, 3, instance_of(ActiveResource::ServerError))
|
46
|
+
|
47
|
+
described_class.wait_retry(3, callback) do
|
48
|
+
counter += 1
|
49
|
+
|
50
|
+
if counter < 3
|
51
|
+
raise ActiveResource::ServerError.new(response_stub.new("503", "0"))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should pass attempt number to block' do
|
57
|
+
last_attempt_no = 0
|
58
|
+
described_class.wait_retry(3) do |x|
|
59
|
+
last_attempt_no = x
|
60
|
+
|
61
|
+
if last_attempt_no < 3
|
62
|
+
raise ActiveResource::ServerError.new(response_stub.new("503", "0"))
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
expect(last_attempt_no).to eq(3)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should raise if no attempts left' do
|
70
|
+
expect do
|
71
|
+
described_class.wait_retry(3) do |x|
|
72
|
+
raise ActiveResource::ServerError.new(response_stub.new("503", "0"))
|
73
|
+
end
|
74
|
+
end.to raise_error(ActiveResource::ServerError)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should raise on user errors' do
|
78
|
+
attempts = 0
|
79
|
+
expect do
|
80
|
+
described_class.wait_retry(3) do |x|
|
81
|
+
attempts = x
|
82
|
+
raise 'Some other error'
|
83
|
+
end
|
84
|
+
end.to raise_error(StandardError)
|
85
|
+
expect(attempts).to eq(1)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should raise on other server errors' do
|
89
|
+
attempts = 0
|
90
|
+
expect do
|
91
|
+
described_class.wait_retry(3) do |x|
|
92
|
+
attempts = x
|
93
|
+
raise ActiveResource::ServerError.new(response_stub.new("502", "0"))
|
94
|
+
end
|
95
|
+
end.to raise_error(ActiveResource::ServerError)
|
96
|
+
expect(attempts).to eq(1)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should run until success' do |x|
|
100
|
+
success = false
|
101
|
+
described_class.wait_retry do |x|
|
102
|
+
raise ActiveResource::ServerError.new(response_stub.new("503", "0")) if x < 10
|
103
|
+
success = true
|
104
|
+
end
|
105
|
+
|
106
|
+
expect(success).to be_true
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
3
|
require 'insales_api'
|
4
4
|
|
5
|
-
InsalesApi::App.api_key
|
6
|
-
InsalesApi::App.api_secret
|
7
|
-
InsalesApi::App.
|
8
|
-
InsalesApi::App.api_autologin_path = 'session/autologin'
|
5
|
+
InsalesApi::App.api_key = 'test'
|
6
|
+
InsalesApi::App.api_secret = 'test'
|
7
|
+
InsalesApi::App.api_autologin_url = 'https://host.com/session/autologin'
|
9
8
|
|
10
9
|
RSpec.configure do |config|
|
11
10
|
# == Mock Framework
|