pipedrive.rb 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 +7 -0
- data/.cane +5 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/.rubocop.yml +17 -0
- data/.travis.yml +10 -0
- data/Gemfile +20 -0
- data/Guardfile +24 -0
- data/LICENSE.txt +22 -0
- data/README.md +100 -0
- data/Rakefile +27 -0
- data/defaults.reek +11 -0
- data/lib/pipedrive.rb +92 -0
- data/lib/pipedrive/activity.rb +8 -0
- data/lib/pipedrive/activity_type.rb +12 -0
- data/lib/pipedrive/base.rb +87 -0
- data/lib/pipedrive/deal.rb +8 -0
- data/lib/pipedrive/deal_field.rb +11 -0
- data/lib/pipedrive/file.rb +8 -0
- data/lib/pipedrive/filter.rb +6 -0
- data/lib/pipedrive/goal.rb +8 -0
- data/lib/pipedrive/note.rb +8 -0
- data/lib/pipedrive/operations/create.rb +11 -0
- data/lib/pipedrive/operations/delete.rb +15 -0
- data/lib/pipedrive/operations/read.rb +29 -0
- data/lib/pipedrive/operations/update.rb +15 -0
- data/lib/pipedrive/organization.rb +8 -0
- data/lib/pipedrive/organization_field.rb +11 -0
- data/lib/pipedrive/person.rb +18 -0
- data/lib/pipedrive/person_field.rb +11 -0
- data/lib/pipedrive/product.rb +8 -0
- data/lib/pipedrive/product_field.rb +11 -0
- data/lib/pipedrive/railties.rb +7 -0
- data/lib/pipedrive/role.rb +8 -0
- data/lib/pipedrive/stage.rb +8 -0
- data/lib/pipedrive/utils.rb +18 -0
- data/lib/pipedrive/version.rb +3 -0
- data/pipedrive.gemspec +29 -0
- data/spec/lib/pipedrive/activity_spec.rb +9 -0
- data/spec/lib/pipedrive/activity_type_spec.rb +9 -0
- data/spec/lib/pipedrive/base_spec.rb +122 -0
- data/spec/lib/pipedrive/deal_field_spec.rb +9 -0
- data/spec/lib/pipedrive/deal_spec.rb +9 -0
- data/spec/lib/pipedrive/file_spec.rb +9 -0
- data/spec/lib/pipedrive/filter_spec.rb +9 -0
- data/spec/lib/pipedrive/goal_spec.rb +9 -0
- data/spec/lib/pipedrive/note_spec.rb +9 -0
- data/spec/lib/pipedrive/ogranization_spec.rb +9 -0
- data/spec/lib/pipedrive/operations/create_spec.rb +16 -0
- data/spec/lib/pipedrive/operations/delete_spec.rb +22 -0
- data/spec/lib/pipedrive/operations/read_spec.rb +69 -0
- data/spec/lib/pipedrive/operations/update_spec.rb +20 -0
- data/spec/lib/pipedrive/organization_field_spec.rb +9 -0
- data/spec/lib/pipedrive/person_field_spec.rb +9 -0
- data/spec/lib/pipedrive/person_spec.rb +24 -0
- data/spec/lib/pipedrive/product_field_spec.rb +9 -0
- data/spec/lib/pipedrive/product_spec.rb +9 -0
- data/spec/lib/pipedrive_spec.rb +65 -0
- data/spec/spec_helper.rb +17 -0
- metadata +235 -0
@@ -0,0 +1,29 @@
|
|
1
|
+
module Pipedrive
|
2
|
+
module Operations
|
3
|
+
module Read
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
include ::Enumerable
|
6
|
+
include ::Pipedrive::Utils
|
7
|
+
|
8
|
+
# This method smells of :reek:TooManyStatements but ignores them
|
9
|
+
def each(params = {})
|
10
|
+
return to_enum(:each, params) unless block_given?
|
11
|
+
follow_pagination(:chunk, [], params) { |item| yield item }
|
12
|
+
end
|
13
|
+
|
14
|
+
def all(params = {})
|
15
|
+
each(params).to_a
|
16
|
+
end
|
17
|
+
|
18
|
+
def chunk(params = {})
|
19
|
+
res = make_api_call(:get, params)
|
20
|
+
return [] unless res.success?
|
21
|
+
res
|
22
|
+
end
|
23
|
+
|
24
|
+
def find_by_id(id)
|
25
|
+
make_api_call(:get, id)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Pipedrive
|
2
|
+
module Operations
|
3
|
+
module Update
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def update(*args)
|
7
|
+
params = args.extract_options!
|
8
|
+
params.symbolize_keys!
|
9
|
+
id = params.delete(:id) || args[0]
|
10
|
+
fail 'id must be provided' unless id
|
11
|
+
make_api_call(:put, id, params)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Pipedrive
|
2
|
+
class Person < Base
|
3
|
+
include ::Pipedrive::Operations::Read
|
4
|
+
include ::Pipedrive::Operations::Create
|
5
|
+
include ::Pipedrive::Operations::Update
|
6
|
+
include ::Pipedrive::Operations::Delete
|
7
|
+
include ::Pipedrive::Utils
|
8
|
+
|
9
|
+
def find_by_name(*args)
|
10
|
+
params = args.extract_options!
|
11
|
+
params[:term] ||= args[0]
|
12
|
+
fail 'term is missing' unless params[:term]
|
13
|
+
params[:search_by_email] ||= args[1] ? 1 : 0
|
14
|
+
return to_enum(:find_by_name, params) unless block_given?
|
15
|
+
follow_pagination(:make_api_call, [:get, 'find'], params) { |item| yield item }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Pipedrive
|
2
|
+
module Utils
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
def follow_pagination(method, args, params)
|
6
|
+
start = params[:start] || 0
|
7
|
+
loop do
|
8
|
+
res = __send__(method, *args, params.merge(start: start))
|
9
|
+
break if !res.try(:data) || !res.success?
|
10
|
+
res.data.each do |item|
|
11
|
+
yield item
|
12
|
+
end
|
13
|
+
break unless res.try(:additional_data).try(:pagination).try(:more_items_in_collection?)
|
14
|
+
start = res.try(:additional_data).try(:pagination).try(:next_start)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/pipedrive.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'pipedrive/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "pipedrive.rb"
|
8
|
+
gem.version = Pipedrive::VERSION
|
9
|
+
gem.authors = ["Alexander Simonov"]
|
10
|
+
gem.email = ["alex@simonov.me"]
|
11
|
+
gem.summary = %q{Pipedrive.com API Wrapper}
|
12
|
+
gem.description = %q{Pipedrive.com API Wrapper}
|
13
|
+
gem.homepage = 'https://github.com/dotpromo/pipedrive.rb'
|
14
|
+
gem.license = 'MIT'
|
15
|
+
|
16
|
+
gem.files = `git ls-files -z`.split("\x0")
|
17
|
+
gem.executables = gem.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
|
+
gem.require_paths = ["lib"]
|
20
|
+
|
21
|
+
gem.add_dependency('faraday')
|
22
|
+
gem.add_dependency('faraday_middleware')
|
23
|
+
gem.add_dependency('activesupport', '>= 4.0.0')
|
24
|
+
gem.add_dependency('hashie', '>= 3.0')
|
25
|
+
gem.add_development_dependency('bundler', '~> 1.6')
|
26
|
+
gem.add_development_dependency('rake')
|
27
|
+
gem.add_development_dependency('rspec', '>= 3.0')
|
28
|
+
gem.add_development_dependency('webmock')
|
29
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe ::Pipedrive::Base do
|
4
|
+
subject { described_class.new('token') }
|
5
|
+
context '#entity_name' do
|
6
|
+
subject { super().entity_name }
|
7
|
+
it { is_expected.to eq described_class.name.split('::')[-1].downcase.pluralize }
|
8
|
+
end
|
9
|
+
|
10
|
+
context '::faraday_options' do
|
11
|
+
subject { described_class.faraday_options }
|
12
|
+
it { is_expected.to eq({
|
13
|
+
url: 'https://api.pipedrive.com',
|
14
|
+
headers: { accept: 'application/json', user_agent: 'Pipedrive Ruby Client v0.0.1' }
|
15
|
+
}) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context '::connection' do
|
19
|
+
subject { super().connection }
|
20
|
+
it { is_expected.to be_kind_of(::Faraday::Connection) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context '#failed_response' do
|
24
|
+
let(:res) { double('res', body: ::Hashie::Mash.new({}), status: status) }
|
25
|
+
subject { super().failed_response(res) }
|
26
|
+
context 'status is 401' do
|
27
|
+
let(:status) { 401 }
|
28
|
+
it { is_expected.to eq(::Hashie::Mash.new({
|
29
|
+
failed: false,
|
30
|
+
not_authorized: true,
|
31
|
+
success: false
|
32
|
+
})) }
|
33
|
+
end
|
34
|
+
context 'status is 420' do
|
35
|
+
let(:status) { 420 }
|
36
|
+
it { is_expected.to eq(::Hashie::Mash.new({
|
37
|
+
failed: true,
|
38
|
+
not_authorized: false,
|
39
|
+
success: false
|
40
|
+
})) }
|
41
|
+
end
|
42
|
+
context 'status is 400' do
|
43
|
+
let(:status) { 400 }
|
44
|
+
it { is_expected.to eq(::Hashie::Mash.new({
|
45
|
+
failed: false,
|
46
|
+
not_authorized: false,
|
47
|
+
success: false
|
48
|
+
})) }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
context '#make_api_call' do
|
52
|
+
it 'should failed no method' do
|
53
|
+
expect { subject.make_api_call(test: 'foo') }.to raise_error('method param missing')
|
54
|
+
end
|
55
|
+
context 'without id' do
|
56
|
+
it 'should call :get' do
|
57
|
+
stub_request(:get, 'https://api.pipedrive.com/v1/bases?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
58
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:get).with('/v1/bases?api_token=token', {}).and_call_original
|
59
|
+
expect(subject.make_api_call(:get))
|
60
|
+
end
|
61
|
+
it 'should call :post' do
|
62
|
+
stub_request(:post, 'https://api.pipedrive.com/v1/bases?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
63
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:post).with('/v1/bases?api_token=token', { test: 'bar' }).and_call_original
|
64
|
+
expect(subject.make_api_call(:post, test: 'bar'))
|
65
|
+
end
|
66
|
+
it 'should call :put' do
|
67
|
+
stub_request(:put, 'https://api.pipedrive.com/v1/bases?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
68
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:put).with('/v1/bases?api_token=token', { test: 'bar' }).and_call_original
|
69
|
+
expect(subject.make_api_call(:put, test: 'bar'))
|
70
|
+
end
|
71
|
+
it 'should use field_selector properly' do
|
72
|
+
stub_request(:get, 'https://api.pipedrive.com/v1/bases:(a,b,c)?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
73
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:get).
|
74
|
+
with('/v1/bases:(a,b,c)?api_token=token', {}).and_call_original
|
75
|
+
expect(subject.make_api_call(:get, fields_to_select: %w(a b c)))
|
76
|
+
end
|
77
|
+
it 'should not use field_selector if it empty' do
|
78
|
+
stub_request(:get, 'https://api.pipedrive.com/v1/bases?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
79
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:get).
|
80
|
+
with('/v1/bases?api_token=token', {}).and_call_original
|
81
|
+
expect(subject.make_api_call(:get, fields_to_select: []))
|
82
|
+
end
|
83
|
+
it 'should retry if Errno::ETIMEDOUT' do
|
84
|
+
stub_request(:get, 'https://api.pipedrive.com/v1/bases?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
85
|
+
connection = subject.connection
|
86
|
+
allow(subject).to receive(:connection).and_return(connection)
|
87
|
+
allow(connection).to receive(:get).
|
88
|
+
with('/v1/bases?api_token=token', {}).and_raise(Errno::ETIMEDOUT)
|
89
|
+
expect(connection).to receive(:get).
|
90
|
+
with('/v1/bases?api_token=token', {}).and_call_original
|
91
|
+
expect(subject.make_api_call(:get, fields_to_select: []))
|
92
|
+
end
|
93
|
+
end
|
94
|
+
context 'with id' do
|
95
|
+
it 'should call :get' do
|
96
|
+
stub_request(:get, 'https://api.pipedrive.com/v1/bases/12?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
97
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:get).with('/v1/bases/12?api_token=token', {}).and_call_original
|
98
|
+
expect(subject.make_api_call(:get, 12))
|
99
|
+
end
|
100
|
+
it 'should call :post' do
|
101
|
+
stub_request(:post, 'https://api.pipedrive.com/v1/bases/13?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
102
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:post).with('/v1/bases/13?api_token=token', { test: 'bar' }).and_call_original
|
103
|
+
expect(subject.make_api_call(:post, 13, test: 'bar'))
|
104
|
+
end
|
105
|
+
it 'should call :put' do
|
106
|
+
stub_request(:put, 'https://api.pipedrive.com/v1/bases/14?api_token=token').to_return(:status => 200, :body => {}, :headers => {})
|
107
|
+
expect_any_instance_of(::Faraday::Connection).to receive(:put).with('/v1/bases/14?api_token=token', { test: 'bar' }).and_call_original
|
108
|
+
expect(subject.make_api_call(:put, 14, test: 'bar'))
|
109
|
+
end
|
110
|
+
end
|
111
|
+
it 'should call Hashie::Mash if return empty string' do
|
112
|
+
stub_request(:get, 'https://api.pipedrive.com/v1/bases?api_token=token').to_return(:status => 200, :body => '', :headers => {})
|
113
|
+
expect(::Hashie::Mash).to receive(:new).with(success: true).and_call_original
|
114
|
+
expect(subject.make_api_call(:get))
|
115
|
+
end
|
116
|
+
it 'should call #failed_response if failed status' do
|
117
|
+
stub_request(:get, 'https://api.pipedrive.com/v1/bases?api_token=token').to_return(:status => 400, :body => '', :headers => {})
|
118
|
+
expect(subject).to receive(:failed_response)
|
119
|
+
expect(subject.make_api_call(:get))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|