relateiq_client 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'Update a list item for a contact' do
4
+ let(:accounts_url) { 'https://test.relateiq.com/accounts' }
5
+ let(:contacts_url) { 'https://test.relateiq.com/contacts' }
6
+ let(:lists_url) { 'https://test.relateiq.com/lists' }
7
+ let(:email) { 'gulgowski.devyn@example.com' }
8
+
9
+ before do
10
+ stub_request(:get, lists_url)
11
+ .to_return(body: File.readlines('spec/fixtures/lists.json').join)
12
+
13
+ stub_request(:get, "#{lists_url}/list2id/listitems/?contactIds=contactid")
14
+ .to_return(body: File.readlines('spec/fixtures/list_items_by_contact_id.json').join)
15
+
16
+ stub_request(:post, "#{lists_url}/list2id/listitems")
17
+ .to_return(body: File.readlines('spec/fixtures/list_item.json').join)
18
+
19
+ stub_request(:post, "#{accounts_url}")
20
+ .to_return(body: File.readlines('spec/fixtures/account_by_id.json').join)
21
+
22
+ stub_request(:get, "#{contacts_url}/?properties.email=#{email}")
23
+ .to_return(body: File.readlines('spec/fixtures/contacts_by_email.json').join)
24
+
25
+ stub_request(:put, "#{lists_url}/list2id/listitems/listitem1")
26
+ .to_return(body: File.readlines('spec/fixtures/list_item.json').join)
27
+
28
+ stub_request(:put, "#{lists_url}/list2id/listitems/listitem2")
29
+ .to_return(body: File.readlines('spec/fixtures/list_item.json').join)
30
+ end
31
+
32
+ it 'finds list by name, creates an account and creates a list item for that list and account' do
33
+ list = RelateIq::List.find_by_title('Burundi')
34
+ account = RelateIq::Account.create(name: 'Simple Company')
35
+ list_item = list.upsert_item(
36
+ name: 'Simple Name',
37
+ account_id: account.id,
38
+ field_values: [
39
+ { 'sint' => 'Administrator, Civil Service' },
40
+ { 'status' => 'Homeopath' },
41
+ { 'maiores' => 'test123' }
42
+ ]
43
+ )
44
+
45
+ expect(list_item.id).to eq('listitemid')
46
+ expect(list_item.account_id).to eq('accountid')
47
+ end
48
+
49
+ it 'can find a list items by contact id and update their status' do
50
+ contacts = RelateIq::Contact.find_by_email(email)
51
+ list = RelateIq::List.find_by_title('Burundi')
52
+ contacts.each do |contact|
53
+ list_items = list.items_by_contact_id(contact.id)
54
+ list_items.each do |list_item|
55
+ list_item.field_values << { 'status' => 'Homeopath' }
56
+ list_item.save
57
+ end
58
+ end
59
+
60
+ expect(WebMock).to have_requested(:put, "#{lists_url}/list2id/listitems/listitem1")
61
+ .with(body: '{"listId":"list2id","id":"listitem1","name":"hello+test@example.com",' \
62
+ '"contactIds":["contactid"],"fieldValues":{"0":[{"raw":"3"}],"44":[' \
63
+ '{"raw":"3"}]}}')
64
+ expect(WebMock).to have_requested(:put, "#{lists_url}/list2id/listitems/listitem2")
65
+ .with(body: '{"listId":"list2id","id":"listitem2","name":"hello@example.com",' \
66
+ '"contactIds":["contactid"],"fieldValues":{"0":[{"raw":"2"}],"' \
67
+ '44":[{"raw":"3"}]}}')
68
+ end
69
+ end
@@ -0,0 +1,66 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RelateIq::Account do
4
+ let(:account) { RelateIq::Account.new(id: 'accountid', name: 'account_name') }
5
+ let(:accounts_url) { 'https://test.relateiq.com/accounts' }
6
+ let(:json) { '{ "id": "accountid", "name": "account_name" }' }
7
+
8
+ before do
9
+ stub_request(:get, "#{accounts_url}/accountid")
10
+ .to_return(body: File.readlines('spec/fixtures/account_by_id.json').join)
11
+ stub_request(:put, "#{accounts_url}/accountid")
12
+ .to_return(body: File.readlines('spec/fixtures/account_by_id.json').join)
13
+ stub_request(:post, "#{accounts_url}")
14
+ .to_return(body: File.readlines('spec/fixtures/account_by_id.json').join)
15
+ end
16
+
17
+ context '#initiazlie' do
18
+ it 'sets account id and name from initializer' do
19
+ expect(account.id).to eq('accountid')
20
+ expect(account.name).to eq('account_name')
21
+ end
22
+ end
23
+
24
+ context '#to_json' do
25
+ it 'returns a properly serialized account' do
26
+ expect(JSON.parse(account.to_json)).to eq(JSON.parse(json))
27
+ end
28
+ end
29
+
30
+ context '#save' do
31
+ it 'calls correct save url with account serialized to JSON' do
32
+ RelateIq::Account.new(id: 'accountid', name: 'Testing Account').save
33
+ expect(WebMock).to have_requested(:put, "#{accounts_url}/accountid")
34
+ .with(body: '{"name":"Testing Account","id":"accountid"}')
35
+ end
36
+ end
37
+
38
+ context '.find' do
39
+ it 'returns a single account by id' do
40
+ account = RelateIq::Account.find('accountid')
41
+ expect(account.id).to eq('accountid')
42
+ expect(account.name).to eq('Bolstr, Inc.')
43
+ end
44
+ end
45
+
46
+ context '.from_json' do
47
+ it 'returns an account object from json representation' do
48
+ account_from_json = RelateIq::Account.from_json(json)
49
+ expect(account_from_json.id).to eq('accountid')
50
+ expect(account_from_json.name).to eq('account_name')
51
+ end
52
+ end
53
+
54
+ context '.create' do
55
+ it 'creates an account and returns its id' do
56
+ account = RelateIq::Account.create(name: 'Testing Account')
57
+ expect(account.id).to eq('accountid')
58
+ end
59
+
60
+ it 'calls the correct url with body params' do
61
+ RelateIq::Account.create(name: 'Testing Account')
62
+ expect(WebMock).to have_requested(:post, accounts_url)
63
+ .with(body: '{"name":"Testing Account"}').once
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,161 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RelateIq::Contact do
4
+ let(:contacts_url) { 'https://test.relateiq.com/contacts' }
5
+ let(:email) { 'gulgowski.devyn@example.com' }
6
+ let(:id) { 'contactid' }
7
+ before do
8
+ stub_request(:get, "#{contacts_url}/?properties.email=#{email}")
9
+ .to_return(body: File.readlines('spec/fixtures/contacts_by_email.json').join)
10
+
11
+ stub_request(:get, "#{contacts_url}/#{id}")
12
+ .to_return(body: File.readlines('spec/fixtures/contact.json').join)
13
+
14
+ stub_request(:post, "#{contacts_url}")
15
+ .to_return(body: File.readlines('spec/fixtures/contact.json').join)
16
+
17
+ stub_request(:put, "#{contacts_url}/#{id}")
18
+ .to_return(body: File.readlines('spec/fixtures/contact.json').join)
19
+ end
20
+
21
+ context '.find_by_email' do
22
+ it 'returns a Contact with a matching title' do
23
+ contacts = RelateIq::Contact.find_by_email(email)
24
+ expect(contacts[0].id).to eq(id)
25
+ end
26
+
27
+ it 'requests the correct url' do
28
+ RelateIq::Contact.find_by_email(email)
29
+ url = "#{contacts_url}/?properties.email=gulgowski.devyn@example.com"
30
+ expect(WebMock).to have_requested(:get, url).once
31
+ end
32
+ end
33
+
34
+ context '.find' do
35
+ let(:contact) { RelateIq::Contact.find(id) }
36
+
37
+ it 'requests the correct url' do
38
+ RelateIq::Contact.find(id)
39
+ url = "#{contacts_url}/#{id}"
40
+ expect(WebMock).to have_requested(:get, url).once
41
+ end
42
+
43
+ it 'assigns relateiq properties to returned contact' do
44
+ expect(contact.email).to eq(email)
45
+ end
46
+ end
47
+
48
+ context '#initialize' do
49
+ let(:contact_from_api) do
50
+ RelateIq::Contact.new(
51
+ id: 'someid',
52
+ properties: {
53
+ email: [{ value: 'hello@hello.com' }],
54
+ company: [
55
+ { value: 'Bolstr' },
56
+ { value: 'Bolstr, Inc.' }
57
+ ],
58
+ liurl: [{ value: 'https://www.linkedin.com/in/doriankarter' }],
59
+ twhan: [{ value: '@test' }]
60
+ }
61
+ )
62
+ end
63
+
64
+ let(:contact) do
65
+ RelateIq::Contact.new(
66
+ id: 'someid',
67
+ email: 'hello@hello.com',
68
+ first_name: 'Little',
69
+ last_name: 'Wuckert',
70
+ company: ['Bolstr', 'Bolstr, Inc.'],
71
+ linkedin: 'https://www.linkedin.com/in/doriankarter'
72
+ )
73
+ end
74
+
75
+ it 'can have mutltiple values on contact' do
76
+ expect(contact_from_api.company).to eq(['Bolstr', 'Bolstr, Inc.'])
77
+ expect(contact.company).to eq(['Bolstr', 'Bolstr, Inc.'])
78
+ end
79
+
80
+ it 'translates and cleans up relateiq keys' do
81
+ expect(contact_from_api.linkedin).to eq('https://www.linkedin.com/in/doriankarter')
82
+ expect(contact_from_api.twitter).to eq('@test')
83
+ expect(contact_from_api).to_not respond_to(:liurl)
84
+ expect(contact_from_api).to_not respond_to(:twhan)
85
+ end
86
+
87
+ it 'allows initializing by user' do
88
+ expect(contact.id).to eq('someid')
89
+ expect(contact.email).to eq('hello@hello.com')
90
+ expect(contact.first_name).to eq('Little')
91
+ expect(contact.last_name).to eq('Wuckert')
92
+ expect(contact.linkedin).to eq('https://www.linkedin.com/in/doriankarter')
93
+ end
94
+
95
+ it 'assigns relateiq properties contact object' do
96
+ expect(contact_from_api.email).to eq('hello@hello.com')
97
+ end
98
+ end
99
+
100
+ context '#save' do
101
+ let(:contact_to_update) do
102
+ RelateIq::Contact.new(
103
+ id: id,
104
+ email: 'hello@hello.com',
105
+ company: ['Bolstr', 'Bolstr, Inc.'],
106
+ linkedin: 'https://www.linkedin.com/in/doriankarter'
107
+ )
108
+ end
109
+
110
+ let(:contact_to_create) do
111
+ RelateIq::Contact.new(
112
+ email: 'hello@hello.com',
113
+ company: ['Bolstr', 'Bolstr, Inc.'],
114
+ linkedin: 'https://www.linkedin.com/in/doriankarter'
115
+ )
116
+ end
117
+
118
+ it 'executes update when contact has no id' do
119
+ contact_to_create.save
120
+ url = "#{contacts_url}"
121
+ expect(WebMock).to have_requested(:post, url).once
122
+ end
123
+
124
+ it 'executes create (post) when contact has id' do
125
+ contact_to_update.save
126
+ url = "#{contacts_url}/#{contact_to_update.id}"
127
+ expect(WebMock).to have_requested(:put, url).once
128
+ end
129
+ end
130
+
131
+ context '#to_json' do
132
+ let(:contact) do
133
+ RelateIq::Contact.new(
134
+ id: 'someid',
135
+ first_name: 'Little',
136
+ last_name: 'Wuckert',
137
+ email: 'hello@hello.com',
138
+ company: ['Bolstr', 'Bolstr, Inc.'],
139
+ linkedin: 'https://www.linkedin.com/in/doriankarter',
140
+ twitter: '@test'
141
+ )
142
+ end
143
+
144
+ it 'should return a proper relateiq json contact and not include unset attributes' do
145
+ expected_json_hash = {
146
+ id: 'someid',
147
+ properties: {
148
+ name: [{ value: 'Little Wuckert' }],
149
+ email: [{ value: 'hello@hello.com' }],
150
+ company: [
151
+ { value: 'Bolstr' },
152
+ { value: 'Bolstr, Inc.' }
153
+ ],
154
+ liurl: [{ value: 'https://www.linkedin.com/in/doriankarter' }],
155
+ twhan: [{ value: '@test' }]
156
+ }
157
+ }
158
+ expect(JSON.parse(contact.to_json, symbolize_names: true)).to eq(expected_json_hash)
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,133 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RelateIq::ListItem do
4
+ let(:lists_url) { 'https://test.relateiq.com/lists' }
5
+
6
+ before do
7
+ stub_request(:get, lists_url)
8
+ .to_return(body: File.readlines('spec/fixtures/lists.json').join)
9
+
10
+ stub_request(:get, "#{lists_url}/list2id/listitems/?contactIds=contactid")
11
+ .to_return(body: File.readlines('spec/fixtures/list_items_by_contact_id.json').join)
12
+
13
+ stub_request(:put, "#{lists_url}/list2id/listitems/listitemid")
14
+ .to_return(body: File.readlines('spec/fixtures/list_item.json').join)
15
+
16
+ stub_request(:post, "#{lists_url}/list2id/listitems")
17
+ .to_return(body: File.readlines('spec/fixtures/list_item.json').join)
18
+ end
19
+
20
+ context '.create' do
21
+ it 'requests correct url with all parameters' do
22
+ RelateIq::ListItem.create(name: 'itemname', list_id: 'list2id')
23
+ url = "#{lists_url}/list2id/listitems"
24
+ expect(WebMock).to have_requested(:post, url)
25
+ .with(body: '{"listId":"list2id","name":"itemname"}')
26
+ end
27
+
28
+ it 'returns the id of the list item' do
29
+ item = RelateIq::ListItem.create(name: 'itemname', list_id: 'list2id')
30
+ expect(item.id).to eq('listitemid')
31
+ end
32
+ end
33
+
34
+ context '.find_by_contact' do
35
+ let(:list_items) do
36
+ RelateIq::ListItem.find_by_contact('list2id', 'contactid')
37
+ end
38
+
39
+ it 'requests correct url with all parameters' do
40
+ RelateIq::ListItem.find_by_contact('list2id', 'contactid')
41
+ expect(WebMock).to have_requested(:get, "#{lists_url}/list2id/listitems/?contactIds=contactid")
42
+ end
43
+
44
+ it 'returns 2 list items' do
45
+ expect(list_items.count).to eq(2)
46
+ expect(list_items[0].is_a? RelateIq::ListItem).to eq(true)
47
+ expect(list_items[1].is_a? RelateIq::ListItem).to eq(true)
48
+ end
49
+ end
50
+
51
+ context '.from_json' do
52
+ it 'returns an instance of ListItem containing all properties specified in json' do
53
+ json = '{ "listId": "list2id", "name": "test" }'
54
+ deserialized_list_item = RelateIq::ListItem.from_json(json)
55
+ expect(deserialized_list_item.list_id).to eq('list2id')
56
+ end
57
+ end
58
+
59
+ context '#to_json' do
60
+ it 'returns a full representation of list item in relateiq json format' do
61
+ list_item = RelateIq::ListItem.new(
62
+ name: 'itemname',
63
+ list_id: 'list2id',
64
+ field_values: [{ 'nobis' => 'Dancer' }],
65
+ contact_ids: ['contactid1', 'contactid2'],
66
+ account_id: 'accountid'
67
+ )
68
+ json_hash = {
69
+ 'listId' => 'list2id',
70
+ 'name' => 'itemname',
71
+ 'accountId' => 'accountid',
72
+ 'contactIds' => ['contactid1', 'contactid2'],
73
+ 'fieldValues' => {
74
+ '0' => [{ 'raw' => '17' }]
75
+ }
76
+ }
77
+ expect(list_item.to_json).to eq(json_hash.to_json)
78
+ end
79
+
80
+ it 'does not render an account id to a contact type list' do
81
+ list_item = RelateIq::ListItem.new(
82
+ list_id: 'list1id',
83
+ contact_ids: ['contactid1', 'contactid2'],
84
+ account_id: 'accountid'
85
+ )
86
+ json_hash = {
87
+ 'listId' => 'list1id',
88
+ 'contactIds' => ['contactid1', 'contactid2'],
89
+ }
90
+ expect(list_item.to_json).to eq(json_hash.to_json)
91
+ end
92
+
93
+ it 'omits properties that are not filled' do
94
+ list_item = RelateIq::ListItem.new(
95
+ name: 'itemname',
96
+ list_id: 'list2id',
97
+ field_values: [{ 'nobis' => 'Dancer' }]
98
+ )
99
+ json_hash = {
100
+ 'listId' => 'list2id',
101
+ 'name' => 'itemname',
102
+ 'fieldValues' => {
103
+ '0' => [{ 'raw' => '17' }]
104
+ }
105
+ }
106
+ expect(list_item.to_json).to eq(json_hash.to_json)
107
+ end
108
+ end
109
+
110
+ context '#save' do
111
+ it 'saves existing list item' do
112
+ RelateIq::ListItem.new(
113
+ id: 'listitemid',
114
+ name: 'itemname',
115
+ list_id: 'list2id',
116
+ field_values: nil
117
+ ).save
118
+ url = "#{lists_url}/list2id/listitems/listitemid"
119
+ expect(WebMock).to have_requested(:put, url)
120
+ .with(body: '{"listId":"list2id","id":"listitemid","name":"itemname"}')
121
+ end
122
+
123
+ it 'creates new item when no id is supplied' do
124
+ RelateIq::ListItem.new(
125
+ name: 'itemname',
126
+ list_id: 'list2id'
127
+ ).save
128
+ url = "#{lists_url}/list2id/listitems"
129
+ expect(WebMock).to have_requested(:post, url)
130
+ .with(body: '{"listId":"list2id","name":"itemname"}')
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,145 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe RelateIq::List do
4
+ let(:lists_url) { 'https://test.relateiq.com/lists' }
5
+ let(:list_class) { RelateIq::List }
6
+ let(:list_2) { RelateIq::List.find_by_title('Burundi') }
7
+ let(:list_hash) do
8
+ {
9
+ id: 'someid',
10
+ title: 'List Title',
11
+ listType: 'contact',
12
+ modifiedDate: 12345678,
13
+ fields: [
14
+ {
15
+ id: '5',
16
+ name: 'unde',
17
+ listOptions: [],
18
+ isMultiSelect: false,
19
+ isEditable: false,
20
+ dataType: 'DateTime'
21
+ },
22
+ {
23
+ id: '9',
24
+ name: 'porro',
25
+ listOptions: [
26
+ {
27
+ id: '0',
28
+ display: 'Teacher, special educational needs'
29
+ },
30
+ {
31
+ id: '1',
32
+ display: 'Applications developer'
33
+ }
34
+ ],
35
+ isMultiSelect: false,
36
+ isEditable: true,
37
+ dataType: 'List'
38
+ }
39
+ ]
40
+ }
41
+ end
42
+ let(:list_json) { list_hash.to_json }
43
+
44
+ before do
45
+ stub_request(:get, lists_url)
46
+ .to_return(body: File.readlines('spec/fixtures/lists.json').join)
47
+
48
+ stub_request(:get, "#{lists_url}/list2id/listitems/?contactIds=contactid")
49
+ .to_return(body: File.readlines('spec/fixtures/list_items_by_contact_id.json').join)
50
+ end
51
+
52
+ context '.all' do
53
+ it 'returns an array of lists' do
54
+ expect(list_class.all.count).to eq(6)
55
+ list_class.all.each do |item|
56
+ expect(item.is_a? list_class).to eq(true)
57
+ end
58
+ end
59
+
60
+ it 'returns field list_options as an array' do
61
+ status_field = RelateIq::List.all[0].fields.find { |f| f[:name] == 'status' }
62
+ status_field[:listOptions].is_a? Array
63
+ end
64
+
65
+ it 'caches a copy in memory and does not call web method more than once' do
66
+ list_class.clean_cache
67
+ list_class.all
68
+ list_class.all
69
+ expect(WebMock).to have_requested(:get, lists_url).once
70
+ end
71
+ end
72
+
73
+ context '.find_by_title' do
74
+ it 'returns a List with a matching title' do
75
+ expect(list_class.find_by_title('Swaziland')).to eq(list_class.all[2])
76
+ end
77
+
78
+ it 'is case insensitive' do
79
+ expect(list_class.find_by_title('swaziland')).to eq(list_class.all[2])
80
+ end
81
+ end
82
+
83
+ context '.from_json' do
84
+ it 'can create an array of lists from json' do
85
+ lists_from_json = RelateIq::List.from_json(File.readlines('spec/fixtures/lists.json').join)
86
+ lists_from_json.each do |l|
87
+ expect(l.is_a?(RelateIq::List)).to eq(true)
88
+ end
89
+ expect(lists_from_json.count).to eq(6)
90
+ end
91
+
92
+ it 'can create a single list from json' do
93
+ list_from_json = RelateIq::List.from_json(list_json)
94
+ expect(list_from_json.id).to eq('someid')
95
+ end
96
+ end
97
+
98
+ context '#initialize' do
99
+ let(:list_from_api) do
100
+ RelateIq::List.new(list_hash)
101
+ end
102
+
103
+ let(:list) do
104
+ RelateIq::List.new(
105
+ id: 'someid',
106
+ title: 'List Title',
107
+ list_type: 'contact'
108
+ )
109
+ end
110
+
111
+ it 'translates and cleans up relateiq keys' do
112
+ expect(list_from_api.list_type).to eq('contact')
113
+ expect(list_from_api.modified_date).to eq(12345678)
114
+ end
115
+
116
+ it 'allows setting attributes directly through the constructor' do
117
+ expect(list.list_type).to eq('contact')
118
+ end
119
+ end
120
+
121
+ context '#items_by_contact_id' do
122
+ it 'can accept a single contact id' do
123
+ list_item_class = RelateIq::ListItem
124
+ allow(list_item_class).to receive(:find_by_contact)
125
+ list_2.items_by_contact_id('contactid')
126
+ expect(list_item_class).to have_received(:find_by_contact).with('list2id', 'contactid')
127
+ end
128
+ end
129
+
130
+ context '#upsert_item' do
131
+ before do
132
+ stub_request(:put, "#{lists_url}/list2id/listitems/listitemid")
133
+ .to_return(body: File.readlines('spec/fixtures/list_item.json').join)
134
+
135
+ stub_request(:post, "#{lists_url}/list2id/listitems")
136
+ .to_return(body: File.readlines('spec/fixtures/list_item.json').join)
137
+ end
138
+
139
+ it 'creates a post request if no id is provided includes current list id' do
140
+ list_2.upsert_item(name: 'test')
141
+ expect(WebMock).to have_requested(:post, "#{lists_url}/list2id/listitems")
142
+ .with(body: '{"listId":"list2id","name":"test"}')
143
+ end
144
+ end
145
+ end