parity-sendgrid-api 0.0.4

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 (99) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +6 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +3 -0
  5. data/.yardopts +6 -0
  6. data/Gemfile +17 -0
  7. data/Gemfile.lock +67 -0
  8. data/LICENSE +22 -0
  9. data/README.md +261 -0
  10. data/Rakefile +12 -0
  11. data/lib/sendgrid/api.rb +7 -0
  12. data/lib/sendgrid/api/client.rb +43 -0
  13. data/lib/sendgrid/api/entities/category.rb +13 -0
  14. data/lib/sendgrid/api/entities/email.rb +13 -0
  15. data/lib/sendgrid/api/entities/entity.rb +83 -0
  16. data/lib/sendgrid/api/entities/list.rb +30 -0
  17. data/lib/sendgrid/api/entities/marketing_email.rb +20 -0
  18. data/lib/sendgrid/api/entities/profile.rb +14 -0
  19. data/lib/sendgrid/api/entities/response.rb +21 -0
  20. data/lib/sendgrid/api/entities/response_insert.rb +23 -0
  21. data/lib/sendgrid/api/entities/response_remove.rb +23 -0
  22. data/lib/sendgrid/api/entities/schedule.rb +13 -0
  23. data/lib/sendgrid/api/entities/sender_address.rb +13 -0
  24. data/lib/sendgrid/api/entities/stats.rb +14 -0
  25. data/lib/sendgrid/api/newsletter/categories.rb +74 -0
  26. data/lib/sendgrid/api/newsletter/emails.rb +69 -0
  27. data/lib/sendgrid/api/newsletter/lists.rb +64 -0
  28. data/lib/sendgrid/api/newsletter/marketing_emails.rb +72 -0
  29. data/lib/sendgrid/api/newsletter/recipients.rb +55 -0
  30. data/lib/sendgrid/api/newsletter/schedule.rb +70 -0
  31. data/lib/sendgrid/api/newsletter/sender_addresses.rb +80 -0
  32. data/lib/sendgrid/api/newsletter/utils.rb +34 -0
  33. data/lib/sendgrid/api/rest/errors/error.rb +66 -0
  34. data/lib/sendgrid/api/rest/resource.rb +58 -0
  35. data/lib/sendgrid/api/rest/response/parse_error.rb +19 -0
  36. data/lib/sendgrid/api/rest/response/parse_json.rb +24 -0
  37. data/lib/sendgrid/api/service.rb +23 -0
  38. data/lib/sendgrid/api/version.rb +5 -0
  39. data/lib/sendgrid/api/web/mail.rb +44 -0
  40. data/lib/sendgrid/api/web/profile.rb +38 -0
  41. data/lib/sendgrid/api/web/stats.rb +36 -0
  42. data/sendgrid-api.gemspec +23 -0
  43. data/spec/fixtures/categories.json +11 -0
  44. data/spec/fixtures/emails/email.json +6 -0
  45. data/spec/fixtures/emails/emails.json +10 -0
  46. data/spec/fixtures/errors/already_exists.json +3 -0
  47. data/spec/fixtures/errors/bad_request.json +6 -0
  48. data/spec/fixtures/errors/database_error.json +3 -0
  49. data/spec/fixtures/errors/does_not_exist.json +3 -0
  50. data/spec/fixtures/errors/forbidden.json +3 -0
  51. data/spec/fixtures/errors/invalid_fields.json +3 -0
  52. data/spec/fixtures/errors/not_scheduled.json +3 -0
  53. data/spec/fixtures/errors/unauthorized.json +6 -0
  54. data/spec/fixtures/lists/list.json +5 -0
  55. data/spec/fixtures/lists/lists.json +11 -0
  56. data/spec/fixtures/marketing_emails/marketing_email.json +19 -0
  57. data/spec/fixtures/marketing_emails/marketing_emails.json +10 -0
  58. data/spec/fixtures/profile.json +18 -0
  59. data/spec/fixtures/recipients.json +8 -0
  60. data/spec/fixtures/schedule.json +3 -0
  61. data/spec/fixtures/sender_addresses/sender_address.json +11 -0
  62. data/spec/fixtures/sender_addresses/sender_addresses.json +11 -0
  63. data/spec/fixtures/stats.json +50 -0
  64. data/spec/fixtures/success.json +3 -0
  65. data/spec/sendgrid/api/client_spec.rb +38 -0
  66. data/spec/sendgrid/api/entities/category_spec.rb +14 -0
  67. data/spec/sendgrid/api/entities/email_spec.rb +15 -0
  68. data/spec/sendgrid/api/entities/entity_spec.rb +279 -0
  69. data/spec/sendgrid/api/entities/list_spec.rb +34 -0
  70. data/spec/sendgrid/api/entities/marketing_email_spec.rb +31 -0
  71. data/spec/sendgrid/api/entities/profile_spec.rb +26 -0
  72. data/spec/sendgrid/api/entities/response_insert_spec.rb +28 -0
  73. data/spec/sendgrid/api/entities/response_remove_spec.rb +28 -0
  74. data/spec/sendgrid/api/entities/response_spec.rb +28 -0
  75. data/spec/sendgrid/api/entities/schedule_spec.rb +14 -0
  76. data/spec/sendgrid/api/entities/sender_address_spec.rb +21 -0
  77. data/spec/sendgrid/api/entities/stats_spec.rb +25 -0
  78. data/spec/sendgrid/api/newsletter/categories_spec.rb +247 -0
  79. data/spec/sendgrid/api/newsletter/emails_spec.rb +265 -0
  80. data/spec/sendgrid/api/newsletter/lists_spec.rb +307 -0
  81. data/spec/sendgrid/api/newsletter/marketing_emails_spec.rb +306 -0
  82. data/spec/sendgrid/api/newsletter/recipients_spec.rb +252 -0
  83. data/spec/sendgrid/api/newsletter/schedule_spec.rb +263 -0
  84. data/spec/sendgrid/api/newsletter/sender_addresses_spec.rb +300 -0
  85. data/spec/sendgrid/api/rest/errors/error_spec.rb +121 -0
  86. data/spec/sendgrid/api/rest/resource_spec.rb +145 -0
  87. data/spec/sendgrid/api/rest/response/parse_error_spec.rb +39 -0
  88. data/spec/sendgrid/api/rest/response/parse_json_spec.rb +45 -0
  89. data/spec/sendgrid/api/service_spec.rb +44 -0
  90. data/spec/sendgrid/api/version_spec.rb +11 -0
  91. data/spec/sendgrid/api/web/mail_spec.rb +111 -0
  92. data/spec/sendgrid/api/web/profile_spec.rb +110 -0
  93. data/spec/sendgrid/api/web/stats_spec.rb +94 -0
  94. data/spec/spec_helper.rb +23 -0
  95. data/spec/support/helpers.rb +23 -0
  96. data/spec/support/mock.rb +30 -0
  97. data/spec/support/online.rb +114 -0
  98. data/spec/support/shared_examples.rb +104 -0
  99. metadata +225 -0
@@ -0,0 +1,110 @@
1
+ require 'spec_helper'
2
+
3
+ module Sendgrid
4
+ module API
5
+ module Web
6
+ module Profile
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
+ describe '#get' do
17
+ let(:url) { 'profile.get.json' }
18
+ let(:stub_post) { sg_mock.stub_post(url) }
19
+ subject { service.get }
20
+
21
+ context 'when request is successfull' do
22
+ before do
23
+ stub_post.to_return(:body => fixture('profile.json'))
24
+ end
25
+
26
+ it 'performs the request' do
27
+ subject
28
+ sg_mock.a_post(url).should have_been_made
29
+ end
30
+
31
+ it { should be_instance_of Entities::Profile }
32
+
33
+ its(:username) { should == 'sendgrid' }
34
+ its(:email) { should == 'contact@sendgrid.com' }
35
+ its(:active) { should == 'true' }
36
+ its(:first_name) { should == 'Jim' }
37
+ its(:last_name) { should == 'Franklin' }
38
+ its(:address) { should == '1065 N Pacificenter Drive, Suite 425' }
39
+ its(:address2) { should == '' }
40
+ its(:city) { should == 'Anaheim' }
41
+ its(:state) { should == 'CA' }
42
+ its(:zip) { should == '92806' }
43
+ its(:country) { should == 'US' }
44
+ its(:phone) { should == '123456789' }
45
+ its(:website) { should == 'http://www.sendgrid.com' }
46
+ its(:website_access) { should == 'true' }
47
+ end
48
+
49
+ context 'when permission failed' do
50
+ it_behaves_like 'an unauthorized response'
51
+ end
52
+ end
53
+
54
+ describe '#set' do
55
+ let(:url) { 'profile.set.json' }
56
+ let(:profile) { Entities::Profile.new(:first_name => 'Brian', :last_name => 'O\'Neill') }
57
+ let(:stub_post) { sg_mock.stub_post(url, profile.as_json) }
58
+ subject { service.set(profile) }
59
+
60
+ context 'when request is successfull' do
61
+ it_behaves_like 'a success response'
62
+ end
63
+
64
+ context 'when permission failed' do
65
+ it_behaves_like 'an unauthorized response'
66
+ end
67
+ end
68
+
69
+ describe 'online tests', :online => true do
70
+ include_examples 'online tests'
71
+
72
+ context 'when credentials are valid' do
73
+ let(:resource) { REST::Resource.new(env_user, env_key) }
74
+
75
+ describe '#get' do
76
+ it 'gets profile' do
77
+ subject.get.should be_instance_of(Entities::Profile)
78
+ end
79
+ end
80
+
81
+ describe '#set' do
82
+ it 'updates profile' do
83
+ profile = subject.get
84
+ subject.set(profile).success?.should be_true
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'when credentials are invalid' do
90
+ describe '#get' do
91
+ it 'raises error' do
92
+ expect { subject.get }.to raise_error(REST::Errors::Unauthorized)
93
+ end
94
+ end
95
+
96
+ describe '#set' do
97
+ let(:profile) { Entities::Profile.new(:first_name => 'Brian', :last_name => 'O\'Neill') }
98
+
99
+ it 'raises error' do
100
+ expect { subject.set(profile) }.to raise_error(REST::Errors::Unauthorized)
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ module Sendgrid
4
+ module API
5
+ module Web
6
+ module Stats
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
+ describe '#advanced' do
17
+ let(:url) { 'stats.getAdvanced.json' }
18
+ let(:stub_post) { sg_mock.stub_post(url) }
19
+ subject { service.advanced }
20
+
21
+ context 'when request is successfull' do
22
+ before do
23
+ stub_post.to_return(:body => fixture('stats.json'))
24
+ end
25
+
26
+ it 'performs the request' do
27
+ subject
28
+ sg_mock.a_post(url).should have_been_made
29
+ end
30
+
31
+ it { should_not be_empty }
32
+
33
+ describe 'first result' do
34
+ subject { service.advanced.first }
35
+
36
+ its(:delivered) { should == 4792 }
37
+ its(:unique_open) { should == 308 }
38
+ its(:spamreport) { should == 3 }
39
+ its(:unique_click) { should == 11 }
40
+ its(:drop) { should == 57 }
41
+ its(:request) { should == 5359 }
42
+ its(:bounce) { should == 622 }
43
+ its(:deferred) { should == 1975 }
44
+ its(:processed) { should == 5302 }
45
+ its(:date) { should == '2013-06-18' }
46
+ its(:open) { pending('debugs open method') }
47
+ its(:click) { should == 11 }
48
+ its(:blocked) { should == 29 }
49
+ end
50
+ end
51
+
52
+ context 'when permission failed' do
53
+ it_behaves_like 'a forbidden response'
54
+ end
55
+ end
56
+
57
+ describe 'online tests', :online => true do
58
+ include_examples 'online tests'
59
+
60
+ context 'when credentials are valid' do
61
+ let(:resource) { REST::Resource.new(env_user, env_key) }
62
+
63
+ describe '#advanced' do
64
+ context 'with required params' do
65
+ # 90 days from now
66
+ let(:start_date) { (Time.now - (90*24*60*60)).strftime("%Y-%m-%d") }
67
+
68
+ it 'gets stats' do
69
+ subject.advanced(:start_date => start_date, :data_type => :global).should_not be_empty
70
+ end
71
+ end
72
+
73
+ context 'without required params' do
74
+ it 'raises error' do
75
+ expect { subject.advanced }.to raise_error(REST::Errors::BadRequest)
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ context 'when credentials are invalid' do
82
+ describe '#advanced' do
83
+ it 'raises error' do
84
+ expect { subject.advanced }.to raise_error(REST::Errors::Forbidden)
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,23 @@
1
+ require 'simplecov'
2
+ require 'coveralls'
3
+
4
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
5
+ SimpleCov::Formatter::HTMLFormatter,
6
+ Coveralls::SimpleCov::Formatter
7
+ ]
8
+ SimpleCov.start do
9
+ add_filter "/vendor/"
10
+ add_filter "/spec/"
11
+ end
12
+
13
+ require 'sendgrid/api'
14
+ require 'rspec'
15
+ require 'webmock/rspec'
16
+
17
+ Dir["./spec/support/**/*.rb"].sort.each { |f| require f }
18
+
19
+ RSpec.configure do |config|
20
+ config.filter_run_excluding :online => true unless ENV['ALL']
21
+ end
22
+
23
+ disable_http
@@ -0,0 +1,23 @@
1
+ def fixture_path
2
+ File.expand_path("../../fixtures", __FILE__)
3
+ end
4
+
5
+ def fixture(file)
6
+ File.new(fixture_path + '/' + file)
7
+ end
8
+
9
+ def enable_http
10
+ WebMock.allow_net_connect!
11
+ end
12
+
13
+ def disable_http
14
+ WebMock.disable_net_connect!(:allow => 'coveralls.io')
15
+ end
16
+
17
+ def sample_file(options = {})
18
+ name = options[:name] || 'sample.txt'
19
+ type = options[:type] || 'plain/text'
20
+ content = options[:content] || 'This is my file content'
21
+ stream = StringIO.new(content)
22
+ Faraday::UploadIO.new(stream, type, name)
23
+ end
@@ -0,0 +1,30 @@
1
+ module Sendgrid
2
+ class Mock
3
+ include WebMock::API
4
+
5
+ def initialize(user, key)
6
+ @user = user
7
+ @key = key
8
+ end
9
+
10
+ def stub_post(path, params = {})
11
+ stub_request(:post, uri(path)).
12
+ with(:body => params.merge(authentication_params))
13
+ end
14
+
15
+ def a_post(path, params = {})
16
+ a_request(:post, uri(path)).
17
+ with(:body => params.merge(authentication_params))
18
+ end
19
+
20
+ def uri(path)
21
+ Sendgrid::API::REST::Resource::ENDPOINT + '/' + path
22
+ end
23
+
24
+ private
25
+
26
+ def authentication_params
27
+ { :api_key => @key, :api_user => @user }
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,114 @@
1
+ class Online
2
+
3
+ attr_reader :client
4
+
5
+ def initialize(user, key)
6
+ @client = Sendgrid::API::Client.new(user, key)
7
+ end
8
+
9
+ def sender_address_example
10
+ Sendgrid::API::Entities::SenderAddress.new(
11
+ :identity => 'sendgrid-api sender address test',
12
+ :name => 'Sendgrid',
13
+ :email => 'contact@sendgrid.com',
14
+ :address => '1065 N Pacificenter Drive, Suite 425',
15
+ :city => 'Anaheim',
16
+ :state => 'CA',
17
+ :zip => '92806',
18
+ :country => 'US'
19
+ )
20
+ end
21
+
22
+ def marketing_email_example
23
+ identity = sender_address_example.identity
24
+ Sendgrid::API::Entities::MarketingEmail.new(
25
+ :identity => identity,
26
+ :name => 'sendgrid-api marketing email test',
27
+ :subject => 'My Marketing Email Test',
28
+ :text => 'My text',
29
+ :html => 'My HTML'
30
+ )
31
+ end
32
+
33
+ def category_example
34
+ Sendgrid::API::Entities::Category.new(
35
+ :category => 'sendgrid-api test'
36
+ )
37
+ end
38
+
39
+ def list_example
40
+ Sendgrid::API::Entities::List.new(
41
+ :list => 'sendgrid-api list test'
42
+ )
43
+ end
44
+
45
+ def emails_example
46
+ [
47
+ Sendgrid::API::Entities::Email.new(:email => 'john@example.com', :name => 'John'),
48
+ Sendgrid::API::Entities::Email.new(:email => 'brian@example.com', :name => 'Brian')
49
+ ]
50
+ end
51
+
52
+ def add_marketing_email
53
+ client.sender_addresses.add(sender_address_example)
54
+ client.marketing_emails.add(marketing_email_example)
55
+ end
56
+
57
+ def delete_marketing_email
58
+ client.marketing_emails.delete(marketing_email_example)
59
+ client.sender_addresses.delete(sender_address_example)
60
+ end
61
+
62
+ def add_list
63
+ client.lists.add(list_example)
64
+ client.emails.add(list_example, emails_example)
65
+ end
66
+
67
+ def delete_list
68
+ client.lists.delete(list_example)
69
+ end
70
+
71
+ def add_recipient_list
72
+ check_completed do
73
+ begin
74
+ client.recipients.add(list_example, marketing_email_example).success?
75
+ rescue Sendgrid::API::REST::Errors::UnprocessableEntity
76
+ false
77
+ end
78
+ end
79
+ end
80
+
81
+ def add_marketing_email_with_list
82
+ add_marketing_email
83
+ add_list
84
+ add_recipient_list
85
+ end
86
+
87
+ def delete_marketing_email_with_list
88
+ delete_marketing_email
89
+ delete_list
90
+ end
91
+
92
+ private
93
+
94
+ # Check if some operation is completed or not.
95
+ #
96
+ # @see http://support.sendgrid.com/hc/en-us/articles/200185208-SendGrid-Web-API-may-return-successful-but-doesn-t-mean-it-has-completed
97
+ # @param timeout [Fixnum] The maximum number of seconds to check the operation status. Default: 60 seconds.
98
+ # @param delay [Fixnum] The number of seconds between each check. Default: 3 seconds.
99
+ # @param &block [Block] The given block should return true if completed, otherwise false.
100
+ # @return [Bool] The operation status
101
+ def check_completed(timeout = 60, delay = 3)
102
+ start = Time.now
103
+ response = nil
104
+ loop do
105
+ response = yield
106
+ duration = Time.now - start
107
+ # puts "Checking operation - status: #{response.inspect} - duration: #{duration} seconds"
108
+ break if response || (duration > timeout)
109
+ sleep delay
110
+ end
111
+ response
112
+ end
113
+
114
+ end
@@ -0,0 +1,104 @@
1
+ shared_examples 'online tests' do
2
+ before do
3
+ enable_http
4
+ end
5
+ after do
6
+ disable_http
7
+ end
8
+
9
+ let(:env_user) { ENV['SENDGRID_USER'] }
10
+ let(:env_key) { ENV['SENDGRID_KEY'] }
11
+ end
12
+
13
+ shared_examples 'a success response' do
14
+ before do
15
+ stub_post.to_return(:body => fixture('success.json'))
16
+ end
17
+ its(:success?) { should be_true }
18
+ end
19
+
20
+ shared_examples 'an unauthorized response' do
21
+ before do
22
+ stub_post.to_return(:body => fixture('errors/unauthorized.json'), :status => 401)
23
+ end
24
+ it 'raises an error' do
25
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
26
+ end
27
+ end
28
+
29
+ shared_examples 'a forbidden response' do
30
+ before do
31
+ stub_post.to_return(:body => fixture('errors/forbidden.json'), :status => 403)
32
+ end
33
+ it 'raises an error' do
34
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::Forbidden)
35
+ end
36
+ end
37
+
38
+ shared_examples 'an invalid fields response' do
39
+ before do
40
+ stub_post.to_return(:body => fixture('errors/invalid_fields.json'), :status => 400)
41
+ end
42
+ it 'raises an error' do
43
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::BadRequest)
44
+ end
45
+ end
46
+
47
+ shared_examples 'a does not exist response' do
48
+ before do
49
+ stub_post.to_return(:body => fixture('errors/does_not_exist.json'), :status => 401)
50
+ end
51
+ it 'raises an error' do
52
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
53
+ end
54
+ end
55
+
56
+ shared_examples 'an already exists response' do
57
+ before do
58
+ stub_post.to_return(:body => fixture('errors/already_exists.json'))
59
+ end
60
+
61
+ it 'raises an error' do
62
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::UnprocessableEntity)
63
+ end
64
+ end
65
+
66
+ shared_examples 'an already exists unauthorized response' do
67
+ before do
68
+ stub_post.to_return(:body => fixture('errors/already_exists.json'), :status => 401)
69
+ end
70
+
71
+ it 'raises an error' do
72
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
73
+ end
74
+ end
75
+
76
+ shared_examples 'a database error response' do
77
+ before do
78
+ stub_post.to_return(:body => fixture('errors/database_error.json'), :status => 500)
79
+ end
80
+
81
+ it 'raises an error' do
82
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::Unknown)
83
+ end
84
+ end
85
+
86
+ shared_examples 'a not scheduled response' do
87
+ before do
88
+ stub_post.to_return(:body => fixture('errors/bad_request.json'), :status => 401)
89
+ end
90
+
91
+ it 'raises an error' do
92
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::Unauthorized)
93
+ end
94
+ end
95
+
96
+ shared_examples 'a bad request response' do
97
+ before do
98
+ stub_post.to_return(:body => fixture('errors/bad_request.json'), :status => 400)
99
+ end
100
+
101
+ it 'raises an error' do
102
+ expect { subject }.to raise_error(Sendgrid::API::REST::Errors::BadRequest)
103
+ end
104
+ end