sparkpost 0.1.2 → 0.1.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.
@@ -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