sendgrid-ruby 6.2.0 → 6.6.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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/config.yml +10 -0
- data/.github/workflows/test-and-deploy.yml +120 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +8 -0
- data/.rubocop_todo.yml +127 -0
- data/CHANGELOG.md +147 -9
- data/CONTRIBUTING.md +11 -21
- data/Dockerfile +14 -0
- data/FIRST_TIMERS.md +79 -0
- data/Gemfile +0 -1
- data/ISSUE_TEMPLATE.md +5 -1
- data/{LICENSE.md → LICENSE} +1 -1
- data/Makefile +9 -2
- data/PULL_REQUEST_TEMPLATE.md +5 -5
- data/README.md +23 -31
- data/Rakefile +2 -3
- data/TROUBLESHOOTING.md +17 -5
- data/USAGE.md +146 -39
- data/examples/accesssettings/accesssettings.rb +9 -12
- data/examples/alerts/alerts.rb +8 -11
- data/examples/apikeys/apikeys.rb +12 -15
- data/examples/asm/asm.rb +27 -30
- data/examples/browsers/browsers.rb +0 -3
- data/examples/campaigns/campaigns.rb +29 -32
- data/examples/categories/categories.rb +0 -3
- data/examples/clients/clients.rb +1 -4
- data/examples/contactdb/contactdb.rb +63 -66
- data/examples/devices/devices.rb +0 -3
- data/examples/emailactivity/emailactivity.rb +52 -0
- data/examples/geo/geo.rb +0 -3
- data/examples/helpers/eventwebhook/example.rb +16 -0
- data/examples/helpers/mail/example.rb +24 -13
- data/examples/helpers/settings/example.rb +1 -1
- data/examples/helpers/stats/example.rb +4 -4
- data/examples/ips/ips.rb +19 -22
- data/examples/mail/mail.rb +72 -75
- data/examples/mailboxproviders/mailboxproviders.rb +0 -3
- data/examples/mailsettings/mailsettings.rb +21 -24
- data/examples/partnersettings/partnersettings.rb +3 -6
- data/examples/scopes/scopes.rb +8 -10
- data/examples/senderauthentication/senderauthentication.rb +41 -44
- data/examples/senders/senders.rb +28 -31
- data/examples/stats/stats.rb +0 -3
- data/examples/subusers/subusers.rb +17 -20
- data/examples/suppression/suppression.rb +15 -18
- data/examples/templates/templates.rb +29 -31
- data/examples/trackingsettings/trackingsettings.rb +14 -17
- data/examples/user/user.rb +41 -44
- data/lib/rack/sendgrid_webhook_verification.rb +55 -0
- data/lib/sendgrid/base_interface.rb +8 -4
- data/lib/sendgrid/helpers/eventwebhook/eventwebhook.rb +50 -0
- data/lib/sendgrid/helpers/inbound/README.md +5 -5
- data/lib/sendgrid/helpers/inbound/app.rb +2 -2
- data/lib/sendgrid/helpers/inbound/public/index.html +1 -1
- data/lib/sendgrid/helpers/inbound/send.rb +3 -3
- data/lib/sendgrid/helpers/ip_management/ip_management.rb +1 -1
- data/lib/sendgrid/helpers/mail/README.md +3 -3
- data/lib/sendgrid/helpers/mail/asm.rb +6 -18
- data/lib/sendgrid/helpers/mail/attachment.rb +12 -42
- data/lib/sendgrid/helpers/mail/bcc_settings.rb +6 -18
- data/lib/sendgrid/helpers/mail/bypass_list_management.rb +8 -18
- data/lib/sendgrid/helpers/mail/category.rb +2 -2
- data/lib/sendgrid/helpers/mail/click_tracking.rb +6 -18
- data/lib/sendgrid/helpers/mail/content.rb +4 -3
- data/lib/sendgrid/helpers/mail/custom_arg.rb +6 -10
- data/lib/sendgrid/helpers/mail/email.rb +10 -5
- data/lib/sendgrid/helpers/mail/footer.rb +7 -27
- data/lib/sendgrid/helpers/mail/ganalytics.rb +10 -54
- data/lib/sendgrid/helpers/mail/header.rb +6 -10
- data/lib/sendgrid/helpers/mail/mail.rb +32 -48
- data/lib/sendgrid/helpers/mail/mail_settings.rb +9 -25
- data/lib/sendgrid/helpers/mail/open_tracking.rb +6 -18
- data/lib/sendgrid/helpers/mail/personalization.rb +40 -27
- data/lib/sendgrid/helpers/mail/section.rb +6 -10
- data/lib/sendgrid/helpers/mail/spam_check.rb +7 -27
- data/lib/sendgrid/helpers/mail/subscription_tracking.rb +8 -36
- data/lib/sendgrid/helpers/mail/substitution.rb +6 -10
- data/lib/sendgrid/helpers/mail/tracking_settings.rb +8 -20
- data/lib/sendgrid/helpers/permissions/scope.rb +2 -2
- data/lib/sendgrid/helpers/settings/README.md +2 -2
- data/lib/sendgrid/helpers/settings/settings.rb +1 -1
- data/lib/sendgrid/helpers/settings/tracking_settings_dto.rb +3 -5
- data/lib/sendgrid/helpers/stats/metrics.rb +5 -5
- data/lib/sendgrid/sendgrid.rb +4 -3
- data/lib/sendgrid/twilio_email.rb +1 -1
- data/lib/sendgrid/version.rb +1 -1
- data/lib/sendgrid-ruby.rb +2 -0
- data/mail_helper_v3.md +12 -12
- data/sendgrid-ruby.gemspec +8 -8
- data/spec/fixtures/event_webhook.rb +22 -0
- data/spec/rack/sendgrid_webhook_verification_spec.rb +142 -0
- data/spec/sendgrid/helpers/eventwebhook/eventwebhook_spec.rb +105 -0
- data/spec/sendgrid/helpers/settings/mail_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/settings/partner_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/settings/settings_spec.rb +2 -2
- data/spec/sendgrid/helpers/settings/tracking_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/settings/user_settings_dto_spec.rb +3 -3
- data/spec/sendgrid/helpers/stats/email_stats_spec.rb +22 -23
- data/spec/sendgrid/helpers/stats/metrics_spec.rb +19 -20
- data/spec/sendgrid/helpers/stats/stats_response_spec.rb +22 -23
- data/spec/spec_helper.rb +3 -1
- data/static/img/github-fork.png +0 -0
- data/static/img/github-sign-up.png +0 -0
- data/test/sendgrid/helpers/mail/test_attachment.rb +4 -6
- data/test/sendgrid/helpers/mail/test_category.rb +0 -2
- data/test/sendgrid/helpers/mail/test_email.rb +17 -10
- data/test/sendgrid/helpers/mail/test_mail.rb +101 -102
- data/test/sendgrid/helpers/mail/test_personalizations.rb +145 -92
- data/test/sendgrid/permissions/test_scopes.rb +1 -3
- data/test/sendgrid/test_sendgrid-ruby.rb +1964 -1986
- data/twilio_sendgrid_logo.png +0 -0
- data/use-cases/README.md +17 -0
- data/use-cases/domain-authentication.md +5 -0
- data/use-cases/email-statistics.md +52 -0
- data/use-cases/legacy-templates.md +98 -0
- data/use-cases/personalizations.md +34 -0
- data/use-cases/sms.md +39 -0
- data/use-cases/transactional-templates.md +111 -0
- data/use-cases/twilio-email.md +13 -0
- data/use-cases/twilio-setup.md +54 -0
- metadata +69 -34
- data/.codeclimate.yml +0 -21
- data/.travis.yml +0 -40
- data/USE_CASES.md +0 -405
- data/docker/Dockerfile +0 -12
- data/docker/README.md +0 -30
- data/test/prism.sh +0 -42
data/sendgrid-ruby.gemspec
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
3
|
require 'sendgrid/version'
|
|
5
4
|
|
|
@@ -14,17 +13,18 @@ Gem::Specification.new do |spec|
|
|
|
14
13
|
|
|
15
14
|
spec.required_ruby_version = '>= 2.2'
|
|
16
15
|
|
|
17
|
-
spec.license
|
|
16
|
+
spec.license = 'MIT'
|
|
18
17
|
spec.files = `git ls-files -z`.split("\x0")
|
|
19
18
|
spec.executables = spec.files.grep(/^bin/) { |f| File.basename(f) }
|
|
20
19
|
spec.test_files = spec.files.grep(/^(test|spec|features)/)
|
|
21
20
|
spec.require_paths = ['lib']
|
|
22
21
|
spec.add_dependency 'ruby_http_client', '~> 3.4'
|
|
23
|
-
spec.add_development_dependency 'sinatra', '>= 1.4.7', '< 3'
|
|
24
|
-
spec.add_development_dependency 'rake', '~> 13.0'
|
|
25
|
-
spec.add_development_dependency 'rspec'
|
|
26
|
-
spec.add_development_dependency 'pry'
|
|
27
22
|
spec.add_development_dependency 'faker'
|
|
28
|
-
spec.add_development_dependency 'rubocop'
|
|
29
23
|
spec.add_development_dependency 'minitest', '~> 5.9'
|
|
24
|
+
spec.add_development_dependency 'pry'
|
|
25
|
+
spec.add_development_dependency 'rack'
|
|
26
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
27
|
+
spec.add_development_dependency 'rspec'
|
|
28
|
+
spec.add_development_dependency 'simplecov', '~> 0.18.5'
|
|
29
|
+
spec.add_development_dependency 'sinatra', '>= 1.4.7', '< 3'
|
|
30
30
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
module Fixtures
|
|
4
|
+
module EventWebhook
|
|
5
|
+
PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE83T4O/n84iotIvIW4mdBgQ/7dAfSmpqIM8kF9mN1flpVKS3GRqe62gw+2fNNRaINXvVpiglSI8eNEc6wEA3F+g=='.freeze
|
|
6
|
+
FAILING_PUBLIC_KEY = 'MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEqTxd43gyp8IOEto2LdIfjRQrIbsd4SXZkLW6jDutdhXSJCWHw8REntlo7aNDthvj+y7GjUuFDb/R1NGe1OPzpA=='.freeze
|
|
7
|
+
SIGNATURE = 'MEUCIGHQVtGj+Y3LkG9fLcxf3qfI10QysgDWmMOVmxG0u6ZUAiEAyBiXDWzM+uOe5W0JuG+luQAbPIqHh89M15TluLtEZtM='.freeze
|
|
8
|
+
FAILING_SIGNATURE = 'MEUCIQCtIHJeH93Y+qpYeWrySphQgpNGNr/U+UyUlBkU6n7RAwIgJTz2C+8a8xonZGi6BpSzoQsbVRamr2nlxFDWYNH3j/0='.freeze
|
|
9
|
+
TIMESTAMP = '1600112502'.freeze
|
|
10
|
+
PAYLOAD = "#{[
|
|
11
|
+
{
|
|
12
|
+
email: 'hello@world.com',
|
|
13
|
+
event: 'dropped',
|
|
14
|
+
reason: 'Bounced Address',
|
|
15
|
+
sg_event_id: 'ZHJvcC0xMDk5NDkxOS1MUnpYbF9OSFN0T0doUTRrb2ZTbV9BLTA',
|
|
16
|
+
sg_message_id: 'LRzXl_NHStOGhQ4kofSm_A.filterdrecv-p3mdw1-756b745b58-kmzbl-18-5F5FC76C-9.0',
|
|
17
|
+
'smtp-id': '<LRzXl_NHStOGhQ4kofSm_A@ismtpd0039p1iad1.sendgrid.net>',
|
|
18
|
+
timestamp: 1_600_112_492
|
|
19
|
+
}
|
|
20
|
+
].to_json}\r\n".freeze # Be sure to include the trailing carriage return and newline!
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rack/mock'
|
|
3
|
+
require './spec/fixtures/event_webhook'
|
|
4
|
+
|
|
5
|
+
unless RUBY_PLATFORM == 'java'
|
|
6
|
+
describe Rack::SendGridWebhookVerification do
|
|
7
|
+
let(:public_key) { Fixtures::EventWebhook::PUBLIC_KEY }
|
|
8
|
+
before do
|
|
9
|
+
@app = ->(_env) { [200, { 'Content-Type' => 'text/plain' }, ['Hello']] }
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe 'new' do
|
|
13
|
+
it 'should initialize with an app, public key and a path' do
|
|
14
|
+
expect do
|
|
15
|
+
Rack::SendGridWebhookVerification.new(@app, 'ABC', %r{/email})
|
|
16
|
+
end.not_to raise_error
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'should initialize with an app, public key and paths' do
|
|
20
|
+
expect do
|
|
21
|
+
Rack::SendGridWebhookVerification.new(@app, 'ABC', %r{/email}, %r{/event})
|
|
22
|
+
end.not_to raise_error
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
describe 'calling against one path' do
|
|
27
|
+
let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, %r{/email}) }
|
|
28
|
+
|
|
29
|
+
it "should not intercept when the path doesn't match" do
|
|
30
|
+
expect(SendGrid::EventWebhook).to_not receive(:new)
|
|
31
|
+
request = Rack::MockRequest.env_for('/login')
|
|
32
|
+
status, headers, body = middleware.call(request)
|
|
33
|
+
expect(status).to eq(200)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'should allow a request through if it is verified' do
|
|
37
|
+
options = {
|
|
38
|
+
:input => Fixtures::EventWebhook::PAYLOAD,
|
|
39
|
+
'Content-Type' => "application/json"
|
|
40
|
+
}
|
|
41
|
+
options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
|
|
42
|
+
options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
|
|
43
|
+
request = Rack::MockRequest.env_for('/email', options)
|
|
44
|
+
status, headers, body = middleware.call(request)
|
|
45
|
+
expect(status).to eq(200)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'should short circuit a request to 403 if there is no signature or timestamp' do
|
|
49
|
+
options = {
|
|
50
|
+
:input => Fixtures::EventWebhook::PAYLOAD,
|
|
51
|
+
'Content-Type' => "application/json"
|
|
52
|
+
}
|
|
53
|
+
request = Rack::MockRequest.env_for('/email', options)
|
|
54
|
+
status, headers, body = middleware.call(request)
|
|
55
|
+
expect(status).to eq(403)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'should short circuit a request to 403 if the signature is incorrect' do
|
|
59
|
+
options = {
|
|
60
|
+
:input => Fixtures::EventWebhook::PAYLOAD,
|
|
61
|
+
'Content-Type' => "application/json"
|
|
62
|
+
}
|
|
63
|
+
options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::FAILING_SIGNATURE
|
|
64
|
+
options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
|
|
65
|
+
request = Rack::MockRequest.env_for('/email', options)
|
|
66
|
+
status, headers, body = middleware.call(request)
|
|
67
|
+
expect(status).to eq(403)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
it 'should short circuit a request to 403 if the payload is incorrect' do
|
|
71
|
+
options = {
|
|
72
|
+
:input => 'payload',
|
|
73
|
+
'Content-Type' => "application/json"
|
|
74
|
+
}
|
|
75
|
+
options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
|
|
76
|
+
options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
|
|
77
|
+
request = Rack::MockRequest.env_for('/email', options)
|
|
78
|
+
status, headers, body = middleware.call(request)
|
|
79
|
+
expect(status).to eq(403)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
describe 'calling with multiple paths' do
|
|
84
|
+
let(:middleware) { Rack::SendGridWebhookVerification.new(@app, public_key, %r{/email}, %r{/events}) }
|
|
85
|
+
|
|
86
|
+
it "should not intercept when the path doesn't match" do
|
|
87
|
+
expect(SendGrid::EventWebhook).to_not receive(:new)
|
|
88
|
+
request = Rack::MockRequest.env_for('/sms_events')
|
|
89
|
+
status, headers, body = middleware.call(request)
|
|
90
|
+
expect(status).to eq(200)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
it 'should allow a request through if it is verified' do
|
|
94
|
+
options = {
|
|
95
|
+
:input => Fixtures::EventWebhook::PAYLOAD,
|
|
96
|
+
'Content-Type' => "application/json"
|
|
97
|
+
}
|
|
98
|
+
options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
|
|
99
|
+
options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
|
|
100
|
+
request = Rack::MockRequest.env_for('/events', options)
|
|
101
|
+
status, headers, body = middleware.call(request)
|
|
102
|
+
expect(status).to eq(200)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
it 'should short circuit a request to 403 if there is no signature or timestamp' do
|
|
106
|
+
options = {
|
|
107
|
+
:input => Fixtures::EventWebhook::PAYLOAD,
|
|
108
|
+
'Content-Type' => "application/json"
|
|
109
|
+
}
|
|
110
|
+
request = Rack::MockRequest.env_for('/events', options)
|
|
111
|
+
status, headers, body = middleware.call(request)
|
|
112
|
+
expect(status).to eq(403)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe 'request body which passed to an app' do
|
|
117
|
+
before do
|
|
118
|
+
@payload = nil
|
|
119
|
+
@spy_app = lambda do |env|
|
|
120
|
+
@payload = Rack::Request.new(env).body
|
|
121
|
+
[200, { 'Content-Type' => 'text/plain' }, ['Hello']]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
let(:middleware) { Rack::SendGridWebhookVerification.new(@spy_app, public_key, %r{/email}) }
|
|
126
|
+
|
|
127
|
+
it 'keeps orignal reading position' do
|
|
128
|
+
options = {
|
|
129
|
+
:input => Fixtures::EventWebhook::PAYLOAD,
|
|
130
|
+
'Content-Type' => "application/json"
|
|
131
|
+
}
|
|
132
|
+
options[SendGrid::EventWebhookHeader::SIGNATURE] = Fixtures::EventWebhook::SIGNATURE
|
|
133
|
+
options[SendGrid::EventWebhookHeader::TIMESTAMP] = Fixtures::EventWebhook::TIMESTAMP
|
|
134
|
+
request = Rack::MockRequest.env_for('/email', options)
|
|
135
|
+
status, headers, body = middleware.call(request)
|
|
136
|
+
expect(status).to eq(200)
|
|
137
|
+
expect(@payload).not_to be_nil
|
|
138
|
+
expect(@payload.pos).to be_zero
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require './spec/fixtures/event_webhook'
|
|
3
|
+
|
|
4
|
+
describe SendGrid::EventWebhook do
|
|
5
|
+
describe '.verify_signature' do
|
|
6
|
+
it 'verifies a valid signature' do
|
|
7
|
+
unless skip_jruby
|
|
8
|
+
expect(verify(
|
|
9
|
+
Fixtures::EventWebhook::PUBLIC_KEY,
|
|
10
|
+
Fixtures::EventWebhook::PAYLOAD,
|
|
11
|
+
Fixtures::EventWebhook::SIGNATURE,
|
|
12
|
+
Fixtures::EventWebhook::TIMESTAMP
|
|
13
|
+
)).to be true
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
it 'rejects a bad key' do
|
|
18
|
+
unless skip_jruby
|
|
19
|
+
expect(verify(
|
|
20
|
+
Fixtures::EventWebhook::FAILING_PUBLIC_KEY,
|
|
21
|
+
Fixtures::EventWebhook::PAYLOAD,
|
|
22
|
+
Fixtures::EventWebhook::SIGNATURE,
|
|
23
|
+
Fixtures::EventWebhook::TIMESTAMP
|
|
24
|
+
)).to be false
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'rejects a bad payload' do
|
|
29
|
+
unless skip_jruby
|
|
30
|
+
expect(verify(
|
|
31
|
+
Fixtures::EventWebhook::PUBLIC_KEY,
|
|
32
|
+
'payload',
|
|
33
|
+
Fixtures::EventWebhook::SIGNATURE,
|
|
34
|
+
Fixtures::EventWebhook::TIMESTAMP
|
|
35
|
+
)).to be false
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'rejects a bad signature' do
|
|
40
|
+
unless skip_jruby
|
|
41
|
+
expect(verify(
|
|
42
|
+
Fixtures::EventWebhook::PUBLIC_KEY,
|
|
43
|
+
Fixtures::EventWebhook::PAYLOAD,
|
|
44
|
+
Fixtures::EventWebhook::FAILING_SIGNATURE,
|
|
45
|
+
Fixtures::EventWebhook::TIMESTAMP
|
|
46
|
+
)).to be false
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'rejects a bad timestamp' do
|
|
51
|
+
unless skip_jruby
|
|
52
|
+
expect(verify(
|
|
53
|
+
Fixtures::EventWebhook::PUBLIC_KEY,
|
|
54
|
+
Fixtures::EventWebhook::PAYLOAD,
|
|
55
|
+
Fixtures::EventWebhook::SIGNATURE,
|
|
56
|
+
'timestamp'
|
|
57
|
+
)).to be false
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'rejects a missing signature' do
|
|
62
|
+
unless skip_jruby
|
|
63
|
+
expect(verify(
|
|
64
|
+
Fixtures::EventWebhook::PUBLIC_KEY,
|
|
65
|
+
Fixtures::EventWebhook::PAYLOAD,
|
|
66
|
+
nil,
|
|
67
|
+
Fixtures::EventWebhook::TIMESTAMP
|
|
68
|
+
)).to be false
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it 'throws an error when using jruby' do
|
|
73
|
+
if skip_jruby
|
|
74
|
+
expect do
|
|
75
|
+
verify(
|
|
76
|
+
Fixtures::EventWebhook::PUBLIC_KEY,
|
|
77
|
+
Fixtures::EventWebhook::PAYLOAD,
|
|
78
|
+
Fixtures::EventWebhook::SIGNATURE,
|
|
79
|
+
Fixtures::EventWebhook::TIMESTAMP
|
|
80
|
+
)
|
|
81
|
+
end.to raise_error(SendGrid::EventWebhook::NotSupportedError)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
describe SendGrid::EventWebhookHeader do
|
|
88
|
+
it 'sets the signature header constant' do
|
|
89
|
+
expect(SendGrid::EventWebhookHeader::SIGNATURE).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_SIGNATURE")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it 'sets the timestamp header constant' do
|
|
93
|
+
expect(SendGrid::EventWebhookHeader::TIMESTAMP).to eq("HTTP_X_TWILIO_EMAIL_EVENT_WEBHOOK_TIMESTAMP")
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def verify(public_key, payload, signature, timestamp)
|
|
98
|
+
ew = SendGrid::EventWebhook.new
|
|
99
|
+
ec_public_key = ew.convert_public_key_to_ecdsa(public_key)
|
|
100
|
+
ew.verify_signature(ec_public_key, payload, signature, timestamp)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def skip_jruby
|
|
104
|
+
RUBY_PLATFORM == 'java'
|
|
105
|
+
end
|
|
@@ -4,7 +4,7 @@ describe SendGrid::MailSettingsDto do
|
|
|
4
4
|
let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
|
|
5
5
|
let(:mail_settings) { SendGrid::MailSettingsDto }
|
|
6
6
|
let(:setting_name) { 'bcc' }
|
|
7
|
-
let(:setting_params) { {email: Faker::Internet.email, enabled: rand(1..100).even?} }
|
|
7
|
+
let(:setting_params) { { email: Faker::Internet.email, enabled: rand(1..100).even? } }
|
|
8
8
|
|
|
9
9
|
it { should respond_to :bcc }
|
|
10
10
|
it { should respond_to :address_whitelist }
|
|
@@ -19,14 +19,14 @@ describe SendGrid::MailSettingsDto do
|
|
|
19
19
|
describe '.fetch' do
|
|
20
20
|
it 'calls get on sendgrid_client' do
|
|
21
21
|
args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
|
|
22
|
-
expect(mail_settings.fetch(args)).to be_a SendGrid::Response
|
|
22
|
+
expect(mail_settings.fetch(**args)).to be_a SendGrid::Response
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
describe '.update' do
|
|
27
27
|
it 'calls patch on sendgrid_client' do
|
|
28
28
|
args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
|
|
29
|
-
expect(mail_settings.update(args)).to be_a SendGrid::Response
|
|
29
|
+
expect(mail_settings.update(**args)).to be_a SendGrid::Response
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
end
|
|
@@ -4,21 +4,21 @@ describe SendGrid::PartnerSettingsDto do
|
|
|
4
4
|
let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
|
|
5
5
|
let(:partner_settings) { SendGrid::PartnerSettingsDto }
|
|
6
6
|
let(:setting_name) { 'new_relic' }
|
|
7
|
-
let(:setting_params) { {license_key: 'key', enabled: rand(1..100).even?} }
|
|
7
|
+
let(:setting_params) { { license_key: 'key', enabled: rand(1..100).even? } }
|
|
8
8
|
|
|
9
9
|
it { should respond_to :new_relic }
|
|
10
10
|
|
|
11
11
|
describe '.fetch' do
|
|
12
12
|
it 'calls get on sendgrid_client' do
|
|
13
13
|
args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
|
|
14
|
-
expect(partner_settings.fetch(args)).to be_a SendGrid::Response
|
|
14
|
+
expect(partner_settings.fetch(**args)).to be_a SendGrid::Response
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
describe '.update' do
|
|
19
19
|
it 'calls patch on sendgrid_client' do
|
|
20
20
|
args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
|
|
21
|
-
expect(partner_settings.update(args)).to be_a SendGrid::Response
|
|
21
|
+
expect(partner_settings.update(**args)).to be_a SendGrid::Response
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -18,8 +18,8 @@ describe SendGrid::Settings do
|
|
|
18
18
|
|
|
19
19
|
describe '.update_bcc' do
|
|
20
20
|
it 'updates bcc' do
|
|
21
|
-
bcc_response = settings.update_bcc(enabled: true, email:
|
|
21
|
+
bcc_response = settings.update_bcc(enabled: true, email: 'email@example.com')
|
|
22
22
|
expect(bcc_response).to be_a SendGrid::Response
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
|
-
end
|
|
25
|
+
end
|
|
@@ -4,7 +4,7 @@ describe SendGrid::TrackingSettingsDto do
|
|
|
4
4
|
let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
|
|
5
5
|
let(:tracking_settings) { SendGrid::TrackingSettingsDto }
|
|
6
6
|
let(:setting_name) { 'open_tracking' }
|
|
7
|
-
let(:setting_params) { {enabled: rand(1..100).even?} }
|
|
7
|
+
let(:setting_params) { { enabled: rand(1..100).even? } }
|
|
8
8
|
|
|
9
9
|
it { should respond_to :open_tracking }
|
|
10
10
|
it { should respond_to :click_tracking }
|
|
@@ -14,14 +14,14 @@ describe SendGrid::TrackingSettingsDto do
|
|
|
14
14
|
describe '.fetch' do
|
|
15
15
|
it 'calls get on sendgrid_client' do
|
|
16
16
|
args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
|
|
17
|
-
expect(tracking_settings.fetch(args)).to be_a SendGrid::Response
|
|
17
|
+
expect(tracking_settings.fetch(**args)).to be_a SendGrid::Response
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
describe '.update' do
|
|
22
22
|
it 'calls patch on sendgrid_client' do
|
|
23
23
|
args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
|
|
24
|
-
expect(tracking_settings.update(args)).to be_a SendGrid::Response
|
|
24
|
+
expect(tracking_settings.update(**args)).to be_a SendGrid::Response
|
|
25
25
|
end
|
|
26
26
|
end
|
|
27
27
|
end
|
|
@@ -4,21 +4,21 @@ describe SendGrid::UserSettingsDto do
|
|
|
4
4
|
let(:sendgrid_client) { SendGrid::API.new(api_key: 'fake_key').client }
|
|
5
5
|
let(:user_settings) { SendGrid::UserSettingsDto }
|
|
6
6
|
let(:setting_name) { 'enforced_tls' }
|
|
7
|
-
let(:setting_params) { {require_tls: rand(1..100).even?} }
|
|
7
|
+
let(:setting_params) { { require_tls: rand(1..100).even? } }
|
|
8
8
|
|
|
9
9
|
it { should respond_to :enforced_tls }
|
|
10
10
|
|
|
11
11
|
describe '.fetch' do
|
|
12
12
|
it 'calls get on sendgrid_client' do
|
|
13
13
|
args = { sendgrid_client: sendgrid_client, name: setting_name, query_params: {} }
|
|
14
|
-
expect(user_settings.fetch(args)).to be_a SendGrid::Response
|
|
14
|
+
expect(user_settings.fetch(**args)).to be_a SendGrid::Response
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
describe '.update' do
|
|
19
19
|
it 'calls patch on sendgrid_client' do
|
|
20
20
|
args = { sendgrid_client: sendgrid_client, name: setting_name, request_body: setting_params }
|
|
21
|
-
expect(user_settings.update(args)).to be_a SendGrid::Response
|
|
21
|
+
expect(user_settings.update(**args)).to be_a SendGrid::Response
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
end
|
|
@@ -7,37 +7,36 @@ describe SendGrid::EmailStats do
|
|
|
7
7
|
|
|
8
8
|
let(:sample_response) do
|
|
9
9
|
[{
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
{
|
|
10
|
+
'date' => '2017-10-01',
|
|
11
|
+
'stats' => [
|
|
12
|
+
{ 'metrics' =>
|
|
13
13
|
{
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
31
|
-
}
|
|
14
|
+
'blocks' => 101,
|
|
15
|
+
'bounce_drops' => 102,
|
|
16
|
+
'bounces' => 103,
|
|
17
|
+
'clicks' => 104,
|
|
18
|
+
'deferred' => 105,
|
|
19
|
+
'delivered' => 106,
|
|
20
|
+
'invalid_emails' => 107,
|
|
21
|
+
'opens' => 108,
|
|
22
|
+
'processed' => 109,
|
|
23
|
+
'requests' => 110,
|
|
24
|
+
'spam_report_drops' => 111,
|
|
25
|
+
'spam_reports' => 112,
|
|
26
|
+
'unique_clicks' => 113,
|
|
27
|
+
'unique_opens' => 114,
|
|
28
|
+
'unsubscribe_drops' => 115,
|
|
29
|
+
'unsubscribes' => 116
|
|
30
|
+
} }
|
|
32
31
|
]
|
|
33
32
|
}]
|
|
34
33
|
end
|
|
35
34
|
|
|
36
35
|
let(:error_response) do
|
|
37
36
|
{
|
|
38
|
-
|
|
37
|
+
'errors' => [
|
|
39
38
|
{
|
|
40
|
-
|
|
39
|
+
'message' => 'end_date should be a YYYY-MM-DD formatted date'
|
|
41
40
|
}
|
|
42
41
|
]
|
|
43
42
|
}
|
|
@@ -3,23 +3,23 @@ require 'spec_helper'
|
|
|
3
3
|
describe SendGrid::Metrics do
|
|
4
4
|
let(:params) do
|
|
5
5
|
{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
6
|
+
'date' => '2017-10-01',
|
|
7
|
+
'blocks' => 101,
|
|
8
|
+
'bounce_drops' => 102,
|
|
9
|
+
'bounces' => 103,
|
|
10
|
+
'clicks' => 104,
|
|
11
|
+
'deferred' => 105,
|
|
12
|
+
'delivered' => 106,
|
|
13
|
+
'invalid_emails' => 107,
|
|
14
|
+
'opens' => 108,
|
|
15
|
+
'processed' => 109,
|
|
16
|
+
'requests' => 110,
|
|
17
|
+
'spam_report_drops' => 111,
|
|
18
|
+
'spam_reports' => 112,
|
|
19
|
+
'unique_clicks' => 113,
|
|
20
|
+
'unique_opens' => 114,
|
|
21
|
+
'unsubscribe_drops' => 115,
|
|
22
|
+
'unsubscribes' => 116
|
|
23
23
|
}
|
|
24
24
|
end
|
|
25
25
|
|
|
@@ -33,14 +33,13 @@ describe SendGrid::Metrics do
|
|
|
33
33
|
expect(subject.date).to be_a Date
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
%w
|
|
36
|
+
%w[
|
|
37
37
|
blocks bounce_drops bounces clicks deferred delivered invalid_emails
|
|
38
38
|
opens processed requests spam_report_drops spam_reports unique_clicks
|
|
39
39
|
unique_opens unsubscribe_drops unsubscribes
|
|
40
|
-
|
|
40
|
+
].each do |attribute|
|
|
41
41
|
it "responds to #{attribute}" do
|
|
42
42
|
expect(subject).to respond_to(attribute.to_sym)
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
|
|
46
45
|
end
|
|
@@ -3,28 +3,27 @@ require 'spec_helper'
|
|
|
3
3
|
describe SendGrid::StatsResponse do
|
|
4
4
|
let(:params) do
|
|
5
5
|
[{
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
{
|
|
6
|
+
'date' => '2017-10-01',
|
|
7
|
+
'stats' => [
|
|
8
|
+
{ 'metrics' =>
|
|
9
9
|
{
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
}
|
|
10
|
+
'blocks' => 101,
|
|
11
|
+
'bounce_drops' => 102,
|
|
12
|
+
'bounces' => 103,
|
|
13
|
+
'clicks' => 104,
|
|
14
|
+
'deferred' => 105,
|
|
15
|
+
'delivered' => 106,
|
|
16
|
+
'invalid_emails' => 107,
|
|
17
|
+
'opens' => 108,
|
|
18
|
+
'processed' => 109,
|
|
19
|
+
'requests' => 110,
|
|
20
|
+
'spam_report_drops' => 111,
|
|
21
|
+
'spam_reports' => 112,
|
|
22
|
+
'unique_clicks' => 113,
|
|
23
|
+
'unique_opens' => 114,
|
|
24
|
+
'unsubscribe_drops' => 115,
|
|
25
|
+
'unsubscribes' => 116
|
|
26
|
+
} }
|
|
28
27
|
]
|
|
29
28
|
}]
|
|
30
29
|
end
|
|
@@ -51,9 +50,9 @@ describe SendGrid::StatsResponse do
|
|
|
51
50
|
context 'errors' do
|
|
52
51
|
let(:error_params) do
|
|
53
52
|
{
|
|
54
|
-
|
|
53
|
+
'errors' => [
|
|
55
54
|
{
|
|
56
|
-
|
|
55
|
+
'message' => 'end_date should be a YYYY-MM-DD formatted date'
|
|
57
56
|
}
|
|
58
57
|
]
|
|
59
58
|
}
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'simplecov'
|
|
2
|
+
SimpleCov.start
|
|
1
3
|
require 'rubygems'
|
|
2
4
|
require 'bundler/setup'
|
|
3
5
|
require 'pry'
|
|
@@ -7,4 +9,4 @@ RSpec.configure do |config|
|
|
|
7
9
|
Dir["#{File.dirname(__FILE__)}/../lib/sendgrid-ruby.rb"].sort.each { |ext| require ext }
|
|
8
10
|
|
|
9
11
|
config.color = true
|
|
10
|
-
end
|
|
12
|
+
end
|
|
Binary file
|
|
Binary file
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
require_relative "../../../../lib/sendgrid/helpers/mail/attachment"
|
|
3
2
|
include SendGrid
|
|
4
3
|
require "json"
|
|
5
4
|
require "minitest/autorun"
|
|
6
5
|
|
|
7
6
|
class TestAttachment < Minitest::Test
|
|
8
|
-
SAMPLE_INPUT = "
|
|
7
|
+
SAMPLE_INPUT = "Es blüht so grün wie Blüten blüh'n im Frühling
|
|
9
8
|
Es blüht so grün wie Blüten blüh'n im Frühling
|
|
10
9
|
Es blüht so grün wie Blüten blüh'n im Frühling
|
|
11
10
|
Es blüht so grün wie Blüten blüh'n im Frühling
|
|
12
11
|
Es blüht so grün wie Blüten blüh'n im Frühling
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
def setup
|
|
16
|
-
end
|
|
12
|
+
".force_encoding('UTF-8').encode
|
|
13
|
+
|
|
14
|
+
def setup; end
|
|
17
15
|
|
|
18
16
|
def test_io_enocding
|
|
19
17
|
attachment = Attachment.new
|
|
@@ -2,7 +2,6 @@ require_relative '../../../../lib/sendgrid/helpers/mail/mail'
|
|
|
2
2
|
require 'minitest/autorun'
|
|
3
3
|
|
|
4
4
|
class TestCategory < Minitest::Test
|
|
5
|
-
|
|
6
5
|
include SendGrid
|
|
7
6
|
|
|
8
7
|
def setup
|
|
@@ -23,5 +22,4 @@ class TestCategory < Minitest::Test
|
|
|
23
22
|
}
|
|
24
23
|
assert_equal @category.to_json, expected_json
|
|
25
24
|
end
|
|
26
|
-
|
|
27
25
|
end
|