contextio 0.5.0 → 1.0.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.
- data/.document +4 -0
- data/.gitignore +8 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +5 -0
- data/Gemfile +3 -0
- data/LICENSE.md +20 -0
- data/README.md +62 -22
- data/Rakefile +46 -36
- data/contextio.gemspec +30 -0
- data/lib/contextio.rb +69 -583
- data/lib/contextio/account.rb +132 -0
- data/lib/contextio/account_collection.rb +57 -0
- data/lib/contextio/account_sync_data.rb +22 -0
- data/lib/contextio/api.rb +162 -0
- data/lib/contextio/api/association_helpers.rb +17 -0
- data/lib/contextio/api/resource.rb +230 -0
- data/lib/contextio/api/resource_collection.rb +174 -0
- data/lib/contextio/api/url_builder.rb +153 -0
- data/lib/contextio/body_part.rb +45 -0
- data/lib/contextio/body_part_collection.rb +13 -0
- data/lib/contextio/connect_token.rb +57 -0
- data/lib/contextio/connect_token_collection.rb +44 -0
- data/lib/contextio/contact.rb +43 -0
- data/lib/contextio/contact_collection.rb +21 -0
- data/lib/contextio/email_address.rb +53 -0
- data/lib/contextio/email_address_collection.rb +21 -0
- data/lib/contextio/email_settings.rb +146 -0
- data/lib/contextio/file.rb +92 -0
- data/lib/contextio/file_collection.rb +13 -0
- data/lib/contextio/folder.rb +56 -0
- data/lib/contextio/folder_collection.rb +18 -0
- data/lib/contextio/folder_sync_data.rb +32 -0
- data/lib/contextio/message.rb +96 -0
- data/lib/contextio/message_collection.rb +35 -0
- data/lib/contextio/oauth_provider.rb +29 -0
- data/lib/contextio/oauth_provider_collection.rb +46 -0
- data/lib/contextio/source.rb +55 -0
- data/lib/contextio/source_collection.rb +41 -0
- data/lib/contextio/source_sync_data.rb +23 -0
- data/lib/contextio/thread.rb +15 -0
- data/lib/contextio/thread_collection.rb +25 -0
- data/lib/contextio/version.rb +11 -0
- data/lib/contextio/webhook.rb +39 -0
- data/lib/contextio/webhook_collection.rb +26 -0
- data/spec/config.yml.example +3 -0
- data/spec/contextio/account_collection_spec.rb +78 -0
- data/spec/contextio/account_spec.rb +52 -0
- data/spec/contextio/api/association_helpers_spec.rb +28 -0
- data/spec/contextio/api/resource_collection_spec.rb +286 -0
- data/spec/contextio/api/resource_spec.rb +467 -0
- data/spec/contextio/api/url_builder_spec.rb +78 -0
- data/spec/contextio/api_spec.rb +123 -0
- data/spec/contextio/connect_token_collection_spec.rb +74 -0
- data/spec/contextio/connect_token_spec.rb +58 -0
- data/spec/contextio/email_settings_spec.rb +112 -0
- data/spec/contextio/oauth_provider_collection_spec.rb +36 -0
- data/spec/contextio/oauth_provider_spec.rb +120 -0
- data/spec/contextio/source_collection_spec.rb +57 -0
- data/spec/contextio/source_spec.rb +52 -0
- data/spec/contextio/version_spec.rb +10 -0
- data/spec/contextio_spec.rb +64 -0
- data/spec/spec_helper.rb +17 -0
- metadata +234 -12
- data/README.textile +0 -29
@@ -0,0 +1,26 @@
|
|
1
|
+
require_relative 'api/resource_collection'
|
2
|
+
require_relative 'webhook'
|
3
|
+
|
4
|
+
class ContextIO
|
5
|
+
class WebhookCollection
|
6
|
+
include ContextIO::API::ResourceCollection
|
7
|
+
|
8
|
+
self.resource_class = ContextIO::Webhook
|
9
|
+
self.association_name = :webhooks
|
10
|
+
|
11
|
+
belongs_to :account
|
12
|
+
|
13
|
+
def create(success_callback_url, failure_callback_url, options={})
|
14
|
+
api_args = options.merge(
|
15
|
+
'callback_url' => success_callback_url,
|
16
|
+
'failure_notif_url' => failure_callback_url
|
17
|
+
)
|
18
|
+
|
19
|
+
result_hash = api.request(:post, resource_url, api_args)
|
20
|
+
|
21
|
+
result_hash.delete('success')
|
22
|
+
|
23
|
+
resource_class.new(api, result_hash)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'contextio/account_collection'
|
3
|
+
|
4
|
+
describe ContextIO::AccountCollection do
|
5
|
+
let(:api) { double('API', url_for: 'url from api') }
|
6
|
+
|
7
|
+
subject { ContextIO::AccountCollection.new(api) }
|
8
|
+
|
9
|
+
describe "#create" do
|
10
|
+
before do
|
11
|
+
api.stub(:request).with(:post, anything, anything).and_return(
|
12
|
+
'success' => true,
|
13
|
+
'id' => '1234',
|
14
|
+
'resource_url' => 'resource_url'
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
context "without where constraints" do
|
19
|
+
it "requires an email address" do
|
20
|
+
expect { subject.create(first_name: 'Bruno') }.to raise_error(ArgumentError)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "posts to the api" do
|
24
|
+
api.should_receive(:request).with(
|
25
|
+
:post,
|
26
|
+
'url from api',
|
27
|
+
hash_including(email: 'hello@email.com')
|
28
|
+
)
|
29
|
+
|
30
|
+
subject.create(email: 'hello@email.com')
|
31
|
+
end
|
32
|
+
|
33
|
+
it "doesn't make any more API calls than it needs to" do
|
34
|
+
api.should_not_receive(:request).with(:get, anything, anything)
|
35
|
+
|
36
|
+
subject.create(email: 'hello@email.com')
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns an Account" do
|
40
|
+
expect(subject.create(email: 'hello@email.com')).to be_a(ContextIO::Account)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "takes an optional first name" do
|
44
|
+
api.should_receive(:request).with(
|
45
|
+
anything,
|
46
|
+
anything,
|
47
|
+
hash_including(first_name: 'Bruno')
|
48
|
+
)
|
49
|
+
|
50
|
+
subject.create(email: 'hello@email.com', first_name: 'Bruno')
|
51
|
+
end
|
52
|
+
|
53
|
+
it "takes an optional last name" do
|
54
|
+
api.should_receive(:request).with(
|
55
|
+
anything,
|
56
|
+
anything,
|
57
|
+
hash_including(last_name: 'Morency')
|
58
|
+
)
|
59
|
+
|
60
|
+
subject.create(email: 'hello@email.com', last_name: 'Morency')
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "with email in the where constraints" do
|
65
|
+
subject { ContextIO::AccountCollection.new(api).where(email: 'hello@email.com')}
|
66
|
+
|
67
|
+
it "allows a missing email address" do
|
68
|
+
expect { subject.create(first_name: 'Bruno') }.to_not raise_error(ArgumentError)
|
69
|
+
end
|
70
|
+
|
71
|
+
it "uses the email address from the where constraints" do
|
72
|
+
api.should_receive(:request).with(anything, anything, hash_including(email: 'hello@email.com'))
|
73
|
+
|
74
|
+
subject.create(first_name: 'Bruno')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'contextio/account'
|
3
|
+
|
4
|
+
describe ContextIO::Account do
|
5
|
+
let(:api) { double('api', url_for: 'url from api') }
|
6
|
+
|
7
|
+
subject { ContextIO::Account.new(api, id: '1234') }
|
8
|
+
|
9
|
+
describe ".new" do
|
10
|
+
context "with an id passed in" do
|
11
|
+
it "doesn't raise an error" do
|
12
|
+
expect { ContextIO::Account.new(api, id: '1234') }.to_not raise_error
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "with neither an id nor a resource_url passed in" do
|
17
|
+
it "raises an ArgumentError" do
|
18
|
+
expect { ContextIO::Account.new(api, foo: 'bar') }.to raise_error(ArgumentError)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#update" do
|
24
|
+
before do
|
25
|
+
api.stub(:request).and_return({'success' => true})
|
26
|
+
end
|
27
|
+
|
28
|
+
subject { ContextIO::Account.new(api, id: '1234', first_name: 'old first name') }
|
29
|
+
|
30
|
+
it "posts to the api" do
|
31
|
+
api.should_receive(:request).with(
|
32
|
+
:post,
|
33
|
+
'url from api',
|
34
|
+
first_name: 'new first name'
|
35
|
+
)
|
36
|
+
|
37
|
+
subject.update(first_name: 'new first name')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "updates the object" do
|
41
|
+
subject.update(first_name: 'new first name')
|
42
|
+
|
43
|
+
expect(subject.first_name).to eq('new first name')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "doesn't make any more API calls than it needs to" do
|
47
|
+
api.should_not_receive(:request).with(:get, anything, anything)
|
48
|
+
|
49
|
+
subject.update(first_name: 'new first name')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'contextio/api/association_helpers'
|
3
|
+
|
4
|
+
describe "ContextIO::API::AssociationHelpers" do
|
5
|
+
subject { ContextIO::API::AssociationHelpers }
|
6
|
+
|
7
|
+
describe ".class_for_association_name" do
|
8
|
+
context "when the resource is registered" do
|
9
|
+
let(:resource_class) do
|
10
|
+
Class.new
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
subject.register_resource(resource_class, :registered)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "makes the resource available" do
|
18
|
+
expect(subject.class_for_association_name(:registered)).to be(resource_class)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when the resource is NOT registered" do
|
23
|
+
it "returns nil" do
|
24
|
+
expect(subject.class_for_association_name(:not_registered)).to be_nil
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,286 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'contextio/api/resource_collection'
|
3
|
+
|
4
|
+
class SingularHelper
|
5
|
+
def initialize(*args); end
|
6
|
+
def self.primary_key; 'token'; end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Owner
|
10
|
+
def self.primary_key; 'id'; end
|
11
|
+
def id; 4; end
|
12
|
+
def initialize(*args); end
|
13
|
+
|
14
|
+
ContextIO::API::AssociationHelpers.register_resource(self, :owner)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe ContextIO::API::ResourceCollection do
|
18
|
+
let(:api) { double('api', url_for: 'url from api') }
|
19
|
+
|
20
|
+
describe ".resource_class=" do
|
21
|
+
let(:helper_class) do
|
22
|
+
Class.new do
|
23
|
+
include ContextIO::API::ResourceCollection
|
24
|
+
|
25
|
+
self.resource_class = SingularHelper
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
subject do
|
30
|
+
helper_class.new(api)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "makes the class available to instances of the collection" do
|
34
|
+
expect(subject.resource_class).to eq(SingularHelper)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe ".belongs_to" do
|
39
|
+
let(:helper_class) do
|
40
|
+
Class.new do
|
41
|
+
include ContextIO::API::ResourceCollection
|
42
|
+
|
43
|
+
belongs_to :owner
|
44
|
+
|
45
|
+
self.association_name = :helper_class
|
46
|
+
self.resource_class = SingularHelper
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:owner) { Owner.new }
|
51
|
+
|
52
|
+
subject { helper_class.new(api, owner: owner) }
|
53
|
+
|
54
|
+
it "makes the belonged-to object available" do
|
55
|
+
expect(subject.owner).to eq(owner)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#api" do
|
60
|
+
let(:helper_class) do
|
61
|
+
Class.new do
|
62
|
+
include ContextIO::API::ResourceCollection
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
subject do
|
67
|
+
helper_class.new(api)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "holds a reference to the api" do
|
71
|
+
expect(subject.api).to eq(api)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe ".where" do
|
76
|
+
let(:helper_class) do
|
77
|
+
Class.new do
|
78
|
+
include ContextIO::API::ResourceCollection
|
79
|
+
|
80
|
+
belongs_to :owner
|
81
|
+
|
82
|
+
self.resource_class = SingularHelper
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
subject do
|
87
|
+
helper_class.new(api, owner: :relation)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "limits the scope of subsequent #each calls" do
|
91
|
+
api.should_receive(:request).with(anything, anything, foo: 'bar').and_return([])
|
92
|
+
|
93
|
+
subject.where(foo: 'bar').each { }
|
94
|
+
end
|
95
|
+
|
96
|
+
it "returns a new object, not the same one, modified" do
|
97
|
+
expect(subject.where(foo: 'bar')).to_not be(subject)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns a collection object" do
|
101
|
+
expect(subject.where(foo: 'bar')).to be_a(helper_class)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "makes the constraints available" do
|
105
|
+
expect(subject.where(foo: 'bar').where_constraints).to eq(foo: 'bar')
|
106
|
+
end
|
107
|
+
|
108
|
+
it "overrides older constraints with newer ones" do
|
109
|
+
expect(subject.where(foo: 'bar').where(foo: 'baz').where_constraints).to eq(foo: 'baz')
|
110
|
+
end
|
111
|
+
|
112
|
+
it "keeps collection relations from the old to new object" do
|
113
|
+
expect(subject.where(foo: 'bar').owner).to eq(subject.owner)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe "#each" do
|
118
|
+
let(:helper_class) do
|
119
|
+
Class.new do
|
120
|
+
include ContextIO::API::ResourceCollection
|
121
|
+
|
122
|
+
self.resource_class = SingularHelper
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context "when no attribute hashes are passed in at creation" do
|
127
|
+
subject do
|
128
|
+
helper_class.new(api)
|
129
|
+
end
|
130
|
+
|
131
|
+
before do
|
132
|
+
api.stub(:request).and_return([{key: 'value 1'}, {key: 'value 2'}])
|
133
|
+
end
|
134
|
+
|
135
|
+
it "yields instances of the singular resource class" do
|
136
|
+
subject.each do |x|
|
137
|
+
expect(x).to be_a(SingularHelper)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
it "gets attributes for the resources from the api" do
|
142
|
+
api.should_receive(:request).exactly(:once).with(:get, 'url from api', {})
|
143
|
+
|
144
|
+
subject.each { }
|
145
|
+
end
|
146
|
+
|
147
|
+
it "passes the api to the singular resource instances" do
|
148
|
+
SingularHelper.should_receive(:new).exactly(:twice).with(api, anything)
|
149
|
+
|
150
|
+
subject.each { }
|
151
|
+
end
|
152
|
+
|
153
|
+
it "passes attributes to the singular resource instances" do
|
154
|
+
SingularHelper.should_receive(:new).exactly(:once).with(anything, key: 'value 1')
|
155
|
+
SingularHelper.should_receive(:new).exactly(:once).with(anything, key: 'value 2')
|
156
|
+
|
157
|
+
subject.each { }
|
158
|
+
end
|
159
|
+
|
160
|
+
context "with a belonged-to resource" do
|
161
|
+
let(:helper_class) do
|
162
|
+
Class.new do
|
163
|
+
include ContextIO::API::ResourceCollection
|
164
|
+
|
165
|
+
belongs_to :owner
|
166
|
+
|
167
|
+
self.resource_class = SingularHelper
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
let(:owner) { Owner.new }
|
172
|
+
|
173
|
+
subject do
|
174
|
+
helper_class.new(api, owner: owner)
|
175
|
+
end
|
176
|
+
|
177
|
+
it "passes the belonged-to resource to the singular resource instances" do
|
178
|
+
SingularHelper.should_receive(:new).exactly(:twice).with(
|
179
|
+
anything,
|
180
|
+
hash_including(owner: owner)
|
181
|
+
)
|
182
|
+
|
183
|
+
subject.each { }
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
context "when attribute hashes are passed in at creation" do
|
189
|
+
subject do
|
190
|
+
helper_class.new(api, attribute_hashes: [{foo: 'bar'}, {foo: 'baz'}])
|
191
|
+
end
|
192
|
+
|
193
|
+
it "yields instances of the singular resource class" do
|
194
|
+
subject.each do |x|
|
195
|
+
expect(x).to be_a(SingularHelper)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
it "doesn't hit the API" do
|
200
|
+
api.should_not_receive(:request)
|
201
|
+
|
202
|
+
subject.each { }
|
203
|
+
end
|
204
|
+
|
205
|
+
it "passes the api to the singular resource instances" do
|
206
|
+
SingularHelper.should_receive(:new).exactly(:twice).with(api, anything)
|
207
|
+
|
208
|
+
subject.each { }
|
209
|
+
end
|
210
|
+
|
211
|
+
it "passes attributes to the singular resource instances" do
|
212
|
+
SingularHelper.should_receive(:new).exactly(:once).with(anything, foo: 'bar')
|
213
|
+
SingularHelper.should_receive(:new).exactly(:once).with(anything, foo: 'baz')
|
214
|
+
|
215
|
+
subject.each { }
|
216
|
+
end
|
217
|
+
|
218
|
+
context "with a belonged-to resource" do
|
219
|
+
let(:helper_class) do
|
220
|
+
Class.new do
|
221
|
+
include ContextIO::API::ResourceCollection
|
222
|
+
|
223
|
+
belongs_to :owner
|
224
|
+
|
225
|
+
self.resource_class = SingularHelper
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
let(:owner) { Owner.new }
|
230
|
+
|
231
|
+
subject do
|
232
|
+
helper_class.new(
|
233
|
+
api,
|
234
|
+
attribute_hashes: [{foo: 'bar'}, {foo: 'baz'}],
|
235
|
+
owner: owner
|
236
|
+
)
|
237
|
+
end
|
238
|
+
|
239
|
+
it "passes the belonged-to resource to the singular resource instances" do
|
240
|
+
SingularHelper.should_receive(:new).exactly(:twice).with(
|
241
|
+
anything,
|
242
|
+
hash_including(owner: owner)
|
243
|
+
)
|
244
|
+
|
245
|
+
subject.each { }
|
246
|
+
end
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
describe "#[]" do
|
252
|
+
let(:helper_class) do
|
253
|
+
Class.new do
|
254
|
+
include ContextIO::API::ResourceCollection
|
255
|
+
|
256
|
+
self.resource_class = SingularHelper
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
subject do
|
261
|
+
helper_class.new(api)
|
262
|
+
end
|
263
|
+
|
264
|
+
it "returns a new instance of the resource class" do
|
265
|
+
expect(subject[1234]).to be_a(SingularHelper)
|
266
|
+
end
|
267
|
+
|
268
|
+
it "feeds the given key to the resource class" do
|
269
|
+
SingularHelper.should_receive(:new).with(anything, 'token' => 1234)
|
270
|
+
|
271
|
+
subject[1234]
|
272
|
+
end
|
273
|
+
|
274
|
+
it "feeds the api to the resource class" do
|
275
|
+
SingularHelper.should_receive(:new).with(api, anything)
|
276
|
+
|
277
|
+
subject[1234]
|
278
|
+
end
|
279
|
+
|
280
|
+
it "doesn't hit the API" do
|
281
|
+
api.should_not_receive(:request)
|
282
|
+
|
283
|
+
subject[1234]
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|