tms_client 0.2.0 → 0.2.1
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/README.md +2 -1
- data/lib/tms_client/client.rb +27 -15
- data/lib/tms_client/connection.rb +19 -3
- data/lib/tms_client/errors.rb +17 -1
- data/lib/tms_client/logger.rb +1 -13
- data/lib/tms_client/resource/email_message.rb +6 -3
- data/lib/tms_client/version.rb +1 -1
- data/lib/tms_client.rb +0 -1
- data/spec/client_spec.rb +9 -1
- data/spec/email_message_spec.rb +66 -0
- data/spec/{message_spec.rb → sms_message_spec.rb} +0 -0
- data/spec/{messages_spec.rb → sms_messages_spec.rb} +0 -0
- metadata +10 -9
- data/lib/tms_client/request.rb +0 -17
data/README.md
CHANGED
@@ -55,7 +55,8 @@ message.get # <TMS::SmsMessage href=/messages/sms/87 attributes={..
|
|
55
55
|
|
56
56
|
```ruby
|
57
57
|
message = client.email_messages.build(:body=>'<p><a href="http://example.com">Visit here</a>',
|
58
|
-
:subject => 'Hey'
|
58
|
+
:subject => 'Hey',
|
59
|
+
:from_email => 'foo@example.com')
|
59
60
|
message.recipients.build(:email=>'example1@example.com')
|
60
61
|
message.recipients.build(:email=>'')
|
61
62
|
message.post # true
|
data/lib/tms_client/client.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
|
+
require 'logger'
|
1
2
|
# The client class to connect and talk to the TMS REST API.
|
2
3
|
class TMS::Client
|
3
4
|
include TMS::Util::HalLinkParser
|
4
5
|
include TMS::CoreExt
|
5
6
|
|
6
|
-
attr_accessor :connection, :href
|
7
|
+
attr_accessor :connection, :href, :api_root, :logger
|
7
8
|
|
8
9
|
DEFAULTS = {:api_root => 'http://localhost:3000', :logger => nil}.freeze
|
9
10
|
|
@@ -20,13 +21,14 @@ class TMS::Client
|
|
20
21
|
# :logger => Logger.new(STDOUT)})
|
21
22
|
#
|
22
23
|
def initialize(auth_token, options = DEFAULTS)
|
23
|
-
@api_root = options
|
24
|
-
|
24
|
+
@api_root = options.delete(:api_root)
|
25
|
+
@logger = options.delete(:logger) || setup_logging(options.delete(:debug))
|
26
|
+
connect!(auth_token, options)
|
25
27
|
discover!
|
26
28
|
end
|
27
29
|
|
28
|
-
def connect!(auth_token,
|
29
|
-
self.connection = TMS::Connection.new(:auth_token => auth_token, :api_root =>
|
30
|
+
def connect!(auth_token, options={})
|
31
|
+
self.connection = TMS::Connection.new({:auth_token => auth_token, :api_root => api_root, :logger => logger}.merge!(options))
|
30
32
|
end
|
31
33
|
|
32
34
|
def discover!
|
@@ -37,12 +39,14 @@ class TMS::Client
|
|
37
39
|
def get(href)
|
38
40
|
response = raw_connection.get(href)
|
39
41
|
case response.status
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
when 500..599
|
43
|
+
raise TMS::Request::Error.new(response.status)
|
44
|
+
when 401..499
|
45
|
+
raise TMS::Request::Error.new(response.status)
|
46
|
+
when 202
|
47
|
+
raise TMS::Request::InProgress.new(response.body['message'])
|
48
|
+
else
|
49
|
+
return response
|
46
50
|
end
|
47
51
|
end
|
48
52
|
|
@@ -65,10 +69,10 @@ class TMS::Client
|
|
65
69
|
def delete(href)
|
66
70
|
response = raw_connection.delete(href)
|
67
71
|
case response.status
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
+
when 200
|
73
|
+
return response
|
74
|
+
else
|
75
|
+
raise TMS::Request::Error.new(response.status)
|
72
76
|
end
|
73
77
|
end
|
74
78
|
|
@@ -80,4 +84,12 @@ class TMS::Client
|
|
80
84
|
self
|
81
85
|
end
|
82
86
|
|
87
|
+
private
|
88
|
+
|
89
|
+
def setup_logging(debug)
|
90
|
+
logger = Logger.new(STDOUT)
|
91
|
+
logger.level = debug ? Logger::DEBUG : Logger::INFO
|
92
|
+
logger
|
93
|
+
end
|
94
|
+
|
83
95
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
class TMS::Connection
|
2
|
-
attr_accessor :auth_token, :api_root, :connection, :logger
|
2
|
+
attr_accessor :auth_token, :api_root, :connection, :logger, :debug
|
3
3
|
|
4
4
|
def get(href)
|
5
5
|
resp = connection.get("#{href}.json")
|
@@ -12,8 +12,9 @@ class TMS::Connection
|
|
12
12
|
|
13
13
|
def initialize(opts={})
|
14
14
|
self.auth_token = opts[:auth_token]
|
15
|
-
self.api_root
|
16
|
-
self.logger
|
15
|
+
self.api_root = opts[:api_root]
|
16
|
+
self.logger = opts[:logger]
|
17
|
+
self.debug = opts[:debug]
|
17
18
|
setup_connection
|
18
19
|
end
|
19
20
|
|
@@ -21,10 +22,25 @@ class TMS::Connection
|
|
21
22
|
self.connection = Faraday.new(:url => self.api_root) do |faraday|
|
22
23
|
faraday.use TMS::Logger, self.logger if self.logger
|
23
24
|
faraday.request :json
|
25
|
+
setup_logging(faraday)
|
24
26
|
faraday.headers['X-AUTH-TOKEN'] = auth_token
|
25
27
|
faraday.headers[:user_agent] = "GovDelivery Ruby TMS::Client #{TMS::VERSION}"
|
26
28
|
faraday.response :json, :content_type => /\bjson$/
|
27
29
|
faraday.adapter :net_http
|
28
30
|
end
|
29
31
|
end
|
32
|
+
|
33
|
+
def setup_logging(faraday)
|
34
|
+
faraday.use FaradayMiddleware::Instrumentation, {:name => 'tms_client'}
|
35
|
+
ActiveSupport::Notifications.subscribe('tms_client') do |name, starts, ends, _, env|
|
36
|
+
duration = ends - starts
|
37
|
+
logger.info "#{env[:method].to_s.upcase.ljust(7)}#{env[:status].to_s.ljust(4)}#{env[:url]} (#{duration} seconds)"
|
38
|
+
logger.debug('response headers') { JSON.pretty_generate env[:response_headers] }
|
39
|
+
logger.debug('response body') { env[:body] }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def dump_headers(headers)
|
44
|
+
headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
|
45
|
+
end
|
30
46
|
end
|
data/lib/tms_client/errors.rb
CHANGED
@@ -1,6 +1,22 @@
|
|
1
1
|
module TMS
|
2
|
+
module Request
|
3
|
+
# The generic TMS error class
|
4
|
+
class Error < StandardError
|
5
|
+
attr_reader :code
|
6
|
+
|
7
|
+
def initialize(code)
|
8
|
+
super("HTTP Error: #{code}")
|
9
|
+
@code=code
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# Raised when a recipient list is still being constructed and a request is made to view the
|
14
|
+
# recipient list for a message.
|
15
|
+
class InProgress < StandardError;end
|
16
|
+
end
|
17
|
+
|
2
18
|
module Errors
|
3
|
-
class ServerError
|
19
|
+
class ServerError < StandardError
|
4
20
|
def initialize(response)
|
5
21
|
super("TMS client encountered a server error: #{response.status} \n#{response.body}")
|
6
22
|
end
|
data/lib/tms_client/logger.rb
CHANGED
@@ -13,22 +13,10 @@ module TMS #:nodoc:
|
|
13
13
|
def_delegators :@logger, :debug, :info, :warn, :error, :fatal
|
14
14
|
|
15
15
|
def call(env)
|
16
|
-
|
17
|
-
info "#{env[:method]} #{env[:url].to_s}"
|
18
|
-
debug('request') { dump_headers env[:request_headers] }
|
16
|
+
debug "performing #{env[:method].to_s.upcase.ljust(7)} #{env[:url]}"
|
19
17
|
super
|
20
18
|
end
|
21
19
|
|
22
|
-
def on_complete(env)
|
23
|
-
info('Status') { env[:status].to_s }
|
24
|
-
debug('response headers') { dump_headers env[:response_headers] }
|
25
|
-
debug('response body') { env[:body].inspect }
|
26
|
-
end
|
27
|
-
|
28
|
-
private
|
29
20
|
|
30
|
-
def dump_headers(headers)
|
31
|
-
headers.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
|
32
|
-
end
|
33
21
|
end
|
34
22
|
end
|
@@ -4,6 +4,7 @@ module TMS #:nodoc:
|
|
4
4
|
# the collection of recipients who clicked or opened the email.
|
5
5
|
#
|
6
6
|
# @attr from_name [String] The name of the person or entity sending the email.
|
7
|
+
# @attr from_email [String] The email adderess of the person or entity sending the email. Must be configured in TMS beforehand. Defaults to the account default from address.
|
7
8
|
# @attr subject [String] The subject of the email
|
8
9
|
# @attr body [String] The body of the email
|
9
10
|
# @attr open_tracking_enabled [Boolean] Whether to track opens on this message. Optional, defaults to true.
|
@@ -12,7 +13,9 @@ module TMS #:nodoc:
|
|
12
13
|
# The message-level macros are used when a recipient has no value for a given macro key.
|
13
14
|
#
|
14
15
|
# @example Sending a message
|
15
|
-
# email_message = client.email_messages.build(:subject => "Great news!",
|
16
|
+
# email_message = client.email_messages.build(:subject => "Great news!",
|
17
|
+
# :body => "You win! <a href='http://example.com/'>click here</a>.",
|
18
|
+
# :from_email => 'foo@example.com')
|
16
19
|
# email_message.recipients.build(:email => "john@example.com")
|
17
20
|
# email_message.recipients.build(:email => "jeff@example.com")
|
18
21
|
# email_message.post
|
@@ -38,8 +41,8 @@ module TMS #:nodoc:
|
|
38
41
|
class EmailMessage
|
39
42
|
include InstanceResource
|
40
43
|
|
41
|
-
# @!parse attr_accessor :body, :from_name, :subject, :open_tracking_enabled, :click_tracking_enabled, :macros
|
42
|
-
writeable_attributes :body, :from_name, :subject, :open_tracking_enabled, :click_tracking_enabled, :macros
|
44
|
+
# @!parse attr_accessor :body, :from_name, :from_email, :subject, :open_tracking_enabled, :click_tracking_enabled, :macros
|
45
|
+
writeable_attributes :body, :from_name, :from_email, :subject, :open_tracking_enabled, :click_tracking_enabled, :macros
|
43
46
|
|
44
47
|
# @!parse attr_reader :created_at, :status
|
45
48
|
readonly_attributes :created_at, :status
|
data/lib/tms_client/version.rb
CHANGED
data/lib/tms_client.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -2,11 +2,15 @@ require 'spec_helper'
|
|
2
2
|
describe TMS::Client do
|
3
3
|
context "creating a new client" do
|
4
4
|
before do
|
5
|
-
response = double('response', :status=>200, :body => {"_links" => [{"self" => "/"}, {"horse" => "/horses/new"}, {"rabbits" => "/rabbits"}]})
|
5
|
+
response = double('response', :status => 200, :body => {"_links" => [{"self" => "/"}, {"horse" => "/horses/new"}, {"rabbits" => "/rabbits"}]})
|
6
6
|
@raw_connection = double('raw_connection', :get => response)
|
7
7
|
@connection = TMS::Connection.stub(:new).and_return(double('connection', :connection => @raw_connection))
|
8
8
|
@client = TMS::Client.new('auth_token', :api_root => 'null_url')
|
9
9
|
end
|
10
|
+
it 'should set up logging' do
|
11
|
+
@client.logger.should_not be_nil
|
12
|
+
@client.logger.level.should eq(Logger::INFO)
|
13
|
+
end
|
10
14
|
it 'should discover endpoints for known services' do
|
11
15
|
@client.horse.should be_kind_of(TMS::Horse)
|
12
16
|
@client.rabbits.should be_kind_of(TMS::Rabbits)
|
@@ -15,6 +19,10 @@ describe TMS::Client do
|
|
15
19
|
@raw_connection.stub(:get).and_return(double('response', :status => 404, :body => {'message' => 'hi'}))
|
16
20
|
expect { @client.get('/blargh') }.to raise_error(TMS::Request::Error)
|
17
21
|
end
|
22
|
+
it 'should handle 5xx responses' do
|
23
|
+
@raw_connection.stub(:get).and_return(double('response', :status => 503, :body => {'message' => 'oops'}))
|
24
|
+
expect { @client.get('/blargh') }.to raise_error(TMS::Request::Error)
|
25
|
+
end
|
18
26
|
it 'should handle 202 responses' do
|
19
27
|
@raw_connection.stub(:get).and_return(double('response', :status => 202, :body => {'message' => 'hi'}))
|
20
28
|
expect { @client.get('/blargh') }.to raise_error(TMS::Request::InProgress)
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe TMS::EmailMessage do
|
4
|
+
context "creating a new message" do
|
5
|
+
let(:client) do
|
6
|
+
double('client')
|
7
|
+
end
|
8
|
+
before do
|
9
|
+
@message = TMS::EmailMessage.new(client, nil, {:body => '12345678',
|
10
|
+
:subject => 'blah',
|
11
|
+
:created_at => 'BAAAAAD',
|
12
|
+
:from_email => 'eric@evotest.govdelivery.com'})
|
13
|
+
end
|
14
|
+
it 'should not render readonly attrs in json hash' do
|
15
|
+
@message.to_json[:body].should == '12345678'
|
16
|
+
@message.to_json[:created_at].should == nil
|
17
|
+
end
|
18
|
+
it 'should initialize with attrs and collections' do
|
19
|
+
@message.body.should == '12345678'
|
20
|
+
@message.subject.should == 'blah'
|
21
|
+
@message.from_email.should == 'eric@evotest.govdelivery.com'
|
22
|
+
@message.recipients.class.should == TMS::EmailRecipients
|
23
|
+
end
|
24
|
+
it 'should post successfully' do
|
25
|
+
response = {:body => 'processed', :subject => 'blah', :from_email => 'eric@evotest.govdelivery.com',
|
26
|
+
:recipients => [{:email => 'billy@evotest.govdelivery.com'}], :created_at => 'time'}
|
27
|
+
@message.client.should_receive('post').with(@message).and_return(double('response', :status => 201, :body => response))
|
28
|
+
@message.post
|
29
|
+
@message.body.should == 'processed'
|
30
|
+
@message.created_at.should == 'time'
|
31
|
+
@message.recipients.class.should == TMS::EmailRecipients
|
32
|
+
@message.recipients.collection.first.class.should == TMS::EmailRecipient
|
33
|
+
end
|
34
|
+
it 'should handle errors' do
|
35
|
+
response = {'errors' => {:body => "can't be nil"}}
|
36
|
+
@message.client.should_receive('post').with(@message).and_return(double('response', :status => 422, :body => response))
|
37
|
+
@message.post
|
38
|
+
@message.body.should == '12345678'
|
39
|
+
@message.errors.should == {:body => "can't be nil"}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context 'an existing message' do
|
44
|
+
let(:client) do
|
45
|
+
double('client')
|
46
|
+
end
|
47
|
+
before do
|
48
|
+
# blank hash prevents the client from doing a GET in the initialize method
|
49
|
+
@message = TMS::EmailMessage.new(client, '/messages/99', {})
|
50
|
+
end
|
51
|
+
it 'should GET cleanly' do
|
52
|
+
response = {:body => 'processed',
|
53
|
+
:subject => 'hey',
|
54
|
+
:from_email => 'eric@evotest.govdelivery.com',
|
55
|
+
:recipients => [{:email => 'billy@evotest.govdelivery.com'}], :created_at => 'time'}
|
56
|
+
@message.client.should_receive('get').with(@message.href).and_return(double('response', :status => 200, :body => response))
|
57
|
+
@message.get
|
58
|
+
@message.body.should == 'processed'
|
59
|
+
@message.subject.should == 'hey'
|
60
|
+
@message.from_email.should == 'eric@evotest.govdelivery.com'
|
61
|
+
@message.created_at.should == 'time'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
end
|
File without changes
|
File without changes
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tms_client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: faraday
|
@@ -80,7 +80,6 @@ files:
|
|
80
80
|
- lib/tms_client/link_header.rb
|
81
81
|
- lib/tms_client/logger.rb
|
82
82
|
- lib/tms_client/mail/delivery_method.rb
|
83
|
-
- lib/tms_client/request.rb
|
84
83
|
- lib/tms_client/resource/collections.rb
|
85
84
|
- lib/tms_client/resource/command.rb
|
86
85
|
- lib/tms_client/resource/command_action.rb
|
@@ -100,13 +99,14 @@ files:
|
|
100
99
|
- lib/tms_client.rb
|
101
100
|
- spec/client_spec.rb
|
102
101
|
- spec/command_types_spec.rb
|
102
|
+
- spec/email_message_spec.rb
|
103
103
|
- spec/inbound_sms_messages_spec.rb
|
104
104
|
- spec/instance_resource_spec.rb
|
105
105
|
- spec/keyword_spec.rb
|
106
106
|
- spec/keywords_spec.rb
|
107
107
|
- spec/mail/delivery_method_spec.rb
|
108
|
-
- spec/
|
109
|
-
- spec/
|
108
|
+
- spec/sms_message_spec.rb
|
109
|
+
- spec/sms_messages_spec.rb
|
110
110
|
- spec/spec_helper.rb
|
111
111
|
- spec/tms_client_spec.rb
|
112
112
|
homepage: http://govdelivery.com
|
@@ -123,7 +123,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
123
|
version: '0'
|
124
124
|
segments:
|
125
125
|
- 0
|
126
|
-
hash:
|
126
|
+
hash: 2675598689048053801
|
127
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
128
128
|
none: false
|
129
129
|
requirements:
|
@@ -132,7 +132,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
132
132
|
version: '0'
|
133
133
|
segments:
|
134
134
|
- 0
|
135
|
-
hash:
|
135
|
+
hash: 2675598689048053801
|
136
136
|
requirements: []
|
137
137
|
rubyforge_project:
|
138
138
|
rubygems_version: 1.8.25
|
@@ -142,12 +142,13 @@ summary: A ruby client to interact with the GovDelivery TMS REST API.
|
|
142
142
|
test_files:
|
143
143
|
- spec/client_spec.rb
|
144
144
|
- spec/command_types_spec.rb
|
145
|
+
- spec/email_message_spec.rb
|
145
146
|
- spec/inbound_sms_messages_spec.rb
|
146
147
|
- spec/instance_resource_spec.rb
|
147
148
|
- spec/keyword_spec.rb
|
148
149
|
- spec/keywords_spec.rb
|
149
150
|
- spec/mail/delivery_method_spec.rb
|
150
|
-
- spec/
|
151
|
-
- spec/
|
151
|
+
- spec/sms_message_spec.rb
|
152
|
+
- spec/sms_messages_spec.rb
|
152
153
|
- spec/spec_helper.rb
|
153
154
|
- spec/tms_client_spec.rb
|
data/lib/tms_client/request.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
module TMS #:nodoc:
|
2
|
-
module Request
|
3
|
-
# The generic TMS error class
|
4
|
-
class Error < StandardError
|
5
|
-
attr_reader :code
|
6
|
-
|
7
|
-
def initialize(code)
|
8
|
-
super("HTTP Error: #{code}")
|
9
|
-
@code=code
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
# Raised when a recipient list is still being constructed and a request is made to view the
|
14
|
-
# recipient list for a message.
|
15
|
-
class InProgress < StandardError; end
|
16
|
-
end
|
17
|
-
end
|