insales_api 0.0.13 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|