sendgrid-api 0.0.1 → 0.0.2
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/.gitignore +2 -0
- data/.rspec +1 -0
- data/.travis.yml +3 -0
- data/Gemfile +6 -3
- data/Gemfile.lock +35 -1
- data/README.md +48 -4
- data/Rakefile +3 -1
- data/lib/sendgrid/api.rb +3 -2
- data/lib/sendgrid/api/client.rb +27 -0
- data/lib/sendgrid/api/entities/entity.rb +83 -0
- data/lib/sendgrid/api/entities/profile.rb +14 -0
- data/lib/sendgrid/api/entities/response.rb +21 -0
- data/lib/sendgrid/api/entities/stats.rb +14 -0
- data/lib/sendgrid/api/rest/errors/error.rb +60 -0
- data/lib/sendgrid/api/rest/resource.rb +56 -0
- data/lib/sendgrid/api/rest/response/parse_error.rb +19 -0
- data/lib/sendgrid/api/rest/response/parse_json.rb +18 -0
- data/lib/sendgrid/api/service.rb +23 -0
- data/lib/sendgrid/api/version.rb +2 -2
- data/lib/sendgrid/api/web/profile.rb +38 -0
- data/lib/sendgrid/api/web/stats.rb +36 -0
- data/sendgrid-api.gemspec +4 -1
- data/spec/fixtures/forbidden.json +3 -0
- data/spec/fixtures/profile.json +18 -0
- data/spec/fixtures/stats.json +50 -0
- data/spec/fixtures/success.json +3 -0
- data/spec/fixtures/unauthorized.json +6 -0
- data/spec/sendgrid/api/client_spec.rb +22 -0
- data/spec/sendgrid/api/entities/entity_spec.rb +279 -0
- data/spec/sendgrid/api/entities/profile_spec.rb +26 -0
- data/spec/sendgrid/api/entities/response_spec.rb +28 -0
- data/spec/sendgrid/api/entities/stats_spec.rb +25 -0
- data/spec/sendgrid/api/rest/errors/error_spec.rb +97 -0
- data/spec/sendgrid/api/rest/resource_spec.rb +143 -0
- data/spec/sendgrid/api/rest/response/parse_error_spec.rb +39 -0
- data/spec/sendgrid/api/rest/response/parse_json_spec.rb +45 -0
- data/spec/sendgrid/api/service_spec.rb +44 -0
- data/spec/sendgrid/api/version_spec.rb +2 -2
- data/spec/sendgrid/api/web/profile_spec.rb +126 -0
- data/spec/sendgrid/api/web/stats_spec.rb +100 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/helpers.rb +15 -0
- data/spec/support/mock.rb +26 -0
- data/spec/support/shared_examples.rb +11 -0
- metadata +78 -9
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
module Entities
|
6
|
+
describe Profile do
|
7
|
+
subject { described_class.new }
|
8
|
+
|
9
|
+
it { should respond_to(:username) }
|
10
|
+
it { should respond_to(:email) }
|
11
|
+
it { should respond_to(:active) }
|
12
|
+
it { should respond_to(:first_name) }
|
13
|
+
it { should respond_to(:last_name) }
|
14
|
+
it { should respond_to(:address) }
|
15
|
+
it { should respond_to(:address2) }
|
16
|
+
it { should respond_to(:city) }
|
17
|
+
it { should respond_to(:state) }
|
18
|
+
it { should respond_to(:zip) }
|
19
|
+
it { should respond_to(:country) }
|
20
|
+
it { should respond_to(:phone) }
|
21
|
+
it { should respond_to(:website) }
|
22
|
+
it { should respond_to(:website_access) }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
module Entities
|
6
|
+
describe Response do
|
7
|
+
subject { described_class.new }
|
8
|
+
|
9
|
+
it { should respond_to(:message) }
|
10
|
+
it { should respond_to(:errors) }
|
11
|
+
|
12
|
+
context 'message is true' do
|
13
|
+
subject { described_class.new(:message => 'success') }
|
14
|
+
|
15
|
+
its(:success?) { should be_true }
|
16
|
+
its(:error?) { should be_false }
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'message is error' do
|
20
|
+
subject { described_class.new(:message => 'error') }
|
21
|
+
|
22
|
+
its(:success?) { should be_false }
|
23
|
+
its(:error?) { should be_true }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
module Entities
|
6
|
+
describe Stats do
|
7
|
+
subject { described_class.new }
|
8
|
+
|
9
|
+
it { should respond_to(:delivered) }
|
10
|
+
it { should respond_to(:request) }
|
11
|
+
it { should respond_to(:unique_open) }
|
12
|
+
it { should respond_to(:unique_click) }
|
13
|
+
it { should respond_to(:processed) }
|
14
|
+
it { should respond_to(:date) }
|
15
|
+
it { should respond_to(:open) }
|
16
|
+
it { should respond_to(:click) }
|
17
|
+
it { should respond_to(:blocked) }
|
18
|
+
it { should respond_to(:spamreport) }
|
19
|
+
it { should respond_to(:drop) }
|
20
|
+
it { should respond_to(:bounce) }
|
21
|
+
it { should respond_to(:deferred) }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
module REST
|
6
|
+
module Errors
|
7
|
+
describe Error do
|
8
|
+
subject { described_class }
|
9
|
+
|
10
|
+
describe '.from_response' do
|
11
|
+
context 'when response has a status error' do
|
12
|
+
context 'known status' do
|
13
|
+
let(:env) do
|
14
|
+
{ :status => 400,
|
15
|
+
:body => nil }
|
16
|
+
end
|
17
|
+
|
18
|
+
subject { described_class.from_response(env) }
|
19
|
+
|
20
|
+
it { should be_instance_of(Errors::BadRequest) }
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'unknown status' do
|
24
|
+
let(:env) do
|
25
|
+
{ :status => 413,
|
26
|
+
:body => nil }
|
27
|
+
end
|
28
|
+
|
29
|
+
subject { described_class.from_response(env) }
|
30
|
+
|
31
|
+
it { should be_instance_of(Errors::Unknown) }
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'with message' do
|
35
|
+
let(:env) do
|
36
|
+
{ :status => 400,
|
37
|
+
:body => { :error => 'error message' } }
|
38
|
+
end
|
39
|
+
|
40
|
+
subject { described_class.from_response(env) }
|
41
|
+
|
42
|
+
it { should == Errors::BadRequest.new('error message') }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when response has body error' do
|
47
|
+
context 'known status' do
|
48
|
+
let(:env) do
|
49
|
+
{ :status => 200,
|
50
|
+
:body => { :error => { :code => 400 } } }
|
51
|
+
end
|
52
|
+
|
53
|
+
subject { described_class.from_response(env) }
|
54
|
+
|
55
|
+
it { should be_instance_of(Errors::BadRequest) }
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'unknown status' do
|
59
|
+
let(:env) do
|
60
|
+
{ :status => 200,
|
61
|
+
:body => { :error => { :code => 413 } } }
|
62
|
+
end
|
63
|
+
|
64
|
+
subject { described_class.from_response(env) }
|
65
|
+
|
66
|
+
it { should be_instance_of(Errors::Unknown) }
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'with message' do
|
70
|
+
let(:env) do
|
71
|
+
{ :status => 200,
|
72
|
+
:body => { :error => { :code => 400,
|
73
|
+
:message => 'error message' } } }
|
74
|
+
end
|
75
|
+
|
76
|
+
subject { described_class.from_response(env) }
|
77
|
+
|
78
|
+
it { should == Errors::BadRequest.new('error message') }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'when response has no error' do
|
83
|
+
let(:env) do
|
84
|
+
{ :status => 200,
|
85
|
+
:body => nil }
|
86
|
+
end
|
87
|
+
|
88
|
+
subject { described_class.from_response(env) }
|
89
|
+
|
90
|
+
it { should be_nil }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
module REST
|
6
|
+
describe Resource do
|
7
|
+
subject { resource }
|
8
|
+
let(:resource) { described_class.new(user, key) }
|
9
|
+
let(:user) { 'my_user' }
|
10
|
+
let(:key) { 'my_key' }
|
11
|
+
|
12
|
+
its(:user) { should == user }
|
13
|
+
its(:key) { should == key }
|
14
|
+
|
15
|
+
it 'should have a valid ENDPOINT' do
|
16
|
+
described_class::ENDPOINT.should == 'https://sendgrid.com/api'
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#post' do
|
20
|
+
let(:url) { 'any_path' }
|
21
|
+
let(:response) { double('response') }
|
22
|
+
|
23
|
+
context 'without params' do
|
24
|
+
before do
|
25
|
+
subject.should_receive(:request).with(:post, url, {}).and_return(response)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should perform the request' do
|
29
|
+
subject.post(url).should == response
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with params' do
|
34
|
+
before do
|
35
|
+
subject.should_receive(:request).with(:post, url, params).and_return(response)
|
36
|
+
end
|
37
|
+
let(:params) { {:name => 'my name'} }
|
38
|
+
|
39
|
+
it 'should perform the request' do
|
40
|
+
subject.post(url, params).should == response
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#request' do
|
46
|
+
let(:url) { 'any_path' }
|
47
|
+
let(:sg_mock) { Sendgrid::Mock.new(user, key) }
|
48
|
+
|
49
|
+
context 'without params' do
|
50
|
+
before do
|
51
|
+
sg_mock.stub_post(url)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should perform a request' do
|
55
|
+
subject.send(:request, :post, url)
|
56
|
+
sg_mock.a_post(url).should have_been_made
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context 'with params' do
|
61
|
+
before do
|
62
|
+
sg_mock.stub_post(url, params)
|
63
|
+
end
|
64
|
+
let(:params) { {:name => 'my name'} }
|
65
|
+
|
66
|
+
it 'should perform a request' do
|
67
|
+
subject.send(:request, :post, url, params)
|
68
|
+
sg_mock.a_post(url, params).should have_been_made
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'catches the errors' do
|
73
|
+
it 'catches Faraday errors' do
|
74
|
+
subject.stub(:connection).and_raise(Faraday::Error::ClientError.new('unknown error'))
|
75
|
+
expect { subject.send(:request, :post, url) }.to raise_error Sendgrid::API::REST::Errors::Unknown
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'catches JSON::ParserError errors' do
|
79
|
+
subject.stub(:connection).and_raise(JSON::ParserError.new('unexpected token"'))
|
80
|
+
expect { subject.send(:request, :post, url) }.to raise_error Sendgrid::API::REST::Errors::Unknown
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'catches status errors' do
|
84
|
+
sg_mock.stub_post(url).to_return(:status => 400)
|
85
|
+
expect { subject.send(:request, :post, url) }.to raise_error Sendgrid::API::REST::Errors::BadRequest
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'catches body errors' do
|
89
|
+
sg_mock.stub_post(url).to_return(:body => {:error => {:code => 401}}.to_json)
|
90
|
+
expect { subject.send(:request, :post, url) }.to raise_error Sendgrid::API::REST::Errors::Unauthorized
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context 'parses body as JSON' do
|
95
|
+
before do
|
96
|
+
sg_mock.stub_post(url).to_return(:body => {'name' => 'my name'}.to_json)
|
97
|
+
end
|
98
|
+
|
99
|
+
subject { resource.send(:request, :post, url).body }
|
100
|
+
|
101
|
+
it { should be_instance_of(Hash) }
|
102
|
+
its([:name]) { should == 'my name'}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
describe '#middleware' do
|
107
|
+
it 'should be a valid Faraday middleware' do
|
108
|
+
subject.send(:middleware).should be_instance_of(Faraday::Builder)
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should memoize the middleware' do
|
112
|
+
middleware = double('middleware')
|
113
|
+
Faraday::Builder.should_receive(:new).once.and_return(middleware)
|
114
|
+
|
115
|
+
subject.send(:middleware).should == middleware
|
116
|
+
subject.send(:middleware).should == middleware
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe '#connection' do
|
121
|
+
it 'should be a valid Faraday connection' do
|
122
|
+
subject.send(:connection).should be_instance_of(Faraday::Connection)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'should memoize the connection' do
|
126
|
+
connection = double('connection')
|
127
|
+
Faraday.should_receive(:new).once.and_return(connection)
|
128
|
+
|
129
|
+
subject.send(:connection).should == connection
|
130
|
+
subject.send(:connection).should == connection
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '#authentication_params' do
|
135
|
+
subject { resource.send(:authentication_params) }
|
136
|
+
|
137
|
+
its([:api_user]) { should == user }
|
138
|
+
its([:api_key]) { should == key }
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
module REST
|
6
|
+
module Response
|
7
|
+
describe ParseError do
|
8
|
+
|
9
|
+
subject { described_class.new }
|
10
|
+
|
11
|
+
describe '#on_complete' do
|
12
|
+
context 'response with error' do
|
13
|
+
before do
|
14
|
+
REST::Errors::Error.should_receive(:from_response).and_return(Errors::Error)
|
15
|
+
end
|
16
|
+
let(:env) { double('env') }
|
17
|
+
|
18
|
+
it 'should raise the error' do
|
19
|
+
expect { subject.on_complete(env) }.to raise_error(Errors::Error)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'response without error' do
|
24
|
+
before do
|
25
|
+
REST::Errors::Error.should_receive(:from_response).and_return(nil)
|
26
|
+
end
|
27
|
+
let(:env) { double('env') }
|
28
|
+
|
29
|
+
it 'should return nil' do
|
30
|
+
subject.on_complete(env).should be_nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
module REST
|
6
|
+
module Response
|
7
|
+
describe ParseJson do
|
8
|
+
|
9
|
+
subject { parse_json }
|
10
|
+
let(:parse_json) { described_class.new }
|
11
|
+
|
12
|
+
describe '#parse' do
|
13
|
+
context 'body is nil' do
|
14
|
+
let(:body) { nil }
|
15
|
+
|
16
|
+
it 'should return nil' do
|
17
|
+
subject.parse(body).should be_nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context 'body is not a valid JSON' do
|
22
|
+
let(:body) { 'some plain text' }
|
23
|
+
|
24
|
+
it 'should raise JSON::ParserError' do
|
25
|
+
expect { subject.parse(body) }.to raise_error(JSON::ParserError)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'body is a valid JSON' do
|
30
|
+
let(:body) do
|
31
|
+
{ 'name' => 'my name' }.to_json
|
32
|
+
end
|
33
|
+
|
34
|
+
subject { parse_json.parse(body) }
|
35
|
+
|
36
|
+
it { should be_instance_of(Hash) }
|
37
|
+
its([:name]) { should == 'my name'}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Sendgrid
|
4
|
+
module API
|
5
|
+
describe Service do
|
6
|
+
|
7
|
+
subject { described_class.new(resource) }
|
8
|
+
let(:resource) { double('resource') }
|
9
|
+
|
10
|
+
its(:resource) { should == resource }
|
11
|
+
|
12
|
+
describe '#perform_request' do
|
13
|
+
before do
|
14
|
+
entity.should_receive(:from_response).and_return(response)
|
15
|
+
end
|
16
|
+
let(:entity) { double('entity') }
|
17
|
+
let(:response) { double('response') }
|
18
|
+
let(:url) { double('url') }
|
19
|
+
|
20
|
+
context 'with params' do
|
21
|
+
before do
|
22
|
+
resource.should_receive(:post).with(url, params)
|
23
|
+
end
|
24
|
+
let(:params) { double('params') }
|
25
|
+
|
26
|
+
it 'should perform a request' do
|
27
|
+
subject.perform_request(entity, url, params).should == response
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'without params' do
|
32
|
+
before do
|
33
|
+
resource.should_receive(:post).with(url, {})
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should perform a request' do
|
37
|
+
subject.perform_request(entity, url).should == response
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|