amorail 0.5.0 → 0.7.1
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/.github/workflows/rspec.yml +23 -0
- data/.gitignore +2 -1
- data/CHANGELOG.md +27 -0
- data/README.md +49 -8
- data/RELEASING.md +43 -0
- data/amorail.gemspec +5 -3
- data/lib/amorail/access_token.rb +44 -0
- data/lib/amorail/client.rb +84 -23
- data/lib/amorail/config.rb +14 -8
- data/lib/amorail/entities/company.rb +2 -0
- data/lib/amorail/entities/contact.rb +2 -0
- data/lib/amorail/entities/contact_link.rb +2 -0
- data/lib/amorail/entities/elementable.rb +4 -2
- data/lib/amorail/entities/lead.rb +2 -0
- data/lib/amorail/entities/leadable.rb +2 -0
- data/lib/amorail/entities/note.rb +2 -0
- data/lib/amorail/entities/task.rb +2 -0
- data/lib/amorail/entities/webhook.rb +2 -0
- data/lib/amorail/entity/finders.rb +2 -0
- data/lib/amorail/entity/params.rb +13 -3
- data/lib/amorail/entity/persistence.rb +2 -0
- data/lib/amorail/entity.rb +20 -3
- data/lib/amorail/exceptions.rb +2 -0
- data/lib/amorail/property.rb +5 -3
- data/lib/amorail/railtie.rb +2 -0
- data/lib/amorail/store_adapters/abstract_store_adapter.rb +23 -0
- data/lib/amorail/store_adapters/memory_store_adapter.rb +50 -0
- data/lib/amorail/store_adapters/redis_store_adapter.rb +83 -0
- data/lib/amorail/store_adapters.rb +15 -0
- data/lib/amorail/version.rb +3 -1
- data/lib/amorail.rb +27 -6
- data/lib/tasks/amorail.rake +2 -0
- data/spec/access_token_spec.rb +59 -0
- data/spec/client_spec.rb +36 -24
- data/spec/company_spec.rb +2 -0
- data/spec/contact_link_spec.rb +2 -0
- data/spec/contact_spec.rb +4 -0
- data/spec/entity_spec.rb +2 -0
- data/spec/fixtures/amorail_test.yml +5 -3
- data/spec/fixtures/authorize.json +6 -0
- data/spec/fixtures/contacts/my_contact_find.json +4 -0
- data/spec/helpers/webmock_helpers.rb +50 -13
- data/spec/lead_spec.rb +2 -0
- data/spec/my_contact_spec.rb +5 -2
- data/spec/note_spec.rb +2 -0
- data/spec/property_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/store_adapters/memory_store_adapter_spec.rb +56 -0
- data/spec/store_adapters/redis_store_adapter_spec.rb +67 -0
- data/spec/support/elementable_example.rb +2 -0
- data/spec/support/entity_class_example.rb +2 -0
- data/spec/support/leadable_example.rb +2 -0
- data/spec/support/my_contact.rb +3 -0
- data/spec/support/my_entity.rb +2 -0
- data/spec/task_spec.rb +2 -0
- data/spec/webhook_spec.rb +2 -0
- metadata +39 -17
- data/.travis.yml +0 -9
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Amorail
|
4
|
+
module StoreAdapters
|
5
|
+
class AbstractStoreAdapter
|
6
|
+
def fetch_access(_secret)
|
7
|
+
raise NotImplementedError
|
8
|
+
end
|
9
|
+
|
10
|
+
def persist_access(_secret, _token, _refresh_token, _expiration)
|
11
|
+
raise NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
def update_refresh(_secret, _token, _refresh_token, _expiration)
|
15
|
+
raise NotImplementedError
|
16
|
+
end
|
17
|
+
|
18
|
+
def access_expired?(_key)
|
19
|
+
raise NotImplementedError
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Amorail
|
4
|
+
module StoreAdapters
|
5
|
+
class MemoryStoreAdapter < AbstractStoreAdapter
|
6
|
+
attr_reader :storage
|
7
|
+
|
8
|
+
def initialize(**options)
|
9
|
+
raise ArgumentError, 'Memory store doesn\'t support any options' if options.any?
|
10
|
+
@storage = Hash.new { |hh, kk| hh[kk] = {} }
|
11
|
+
end
|
12
|
+
|
13
|
+
def fetch_access(secret)
|
14
|
+
value_if_not_expired(secret)
|
15
|
+
end
|
16
|
+
|
17
|
+
def persist_access(secret, token, refresh_token, expiration)
|
18
|
+
access_token = { token: token, refresh_token: refresh_token, expiration: expiration }
|
19
|
+
storage.store(secret, access_token)
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_access(secret, token, refresh_token, expiration)
|
23
|
+
update_access_fields(
|
24
|
+
secret,
|
25
|
+
token: token,
|
26
|
+
refresh_token: refresh_token,
|
27
|
+
expiration: expiration
|
28
|
+
)
|
29
|
+
end
|
30
|
+
|
31
|
+
def access_expired?(key)
|
32
|
+
storage[key][:expiration] && Time.now.to_i >= storage[key][:expiration]
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def value_if_not_expired(key)
|
38
|
+
if !access_expired?(key)
|
39
|
+
storage[key]
|
40
|
+
else
|
41
|
+
{}
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_access_fields(key, fields)
|
46
|
+
storage[key].merge!(fields)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Amorail
|
4
|
+
module StoreAdapters
|
5
|
+
class RedisStoreAdapter < AbstractStoreAdapter
|
6
|
+
attr_reader :storage
|
7
|
+
|
8
|
+
def initialize(**options)
|
9
|
+
begin
|
10
|
+
require 'redis'
|
11
|
+
@storage = configure_redis_client(**options)
|
12
|
+
rescue LoadError => e
|
13
|
+
msg = 'Could not load the \'redis\' gem, please add it to your gemfile or ' \
|
14
|
+
'configure a different adapter (e.g. Amorail.store_adapter = :memory)'
|
15
|
+
raise e.class, msg, e.backtrace
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def fetch_access(secret)
|
20
|
+
token = storage.get(access_key(secret))
|
21
|
+
refresh_token = storage.get(refresh_key(secret))
|
22
|
+
token.nil? ? {} : { token: token, refresh_token: refresh_token }
|
23
|
+
end
|
24
|
+
|
25
|
+
def persist_access(secret, token, refresh_token, expiration)
|
26
|
+
update_data(secret, token, refresh_token, expiration)
|
27
|
+
end
|
28
|
+
|
29
|
+
def update_access(secret, token, refresh_token, expiration)
|
30
|
+
update_data(secret, token, refresh_token, expiration)
|
31
|
+
end
|
32
|
+
|
33
|
+
def access_expired?(secret)
|
34
|
+
access_key = access_key(secret)
|
35
|
+
refresh_key = refresh_key(secret)
|
36
|
+
storage.get(refresh_key) && storage.get(access_key).nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def update_data(secret, token, refresh_token, expiration)
|
42
|
+
access_key = access_key(secret)
|
43
|
+
refresh_key = refresh_key(secret)
|
44
|
+
storage.set(access_key, token)
|
45
|
+
storage.set(refresh_key, refresh_token)
|
46
|
+
storage.expireat(access_key, expiration)
|
47
|
+
end
|
48
|
+
|
49
|
+
def configure_redis_client(redis_url: nil, redis_host: nil, redis_port: nil, redis_db_name: nil)
|
50
|
+
if redis_url && (redis_host || redis_port || redis_db_name)
|
51
|
+
raise ArgumentError, 'redis_url cannot be passed along with redis_host, redis_port or redis_db_name options'
|
52
|
+
end
|
53
|
+
|
54
|
+
redis_url ||= build_redis_url(
|
55
|
+
redis_host: redis_host,
|
56
|
+
redis_port: redis_port,
|
57
|
+
redis_db_name: redis_db_name
|
58
|
+
)
|
59
|
+
|
60
|
+
Redis.new(url: redis_url)
|
61
|
+
end
|
62
|
+
|
63
|
+
def build_redis_url(redis_host: nil, redis_port: nil, redis_db_name: nil)
|
64
|
+
redis_db_name ||= Amorail.config.redis_db_name
|
65
|
+
return URI.join(Amorail.config.redis_url, redis_db_name).to_s if Amorail.config.redis_url
|
66
|
+
|
67
|
+
redis_host ||= Amorail.config.redis_host
|
68
|
+
redis_port ||= Amorail.config.redis_port
|
69
|
+
|
70
|
+
redis_base_url = ENV['REDIS_URL'] || "redis://#{redis_host}:#{redis_port}"
|
71
|
+
URI.join(redis_base_url, redis_db_name).to_s
|
72
|
+
end
|
73
|
+
|
74
|
+
def access_key(secret)
|
75
|
+
"access_#{secret}"
|
76
|
+
end
|
77
|
+
|
78
|
+
def refresh_key(secret)
|
79
|
+
"refresh_#{secret}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'amorail/store_adapters/abstract_store_adapter'
|
4
|
+
require 'amorail/store_adapters/redis_store_adapter'
|
5
|
+
require 'amorail/store_adapters/memory_store_adapter'
|
6
|
+
|
7
|
+
module Amorail
|
8
|
+
module StoreAdapters
|
9
|
+
def self.build_by_name(adapter, options = nil)
|
10
|
+
camelized_adapter = adapter.to_s.split('_').map(&:capitalize).join
|
11
|
+
adapter_class_name = "#{camelized_adapter}StoreAdapter"
|
12
|
+
StoreAdapters.const_get(adapter_class_name).new(**(options || {}))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/amorail/version.rb
CHANGED
data/lib/amorail.rb
CHANGED
@@ -1,37 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'amorail/version'
|
2
4
|
require 'amorail/config'
|
3
5
|
require 'amorail/client'
|
4
6
|
require 'amorail/exceptions'
|
5
7
|
require 'amorail/entity'
|
6
8
|
require 'amorail/property'
|
9
|
+
require 'amorail/access_token'
|
10
|
+
require 'amorail/store_adapters'
|
7
11
|
|
8
12
|
Gem.find_files('amorail/entities/*.rb').each { |path| require path }
|
9
13
|
|
10
14
|
# AmoCRM API integration.
|
11
15
|
# https://www.amocrm.com/
|
12
16
|
module Amorail
|
13
|
-
|
17
|
+
extend self
|
18
|
+
|
19
|
+
def config
|
14
20
|
@config ||= Config.new
|
15
21
|
end
|
16
22
|
|
17
|
-
def
|
23
|
+
def properties
|
18
24
|
client.properties
|
19
25
|
end
|
20
26
|
|
21
|
-
def
|
27
|
+
def configure
|
22
28
|
yield(config) if block_given?
|
23
29
|
end
|
24
30
|
|
25
|
-
def
|
31
|
+
def client
|
26
32
|
ClientRegistry.client || (@client ||= Client.new)
|
27
33
|
end
|
28
34
|
|
29
|
-
def
|
35
|
+
def reset
|
30
36
|
@config = nil
|
31
37
|
@client = nil
|
32
38
|
end
|
33
39
|
|
34
|
-
def
|
40
|
+
def with_client(client)
|
35
41
|
client = Client.new(client) unless client.is_a?(Client)
|
36
42
|
ClientRegistry.client = client
|
37
43
|
yield
|
@@ -39,6 +45,21 @@ module Amorail
|
|
39
45
|
ClientRegistry.client = nil
|
40
46
|
end
|
41
47
|
|
48
|
+
def token_store=(args)
|
49
|
+
adapter, options = Array(args)
|
50
|
+
@token_store = StoreAdapters.build_by_name(adapter, options)
|
51
|
+
rescue NameError => e
|
52
|
+
raise e.class, "Token store adapter for :#{adapter} haven't been found", e.backtrace
|
53
|
+
end
|
54
|
+
|
55
|
+
def token_store
|
56
|
+
unless instance_variable_defined?(:@token_store)
|
57
|
+
self.token_store = :memory
|
58
|
+
end
|
59
|
+
|
60
|
+
@token_store
|
61
|
+
end
|
62
|
+
|
42
63
|
class ClientRegistry # :nodoc:
|
43
64
|
extend ActiveSupport::PerThreadRegistry
|
44
65
|
|
data/lib/tasks/amorail.rake
CHANGED
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
describe Amorail::AccessToken do
|
6
|
+
let(:store) { Amorail.token_store }
|
7
|
+
|
8
|
+
before do
|
9
|
+
Amorail::AccessToken.create(
|
10
|
+
'secret',
|
11
|
+
'token',
|
12
|
+
'refresh_token',
|
13
|
+
Time.now.to_i + 86_000,
|
14
|
+
store
|
15
|
+
)
|
16
|
+
|
17
|
+
Amorail::AccessToken.create(
|
18
|
+
'secret_expired',
|
19
|
+
'token',
|
20
|
+
'refresh_token',
|
21
|
+
Time.now.to_i - 92_000,
|
22
|
+
store
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#find' do
|
27
|
+
context 'when token is not expired' do
|
28
|
+
subject { Amorail::AccessToken.find('secret', store).token }
|
29
|
+
|
30
|
+
it 'should return token' do
|
31
|
+
expect(subject).to eq('token')
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context 'when token is expired' do
|
36
|
+
subject { Amorail::AccessToken.find('secret_expired', store).token }
|
37
|
+
|
38
|
+
it 'should return nil' do
|
39
|
+
expect(subject).to be_nil
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '#refresh' do
|
45
|
+
it 'updates token data' do
|
46
|
+
upd_expiration = Time.now.to_i + 96_000
|
47
|
+
access_token = Amorail::AccessToken.refresh('secret',
|
48
|
+
'upd_token',
|
49
|
+
'upd_refresh',
|
50
|
+
upd_expiration,
|
51
|
+
Amorail.token_store)
|
52
|
+
aggregate_failures do
|
53
|
+
expect(access_token.token).to eq('upd_token')
|
54
|
+
expect(access_token.refresh_token).to eq('upd_refresh')
|
55
|
+
expect(access_token.expiration).to eq(upd_expiration)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/spec/client_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Amorail::Client do
|
@@ -7,8 +9,10 @@ describe Amorail::Client do
|
|
7
9
|
|
8
10
|
context "default client" do
|
9
11
|
it "should create client", :aggregate_failures do
|
10
|
-
expect(subject.
|
11
|
-
expect(subject.
|
12
|
+
expect(subject.client_id).to eq "some_id"
|
13
|
+
expect(subject.client_secret).to eq "some_secret"
|
14
|
+
expect(subject.code).to eq "some_code"
|
15
|
+
expect(subject.redirect_uri).to eq "https://example.ru/redirect/uri"
|
12
16
|
expect(subject.api_endpoint).to eq "https://test.amocrm.ru"
|
13
17
|
end
|
14
18
|
|
@@ -24,40 +28,48 @@ describe Amorail::Client do
|
|
24
28
|
end
|
25
29
|
|
26
30
|
describe "#with_client" do
|
27
|
-
before { mock_custom_api("https://custom.amo.com", "
|
31
|
+
before { mock_custom_api("https://custom.amo.com", "custom_client_id", "custom_client_secret", "custom_code", "https://custom-site.ru/redirecto/uri") }
|
28
32
|
|
29
33
|
let(:new_client) do
|
30
34
|
described_class.new(
|
31
35
|
api_endpoint: "https://custom.amo.com",
|
32
|
-
|
33
|
-
|
36
|
+
client_secret: "custom_client_secret",
|
37
|
+
client_id: "custom_client_id",
|
38
|
+
code: "custom_code",
|
39
|
+
redirect_uri: "https://custom-site.ru/redirecto/uri"
|
34
40
|
)
|
35
41
|
end
|
36
42
|
|
37
43
|
it "use custom client as instance", :aggregate_failures do
|
38
|
-
expect(Amorail.client.
|
44
|
+
expect(Amorail.client.client_id).to eq "some_id"
|
39
45
|
Amorail.with_client(new_client) do
|
40
|
-
expect(Amorail.client.
|
46
|
+
expect(Amorail.client.client_secret).to eq "custom_client_secret"
|
47
|
+
expect(Amorail.client.client_id).to eq "custom_client_id"
|
41
48
|
expect(Amorail.client.api_endpoint).to eq "https://custom.amo.com"
|
42
|
-
expect(Amorail.client.
|
49
|
+
expect(Amorail.client.code).to eq "custom_code"
|
50
|
+
expect(Amorail.client.redirect_uri).to eq "https://custom-site.ru/redirecto/uri"
|
43
51
|
end
|
44
52
|
|
45
|
-
expect(Amorail.client.
|
53
|
+
expect(Amorail.client.client_id).to eq "some_id"
|
46
54
|
end
|
47
55
|
|
48
56
|
it "use custom client as options", :aggregate_failures do
|
49
|
-
expect(Amorail.client.
|
57
|
+
expect(Amorail.client.client_id).to eq "some_id"
|
50
58
|
Amorail.with_client(
|
51
59
|
api_endpoint: "https://custom.amo.com",
|
52
|
-
|
53
|
-
|
60
|
+
client_secret: "custom_client_secret",
|
61
|
+
client_id: "custom_client_id",
|
62
|
+
code: "custom_code",
|
63
|
+
redirect_uri: "https://custom-site.ru/redirecto/uri"
|
54
64
|
) do
|
55
|
-
expect(Amorail.client.
|
65
|
+
expect(Amorail.client.client_secret).to eq "custom_client_secret"
|
66
|
+
expect(Amorail.client.client_id).to eq "custom_client_id"
|
56
67
|
expect(Amorail.client.api_endpoint).to eq "https://custom.amo.com"
|
57
|
-
expect(Amorail.client.
|
68
|
+
expect(Amorail.client.code).to eq "custom_code"
|
69
|
+
expect(Amorail.client.redirect_uri).to eq "https://custom-site.ru/redirecto/uri"
|
58
70
|
end
|
59
71
|
|
60
|
-
expect(Amorail.client.
|
72
|
+
expect(Amorail.client.client_id).to eq "some_id"
|
61
73
|
end
|
62
74
|
|
63
75
|
it "loads custom properties", :aggregate_failures do
|
@@ -81,10 +93,10 @@ describe Amorail::Client do
|
|
81
93
|
# only after the second thread enters block
|
82
94
|
threads << Thread.new do
|
83
95
|
q1.pop
|
84
|
-
Amorail.with_client(
|
96
|
+
Amorail.with_client(client_id: 'some_id_1') do
|
85
97
|
q2 << 1
|
86
98
|
q1.pop
|
87
|
-
results << Amorail.client.
|
99
|
+
results << Amorail.client.client_id
|
88
100
|
q2 << 1
|
89
101
|
end
|
90
102
|
q3 << 1
|
@@ -94,10 +106,10 @@ describe Amorail::Client do
|
|
94
106
|
# after the first block
|
95
107
|
threads << Thread.new do
|
96
108
|
q2.pop
|
97
|
-
Amorail.with_client(
|
109
|
+
Amorail.with_client(client_id: 'some_id_2') do
|
98
110
|
q1 << 1
|
99
111
|
q2.pop
|
100
|
-
results << Amorail.client.
|
112
|
+
results << Amorail.client.client_id
|
101
113
|
end
|
102
114
|
q3 << 1
|
103
115
|
end
|
@@ -105,19 +117,19 @@ describe Amorail::Client do
|
|
105
117
|
# This thread enters block third and commits
|
106
118
|
# after all other threads left blocks
|
107
119
|
threads << Thread.new do
|
108
|
-
Amorail.with_client(
|
120
|
+
Amorail.with_client(client_id: 'some_id_3') do
|
109
121
|
q3.pop
|
110
122
|
q3.pop
|
111
|
-
results << Amorail.client.
|
123
|
+
results << Amorail.client.client_id
|
112
124
|
end
|
113
125
|
end
|
114
126
|
|
115
127
|
q1 << 1
|
116
128
|
threads.each(&:join)
|
117
129
|
|
118
|
-
expect(results[0]).to eq '
|
119
|
-
expect(results[1]).to eq '
|
120
|
-
expect(results[2]).to eq '
|
130
|
+
expect(results[0]).to eq 'some_id_1'
|
131
|
+
expect(results[1]).to eq 'some_id_2'
|
132
|
+
expect(results[2]).to eq 'some_id_3'
|
121
133
|
end
|
122
134
|
end
|
123
135
|
end
|
data/spec/company_spec.rb
CHANGED
data/spec/contact_link_spec.rb
CHANGED
data/spec/contact_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe Amorail::Contact do
|
@@ -166,10 +168,12 @@ describe Amorail::Contact do
|
|
166
168
|
it "update params" do
|
167
169
|
contact.save!
|
168
170
|
contact.name = "foo"
|
171
|
+
contact.phone = "123456789"
|
169
172
|
|
170
173
|
contact_update_stub(Amorail.config.api_endpoint)
|
171
174
|
expect(contact.save!).to be_truthy
|
172
175
|
expect(contact.name).to eq "foo"
|
176
|
+
expect(contact.phone).to eq "123456789"
|
173
177
|
end
|
174
178
|
|
175
179
|
it "raise error if id is blank?" do
|
data/spec/entity_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
client_id: 'some_id'
|
2
|
+
client_secret: 'some_secret'
|
3
|
+
code: 'some_code'
|
4
|
+
redirect_uri: 'https://example.ru/redirect/uri'
|
5
|
+
api_endpoint: 'https://test.amocrm.ru'
|
@@ -0,0 +1,6 @@
|
|
1
|
+
{
|
2
|
+
"token_type": "Bearer",
|
3
|
+
"expires_in": 86400,
|
4
|
+
"access_token": "eyJ0eXAiOiJKf2QihCJhbGciOiJSUzI1NiIsImp0aSI6IjMxMTY3MGY3ZDVjY2IwODRjYTUyOTc5OGVjMzM0ZGU2ZDIzMmYzZDUyMjE0NTFhMTYzZDFlMTM2ZGY3NjA4MGVmMjViZTMwODQwNzFhY2Y0In0.eyJhdWQiOiIwNDA4M2FjZC1iY2ZmLTRiOWItOTJkYS05OTFiOTc0MDBlNzMiLCJqdGkiOiIzMTE2NzBmN2Q1Y2NiMDg0Y2E1Mjk3OThlYzMzNGRlNmQyMzJmM2Q1MjIxNDUxYTE2M2QxZTEzNmRmNzYwODBlZjI1YmUzMDg0MDcxYWNmNCIsImlhdCI6MTYxMzM4NzQ2MiwibmJmIDoxNjEzMzg3NDYyLCJleHAiOjE2MTM0NzM4NyIsInN1YiI6IjYyNjU1OTEiLCJhY2NvdW50X2lkIjoyOTAxMTIzMSwic2NvcGVzIjpbInB1c2hfbm90aWZpY2F0aW9ucyIsImNybSIsIm5vdGlmaWNhdGlvbnMiXX0.HRnJJXSK5KrlkcxHVBQBvE8TS34Rwru4Ba_lBlgzEtfU6FjaOCuBA0VLKJ24lLHz2w9B3lgMn9-OG9ayXAkDqrNPZByOimJ5cdwQExlNws-gvO9Hj27QiWK5JMTvbDE4EjVGvKuH7uXRsFTcsmuP6MA-5hjZ5h2DmNr5gzfZVS2Onh_9vrX75yh5FjFohfoO8izohtQYzZDVNYzek13EBdEK2BiNgLCoGhyGeMRtmTpwdSueD72qFGL80RMkQAGV8mElkZiXeUuGckTvEdIUodlgH6fk_KYG8OF3jozbEpzFKKfgPMUjE3vyCLVPWCEolQZjZPhSd6KbatK-f0oPWA",
|
5
|
+
"refresh_token": "def50200f4151ec4424843abc377eec488c6e8dceeda93b3f0b33d8f02207911533d98b408b97e2b2688acd1d956a44368f51263c7a55253efb543b256b90a2a1dc0ac71bf546374f23ab3d2b07f3ced5ad31e500e16b4d99deb6c735a5001c43c70156feac0a9c94dd24fdc6238ee59603997614ccb28773e4bce14d01e69fa7c04f869088fb1c9c27fea2f68f70E46d615a3982bdcd352Dcd05e3ae70e1d1ba707dcb354e7b611eba6790039a6c4bf2909210a85bdc34a254e9a10f8637aff405938ddcdc8bf88fb4ed8c8f15d7fa1e0e787c624b26c270b43e5877e1b6c87292bd95bb90305f50886b595d5a83c5b9768a8a61c63cdc7b082312ecc32619577253856058e8761c6f1e338e58824d8bed2a227bbe43dd12a69bf347657aa4f41f5d7609b6c5e088a0a0d2b2af9877bf8642c7d44fc6caa3c7dfa342d8b38e37d8a68dd26e814f0bfcdee707bf44ce7ef9e4d57ff5ac6aa52f2259388e5a3b7e5c6689366f43bf9197b2bf0e00470a3031581031b82ade8d8c0f8c01eabb61c312f47a2cfdc2943b10bc1f3d0b7791e1b1487832d3db75908611af90659f721cd3f831dcc76d8da12044611910722c9dc8bc09a5aff82923a2551a5bd5c5c57e4273993e655da7881e3"
|
6
|
+
}
|
@@ -1,36 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# rubocop: disable Metrics/ModuleLength
|
2
4
|
module AmoWebMock
|
3
5
|
def mock_api
|
4
6
|
authorize_stub(
|
5
7
|
Amorail.config.api_endpoint,
|
6
|
-
Amorail.config.
|
7
|
-
Amorail.config.
|
8
|
+
Amorail.config.client_id,
|
9
|
+
Amorail.config.client_secret,
|
10
|
+
'authorization_code',
|
11
|
+
Amorail.config.code,
|
12
|
+
Amorail.config.redirect_uri
|
13
|
+
)
|
14
|
+
|
15
|
+
resresh_token_stub(
|
16
|
+
Amorail.config.api_endpoint,
|
17
|
+
Amorail.config.client_id,
|
18
|
+
Amorail.config.client_secret,
|
19
|
+
'refresh_token',
|
20
|
+
'refresh_token',
|
21
|
+
Amorail.config.redirect_uri
|
22
|
+
)
|
8
23
|
|
9
24
|
account_info_stub(Amorail.config.api_endpoint)
|
10
25
|
end
|
11
26
|
|
12
|
-
def mock_custom_api(endpoint,
|
27
|
+
def mock_custom_api(endpoint, client_id, client_secret, code, redirect_uri, properties = 'response_2.json')
|
13
28
|
authorize_stub(
|
14
29
|
endpoint,
|
15
|
-
|
16
|
-
|
30
|
+
client_id,
|
31
|
+
client_secret,
|
32
|
+
'authorization_code',
|
33
|
+
code,
|
34
|
+
redirect_uri
|
35
|
+
)
|
36
|
+
|
37
|
+
resresh_token_stub(
|
38
|
+
endpoint,
|
39
|
+
client_id,
|
40
|
+
client_secret,
|
41
|
+
'refresh_token',
|
42
|
+
'refresh_token',
|
43
|
+
redirect_uri
|
17
44
|
)
|
18
45
|
|
19
46
|
account_info_stub(endpoint, properties)
|
20
47
|
end
|
21
48
|
|
22
|
-
def authorize_stub(endpoint,
|
23
|
-
|
24
|
-
stub_request(:post, "#{endpoint}/private/api/auth.php?type=json")
|
49
|
+
def authorize_stub(endpoint, client_id, client_secret, grant_type, code, redirect_uri)
|
50
|
+
stub_request(:post, "#{endpoint}/oauth2/access_token")
|
25
51
|
.with(
|
26
|
-
body: "{\"
|
52
|
+
body: "{\"client_id\":\"#{client_id}\",\"client_secret\":\"#{client_secret}\",\"grant_type\":\"#{grant_type}\",\"code\":\"#{code}\",\"redirect_uri\":\"#{redirect_uri}\"}"
|
27
53
|
)
|
28
54
|
.to_return(
|
29
55
|
status: 200,
|
30
|
-
body:
|
31
|
-
headers: {
|
32
|
-
|
33
|
-
|
56
|
+
body: File.read('./spec/fixtures/authorize.json'),
|
57
|
+
headers: {}
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
def resresh_token_stub(endpoint, client_id, client_secret, grant_type, refresh_token, redirect_uri)
|
62
|
+
stub_request(:post, "#{endpoint}/oauth2/access_token")
|
63
|
+
.with(
|
64
|
+
body: "{\"client_id\":\"#{client_id}\",\"client_secret\":\"#{client_secret}\",\"grant_type\":\"#{grant_type}\",\"refresh_token\":\"#{refresh_token}\",\"redirect_uri\":\"#{redirect_uri}\"}"
|
65
|
+
)
|
66
|
+
.to_return(
|
67
|
+
status: 200,
|
68
|
+
body: File.read('./spec/fixtures/authorize.json'),
|
69
|
+
headers: {}
|
70
|
+
)
|
34
71
|
end
|
35
72
|
|
36
73
|
def account_info_stub(endpoint, properties = 'response_1.json')
|
data/spec/lead_spec.rb
CHANGED
data/spec/my_contact_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "spec_helper"
|
2
4
|
|
3
5
|
describe MyContact do
|
@@ -12,7 +14,7 @@ describe MyContact do
|
|
12
14
|
end
|
13
15
|
|
14
16
|
describe "#params" do
|
15
|
-
let(:
|
17
|
+
let(:contact) do
|
16
18
|
described_class.new(
|
17
19
|
name: 'Test inc',
|
18
20
|
phone: '12345678',
|
@@ -21,7 +23,7 @@ describe MyContact do
|
|
21
23
|
)
|
22
24
|
end
|
23
25
|
|
24
|
-
subject {
|
26
|
+
subject { contact.params }
|
25
27
|
|
26
28
|
specify { is_expected.to include(:last_modified) }
|
27
29
|
specify { is_expected.to include(name: 'Test inc') }
|
@@ -41,6 +43,7 @@ describe MyContact do
|
|
41
43
|
expect(obj.id).to eq 11
|
42
44
|
expect(obj.company_name).to eq "Foo Inc."
|
43
45
|
expect(obj.email).to eq "foo@tb.com"
|
46
|
+
expect(obj.phone).to eq ["1111 111 111", "2222 222 222"]
|
44
47
|
expect(obj.teachbase_id).to eq 1123
|
45
48
|
expect(obj.params[:id]).to eq 11
|
46
49
|
end
|
data/spec/note_spec.rb
CHANGED
data/spec/property_spec.rb
CHANGED