sparkpost 0.1.2 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,5 @@
1
1
  require 'net/http'
2
2
  require 'uri'
3
- require 'http'
4
3
  require_relative '../core_extensions/object'
5
4
  require_relative 'request'
6
5
  require_relative 'exceptions'
@@ -12,49 +11,66 @@ module SparkPost
12
11
  def initialize(api_key, api_host)
13
12
  @api_key = api_key
14
13
  @api_host = api_host
14
+ @base_endpoint = "#{@api_host}/api/v1/transmissions"
15
15
  end
16
16
 
17
- def endpoint
18
- @api_host.concat('/api/v1/transmissions')
17
+ def send_payload(data = {})
18
+ # TODO: consider refactoring this into send_message in v2
19
+ request(endpoint, @api_key, data)
19
20
  end
20
21
 
21
22
  def send_message(to, from, subject, html_message = nil, **options)
22
- #todo add validations for to, from
23
- unless to.is_a?(Array)
24
- to = [to]
25
- end
23
+ # TODO: add validations for to, from
24
+ html_message = content_from(options, :html) || html_message
25
+ text_message = content_from(options, :text) || options[:text_message]
26
26
 
27
- if html_message.blank? && options[:text_message].blank?
28
- fail ArgumentError, 'Content missing. Either provide html_message or text_message in options parameter'
27
+ if html_message.blank? && text_message.blank?
28
+ raise ArgumentError, 'Content missing. Either provide html_message or
29
+ text_message in options parameter'
29
30
  end
30
31
 
31
- options.merge!(
32
- {
33
- recipients: prepare_recipients(to),
34
- content: {
35
- from: from,
36
- subject: subject,
37
- text: options['text_message'],
38
- html: html_message
39
- },
40
- options: {}
41
- }
42
- )
43
-
44
- request(endpoint, @api_key, options)
32
+ options_from_args = {
33
+ recipients: prepare_recipients(to),
34
+ content: {
35
+ from: from,
36
+ subject: subject,
37
+ text: options.delete(:text_message),
38
+ html: html_message
39
+ },
40
+ options: {}
41
+ }
42
+
43
+ options.merge!(options_from_args) { |_k, opts, _args| opts }
44
+ add_attachments(options)
45
+
46
+ send_payload(options)
45
47
  end
46
48
 
47
- private
48
49
  def prepare_recipients(recipients)
49
- recipients.map do |recipient|
50
- {
51
- address: {
52
- email: recipient
53
- }
54
- }
50
+ recipients = [recipients] unless recipients.is_a?(Array)
51
+ recipients.map { |recipient| prepare_recipient(recipient) }
52
+ end
53
+
54
+ private
55
+
56
+ def add_attachments(options)
57
+ if options[:attachments].present?
58
+ options[:content][:attachments] = options.delete(:attachments)
59
+ end
60
+ end
61
+
62
+ def prepare_recipient(recipient)
63
+ if recipient.is_a?(Hash)
64
+ raise ArgumentError,
65
+ "email missing - '#{recipient.inspect}'" unless recipient[:email]
66
+ { address: recipient }
67
+ else
68
+ { address: { email: recipient } }
55
69
  end
56
70
  end
57
71
 
72
+ def content_from(options, key)
73
+ (options || {}).fetch(:content, {}).fetch(key, nil)
74
+ end
58
75
  end
59
76
  end
60
-
@@ -1,3 +1,3 @@
1
1
  module SparkPost
2
- VERSION = '0.1.2'.freeze
2
+ VERSION = '0.1.4'.freeze
3
3
  end
data/sparkpost.gemspec CHANGED
@@ -4,25 +4,26 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require './lib/sparkpost/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "sparkpost"
7
+ spec.name = 'sparkpost'
8
8
  spec.version = SparkPost::VERSION
9
- spec.authors = ["SparkPost", "Aimee Knight", "Mohammad Hossain"]
10
- spec.email = "developers@sparkpost.com"
11
- spec.summary = "SparkPost Ruby API client"
12
- spec.homepage = "https://github.com/SparkPost/ruby-sparkpost"
13
- spec.license = "Apache-2.0"
9
+ spec.authors = ['SparkPost', 'Aimee Knight', 'Mohammad Hossain']
10
+ spec.email = 'developers@sparkpost.com'
11
+ spec.summary = 'SparkPost Ruby API client'
12
+ spec.homepage = 'https://github.com/SparkPost/ruby-sparkpost'
13
+ spec.license = 'Apache-2.0'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
16
16
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ["lib"]
18
+ spec.require_paths = ['lib']
19
19
 
20
20
  spec.add_dependency 'http', '0.9.8'
21
21
 
22
- spec.add_development_dependency "bundler", "~> 1.5"
23
- spec.add_development_dependency "rake"
24
- spec.add_development_dependency "rspec", "~> 3.3.0"
25
- spec.add_development_dependency "simplecov", "~> 0.11.1"
26
- spec.add_development_dependency "webmock", "~> 1.22.3"
27
- spec.add_development_dependency "coveralls"
22
+ spec.add_development_dependency 'bundler', '~> 1.5'
23
+ spec.add_development_dependency 'rake', '<11'
24
+ spec.add_development_dependency 'rspec', '~> 3.3.0'
25
+ spec.add_development_dependency 'simplecov', '~> 0.11.1'
26
+ spec.add_development_dependency 'webmock', '~> 1.22.3'
27
+ spec.add_development_dependency 'coveralls'
28
+ spec.add_development_dependency 'rubocop', '~> 0.37.2'
28
29
  end
@@ -1,39 +1,58 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe SparkPost::Transmission do
4
- describe '#initialize' do
4
+ describe '#initialize' do
5
5
  context 'when api key and host are passed'
6
6
  let(:client) { SparkPost::Client.new('123', 'http://sparkpost.com') }
7
7
 
8
8
  it { expect(client.instance_variables).to include(:@api_key) }
9
9
  it { expect(client.instance_variables).to include(:@api_host) }
10
10
  it { expect(client.instance_variable_get(:@api_key)).to eq('123') }
11
- it { expect(client.instance_variable_get(:@api_host)).to eq('http://sparkpost.com') }
11
+ it do
12
+ expect(client.instance_variable_get(:@api_host))
13
+ .to eq('http://sparkpost.com')
14
+ end
12
15
 
13
- context 'when api key not passed' do
14
- before do
15
- ENV['SPARKPOST_API_KEY'] = nil
16
- end
17
- it { expect {SparkPost::Client.new }.to raise_error(ArgumentError) }
16
+ context 'when api key not passed' do
17
+ before do
18
+ ENV['SPARKPOST_API_KEY'] = nil
19
+ end
20
+ it { expect { SparkPost::Client.new }.to raise_error(ArgumentError) }
18
21
  end
19
22
 
20
- context 'when api host not passed' do
21
- before do
22
- ENV['SPARKPOST_API_HOST'] = nil
23
- end
24
- it { expect(SparkPost::Client.new('abc').instance_variable_get(:@api_host)).to eq('https://api.sparkpost.com') }
25
- it { expect { SparkPost::Client.new('abc', nil) }.to raise_error(ArgumentError) }
23
+ context 'when api host not passed' do
24
+ before do
25
+ ENV['SPARKPOST_API_HOST'] = nil
26
+ end
27
+ it do
28
+ client = SparkPost::Client.new('abc')
29
+ expect(client.instance_variable_get(:@api_host))
30
+ .to eq('https://api.sparkpost.com')
31
+ end
32
+ it do
33
+ expect { SparkPost::Client.new('abc', nil) }
34
+ .to raise_error(ArgumentError)
35
+ end
26
36
  end
27
37
  end
28
38
 
29
- describe '#transmission' do
39
+ describe '#transmission' do
30
40
  let(:client) { SparkPost::Client.new('123', 'http://sparkpost.com') }
31
41
 
32
42
  it { expect(client.transmission).to be_kind_of(SparkPost::Transmission) }
33
43
 
34
- it 'returns same instances on subsequent call' do
35
- expect(client.transmission).to eq(client.transmission)
44
+ it 'returns same instances on subsequent call' do
45
+ expect(client.transmission).to eq(client.transmission)
36
46
  end
47
+ end
48
+
49
+ describe '#template' do
50
+ let(:client) { SparkPost::Client.new('123', 'http://sparkpost.com') }
51
+
52
+ it { expect(client.template).to be_kind_of(SparkPost::Template) }
37
53
 
54
+ it 'returns same instances on subsequent call' do
55
+ expect(client.template).to eq(client.template)
56
+ end
38
57
  end
39
- end
58
+ end
@@ -1,22 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
+ describe 'Object' do
4
+ describe '#blank?' do
5
+ it { expect(''.blank?).to be(true) }
6
+ it { expect(nil.blank?).to be(true) }
7
+ it { expect(true.blank?).to be(false) }
8
+ it { expect({}.blank?).to be(true) }
9
+ it { expect({}.blank?).to be(true) }
10
+ it { expect([].blank?).to be(true) }
11
+ end
3
12
 
4
- describe 'Object' do
5
- describe '#blank?' do
6
- it { expect(''.blank?).to be(true)}
7
- it { expect(nil.blank?).to be(true)}
8
- it { expect(true.blank?).to be(false)}
9
- it { expect(Hash.new.blank?).to be(true)}
10
- it { expect({}.blank?).to be(true)}
11
- it { expect([].blank?).to be(true)}
12
- end
13
-
14
- describe '#present?' do
15
- it { expect(''.present?).to be(false)}
16
- it { expect(nil.present?).to be(false)}
17
- it { expect(true.present?).to be(true)}
18
- it { expect(Hash.new.present?).to be(false)}
19
- it { expect({}.present?).to be(false)}
20
- it { expect([].present?).to be(false)}
21
- end
22
- end
13
+ describe '#present?' do
14
+ it { expect(''.present?).to be(false) }
15
+ it { expect(nil.present?).to be(false) }
16
+ it { expect(true.present?).to be(true) }
17
+ it { expect({}.present?).to be(false) }
18
+ it { expect({}.present?).to be(false) }
19
+ it { expect([].present?).to be(false) }
20
+ end
21
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe SparkPost::Helpers do
4
+ let(:helpers) { SparkPost::Helpers }
5
+
6
+ describe '#copy_value' do
7
+ context 'when source is empty' do
8
+ let(:src_hash) { {} }
9
+ let(:dst_hash) { { dkey: 'val' } }
10
+
11
+ copied_hash = { dkey: 'val' }
12
+
13
+ it 'does not copy values' do
14
+ helpers.copy_value(src_hash, :skey, dst_hash, :dkey)
15
+ expect(dst_hash).to eq(copied_hash)
16
+ end
17
+ end
18
+
19
+ context 'when source is not empty' do
20
+ let(:src_hash) { { skey: 'val' } }
21
+ let(:dst_hash) { {} }
22
+
23
+ copied_hash = { dkey: 'val' }
24
+
25
+ it 'copies values' do
26
+ helpers.copy_value(src_hash, :skey, dst_hash, :dkey)
27
+ expect(dst_hash).to eq(copied_hash)
28
+ end
29
+ end
30
+ end
31
+
32
+ describe '#deep_merge' do
33
+ context 'when source_hash and other_hash have different keys' do
34
+ let(:source_hash) { { key1: 'val1', key2: 'val2' } }
35
+ let(:other_hash) { { key3: 'val3', key4: 'val4' } }
36
+
37
+ merged_hash = {
38
+ key1: 'val1',
39
+ key2: 'val2',
40
+ key3: 'val3',
41
+ key4: 'val4'
42
+ }
43
+
44
+ it 'merges source_hash and other_hash' do
45
+ expect(helpers.deep_merge(source_hash, other_hash)).to eq(merged_hash)
46
+ end
47
+ end
48
+
49
+ context 'when other_hash has nil value' do
50
+ let(:source_hash) { { key1: 'val1', key2: 'val2' } }
51
+ let(:other_hash) { { key1: nil } }
52
+
53
+ merged_hash = {
54
+ key1: 'val1',
55
+ key2: 'val2'
56
+ }
57
+
58
+ it 'merges source_hash and other_hash' do
59
+ expect(helpers.deep_merge(source_hash, other_hash)).to eq(merged_hash)
60
+ end
61
+ end
62
+
63
+ context 'when source_hash has nil value' do
64
+ let(:source_hash) { { key1: nil } }
65
+ let(:other_hash) { { key1: 'val1', key2: 'val2' } }
66
+
67
+ merged_hash = {
68
+ key1: 'val1',
69
+ key2: 'val2'
70
+ }
71
+
72
+ it 'merges source_hash and other_hash' do
73
+ expect(helpers.deep_merge(source_hash, other_hash)).to eq(merged_hash)
74
+ end
75
+ end
76
+
77
+ context 'when source_hash and other_hash have nested hash' do
78
+ let(:source_hash) { { key1: { s1: 'sv1' } } }
79
+ let(:other_hash) { { key1: { s2: 'sv2' }, key2: 'val2' } }
80
+
81
+ merged_hash = {
82
+ key1: { s1: 'sv1', s2: 'sv2' },
83
+ key2: 'val2'
84
+ }
85
+
86
+ it 'merges source_hash and other_hash' do
87
+ expect(helpers.deep_merge(source_hash, other_hash)).to eq(merged_hash)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -1,26 +1,100 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  RSpec.describe SparkPost::Request do
4
- describe '#request' do
5
- api_url = 'https://api.sparkpost.com/api/'
6
-
7
- let(:api_key) { '123' }
8
- let(:request) { SparkPost::Request.request }
9
-
10
- context 'when was successful' do
11
- response = {results: {"total_rejected_recipients"=>0, "total_accepted_recipients"=>1, "id"=>"102238681582044821"} }
12
- before do
13
- stub_request(:post, api_url).to_return(body: response.to_json, status: 200)
14
- end
15
- it { expect(SparkPost::Request.request(api_url, '123', {})).to eq(response[:results]) }
16
- end
17
- context 'when was not successful' do
18
- response = {errors: {message: 'end of world'} }
19
- before do
20
- stub_request(:post, api_url).to_return(body: response.to_json, status: 500)
21
- end
22
-
23
- it { expect { SparkPost::Request.request(api_url, '123', {})}.to raise_error(SparkPost::DeliveryException).with_message(/end of world/) }
24
- end
4
+ describe '#request' do
5
+ api_url = 'https://api.sparkpost.com/api/'
6
+
7
+ let(:api_key) { '123' }
8
+ let(:request) { SparkPost::Request.request }
9
+
10
+ success_response = {
11
+ results: {
12
+ 'total_rejected_recipients' => 0,
13
+ 'total_accepted_recipients' => 1,
14
+ 'id' => '123456789123456789'
15
+ }
16
+ }
17
+
18
+ context 'when GET request was successful' do
19
+ before do
20
+ stub_request(:get, api_url).to_return(
21
+ body: JSON.generate(success_response),
22
+ status: 200)
23
+ end
24
+ it do
25
+ expect(SparkPost::Request.request(api_url, '123', {}, 'GET'))
26
+ .to eq(success_response[:results])
27
+ end
28
+ end
29
+
30
+ context 'when PUT request was successful' do
31
+ before do
32
+ stub_request(:put, api_url).to_return(
33
+ body: JSON.generate(success_response),
34
+ status: 200)
35
+ end
36
+ it do
37
+ expect(SparkPost::Request.request(api_url, '123', {}, 'PUT'))
38
+ .to eq(success_response[:results])
39
+ end
40
+ end
41
+
42
+ context 'when DELETE request was successful' do
43
+ before do
44
+ stub_request(:delete, api_url).to_return(
45
+ body: JSON.generate(success_response),
46
+ status: 200)
47
+ end
48
+ it do
49
+ expect(SparkPost::Request.request(api_url, '123', {}, 'DELETE'))
50
+ .to eq(success_response[:results])
51
+ end
52
+ end
53
+
54
+ context 'when POST request was successful' do
55
+ before do
56
+ stub_request(:post, api_url).to_return(
57
+ body: JSON.generate(success_response),
58
+ status: 200)
59
+ end
60
+ it do
61
+ expect(SparkPost::Request.request(api_url, '123', {}))
62
+ .to eq(success_response[:results])
63
+ end
64
+ end
65
+
66
+ context 'when request was not successful' do
67
+ response = { errors: { message: 'end of world' } }
68
+ before do
69
+ stub_request(:post, api_url).to_return(
70
+ body: JSON.generate(response),
71
+ status: 500)
72
+ end
73
+
74
+ it do
75
+ expect { SparkPost::Request.request(api_url, '123', {}) }
76
+ .to raise_error(SparkPost::DeliveryException).with_message(
77
+ /end of world/)
78
+ end
79
+ end
80
+
81
+ describe 'json encoding' do
82
+ api_url = 'https://api.sparkpost.com/api/'
83
+ before do
84
+ stub_request(:post, api_url).to_return(
85
+ body: JSON.generate({}),
86
+ status: 200)
87
+ end
88
+
89
+ it 'encodes hash to json' do
90
+ allow(JSON).to receive(:generate).with(foo: 'bar')
91
+ SparkPost::Request.request(api_url, '123', foo: 'bar')
92
+ end
93
+
94
+ it 'does not encode nil to json' do
95
+ expect(JSON).to_not receive(:generate)
96
+ SparkPost::Request.request(api_url, '123', nil)
97
+ end
25
98
  end
26
- end
99
+ end
100
+ end