contactually-api 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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +22 -0
  3. data/README.md +62 -0
  4. data/Rakefile +7 -0
  5. data/lib/contactually-api.rb +34 -0
  6. data/lib/contactually/accounts.rb +31 -0
  7. data/lib/contactually/api.rb +70 -0
  8. data/lib/contactually/contact_groupings.rb +16 -0
  9. data/lib/contactually/contacts.rb +57 -0
  10. data/lib/contactually/contents.rb +38 -0
  11. data/lib/contactually/errors.rb +18 -0
  12. data/lib/contactually/groupings.rb +49 -0
  13. data/lib/contactually/middleware/error_detector.rb +27 -0
  14. data/lib/contactually/notes.rb +39 -0
  15. data/lib/contactually/representer/account_representer.rb +13 -0
  16. data/lib/contactually/representer/contact_representer.rb +46 -0
  17. data/lib/contactually/representer/content_representer.rb +16 -0
  18. data/lib/contactually/representer/grouping_representer.rb +28 -0
  19. data/lib/contactually/representer/grouping_statistics_representer.rb +12 -0
  20. data/lib/contactually/representer/note_representer.rb +13 -0
  21. data/lib/contactually/representer/task_representer.rb +19 -0
  22. data/lib/contactually/tasks.rb +12 -0
  23. data/lib/contactually/version.rb +3 -0
  24. data/spec/accounts_spec.rb +57 -0
  25. data/spec/api_spec.rb +87 -0
  26. data/spec/contact_groupings_spec.rb +43 -0
  27. data/spec/contacts_spec.rb +117 -0
  28. data/spec/contents_spec.rb +81 -0
  29. data/spec/fixtures/account.json +10 -0
  30. data/spec/fixtures/accounts_index.json +16 -0
  31. data/spec/fixtures/contact.json +38 -0
  32. data/spec/fixtures/contacts_index.json +169 -0
  33. data/spec/fixtures/content.json +10 -0
  34. data/spec/fixtures/contents_index.json +26 -0
  35. data/spec/fixtures/grouping.json +19 -0
  36. data/spec/fixtures/groupings_index.json +24 -0
  37. data/spec/fixtures/groupings_statistics.json +46 -0
  38. data/spec/fixtures/note.json +7 -0
  39. data/spec/fixtures/note_destroy.json +4 -0
  40. data/spec/fixtures/notes_index.json +27 -0
  41. data/spec/fixtures/task.json +27 -0
  42. data/spec/groupings_spec.rb +100 -0
  43. data/spec/notes_spec.rb +89 -0
  44. data/spec/spec_helper.rb +14 -0
  45. data/spec/tasks_spec.rb +36 -0
  46. metadata +194 -0
@@ -0,0 +1,39 @@
1
+ module Contactually
2
+ class Notes
3
+ def initialize(master)
4
+ @master = master
5
+ end
6
+
7
+ def index(params = {})
8
+ hash = @master.call('notes.json', :get, params)
9
+ notes_hash_to_objects(hash)
10
+ end
11
+
12
+ def show(id, params = {})
13
+ hash = @master.call("notes/#{id}.json", :get, params)
14
+ NoteRepresenter.new(Note.new).from_hash(hash)
15
+ end
16
+
17
+ def create(params = {})
18
+ hash = @master.call('notes.json', :post, params)
19
+ NoteRepresenter.new(Note.new).from_hash(hash)
20
+ end
21
+
22
+ def destroy(id, params = {})
23
+ @master.call("notes/#{id}.json", :delete, params)
24
+ end
25
+
26
+ def update(id, params = {})
27
+ hash = @master.call("notes/#{id}.json", :put, params)
28
+ NoteRepresenter.new(Note.new).from_hash(hash)
29
+ end
30
+
31
+ private
32
+
33
+ def notes_hash_to_objects(hash)
34
+ hash['notes'].inject([]) do |arr, note|
35
+ arr << NoteRepresenter.new(Note.new).from_hash(note)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,13 @@
1
+ module Contactually
2
+ class Account < OpenStruct
3
+ end
4
+
5
+ class AccountRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+ property :id
8
+ property :username
9
+ property :remote_id
10
+ property :type
11
+ property :disabled_at
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ module Contactually
2
+ class Contact < OpenStruct
3
+ end
4
+
5
+ class ContactRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+ property :id
8
+ property :user_id
9
+ property :first_name
10
+ property :last_name
11
+ property :full_name
12
+ property :initials
13
+ property :title
14
+ property :company
15
+ property :email
16
+ property :avatar
17
+ property :avatar_url
18
+ property :last_contacted
19
+ property :visible
20
+ property :twitter
21
+ property :facebook_url
22
+ property :linkedin_url
23
+ property :first_contacted
24
+ property :created_at
25
+ property :updated_at
26
+ property :hits
27
+ property :team_parent_id
28
+ property :snoozed_at
29
+ property :snooze_days
30
+ property :email_addresses
31
+ property :tags
32
+ property :contact_status
33
+ property :team_last_contacted
34
+ property :team_last_contacted_by
35
+ property :phone_numbers
36
+ property :addresses
37
+ property :social_profiles
38
+ property :websites
39
+ property :custom_fields
40
+ property :sent
41
+ property :received
42
+ property :link
43
+ property :content
44
+ collection :groupings, extend: GroupingRepresenter, class: Grouping
45
+ end
46
+ end
@@ -0,0 +1,16 @@
1
+ module Contactually
2
+ class Content < OpenStruct
3
+ end
4
+
5
+ class ContentRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+ property :id
8
+ property :user_id
9
+ property :url
10
+ property :title
11
+ property :description
12
+ property :article
13
+ property :original_content_id
14
+ collection :groupings, extend: GroupingRepresenter, class: Grouping
15
+ end
16
+ end
@@ -0,0 +1,28 @@
1
+ module Contactually
2
+ class Grouping < OpenStruct
3
+ end
4
+
5
+ class GroupingRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+ property :id
8
+ property :type
9
+ property :name
10
+ property :stub
11
+ property :user_id
12
+ property :domain_id
13
+ property :editable
14
+ property :conversable
15
+ property :locked
16
+ property :derived_from_id
17
+ property :created_at
18
+ property :updated_at
19
+ property :has_followups
20
+ property :num_days_to_followup
21
+ property :program_id
22
+ property :objective
23
+ property :sort_order
24
+ property :accounts
25
+ property :number_of_contacts
26
+ property :goal
27
+ end
28
+ end
@@ -0,0 +1,12 @@
1
+ module Contactually
2
+ class GroupingStatistics < OpenStruct
3
+ end
4
+
5
+ class GroupingStatisticsRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+ property :messages_sent
8
+ property :messages_received
9
+ property :status
10
+ collection :contacts, extend: ContactRepresenter, class: Contact
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ module Contactually
2
+ class Note < OpenStruct
3
+ end
4
+
5
+ class NoteRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+ property :id
8
+ property :body
9
+ property :contact_id
10
+ property :timestamp
11
+ property :user_id
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Contactually
2
+ class Task < OpenStruct
3
+ end
4
+
5
+ class TaskRepresenter < Roar::Decorator
6
+ include Roar::Representer::JSON
7
+ property :id
8
+ property :title
9
+ property :due_date
10
+ property :completed_at
11
+ property :deleted_at
12
+ property :is_follow_up
13
+ property :last_contacted
14
+ property :contact_id
15
+ property :ignored
16
+ property :completed_via
17
+ property :approval_data
18
+ end
19
+ end
@@ -0,0 +1,12 @@
1
+ module Contactually
2
+ class Tasks
3
+ def initialize(master)
4
+ @master = master
5
+ end
6
+
7
+ def show(id, params = {})
8
+ hash = @master.call("tasks/#{id}.json", :get, params)
9
+ TaskRepresenter.new(Task.new).from_hash(hash)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,3 @@
1
+ module Contactually
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Contactually::Accounts do
4
+
5
+ before(:all) do
6
+ Contactually.configure { |c| c.api_key = 'VALID_API_KEY' }
7
+ @master = Contactually::API.new
8
+ end
9
+
10
+ subject { described_class.new @master }
11
+ describe '#initialize' do
12
+ specify do
13
+ expect(subject).to be_kind_of Contactually::Accounts
14
+ end
15
+
16
+ specify do
17
+ expect(subject.instance_variable_get(:@master)).to be_kind_of Contactually::API
18
+ end
19
+ end
20
+
21
+ describe '#index' do
22
+ it 'calls the api with correct params' do
23
+ allow(@master).to receive(:call).with('accounts.json', :get, { foo: :bar }).and_return({ 'accounts' => [] })
24
+ subject.index({ foo: :bar })
25
+ expect(@master).to have_received(:call)
26
+ end
27
+
28
+ it 'returns accounts from json response' do
29
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/accounts_index.json"))
30
+ allow(@master).to receive(:call).with('accounts.json', :get, {}).and_return(JSON.load(json))
31
+ expect(subject.index({})).to be_kind_of Array
32
+ expect(subject.index({})[0]).to be_kind_of Contactually::Account
33
+ end
34
+ end
35
+
36
+ describe '#show' do
37
+ it 'calls the api with correct params' do
38
+ allow(@master).to receive(:call).with('accounts/1.json', :get, { foo: :bar }).and_return({ id: 1 })
39
+ subject.show(1, { foo: :bar })
40
+ expect(@master).to have_received(:call)
41
+ end
42
+
43
+ it 'returns an account' do
44
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/account.json"))
45
+ allow(@master).to receive(:call).with('accounts/1.json', :get, { foo: :bar }).and_return(JSON.load(json))
46
+ expect(subject.show(1, { foo: :bar })).to be_kind_of Contactually::Account
47
+ end
48
+ end
49
+
50
+ describe '#destroy' do
51
+ it 'calls the api with correct params' do
52
+ allow(@master).to receive(:call).with('accounts/1.json', :delete, {})
53
+ subject.destroy(1)
54
+ expect(@master).to have_received(:call)
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ describe Contactually::API do
4
+
5
+ describe 'missing configuration' do
6
+ before(:all) { Contactually.configure { |c| c.api_key = nil } }
7
+ specify do
8
+ expect{ subject }.to raise_error Contactually::ConfigMissingApiKeyError
9
+ end
10
+ end
11
+
12
+ describe 'valid configuration' do
13
+ before(:all) { Contactually.configure { |c| c.api_key = 'VALID_API_KEY' } }
14
+
15
+ describe '#initialize' do
16
+ it 'initializes correctly' do
17
+ expect{ subject }.not_to raise_error
18
+ expect(subject).to be_kind_of Contactually::API
19
+ end
20
+
21
+ it 'sets instance variables' do
22
+ expect(subject.instance_variable_get(:@api_key)).to eq 'VALID_API_KEY'
23
+ expect(subject.instance_variable_get(:@base_url)).to eq Contactually.contactually_url
24
+ end
25
+ end
26
+
27
+ describe '#call' do
28
+ it 'redirects get request to get' do
29
+ allow(subject).to receive(:get).and_return(Struct.new(:status, :body).new(200, {}))
30
+ subject.call('bla', :get, {})
31
+ expect(subject).to have_received(:get).with('bla', {})
32
+ end
33
+
34
+ it 'redirects post request to post' do
35
+ allow(subject).to receive(:post).and_return(Struct.new(:status, :body).new(200, {}))
36
+ subject.call('bla', :post, {})
37
+ expect(subject).to have_received(:post).with('bla', {})
38
+ end
39
+ end
40
+
41
+ describe '#call_params' do
42
+ specify do
43
+ expect(subject.send(:call_params, { foo: :bar })).to eql({ api_key: 'VALID_API_KEY', foo: :bar })
44
+ end
45
+ end
46
+
47
+ describe '#base_url' do
48
+ specify do
49
+ expect(subject.send(:base_url, 'foo/bar')).to eql("#{Contactually.contactually_url}foo/bar")
50
+ end
51
+ end
52
+
53
+ describe '#contacts' do
54
+ specify do
55
+ expect(subject.contacts).to be_kind_of Contactually::Contacts
56
+ end
57
+ end
58
+
59
+ describe '#notes' do
60
+ specify do
61
+ expect(subject.notes).to be_kind_of Contactually::Notes
62
+ end
63
+ end
64
+
65
+ describe '#groupings' do
66
+ specify do
67
+ expect(subject.groupings).to be_kind_of Contactually::Groupings
68
+ end
69
+ end
70
+
71
+ describe '#get' do
72
+ it 'parses from json response' do
73
+ allow(subject.connection).to receive(:get).
74
+ with('https://www.contactually.com/api/v1/url', { foo: :bar, api_key: 'VALID_API_KEY' }).
75
+ and_return(Struct.new(:status, :body).new(200, "{ \"foo\": \"bar\" }"))
76
+ expect(subject.call('url', :get, { foo: :bar })).to be_kind_of Hash
77
+ end
78
+ end
79
+
80
+ describe '#post' do
81
+ it 'parses from json response' do
82
+ allow(subject.connection).to receive(:post).and_return(Struct.new(:status, :body).new(200, "{ \"foo\": \"bar\" }"))
83
+ expect(subject.call('url', :post, { foo: :bar })).to be_kind_of Hash
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+
3
+ describe Contactually::ContactGroupings do
4
+
5
+ before(:all) do
6
+ Contactually.configure { |c| c.api_key = 'VALID_API_KEY' }
7
+ @master = Contactually::API.new
8
+ end
9
+
10
+ subject { described_class.new @master }
11
+ describe '#initialize' do
12
+ specify do
13
+ expect(subject).to be_kind_of Contactually::ContactGroupings
14
+ end
15
+
16
+ specify do
17
+ expect(subject.instance_variable_get(:@master)).to be_kind_of Contactually::API
18
+ end
19
+ end
20
+
21
+
22
+ describe '#create' do
23
+ it 'calls the api with correct params' do
24
+ allow(@master).to receive(:call).with('contacts/1/groupings.json', :post, { grouping_id: 512 }).and_return({ 'id' => 1234 })
25
+ subject.create(1, { grouping_id: 512 })
26
+ expect(@master).to have_received(:call)
27
+ end
28
+
29
+ it 'returns grouping from json response' do
30
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/grouping.json"))
31
+ allow(@master).to receive(:call).with('contacts/1/groupings.json', :post, { grouping_id: 512 }).and_return(JSON.load(json))
32
+ expect(subject.create(1, { grouping_id: 512 })).to be_kind_of Contactually::Grouping
33
+ end
34
+ end
35
+
36
+ describe '#destroy' do
37
+ it 'calls the api with correct params' do
38
+ allow(@master).to receive(:call).with('contacts/1/groupings/15.json', :delete, { foo: :bar }).and_return({ 'success' => true })
39
+ subject.destroy(1, 15, { foo: :bar })
40
+ expect(@master).to have_received(:call)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,117 @@
1
+ require 'spec_helper'
2
+
3
+ describe Contactually::Contacts do
4
+
5
+ before(:all) do
6
+ Contactually.configure { |c| c.api_key = 'VALID_API_KEY' }
7
+ @master = Contactually::API.new
8
+ end
9
+
10
+ subject { described_class.new @master }
11
+ describe '#initialize' do
12
+ specify do
13
+ expect(subject).to be_kind_of Contactually::Contacts
14
+ end
15
+
16
+ specify do
17
+ expect(subject.instance_variable_get(:@master)).to be_kind_of Contactually::API
18
+ end
19
+ end
20
+
21
+ describe '#create' do
22
+ it 'calls the api with correct params' do
23
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/contact.json"))
24
+ allow(@master).to receive(:call).with('contacts.json', :post, { contact: { foo: :bar }}).and_return(JSON.load(json))
25
+ subject.create({ contact: { foo: :bar }})
26
+ expect(@master).to have_received(:call)
27
+ end
28
+
29
+ it 'returns a contact' do
30
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/contact.json"))
31
+ allow(@master).to receive(:call).with('contacts.json', :post, { contact: { foo: :bar }}).and_return(JSON.load(json))
32
+ expect(subject.create({ contact: { foo: :bar } })).to be_kind_of Contactually::Contact
33
+ end
34
+ end
35
+
36
+ describe '#destroy' do
37
+ it 'calls the api with correct params' do
38
+ allow(@master).to receive(:call).with('contacts/1.json', :delete, {})
39
+ subject.destroy(1)
40
+ expect(@master).to have_received(:call)
41
+ end
42
+ end
43
+
44
+ describe '#destroy_multiple' do
45
+ it 'calls the api with correct params' do
46
+ allow(@master).to receive(:call).with('contacts.json', :delete, { ids: [ 1, 2, 3 ]})
47
+ subject.destroy_multiple({ ids: [ 1, 2, 3 ]})
48
+ expect(@master).to have_received(:call)
49
+ end
50
+ end
51
+
52
+ describe '#show' do
53
+ it 'calls the api with correct params' do
54
+ allow(@master).to receive(:call).with('contacts/1.json', :get, { foo: :bar }).and_return({ id: 1 })
55
+ subject.show(1, { foo: :bar })
56
+ expect(@master).to have_received(:call)
57
+ end
58
+
59
+ it 'returns a contact' do
60
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/contact.json"))
61
+ allow(@master).to receive(:call).with('contacts/1.json', :get, { foo: :bar }).and_return(JSON.load(json))
62
+ expect(subject.show(1, { foo: :bar })).to be_kind_of Contactually::Contact
63
+ end
64
+ end
65
+
66
+ describe '#tags' do
67
+ it 'calls the api with correct params - Array' do
68
+ allow(@master).to receive(:call).with('contacts/1/tags.json', :post, { tags: 'lol, haha' })
69
+ subject.tags(1, { tags: [ 'lol', 'haha' ]})
70
+ expect(@master).to have_received(:call)
71
+ end
72
+
73
+ it 'calls the api with correct params - String' do
74
+ allow(@master).to receive(:call).with('contacts/1/tags.json', :post, { tags: 'lol, haha' })
75
+ subject.tags(1, { tags: 'lol, haha' })
76
+ expect(@master).to have_received(:call)
77
+ end
78
+ end
79
+
80
+ describe '#update' do
81
+ it 'calls the api with correct params' do
82
+ allow(@master).to receive(:call).with('contacts/1.json', :put, { contact: { foo: :bar }})
83
+ subject.update(1, { contact: { foo: :bar } })
84
+ expect(@master).to have_received(:call)
85
+ end
86
+ end
87
+
88
+ describe '#index' do
89
+ it 'calls the api with correct params' do
90
+ allow(@master).to receive(:call).with('contacts.json', :get, { foo: :bar }).and_return({ 'contacts' => [] })
91
+ subject.index({ foo: :bar })
92
+ expect(@master).to have_received(:call)
93
+ end
94
+
95
+ it 'returns contacts from json response' do
96
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/contacts_index.json"))
97
+ allow(@master).to receive(:call).with('contacts.json', :get, {}).and_return(JSON.load(json))
98
+ expect(subject.index({})).to be_kind_of Array
99
+ expect(subject.index({})[0]).to be_kind_of Contactually::Contact
100
+ end
101
+ end
102
+
103
+ describe '#search' do
104
+ it 'calls the api with correct params' do
105
+ allow(@master).to receive(:call).with('contacts/search.json', :get, { term: :foo_bar }).and_return({ 'contacts' => [] })
106
+ subject.search({ term: :foo_bar})
107
+ expect(@master).to have_received(:call)
108
+ end
109
+
110
+ it 'returns contacts from json response' do
111
+ json = File.read(File.join(File.dirname(__FILE__),"fixtures/contacts_index.json"))
112
+ allow(@master).to receive(:call).with('contacts/search.json', :get, { term: :foo_bar }).and_return(JSON.load(json))
113
+ expect(subject.search({ term: :foo_bar })).to be_kind_of Array
114
+ expect(subject.search({ term: :foo_bar })[0]).to be_kind_of Contactually::Contact
115
+ end
116
+ end
117
+ end