sendgrid-api 0.0.2 → 0.0.3

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 (76) hide show
  1. data/.gitignore +4 -2
  2. data/.yardopts +6 -0
  3. data/Gemfile +2 -0
  4. data/Gemfile.lock +5 -1
  5. data/README.md +200 -12
  6. data/Rakefile +3 -0
  7. data/lib/sendgrid/api/client.rb +16 -0
  8. data/lib/sendgrid/api/entities/category.rb +13 -0
  9. data/lib/sendgrid/api/entities/email.rb +13 -0
  10. data/lib/sendgrid/api/entities/entity.rb +2 -2
  11. data/lib/sendgrid/api/entities/list.rb +30 -0
  12. data/lib/sendgrid/api/entities/marketing_email.rb +20 -0
  13. data/lib/sendgrid/api/entities/response_insert.rb +23 -0
  14. data/lib/sendgrid/api/entities/response_remove.rb +23 -0
  15. data/lib/sendgrid/api/entities/schedule.rb +13 -0
  16. data/lib/sendgrid/api/entities/sender_address.rb +13 -0
  17. data/lib/sendgrid/api/newsletter/categories.rb +74 -0
  18. data/lib/sendgrid/api/newsletter/emails.rb +69 -0
  19. data/lib/sendgrid/api/newsletter/lists.rb +64 -0
  20. data/lib/sendgrid/api/newsletter/marketing_emails.rb +72 -0
  21. data/lib/sendgrid/api/newsletter/recipients.rb +55 -0
  22. data/lib/sendgrid/api/newsletter/schedule.rb +70 -0
  23. data/lib/sendgrid/api/newsletter/sender_addresses.rb +80 -0
  24. data/lib/sendgrid/api/newsletter/utils.rb +34 -0
  25. data/lib/sendgrid/api/rest/errors/error.rb +9 -3
  26. data/lib/sendgrid/api/rest/resource.rb +3 -1
  27. data/lib/sendgrid/api/version.rb +1 -1
  28. data/lib/sendgrid/api/web/mail.rb +44 -0
  29. data/lib/sendgrid/api/web/profile.rb +3 -3
  30. data/lib/sendgrid/api/web/stats.rb +3 -3
  31. data/spec/fixtures/categories.json +11 -0
  32. data/spec/fixtures/emails/email.json +6 -0
  33. data/spec/fixtures/emails/emails.json +10 -0
  34. data/spec/fixtures/errors/already_exists.json +3 -0
  35. data/spec/fixtures/errors/bad_request.json +6 -0
  36. data/spec/fixtures/errors/database_error.json +3 -0
  37. data/spec/fixtures/errors/does_not_exist.json +3 -0
  38. data/spec/fixtures/{forbidden.json → errors/forbidden.json} +0 -0
  39. data/spec/fixtures/errors/invalid_fields.json +3 -0
  40. data/spec/fixtures/errors/not_scheduled.json +3 -0
  41. data/spec/fixtures/errors/unauthorized.json +6 -0
  42. data/spec/fixtures/lists/list.json +5 -0
  43. data/spec/fixtures/lists/lists.json +11 -0
  44. data/spec/fixtures/marketing_emails/marketing_email.json +19 -0
  45. data/spec/fixtures/marketing_emails/marketing_emails.json +10 -0
  46. data/spec/fixtures/recipients.json +8 -0
  47. data/spec/fixtures/schedule.json +3 -0
  48. data/spec/fixtures/sender_addresses/sender_address.json +11 -0
  49. data/spec/fixtures/sender_addresses/sender_addresses.json +11 -0
  50. data/spec/sendgrid/api/client_spec.rb +16 -0
  51. data/spec/sendgrid/api/entities/category_spec.rb +14 -0
  52. data/spec/sendgrid/api/entities/email_spec.rb +15 -0
  53. data/spec/sendgrid/api/entities/list_spec.rb +34 -0
  54. data/spec/sendgrid/api/entities/marketing_email_spec.rb +31 -0
  55. data/spec/sendgrid/api/entities/response_insert_spec.rb +28 -0
  56. data/spec/sendgrid/api/entities/response_remove_spec.rb +28 -0
  57. data/spec/sendgrid/api/entities/schedule_spec.rb +14 -0
  58. data/spec/sendgrid/api/entities/sender_address_spec.rb +21 -0
  59. data/spec/sendgrid/api/newsletter/categories_spec.rb +247 -0
  60. data/spec/sendgrid/api/newsletter/emails_spec.rb +265 -0
  61. data/spec/sendgrid/api/newsletter/lists_spec.rb +307 -0
  62. data/spec/sendgrid/api/newsletter/marketing_emails_spec.rb +306 -0
  63. data/spec/sendgrid/api/newsletter/recipients_spec.rb +252 -0
  64. data/spec/sendgrid/api/newsletter/schedule_spec.rb +263 -0
  65. data/spec/sendgrid/api/newsletter/sender_addresses_spec.rb +300 -0
  66. data/spec/sendgrid/api/rest/errors/error_spec.rb +40 -16
  67. data/spec/sendgrid/api/rest/resource_spec.rb +2 -0
  68. data/spec/sendgrid/api/web/mail_spec.rb +111 -0
  69. data/spec/sendgrid/api/web/profile_spec.rb +13 -29
  70. data/spec/sendgrid/api/web/stats_spec.rb +9 -15
  71. data/spec/support/helpers.rb +8 -0
  72. data/spec/support/mock.rb +6 -2
  73. data/spec/support/online.rb +114 -0
  74. data/spec/support/shared_examples.rb +93 -0
  75. metadata +96 -10
  76. data/spec/fixtures/unauthorized.json +0 -6
@@ -0,0 +1,300 @@
1
+ require 'spec_helper'
2
+
3
+ module Sendgrid
4
+ module API
5
+ module Newsletter
6
+ module SenderAddresses
7
+ describe Services do
8
+
9
+ subject { service }
10
+ let(:service) { described_class.new(resource) }
11
+ let(:resource) { REST::Resource.new(user, key) }
12
+ let(:user) { 'my_user' }
13
+ let(:key) { 'my_key' }
14
+ let(:sg_mock) { Sendgrid::Mock.new(user, key) }
15
+
16
+ let(:sender_address) { Entities::SenderAddress.new(:identity => identity, :email => email) }
17
+ let(:identity) { 'my sender address' }
18
+ let(:email) { 'john@example.com' }
19
+
20
+ describe '#add' do
21
+ let(:url) { 'newsletter/identity/add.json' }
22
+ let(:stub_post) { sg_mock.stub_post(url, sender_address.as_json) }
23
+ subject { service.add(sender_address) }
24
+
25
+ context 'when add a sender address successfully' do
26
+ it_behaves_like 'a success response'
27
+ end
28
+
29
+ context 'when the sender address already exists' do
30
+ it_behaves_like 'an unauthorized response'
31
+ end
32
+
33
+ context 'when the sender address is invalid' do
34
+ it_behaves_like 'an invalid fields response'
35
+ end
36
+
37
+ context 'when permission failed' do
38
+ it_behaves_like 'a forbidden response'
39
+ end
40
+ end
41
+
42
+ describe '#edit' do
43
+ let(:url) { 'newsletter/identity/edit.json' }
44
+ let(:stub_post) { sg_mock.stub_post(url, sender_address.as_json) }
45
+ subject { service.edit(sender_address) }
46
+
47
+ context 'when edit a sender address successfully' do
48
+ it_behaves_like 'a success response'
49
+ end
50
+
51
+ context 'when edit the sender address identity successfully' do
52
+ let(:stub_post) { sg_mock.stub_post(url, sender_address.as_json.merge(:newidentity => new_identity)) }
53
+ let(:new_identity) { 'my new sender address' }
54
+ subject { service.edit(sender_address, new_identity) }
55
+ it_behaves_like 'a success response'
56
+ end
57
+
58
+ context 'when the sender address is invalid' do
59
+ it_behaves_like 'a does not exist response'
60
+ end
61
+
62
+ context 'when permission failed' do
63
+ it_behaves_like 'a forbidden response'
64
+ end
65
+ end
66
+
67
+ describe '#get' do
68
+ let(:url) { 'newsletter/identity/get.json' }
69
+ let(:stub_post) { sg_mock.stub_post(url, :identity => identity) }
70
+ subject { service.get(sender_address) }
71
+
72
+ context 'when get the sender address successfully' do
73
+ before do
74
+ stub_post.to_return(:body => fixture('sender_addresses/sender_address.json'))
75
+ end
76
+
77
+ context 'with name' do
78
+ subject { service.get(identity) }
79
+ its(:identity) { should == 'sendgrid' }
80
+ end
81
+
82
+ context 'with object' do
83
+ its(:identity) { should == 'sendgrid' }
84
+ end
85
+ end
86
+
87
+ context 'when the sender address is not found' do
88
+ before do
89
+ stub_post.to_return(:body => fixture('errors/does_not_exist.json'), :status => 401)
90
+ end
91
+
92
+ it 'raises an error' do
93
+ expect { subject }.to raise_error(REST::Errors::Unauthorized)
94
+ end
95
+ end
96
+
97
+ context 'when permission failed' do
98
+ it_behaves_like 'a forbidden response'
99
+ end
100
+ end
101
+
102
+ describe '#list' do
103
+ let(:url) { 'newsletter/identity/list.json' }
104
+ let(:stub_post) { sg_mock.stub_post(url) }
105
+ subject { service.list }
106
+
107
+ context 'when list sender addresses successfully' do
108
+ before do
109
+ stub_post.to_return(:body => fixture('sender_addresses/sender_addresses.json'))
110
+ end
111
+ it { should have(3).items }
112
+ describe 'first item' do
113
+ subject { service.list.first }
114
+ its(:identity) { should == 'sendgrid' }
115
+ end
116
+ end
117
+
118
+ context 'when permission failed' do
119
+ it_behaves_like 'a forbidden response'
120
+ end
121
+ end
122
+
123
+ describe '#delete' do
124
+ let(:url) { 'newsletter/identity/delete.json' }
125
+ let(:stub_post) { sg_mock.stub_post(url, :identity => identity) }
126
+ subject { service.delete(sender_address) }
127
+
128
+ context 'when delete the sender address successfully' do
129
+ it_behaves_like 'a success response'
130
+ end
131
+
132
+ context 'when the sender address is not found' do
133
+ it_behaves_like 'a does not exist response'
134
+ end
135
+
136
+ context 'when permission failed' do
137
+ it_behaves_like 'a forbidden response'
138
+ end
139
+ end
140
+
141
+ describe 'online tests', :online => true do
142
+ include_examples 'online tests'
143
+ let(:online) { Online.new(env_user, env_key) }
144
+ let(:sender_address) { online.sender_address_example }
145
+
146
+ context 'when credentials are valid' do
147
+ let(:resource) { REST::Resource.new(env_user, env_key) }
148
+
149
+ describe '#add' do
150
+ context 'when add a sender address successfully' do
151
+ after do
152
+ subject.delete(sender_address)
153
+ end
154
+ it 'adds the sender address' do
155
+ subject.add(sender_address).success?.should be_true
156
+ end
157
+ end
158
+
159
+ context 'when the sender address already exists' do
160
+ before do
161
+ subject.add(sender_address)
162
+ end
163
+ after do
164
+ subject.delete(sender_address)
165
+ end
166
+ it 'raises an error' do
167
+ expect { subject.add(sender_address) }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
168
+ end
169
+ end
170
+
171
+ context 'when the sender address is invalid' do
172
+ let(:email) { nil }
173
+ it 'raises an error' do
174
+ sender_address.email = email
175
+ expect { subject.add(sender_address) }.to raise_error(Sendgrid::API::REST::Errors::BadRequest)
176
+ end
177
+ end
178
+ end
179
+
180
+ describe '#edit' do
181
+ context 'when edit a sender address successfully' do
182
+ let(:address) { 'new address' }
183
+ before do
184
+ subject.add(sender_address)
185
+ end
186
+ after do
187
+ subject.delete(sender_address)
188
+ end
189
+ it 'edits the sender address' do
190
+ sender_address.address = address
191
+ subject.edit(sender_address).success?.should be_true
192
+ end
193
+ end
194
+
195
+ context 'when edit the sender address identity successfully' do
196
+ let(:newidentity) { 'sendgrid-api sender address new' }
197
+ before do
198
+ subject.add(sender_address)
199
+ end
200
+ after do
201
+ subject.delete(newidentity)
202
+ end
203
+ it 'edits the sender address' do
204
+ subject.edit(sender_address, newidentity).success?.should be_true
205
+ end
206
+ end
207
+
208
+ context 'when the sender address is invalid' do
209
+ it 'raises an error' do
210
+ expect { subject.edit(sender_address) }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
211
+ end
212
+ end
213
+ end
214
+
215
+ describe '#get' do
216
+ context 'when get the sender address successfully' do
217
+ before do
218
+ subject.add(sender_address)
219
+ end
220
+ after do
221
+ subject.delete(sender_address)
222
+ end
223
+ it 'edits the sender address' do
224
+ sender = subject.get(sender_address)
225
+ sender.name.should == sender_address.name
226
+ sender.address.should == sender_address.address
227
+ end
228
+ end
229
+
230
+ context 'when the sender address is not found' do
231
+ it 'raises an error' do
232
+ expect { subject.edit(sender_address) }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
233
+ end
234
+ end
235
+ end
236
+
237
+ describe '#list' do
238
+ context 'when list sender addresses successfully' do
239
+ it 'gets all the sender addresses' do
240
+ subject.list.should_not be_empty
241
+ end
242
+ end
243
+ end
244
+
245
+ describe '#delete' do
246
+ context 'when delete the sender address successfully' do
247
+ before do
248
+ subject.add(sender_address)
249
+ end
250
+ it 'deletes the sender address' do
251
+ subject.delete(sender_address).success?.should be_true
252
+ end
253
+ end
254
+
255
+ context 'when the sender address is not found' do
256
+ it 'raises an error' do
257
+ expect { subject.delete(sender_address) }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
258
+ end
259
+ end
260
+ end
261
+ end
262
+
263
+ context 'when credentials are invalid' do
264
+ describe '#add' do
265
+ it 'raises an error' do
266
+ expect { subject.add(sender_address) }.to raise_error(REST::Errors::Forbidden)
267
+ end
268
+ end
269
+
270
+ describe '#edit' do
271
+ it 'raises an error' do
272
+ expect { subject.edit(sender_address) }.to raise_error(REST::Errors::Forbidden)
273
+ end
274
+ end
275
+
276
+ describe '#get' do
277
+ it 'raises an error' do
278
+ expect { subject.get(sender_address) }.to raise_error(REST::Errors::Forbidden)
279
+ end
280
+ end
281
+
282
+ describe '#list' do
283
+ it 'raises an error' do
284
+ expect { subject.list }.to raise_error(REST::Errors::Forbidden)
285
+ end
286
+ end
287
+
288
+ describe '#delete' do
289
+ it 'raises an error' do
290
+ expect { subject.delete(sender_address) }.to raise_error(REST::Errors::Forbidden)
291
+ end
292
+ end
293
+ end
294
+ end
295
+
296
+ end
297
+ end
298
+ end
299
+ end
300
+ end
@@ -41,41 +41,65 @@ module Sendgrid
41
41
 
42
42
  it { should == Errors::BadRequest.new('error message') }
43
43
  end
44
- end
45
44
 
46
- context 'when response has body error' do
47
- context 'known status' do
45
+ context 'with multiple messages' do
48
46
  let(:env) do
49
- { :status => 200,
50
- :body => { :error => { :code => 400 } } }
47
+ { :status => 400,
48
+ :body => { :errors => ['error message 1', 'error message 2'] } }
51
49
  end
52
50
 
53
51
  subject { described_class.from_response(env) }
54
52
 
55
- it { should be_instance_of(Errors::BadRequest) }
53
+ it { should == Errors::BadRequest.new('error message 1, error message 2') }
56
54
  end
55
+ end
57
56
 
58
- context 'unknown status' do
59
- let(:env) do
60
- { :status => 200,
61
- :body => { :error => { :code => 413 } } }
57
+ context 'when response has body error' do
58
+ context 'when error is a Hash' do
59
+ context 'known status' do
60
+ let(:env) do
61
+ { :status => 200,
62
+ :body => { :error => { :code => 400 } } }
63
+ end
64
+
65
+ subject { described_class.from_response(env) }
66
+
67
+ it { should be_instance_of(Errors::BadRequest) }
62
68
  end
63
69
 
64
- subject { described_class.from_response(env) }
70
+ context 'unknown status' do
71
+ let(:env) do
72
+ { :status => 200,
73
+ :body => { :error => { :code => 413 } } }
74
+ end
65
75
 
66
- it { should be_instance_of(Errors::Unknown) }
76
+ subject { described_class.from_response(env) }
77
+
78
+ it { should be_instance_of(Errors::Unknown) }
79
+ end
80
+
81
+ context 'with message' do
82
+ let(:env) do
83
+ { :status => 200,
84
+ :body => { :error => { :code => 400,
85
+ :message => 'error message' } } }
86
+ end
87
+
88
+ subject { described_class.from_response(env) }
89
+
90
+ it { should == Errors::BadRequest.new('error message') }
91
+ end
67
92
  end
68
93
 
69
- context 'with message' do
94
+ context 'when error is a String' do
70
95
  let(:env) do
71
96
  { :status => 200,
72
- :body => { :error => { :code => 400,
73
- :message => 'error message' } } }
97
+ :body => { :error => 'error message' } }
74
98
  end
75
99
 
76
100
  subject { described_class.from_response(env) }
77
101
 
78
- it { should == Errors::BadRequest.new('error message') }
102
+ it { should == Errors::UnprocessableEntity.new('error message') }
79
103
  end
80
104
  end
81
105
 
@@ -66,6 +66,8 @@ module Sendgrid
66
66
  it 'should perform a request' do
67
67
  subject.send(:request, :post, url, params)
68
68
  sg_mock.a_post(url, params).should have_been_made
69
+ params.should_not include(:api_user)
70
+ params.should_not include(:api_key)
69
71
  end
70
72
  end
71
73
 
@@ -0,0 +1,111 @@
1
+ require 'spec_helper'
2
+
3
+ module Sendgrid
4
+ module API
5
+ module Web
6
+ module Mail
7
+ describe Services do
8
+
9
+ subject { service }
10
+ let(:service) { described_class.new(resource) }
11
+ let(:resource) { REST::Resource.new(user, key) }
12
+ let(:user) { 'my_user' }
13
+ let(:key) { 'my_key' }
14
+ let(:sg_mock) { Sendgrid::Mock.new(user, key) }
15
+
16
+ let(:to) { 'test@coffeebeantech.com' }
17
+ let(:from) { 'test@coffeebeantech.com' }
18
+ let(:email_subject) { 'sendgrid-api mail test' }
19
+ let(:text) { 'This is an email to test the sendgrid-api gem' }
20
+ let(:files) do
21
+ { 'sample1.txt' => sample_file(:name => 'sample1.txt'),
22
+ 'sample2.txt' => sample_file(:name => 'sample2.txt') }
23
+ end
24
+ let(:x_smtpapi) do
25
+ { :category => ['sendgrid-api test'] }.to_json
26
+ end
27
+ let(:required_options) do
28
+ { :to => to, :subject => email_subject, :text => text, :from => from }
29
+ end
30
+
31
+ describe '#mail' do
32
+ let(:url) { 'mail.send.json' }
33
+
34
+ context 'with required fields' do
35
+ let(:stub_post) { sg_mock.stub_post(url, required_options) }
36
+ subject { service.send(required_options) }
37
+ it_behaves_like 'a success response'
38
+ end
39
+
40
+ context 'without required fields' do
41
+ let(:stub_post) { sg_mock.stub_post(url, :to => to) }
42
+ subject { service.send(:to => to) }
43
+ it_behaves_like 'an invalid fields response'
44
+ end
45
+
46
+ context 'with files attached' do
47
+ let(:stub_post) { stub_request(:post, sg_mock.uri(url)).with(:body => /sample1.txt/) }
48
+ subject { service.send(required_options.merge(:files => files)) }
49
+ it_behaves_like 'a success response'
50
+ end
51
+
52
+ context 'with SMTP API headers' do
53
+ let(:stub_post) { sg_mock.stub_post(url, :to => to, :subject => email_subject, :text => text, :from => from, 'x-smtpapi' => x_smtpapi) }
54
+ subject { service.send(required_options.merge(:x_smtpapi => x_smtpapi)) }
55
+ it_behaves_like 'a success response'
56
+ end
57
+
58
+ context 'when permission failed' do
59
+ let(:stub_post) { sg_mock.stub_post(url) }
60
+ subject { service.send }
61
+ it_behaves_like 'a bad request response'
62
+ end
63
+ end
64
+
65
+ describe 'online tests', :online => true do
66
+ include_examples 'online tests'
67
+
68
+ context 'when credentials are valid' do
69
+ let(:resource) { REST::Resource.new(env_user, env_key) }
70
+
71
+ describe '#mail' do
72
+ context 'with required fields' do
73
+ it 'sends the email' do
74
+ subject.send(required_options).success?.should be_true
75
+ end
76
+ end
77
+
78
+ context 'without required fields' do
79
+ it 'raises an error' do
80
+ expect { subject.send(:to => to) }.to raise_error(REST::Errors::BadRequest)
81
+ end
82
+ end
83
+
84
+ context 'with files attached' do
85
+ it 'sends the email' do
86
+ subject.send(required_options.merge(:files => files)).success?.should be_true
87
+ end
88
+ end
89
+
90
+ context 'with SMTP API headers' do
91
+ it 'sends the email' do
92
+ subject.send(required_options.merge(:x_smtpapi => x_smtpapi)).success?.should be_true
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ context 'when credentials are invalid' do
99
+ describe '#mail' do
100
+ it 'raises error' do
101
+ expect { subject.send(required_options) }.to raise_error(REST::Errors::BadRequest)
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end