basecrm 0.0.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.
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/Gemfile +8 -0
- data/LICENSE +22 -0
- data/README.md +34 -0
- data/Rakefile +2 -0
- data/basecrm.gemspec +19 -0
- data/lib/base_crm.rb +22 -0
- data/lib/base_crm/account.rb +11 -0
- data/lib/base_crm/api_client_ext.rb +6 -0
- data/lib/base_crm/config.rb +21 -0
- data/lib/base_crm/contact.rb +40 -0
- data/lib/base_crm/custom_fieldable.rb +35 -0
- data/lib/base_crm/deal.rb +40 -0
- data/lib/base_crm/lead.rb +36 -0
- data/lib/base_crm/note.rb +15 -0
- data/lib/base_crm/noteable.rb +21 -0
- data/lib/base_crm/resource.rb +14 -0
- data/lib/base_crm/session.rb +48 -0
- data/lib/base_crm/source.rb +14 -0
- data/lib/base_crm/task.rb +16 -0
- data/lib/base_crm/taskable.rb +20 -0
- data/lib/base_crm/version.rb +3 -0
- data/lib/basecrm.rb +2 -0
- data/spec/base_crm/account_spec.rb +20 -0
- data/spec/base_crm/contact_spec.rb +81 -0
- data/spec/base_crm/deal_spec.rb +97 -0
- data/spec/base_crm/lead_spec.rb +63 -0
- data/spec/base_crm/note_spec.rb +20 -0
- data/spec/base_crm/resource_mixin_spec.rb +26 -0
- data/spec/base_crm/session_spec.rb +97 -0
- data/spec/base_crm/source_spec.rb +20 -0
- data/spec/base_crm/task_spec.rb +21 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/support/noteable_shared_examples.rb +43 -0
- data/spec/support/taskable_shared_examples.rb +47 -0
- metadata +110 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Marcin Bunsch
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Base CRM API client
|
2
|
+
|
3
|
+
New and shiny client for the Base CRM API
|
4
|
+
|
5
|
+
NOTE: This is still a very early release. There might be a lot of
|
6
|
+
breaking changes. You have been warned.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
The gem is no available via Rubygems just yet. To install it, put this on your Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'basecrm', :git => 'git://github.com/basecrm/basecrm.git'
|
14
|
+
```
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
Before using this gem you must require it by calling:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
require 'basecrm'
|
22
|
+
```
|
23
|
+
|
24
|
+
## Usage
|
25
|
+
|
26
|
+
TODO: Write usage instructions here
|
27
|
+
|
28
|
+
## Contributing
|
29
|
+
|
30
|
+
1. Fork it
|
31
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
32
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
33
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
34
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/basecrm.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/base_crm/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Marcin Bunsch"]
|
6
|
+
gem.email = ["marcin@futuresimple.com"]
|
7
|
+
gem.description = %q{Base CRM API Client}
|
8
|
+
gem.summary = %q{Base CRM API Client}
|
9
|
+
gem.homepage = "https://github.com/basecrm/basecrm"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "basecrm"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = BaseCrm::VERSION
|
17
|
+
gem.add_dependency "api_client", '>=0.4.1'
|
18
|
+
end
|
19
|
+
|
data/lib/base_crm.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "api_client"
|
2
|
+
require "base_crm/version"
|
3
|
+
require "base_crm/config"
|
4
|
+
require "base_crm/api_client_ext"
|
5
|
+
|
6
|
+
module BaseCrm
|
7
|
+
|
8
|
+
autoload :Account, "base_crm/account"
|
9
|
+
autoload :Contact, "base_crm/contact"
|
10
|
+
autoload :Session, "base_crm/session"
|
11
|
+
autoload :Deal, "base_crm/deal"
|
12
|
+
autoload :Source, "base_crm/source"
|
13
|
+
autoload :Resource, "base_crm/resource"
|
14
|
+
autoload :Note, "base_crm/note"
|
15
|
+
autoload :Noteable, "base_crm/noteable"
|
16
|
+
autoload :Task, "base_crm/task"
|
17
|
+
autoload :Taskable, "base_crm/taskable"
|
18
|
+
autoload :Lead, "base_crm/lead"
|
19
|
+
autoload :CustomFieldable, "base_crm/custom_fieldable"
|
20
|
+
|
21
|
+
end
|
22
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "hashie/mash"
|
2
|
+
|
3
|
+
module BaseCrm
|
4
|
+
|
5
|
+
def self.config
|
6
|
+
@config ||= Hashie::Mash.new
|
7
|
+
end
|
8
|
+
|
9
|
+
self.config.token_name = "X-Pipejump-Auth"
|
10
|
+
|
11
|
+
self.config.endpoints = {
|
12
|
+
:app => "https://app.futuresimple.com",
|
13
|
+
:core => "https://core.futuresimple.com",
|
14
|
+
:crm => "https://crm.futuresimple.com",
|
15
|
+
:sales => "https://sales.futuresimple.com",
|
16
|
+
:leads => "https://leads.futuresimple.com",
|
17
|
+
:common => "https://common.futuresimple.com"
|
18
|
+
}
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module BaseCrm
|
2
|
+
class Contact < ApiClient::Resource::Base
|
3
|
+
|
4
|
+
include BaseCrm::Resource
|
5
|
+
include BaseCrm::Noteable
|
6
|
+
include BaseCrm::Taskable
|
7
|
+
include BaseCrm::CustomFieldable
|
8
|
+
|
9
|
+
namespace "contact"
|
10
|
+
|
11
|
+
prefix "api/v1"
|
12
|
+
|
13
|
+
always do
|
14
|
+
endpoint BaseCrm.config.endpoints.crm
|
15
|
+
end
|
16
|
+
|
17
|
+
def payload
|
18
|
+
hash = super
|
19
|
+
hash.delete('tags_joined_by_comma')
|
20
|
+
hash.delete('linkedin_display')
|
21
|
+
hash
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.fetch_for_deal(deal)
|
25
|
+
scope.
|
26
|
+
endpoint(BaseCrm.config.endpoints.sales).
|
27
|
+
path("/api/v1/deals/#{deal.id}/contacts")
|
28
|
+
end
|
29
|
+
|
30
|
+
def noteable_type
|
31
|
+
"Contact"
|
32
|
+
end
|
33
|
+
|
34
|
+
def taskable_type
|
35
|
+
"Contact"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module BaseCrm
|
2
|
+
|
3
|
+
module CustomFieldable
|
4
|
+
|
5
|
+
def initialize(attributes, original_scope = nil)
|
6
|
+
super
|
7
|
+
simplify_custom_fields
|
8
|
+
end
|
9
|
+
|
10
|
+
def simplify_custom_fields
|
11
|
+
fields = self['custom_fields'] || {}
|
12
|
+
self['custom_fields'] = fields.inject(Hashie::Mash.new) do |memo, field|
|
13
|
+
name, value = field
|
14
|
+
memo[name] = value['value']
|
15
|
+
memo
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Because custom fields are hashes, and hashes result in
|
22
|
+
# new instances of BaseCrm::Contact, we end up with a stack level too deep
|
23
|
+
# because simplify_custom_fields gets fired all the time
|
24
|
+
def convert_value(val, duping=false) #:nodoc:
|
25
|
+
if val.is_a?(Hash) or val.is_a?(::Hash)
|
26
|
+
val
|
27
|
+
else
|
28
|
+
super
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module BaseCrm
|
2
|
+
class Deal < ApiClient::Resource::Base
|
3
|
+
|
4
|
+
include BaseCrm::Resource
|
5
|
+
include BaseCrm::Noteable
|
6
|
+
include BaseCrm::Taskable
|
7
|
+
|
8
|
+
namespace "deal"
|
9
|
+
|
10
|
+
prefix "api/v1"
|
11
|
+
|
12
|
+
always do
|
13
|
+
endpoint BaseCrm.config.endpoints.sales
|
14
|
+
end
|
15
|
+
|
16
|
+
def source
|
17
|
+
Source.find(self.source_id)
|
18
|
+
rescue ApiClient::Errors::NotFound
|
19
|
+
end
|
20
|
+
|
21
|
+
def contact
|
22
|
+
Contact.find(self.entity_id)
|
23
|
+
rescue ApiClient::Errors::NotFound
|
24
|
+
end
|
25
|
+
|
26
|
+
def contacts
|
27
|
+
pass_headers(Contact).fetch_for_deal(self)
|
28
|
+
end
|
29
|
+
|
30
|
+
def noteable_type
|
31
|
+
"Deal"
|
32
|
+
end
|
33
|
+
|
34
|
+
def taskable_type
|
35
|
+
"Deal"
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module BaseCrm
|
2
|
+
class Lead < ApiClient::Resource::Base
|
3
|
+
|
4
|
+
include BaseCrm::Resource
|
5
|
+
include BaseCrm::Noteable
|
6
|
+
include BaseCrm::Taskable
|
7
|
+
include BaseCrm::CustomFieldable
|
8
|
+
|
9
|
+
namespace "lead"
|
10
|
+
|
11
|
+
prefix "api/v1"
|
12
|
+
|
13
|
+
always do
|
14
|
+
endpoint BaseCrm.config.endpoints.leads
|
15
|
+
end
|
16
|
+
|
17
|
+
def noteable_type
|
18
|
+
"Lead"
|
19
|
+
end
|
20
|
+
|
21
|
+
def taskable_type
|
22
|
+
"Lead"
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.build(result_or_array)
|
26
|
+
if result_or_array.has_key?('items')
|
27
|
+
build_many(result_or_array['items'])
|
28
|
+
else
|
29
|
+
build_one(result_or_array)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module BaseCrm
|
2
|
+
module Noteable
|
3
|
+
|
4
|
+
def notes
|
5
|
+
pass_headers(Note).params({
|
6
|
+
:noteable_type => self.noteable_type,
|
7
|
+
:noteable_id => self.id
|
8
|
+
})
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_note(message)
|
12
|
+
pass_headers(Note).create({
|
13
|
+
:content => message,
|
14
|
+
:noteable_type => self.noteable_type,
|
15
|
+
:noteable_id => self.id
|
16
|
+
})
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module BaseCrm
|
2
|
+
class Session
|
3
|
+
|
4
|
+
attr_accessor :token
|
5
|
+
|
6
|
+
def initialize(token)
|
7
|
+
@token = token
|
8
|
+
end
|
9
|
+
|
10
|
+
def account
|
11
|
+
pass_headers(BaseCrm::Account).
|
12
|
+
fetch('/api/v1/account.json')
|
13
|
+
end
|
14
|
+
|
15
|
+
def contacts
|
16
|
+
pass_headers BaseCrm::Contact
|
17
|
+
end
|
18
|
+
|
19
|
+
def deals
|
20
|
+
pass_headers BaseCrm::Deal
|
21
|
+
end
|
22
|
+
|
23
|
+
def sources
|
24
|
+
pass_headers BaseCrm::Source
|
25
|
+
end
|
26
|
+
|
27
|
+
def notes
|
28
|
+
pass_headers BaseCrm::Note
|
29
|
+
end
|
30
|
+
|
31
|
+
def tasks
|
32
|
+
pass_headers BaseCrm::Task
|
33
|
+
end
|
34
|
+
|
35
|
+
def leads
|
36
|
+
pass_headers BaseCrm::Lead
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def pass_headers(klass)
|
42
|
+
klass.
|
43
|
+
headers("X-Pipejump-Auth" => self.token).
|
44
|
+
headers("X-Futuresimple-Token" => self.token)
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module BaseCrm
|
2
|
+
module Taskable
|
3
|
+
|
4
|
+
def tasks
|
5
|
+
pass_headers(Task).params({
|
6
|
+
:taskable_type => self.taskable_type,
|
7
|
+
:taskable_id => self.id
|
8
|
+
})
|
9
|
+
end
|
10
|
+
|
11
|
+
def create_task(params)
|
12
|
+
pass_headers(Task).create({
|
13
|
+
:taskable_type => self.taskable_type,
|
14
|
+
:taskable_id => self.id
|
15
|
+
}.merge(params))
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/lib/basecrm.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Account do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BaseCrm::Account.new({})
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "endpoint" do
|
10
|
+
|
11
|
+
it "uses the production endpoint" do
|
12
|
+
BaseCrm::Account.scope.instance_eval do
|
13
|
+
@endpoint.should == "https://sales.futuresimple.com"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Contact do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BaseCrm::Contact.new({ :id => 1234 })
|
7
|
+
end
|
8
|
+
|
9
|
+
it_behaves_like "noteable", "Contact"
|
10
|
+
it_behaves_like "taskable", "Contact"
|
11
|
+
|
12
|
+
describe "endpoint" do
|
13
|
+
|
14
|
+
it "uses the production endpoint" do
|
15
|
+
BaseCrm::Contact.scope.instance_eval do
|
16
|
+
@endpoint.should == "https://crm.futuresimple.com"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "simplify_custom_fields" do
|
23
|
+
|
24
|
+
it "converts a hash into the value" do
|
25
|
+
subject.custom_fields = {
|
26
|
+
'test' => { 'value' => 'yes!' }
|
27
|
+
}
|
28
|
+
result = subject.simplify_custom_fields
|
29
|
+
result.should == { 'test' => 'yes!' }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#payload" do
|
34
|
+
|
35
|
+
it "removes wrong fields from payload" do
|
36
|
+
subject.tags_joined_by_comma = 'ARRG'
|
37
|
+
subject.linkedin_display = 'THIS IS SO WRONG'
|
38
|
+
hash = subject.payload
|
39
|
+
hash.has_key?('tags_joined_by_comma').should be_false
|
40
|
+
hash.has_key?('linkedin_display').should be_false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe ".fetch_for_deal" do
|
45
|
+
let(:scope) { mock }
|
46
|
+
let(:deal) { mock(:id => 444) }
|
47
|
+
|
48
|
+
it "returns the scope" do
|
49
|
+
BaseCrm::Contact.should_receive(:scope).and_return(scope)
|
50
|
+
scope.should_receive(:endpoint).
|
51
|
+
with(BaseCrm.config.endpoints.sales).
|
52
|
+
and_return(scope)
|
53
|
+
scope.should_receive(:path).
|
54
|
+
with("/api/v1/deals/#{deal.id}/contacts").
|
55
|
+
and_return(scope)
|
56
|
+
BaseCrm::Contact.fetch_for_deal(deal).should == scope
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#notes" do
|
62
|
+
let(:scope) { mock }
|
63
|
+
let(:fetch_scope) { mock }
|
64
|
+
|
65
|
+
it "passes the token and applies the params" do
|
66
|
+
subject.
|
67
|
+
should_receive(:pass_headers).
|
68
|
+
with(BaseCrm::Note).
|
69
|
+
and_return(scope)
|
70
|
+
scope.should_receive(:params).
|
71
|
+
with({
|
72
|
+
:noteable_type => "Contact",
|
73
|
+
:noteable_id => subject.id
|
74
|
+
}).and_return(fetch_scope)
|
75
|
+
subject.notes.should == fetch_scope
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Deal do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BaseCrm::Deal.new({ :id => 334 })
|
7
|
+
end
|
8
|
+
|
9
|
+
it_behaves_like "noteable", "Deal"
|
10
|
+
it_behaves_like "taskable", "Deal"
|
11
|
+
|
12
|
+
describe "endpoint" do
|
13
|
+
|
14
|
+
it "uses the production endpoint" do
|
15
|
+
BaseCrm::Deal.scope.instance_eval do
|
16
|
+
@endpoint.should == "https://sales.futuresimple.com"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#source" do
|
23
|
+
|
24
|
+
let(:source) { mock }
|
25
|
+
let(:source_id) { mock }
|
26
|
+
|
27
|
+
before do
|
28
|
+
subject.source_id = source_id
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when it is found" do
|
32
|
+
before do
|
33
|
+
BaseCrm::Source.
|
34
|
+
stub(:find).
|
35
|
+
with(source_id).
|
36
|
+
and_return(source)
|
37
|
+
end
|
38
|
+
it { subject.source.should == source }
|
39
|
+
end
|
40
|
+
|
41
|
+
context "when it is not found" do
|
42
|
+
before do
|
43
|
+
BaseCrm::Source.
|
44
|
+
stub(:find).
|
45
|
+
with(source_id).
|
46
|
+
and_raise(ApiClient::Errors::NotFound)
|
47
|
+
end
|
48
|
+
it { subject.source.should == nil }
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#contact" do
|
54
|
+
|
55
|
+
let(:contact) { mock }
|
56
|
+
let(:entity_id) { mock }
|
57
|
+
|
58
|
+
before do
|
59
|
+
subject.entity_id = entity_id
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when it is found" do
|
63
|
+
before do
|
64
|
+
BaseCrm::Contact.
|
65
|
+
stub(:find).
|
66
|
+
with(entity_id).
|
67
|
+
and_return(contact)
|
68
|
+
end
|
69
|
+
it { subject.contact.should == contact }
|
70
|
+
end
|
71
|
+
|
72
|
+
context "when it is not found" do
|
73
|
+
before do
|
74
|
+
BaseCrm::Contact.
|
75
|
+
stub(:find).
|
76
|
+
with(entity_id).
|
77
|
+
and_raise(ApiClient::Errors::NotFound)
|
78
|
+
end
|
79
|
+
it { subject.contact.should == nil }
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
describe "#contacts" do
|
85
|
+
let(:scope) { mock }
|
86
|
+
let(:fetch_scope) { mock }
|
87
|
+
|
88
|
+
it "passes the token and users fetch_for_deal" do
|
89
|
+
subject.should_receive(:pass_headers).with(BaseCrm::Contact).and_return(scope)
|
90
|
+
scope.should_receive(:fetch_for_deal).with(subject).and_return(fetch_scope)
|
91
|
+
subject.contacts.should == fetch_scope
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Lead do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BaseCrm::Lead.new({ :id => 1234 })
|
7
|
+
end
|
8
|
+
|
9
|
+
it_behaves_like "noteable", "Lead"
|
10
|
+
it_behaves_like "taskable", "Lead"
|
11
|
+
|
12
|
+
describe "endpoint" do
|
13
|
+
|
14
|
+
it "uses the production endpoint" do
|
15
|
+
BaseCrm::Lead.scope.instance_eval do
|
16
|
+
@endpoint.should == "https://leads.futuresimple.com"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "simplify_custom_fields" do
|
23
|
+
|
24
|
+
it "converts a hash into the value" do
|
25
|
+
subject.custom_fields = {
|
26
|
+
'test' => { 'value' => 'yes!' }
|
27
|
+
}
|
28
|
+
result = subject.simplify_custom_fields
|
29
|
+
result.should == { 'test' => 'yes!' }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "response parsing" do
|
34
|
+
let(:response) do
|
35
|
+
{}
|
36
|
+
end
|
37
|
+
|
38
|
+
context "collection" do
|
39
|
+
let(:items) { mock }
|
40
|
+
let(:response) do
|
41
|
+
{ "items" => items }
|
42
|
+
end
|
43
|
+
|
44
|
+
it "extracts the items" do
|
45
|
+
BaseCrm::Lead.should_receive(:build_many).with(items)
|
46
|
+
BaseCrm::Lead.build(response)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
context "single" do
|
52
|
+
|
53
|
+
it "extracts the items" do
|
54
|
+
BaseCrm::Lead.should_receive(:build_one).with(response)
|
55
|
+
BaseCrm::Lead.build(response)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Note do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BaseCrm::Note.new({})
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "endpoint" do
|
10
|
+
|
11
|
+
it "uses the production endpoint" do
|
12
|
+
BaseCrm::Note.scope.instance_eval do
|
13
|
+
@endpoint.should == "https://common.futuresimple.com"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class ResourceMixinTestClass < ApiClient::Resource::Base
|
4
|
+
include BaseCrm::Resource
|
5
|
+
end
|
6
|
+
|
7
|
+
describe BaseCrm::Resource do
|
8
|
+
|
9
|
+
describe "#pass_headers" do
|
10
|
+
let(:instance) { ResourceMixinTestClass.headers(headers).build_one({}) }
|
11
|
+
let(:token_name) { BaseCrm.config.token_name }
|
12
|
+
let(:token) { mock }
|
13
|
+
let(:headers) do
|
14
|
+
{ token_name => token }
|
15
|
+
end
|
16
|
+
let(:other_klass) { mock }
|
17
|
+
|
18
|
+
it "copies the token header from the original scope" do
|
19
|
+
other_klass.should_receive(:headers).with(token_name => token)
|
20
|
+
instance.pass_headers(other_klass)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Session do
|
4
|
+
|
5
|
+
let(:token) { "OMGTOKEN" }
|
6
|
+
|
7
|
+
subject do
|
8
|
+
BaseCrm::Session.new(token)
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "passing of headers" do
|
12
|
+
let(:scope) { mock }
|
13
|
+
let(:scope_class) { mock }
|
14
|
+
|
15
|
+
before do
|
16
|
+
scope_class.should_receive(:headers).with({
|
17
|
+
"X-Pipejump-Auth" => token
|
18
|
+
}).and_return(scope)
|
19
|
+
scope.should_receive(:headers).with({
|
20
|
+
"X-Futuresimple-Token" => token
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#contacts" do
|
25
|
+
let(:scope_class) { BaseCrm::Contact }
|
26
|
+
|
27
|
+
it "queries the contacts with the right header" do
|
28
|
+
subject.contacts
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#deals" do
|
34
|
+
let(:scope_class) { BaseCrm::Deal }
|
35
|
+
|
36
|
+
it "queries the deals with the right header" do
|
37
|
+
subject.deals
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#sources" do
|
43
|
+
let(:scope_class) { BaseCrm::Source }
|
44
|
+
|
45
|
+
it "queries the sources with the right header" do
|
46
|
+
subject.sources
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#notes" do
|
52
|
+
let(:scope_class) { BaseCrm::Note }
|
53
|
+
|
54
|
+
it "queries the notes with the right header" do
|
55
|
+
subject.notes
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
describe "#tasks" do
|
61
|
+
let(:scope_class) { BaseCrm::Task }
|
62
|
+
|
63
|
+
it "queries the tasks with the right header" do
|
64
|
+
subject.tasks
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#leads" do
|
70
|
+
let(:scope_class) { BaseCrm::Lead }
|
71
|
+
|
72
|
+
it "queries the leads with the right header" do
|
73
|
+
subject.leads
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#account" do
|
82
|
+
|
83
|
+
it "gets the account" do
|
84
|
+
BaseCrm::Account.should_receive(:headers).with({
|
85
|
+
"X-Pipejump-Auth" => token
|
86
|
+
}).and_return(BaseCrm::Account)
|
87
|
+
BaseCrm::Account.should_receive(:headers).with({
|
88
|
+
"X-Futuresimple-Token" => token
|
89
|
+
}).and_return(BaseCrm::Account)
|
90
|
+
BaseCrm::Account.should_receive(:fetch).with('/api/v1/account.json')
|
91
|
+
subject.account
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Source do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BaseCrm::Source.new({})
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "endpoint" do
|
10
|
+
|
11
|
+
it "uses the production endpoint" do
|
12
|
+
BaseCrm::Source.scope.instance_eval do
|
13
|
+
@endpoint.should == "https://sales.futuresimple.com"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe BaseCrm::Task do
|
4
|
+
|
5
|
+
subject do
|
6
|
+
BaseCrm::Task.new({})
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "endpoint" do
|
10
|
+
|
11
|
+
it "uses the production endpoint" do
|
12
|
+
BaseCrm::Task.scope.instance_eval do
|
13
|
+
@endpoint.should == "https://common.futuresimple.com"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper.rb"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
|
8
|
+
require "base_crm"
|
9
|
+
require "simplecov"
|
10
|
+
|
11
|
+
SimpleCov.start do
|
12
|
+
add_filter '/spec'
|
13
|
+
end
|
14
|
+
|
15
|
+
RSpec.configure do |config|
|
16
|
+
end
|
17
|
+
|
18
|
+
Dir.glob("#{File.dirname(__FILE__)}/support/*.rb").each { |f| require f }
|
19
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
shared_examples "noteable" do |noteable_type|
|
2
|
+
|
3
|
+
let(:scope) { mock }
|
4
|
+
|
5
|
+
describe "#notes" do
|
6
|
+
let(:fetch_scope) { mock }
|
7
|
+
|
8
|
+
it "passes the token and applies the params" do
|
9
|
+
subject.
|
10
|
+
should_receive(:pass_headers).
|
11
|
+
with(BaseCrm::Note).
|
12
|
+
and_return(scope)
|
13
|
+
scope.should_receive(:params).
|
14
|
+
with({
|
15
|
+
:noteable_type => noteable_type,
|
16
|
+
:noteable_id => subject.id
|
17
|
+
}).and_return(fetch_scope)
|
18
|
+
subject.notes.should == fetch_scope
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#create_note" do
|
24
|
+
let(:message) { mock }
|
25
|
+
let(:note) { mock }
|
26
|
+
|
27
|
+
it "creates a new note" do
|
28
|
+
subject.
|
29
|
+
should_receive(:pass_headers).
|
30
|
+
with(BaseCrm::Note).
|
31
|
+
and_return(scope)
|
32
|
+
scope.should_receive(:create).with({
|
33
|
+
:content => message,
|
34
|
+
:noteable_type => noteable_type,
|
35
|
+
:noteable_id => subject.id
|
36
|
+
}).and_return(note)
|
37
|
+
subject.create_note(message).should == note
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
shared_examples "taskable" do |taskable_type|
|
2
|
+
|
3
|
+
let(:scope) { mock }
|
4
|
+
|
5
|
+
describe "#tasks" do
|
6
|
+
let(:fetch_scope) { mock }
|
7
|
+
|
8
|
+
it "passes the token and applies the params" do
|
9
|
+
subject.
|
10
|
+
should_receive(:pass_headers).
|
11
|
+
with(BaseCrm::Task).
|
12
|
+
and_return(scope)
|
13
|
+
scope.should_receive(:params).
|
14
|
+
with({
|
15
|
+
:taskable_type => taskable_type,
|
16
|
+
:taskable_id => subject.id
|
17
|
+
}).and_return(fetch_scope)
|
18
|
+
subject.tasks.should == fetch_scope
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#create_task" do
|
24
|
+
let(:params) do
|
25
|
+
{ :content => task_content }
|
26
|
+
end
|
27
|
+
let(:task_content) { mock }
|
28
|
+
let(:task) { mock }
|
29
|
+
|
30
|
+
it "creates a new task" do
|
31
|
+
subject.
|
32
|
+
should_receive(:pass_headers).
|
33
|
+
with(BaseCrm::Task).
|
34
|
+
and_return(scope)
|
35
|
+
scope.should_receive(:create).with({
|
36
|
+
:content => task_content,
|
37
|
+
:taskable_type => taskable_type,
|
38
|
+
:taskable_id => subject.id
|
39
|
+
}).and_return(task)
|
40
|
+
subject.create_task(params).should == task
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: basecrm
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Marcin Bunsch
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-04-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: api_client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.4.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.4.1
|
30
|
+
description: Base CRM API Client
|
31
|
+
email:
|
32
|
+
- marcin@futuresimple.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- .rspec
|
39
|
+
- Gemfile
|
40
|
+
- LICENSE
|
41
|
+
- README.md
|
42
|
+
- Rakefile
|
43
|
+
- basecrm.gemspec
|
44
|
+
- lib/base_crm.rb
|
45
|
+
- lib/base_crm/account.rb
|
46
|
+
- lib/base_crm/api_client_ext.rb
|
47
|
+
- lib/base_crm/config.rb
|
48
|
+
- lib/base_crm/contact.rb
|
49
|
+
- lib/base_crm/custom_fieldable.rb
|
50
|
+
- lib/base_crm/deal.rb
|
51
|
+
- lib/base_crm/lead.rb
|
52
|
+
- lib/base_crm/note.rb
|
53
|
+
- lib/base_crm/noteable.rb
|
54
|
+
- lib/base_crm/resource.rb
|
55
|
+
- lib/base_crm/session.rb
|
56
|
+
- lib/base_crm/source.rb
|
57
|
+
- lib/base_crm/task.rb
|
58
|
+
- lib/base_crm/taskable.rb
|
59
|
+
- lib/base_crm/version.rb
|
60
|
+
- lib/basecrm.rb
|
61
|
+
- spec/base_crm/account_spec.rb
|
62
|
+
- spec/base_crm/contact_spec.rb
|
63
|
+
- spec/base_crm/deal_spec.rb
|
64
|
+
- spec/base_crm/lead_spec.rb
|
65
|
+
- spec/base_crm/note_spec.rb
|
66
|
+
- spec/base_crm/resource_mixin_spec.rb
|
67
|
+
- spec/base_crm/session_spec.rb
|
68
|
+
- spec/base_crm/source_spec.rb
|
69
|
+
- spec/base_crm/task_spec.rb
|
70
|
+
- spec/spec_helper.rb
|
71
|
+
- spec/support/noteable_shared_examples.rb
|
72
|
+
- spec/support/taskable_shared_examples.rb
|
73
|
+
homepage: https://github.com/basecrm/basecrm
|
74
|
+
licenses: []
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ! '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
none: false
|
87
|
+
requirements:
|
88
|
+
- - ! '>='
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
requirements: []
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.8.25
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: Base CRM API Client
|
97
|
+
test_files:
|
98
|
+
- spec/base_crm/account_spec.rb
|
99
|
+
- spec/base_crm/contact_spec.rb
|
100
|
+
- spec/base_crm/deal_spec.rb
|
101
|
+
- spec/base_crm/lead_spec.rb
|
102
|
+
- spec/base_crm/note_spec.rb
|
103
|
+
- spec/base_crm/resource_mixin_spec.rb
|
104
|
+
- spec/base_crm/session_spec.rb
|
105
|
+
- spec/base_crm/source_spec.rb
|
106
|
+
- spec/base_crm/task_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/support/noteable_shared_examples.rb
|
109
|
+
- spec/support/taskable_shared_examples.rb
|
110
|
+
has_rdoc:
|