nexmo 1.3.0 → 2.0.0

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.
Files changed (6) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -83
  3. data/lib/nexmo.rb +62 -75
  4. data/nexmo.gemspec +2 -10
  5. data/spec/nexmo_spec.rb +129 -172
  6. metadata +4 -46
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ae52a9612e17e4e82d62b525f27b1d02523f6d34
4
- data.tar.gz: e0fb13b7e0989a6f591102ff5583120006df6270
3
+ metadata.gz: 47f16f5764c3fe417e459938495ca477c35fe795
4
+ data.tar.gz: ff55281f11a6bde0f430d0b532105055f4e11d81
5
5
  SHA512:
6
- metadata.gz: a9bbfbdf2791eff805283d71bad2812a0900b8e6afee3104e6387136112fe5d303f0557f2a35e09165e57a9e1ab7b693ccea95b7b07c8c79bafaed070be50fc1
7
- data.tar.gz: dc9656dd961d47e4a908077f0fb1b80f1b7fac12f4d410c75b7495f3a10b3ce1f7ee215e1f02c971f80dd6bf5ba529e7ca2fa4e40fc4f4e84ef443144c0cf645
6
+ metadata.gz: fbe03e55277356116df31c26682b2c0ba77adb28e34c854d6f9b7324095add975100e5ad527fa1f74e02e38c0669d78560939813537089c2f7409489001bd62d
7
+ data.tar.gz: 5fc3ff3f2db8e057f92d8910e2a4821319f5c61c0c3fa7b21cfdb3ab73457a8e9a518487ce33616e44f32f385a11476ff0ff1fec8b0d010f13a9fb9c754b2b8e
data/README.md CHANGED
@@ -11,99 +11,34 @@ Installation
11
11
  $ gem install nexmo
12
12
 
13
13
 
14
- Quick start (sending a message)
15
- -------------------------------
14
+ Sending a message
15
+ -----------------
16
16
 
17
- First you need to load up the gem and construct a Nexmo::Client object
18
- with your API credentials, like this:
17
+ Construct a Nexmo::Client object and use the #send_message method to
18
+ send a message. For example:
19
19
 
20
20
  ```ruby
21
21
  require 'nexmo'
22
22
 
23
- nexmo = Nexmo::Client.new('...API KEY...', '...API SECRET...')
24
- ```
25
-
26
- Then you have a choice. For a "fire and forget" approach to sending a message,
27
- use the `send_message!` method, like this:
23
+ nexmo = Nexmo::Client.new(key: 'YOUR API KEY', secret: 'YOUR API SECRET')
28
24
 
29
- ```ruby
30
- nexmo.send_message!({:to => '...NUMBER...', :from => 'Ruby', :text => 'Hello world'})
25
+ nexmo.send_message(from: 'Ruby', to: 'YOUR NUMBER', text: 'Hello world')
31
26
  ```
32
27
 
33
28
  This method call returns the message id if the message was sent successfully,
34
- or raises an exception if there was an error. If you need more robust error
35
- handling use the `send_message` method instead, like this:
36
-
37
- ```ruby
38
- response = nexmo.send_message({:to => '...NUMBER...', :from => 'Ruby', :text => 'Hello world'})
39
-
40
- if response.ok?
41
- # do something with response.object
42
- else
43
- # handle the error
44
- end
45
- ```
29
+ or raises an exception if there was an error. The Nexmo documentation contains
30
+ a [list of error codes](https://docs.nexmo.com/index.php/sms-api/send-message#response_code)
31
+ which may be useful for debugging exceptions.
46
32
 
47
- This method call returns a `Nexmo::Response` object, which wraps the underlying
48
- Net::HTTP response and adds a few convenience methods. Additional methods are
49
- also provided for managing your account and messages.
50
33
 
51
-
52
- Authenticating with OAuth (beta)
34
+ Production environment variables
53
35
  --------------------------------
54
36
 
55
- If you are building an app that needs access to Nexmo resources on behalf of
56
- other accounts then you will want to use OAuth to authenticate your requests.
57
- Authorizing access and fetching access tokens can be achieved using the
58
- [oauth gem](http://rubygems.org/gems/oauth) directly. You can then use an
59
- OAuth::AccessToken object together with a Nexmo::Client object to make calls
60
- to the API that are authenticated using OAuth. For example:
61
-
62
- ```ruby
63
- require 'nexmo'
64
- require 'oauth'
65
-
66
- nexmo = Nexmo::Client.new
67
- nexmo.oauth_access_token = OAuth::AccessToken.new(consumer, token, secret)
68
-
69
- response = nexmo.get_balance
70
-
71
- if response.ok?
72
- # do something with response.object
73
- else
74
- # handle the error
75
- end
76
- ```
77
-
78
- The OAuth::Consumer object should be pointed at `rest.nexmo.com` with the `:scheme` option set to `:header`, like this:
79
-
80
- ```ruby
81
- OAuth::Consumer.new(consumer_key, consumer_secret, {
82
- :site => 'https://rest.nexmo.com',
83
- :scheme => :header
84
- })
85
- ```
86
-
87
- Using the `:body` or `:query_string` authorization mechanisms is not supported.
88
-
89
-
90
- Custom response behaviour
91
- -------------------------
92
-
93
- You can customise the response handling by passing a block when constructing
94
- a Nexmo::Client object. For example, if you want to use an alternative JSON
95
- implementation to decode response bodies, you could do this:
96
-
97
- ```ruby
98
- nexmo = Nexmo::Client.new do |response|
99
- response.object = MultiJson.load(response.body) if response.ok? && response.json?
100
- response
101
- end
102
- ```
103
-
104
- This might also be useful if you prefer a different style of error handling
105
- (e.g. raising exceptions on error and returning the response object directly
106
- for 200 OK responses), if you need to log responses etc.
37
+ Best practice for storing credentials for external services in production is
38
+ to use environment variables, as described by [12factor.net/config](http://12factor.net/config).
39
+ Nexmo::Client defaults to extracting the api key/secret it needs from the
40
+ NEXMO_API_KEY and NEXMO_API_SECRET environment variables if the key/secret
41
+ options were not specified explicitly.
107
42
 
108
43
 
109
44
  Troubleshooting
@@ -111,7 +46,4 @@ Troubleshooting
111
46
 
112
47
  Remember that phone numbers should be specified in international format.
113
48
 
114
- The Nexmo documentation contains a [list of error codes](https://docs.nexmo.com/index.php/sms-api/send-message#response_code)
115
- which may be useful if you have problems sending a message.
116
-
117
49
  Please report all bugs/issues via the GitHub issue tracker.
data/lib/nexmo.rb CHANGED
@@ -1,20 +1,19 @@
1
1
  require 'net/http'
2
- require 'net/https' if RUBY_VERSION == '1.8.7'
3
2
  require 'json'
4
3
  require 'cgi'
5
4
 
6
5
  module Nexmo
6
+ class Error < StandardError; end
7
+
8
+ class AuthenticationError < Error; end
9
+
7
10
  class Client
8
- def initialize(key = ENV['NEXMO_API_KEY'], secret = ENV['NEXMO_API_SECRET'], options = {}, &block)
9
- @key, @secret, @block = key, secret, block
11
+ attr_accessor :key, :secret, :http
10
12
 
11
- if options.has_key?(:json)
12
- Kernel.warn '[nexmo] :json option is deprecated'
13
+ def initialize(options = {})
14
+ @key = options.fetch(:key) { ENV.fetch('NEXMO_API_KEY') }
13
15
 
14
- @json = options[:json]
15
- else
16
- @json = JSON
17
- end
16
+ @secret = options.fetch(:secret) { ENV.fetch('NEXMO_API_SECRET') }
18
17
 
19
18
  @host = options.fetch(:host) { 'rest.nexmo.com' }
20
19
 
@@ -23,27 +22,17 @@ module Nexmo
23
22
  @http.use_ssl = true
24
23
  end
25
24
 
26
- attr_accessor :key, :secret, :http, :oauth_access_token
27
-
28
25
  def send_message(params)
29
- post('/sms/json', params)
30
- end
31
-
32
- def send_message!(params)
33
- response = send_message(params)
26
+ response = post('/sms/json', params)
34
27
 
35
- if response.ok? && response.json?
36
- item = response.object['messages'].first
28
+ item = response['messages'].first
37
29
 
38
- status = item['status'].to_i
30
+ status = item['status'].to_i
39
31
 
40
- if status == 0
41
- item['message-id']
42
- else
43
- raise Error, "#{item['error-text']} (status=#{status})"
44
- end
32
+ if status == 0
33
+ item['message-id']
45
34
  else
46
- raise Error, "Unexpected HTTP response (code=#{response.code})"
35
+ raise Error, "#{item['error-text']} (status=#{status})"
47
36
  end
48
37
  end
49
38
 
@@ -91,32 +80,63 @@ module Nexmo
91
80
  get('/search/messages', Hash === params ? params : {:ids => Array(params)})
92
81
  end
93
82
 
83
+ def send_ussd_push_message(params)
84
+ post('/ussd/json', params)
85
+ end
86
+
87
+ def send_ussd_prompt_message(params)
88
+ post('/ussd-prompt/json', params)
89
+ end
90
+
91
+ def send_2fa_message(params)
92
+ post('/sc/us/2fa/json', params)
93
+ end
94
+
95
+ def send_event_alert_message(params)
96
+ post('/sc/us/alert/json', params)
97
+ end
98
+
99
+ def send_marketing_message(params)
100
+ post('/sc/us/marketing/json', params)
101
+ end
102
+
103
+ def initiate_call(params)
104
+ post('/call/json', params)
105
+ end
106
+
107
+ def initiate_tts_call(params)
108
+ post('/tts/json', params)
109
+ end
110
+
111
+ def initiate_tts_prompt_call(params)
112
+ post('/tts-prompt/json', params)
113
+ end
114
+
94
115
  private
95
116
 
96
117
  def get(path, params = {})
97
- http_response = if oauth_access_token
98
- oauth_access_token.get(request_uri(path, params))
99
- else
100
- @http.get(request_uri(path, params.merge(:api_key => @key, :api_secret => @secret)))
101
- end
102
-
103
- decode(http_response)
118
+ parse @http.get(request_uri(path, params.merge(:api_key => @key, :api_secret => @secret)))
104
119
  end
105
120
 
106
121
  def post(path, params)
107
- http_response = if oauth_access_token
108
- oauth_access_token.post(path, @json.dump(params), {'Content-Type' => 'application/json'})
109
- else
110
- @http.post(path, @json.dump(params.merge(:api_key => @key, :api_secret => @secret)), {'Content-Type' => 'application/json'})
111
- end
122
+ body = URI.encode_www_form(params.merge(:api_key => @key, :api_secret => @secret))
112
123
 
113
- decode(http_response)
124
+ parse @http.post(path, body, {'Content-Type' => 'application/x-www-form-urlencoded'})
114
125
  end
115
126
 
116
- def decode(http_response)
117
- response = Response.new(http_response, :json => @json)
118
-
119
- @block ? @block.call(response) : response
127
+ def parse(http_response)
128
+ case http_response
129
+ when Net::HTTPSuccess
130
+ if http_response['Content-Type'].split(';').first == 'application/json'
131
+ JSON.parse(http_response.body)
132
+ else
133
+ http_response.body
134
+ end
135
+ when Net::HTTPUnauthorized
136
+ raise AuthenticationError
137
+ else
138
+ raise Error, "Unexpected HTTP response (code=#{http_response.code})"
139
+ end
120
140
  end
121
141
 
122
142
  def request_uri(path, hash = {})
@@ -135,37 +155,4 @@ module Nexmo
135
155
  CGI.escape(component.to_s)
136
156
  end
137
157
  end
138
-
139
- class Response
140
- attr_writer :object
141
-
142
- def initialize(http_response, options = {})
143
- @http_response = http_response
144
-
145
- @json = options.fetch(:json) { JSON }
146
- end
147
-
148
- def respond_to_missing?(name, include_private = false)
149
- @http_response.respond_to?(name)
150
- end
151
-
152
- def method_missing(name, *args, &block)
153
- @http_response.send(name, *args, &block)
154
- end
155
-
156
- def ok?
157
- code.to_i == 200
158
- end
159
-
160
- def json?
161
- self['Content-Type'].split(';').first == 'application/json'
162
- end
163
-
164
- def object
165
- @object ||= @json.parse(body)
166
- end
167
- end
168
-
169
- class Error < StandardError
170
- end
171
158
  end
data/nexmo.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'nexmo'
3
- s.version = '1.3.0'
3
+ s.version = '2.0.0'
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.authors = ['Tim Craft']
6
6
  s.email = ['mail@timcraft.com']
@@ -9,14 +9,6 @@ Gem::Specification.new do |s|
9
9
  s.summary = 'See description'
10
10
  s.files = Dir.glob('{lib,spec}/**/*') + %w(README.md nexmo.gemspec)
11
11
  s.add_development_dependency('rake', '>= 0.9.3')
12
- s.add_development_dependency('mocha', '~> 0.13.2')
13
- s.add_development_dependency('oauth', '~> 0.4.7')
14
- s.add_development_dependency('faux', '~> 1.1.0')
15
- s.add_development_dependency('webmock', '~> 1.17.0')
12
+ s.add_development_dependency('webmock', '~> 1.18.0')
16
13
  s.require_path = 'lib'
17
-
18
- if RUBY_VERSION == '1.8.7'
19
- s.add_development_dependency('minitest', '~> 4.2.0')
20
- s.add_development_dependency('json', '~> 1.8.0')
21
- end
22
14
  end
data/spec/nexmo_spec.rb CHANGED
@@ -1,22 +1,24 @@
1
1
  require 'minitest/autorun'
2
2
  require 'webmock/minitest'
3
- require 'mocha/setup'
4
- require 'faux'
5
3
  require 'nexmo'
6
- require 'oauth'
7
- require 'json'
8
4
 
9
5
  describe 'Nexmo::Client' do
6
+ def json_response_body(content)
7
+ {headers: {'Content-Type' => 'application/json;charset=utf-8'}, body: content}
8
+ end
9
+
10
10
  before do
11
11
  @base_url = 'https://rest.nexmo.com'
12
12
 
13
- @json_object = {:body => /\{".+?":".+?"(,".+?":".+?")+\}/, :headers => {'Content-Type' => 'application/json'}}
13
+ @form_urlencoded_data = {body: /(.+?)=(.+?)(&(.+?)=(.+?))+/, headers: {'Content-Type' => 'application/x-www-form-urlencoded'}}
14
14
 
15
- @oauth_header = {'Authorization' => /\AOAuth .+\z/}
15
+ @json_response_body = json_response_body('{"key":"value"}')
16
+
17
+ @json_response_object = {'key' => 'value'}
16
18
 
17
19
  @example_message_hash = {:from => 'ruby', :to => 'number', :text => 'Hey!'}
18
20
 
19
- @client = Nexmo::Client.new('key', 'secret')
21
+ @client = Nexmo::Client.new(key: 'key', secret: 'secret')
20
22
  end
21
23
 
22
24
  describe 'http method' do
@@ -28,283 +30,238 @@ describe 'Nexmo::Client' do
28
30
  end
29
31
 
30
32
  describe 'send_message method' do
31
- it 'posts to the sms json resource and returns a response object' do
32
- stub_request(:post, "#@base_url/sms/json").with(@json_object)
33
-
34
- @client.send_message(@example_message_hash).must_be_instance_of(Nexmo::Response)
35
- end
36
- end
37
-
38
- describe 'send_message bang method' do
39
- before do
40
- @http_response = stub(:code => '200', :[] => 'application/json;charset=utf-8')
41
- end
42
-
43
33
  it 'posts to the sms json resource and returns the message id' do
44
- stub_request(:post, "#@base_url/sms/json").with(@json_object).to_return({
45
- :headers => {'Content-Type' => 'application/json'},
46
- :body => '{"messages":[{"status":0,"message-id":"id"}]}'
47
- })
48
-
49
- @client.send_message!(@example_message_hash).must_equal('id')
50
- end
34
+ response_body = json_response_body('{"messages":[{"status":0,"message-id":"id"}]}')
51
35
 
52
- it 'raises an exception if the response code is not expected' do
53
- stub_request(:post, "#@base_url/sms/json").with(@json_object).to_return(:status => 500)
36
+ stub_request(:post, "#@base_url/sms/json").with(@form_urlencoded_data).to_return(response_body)
54
37
 
55
- proc { @client.send_message!(@example_message_hash) }.must_raise(Nexmo::Error)
38
+ @client.send_message(@example_message_hash).must_equal('id')
56
39
  end
57
40
 
58
41
  it 'raises an exception if the response body contains an error' do
59
- stub_request(:post, "#@base_url/sms/json").with(@json_object).to_return({
60
- :headers => {'Content-Type' => 'application/json'},
61
- :body => '{"messages":[{"status":2,"error-text":"Missing from param"}]}'
62
- })
42
+ response_body = json_response_body('{"messages":[{"status":2,"error-text":"Missing from param"}]}')
43
+
44
+ stub_request(:post, "#@base_url/sms/json").with(@form_urlencoded_data).to_return(response_body)
63
45
 
64
- proc { @client.send_message!(@example_message_hash) }.must_raise(Nexmo::Error)
46
+ exception = proc { @client.send_message(@example_message_hash) }.must_raise(Nexmo::Error)
47
+
48
+ exception.message.must_include('Missing from param')
65
49
  end
66
50
  end
67
51
 
68
52
  describe 'get_balance method' do
69
- it 'fetches the account balance resource and returns a response object' do
70
- stub_request(:get, "#@base_url/account/get-balance?api_key=key&api_secret=secret")
53
+ it 'fetches the account balance resource and returns the response object' do
54
+ url = "#@base_url/account/get-balance?api_key=key&api_secret=secret"
55
+
56
+ stub_request(:get, url).to_return(@json_response_body)
71
57
 
72
- @client.get_balance.must_be_instance_of(Nexmo::Response)
58
+ @client.get_balance.must_equal(@json_response_object)
73
59
  end
74
60
  end
75
61
 
76
62
  describe 'get_country_pricing method' do
77
- it 'fetches the outbound pricing resource for the given country and returns a response object' do
78
- stub_request(:get, "#@base_url/account/get-pricing/outbound?api_key=key&api_secret=secret&country=CA")
63
+ it 'fetches the outbound pricing resource for the given country and returns the response object' do
64
+ url = "#@base_url/account/get-pricing/outbound?api_key=key&api_secret=secret&country=CA"
65
+
66
+ stub_request(:get, url).to_return(@json_response_body)
79
67
 
80
- @client.get_country_pricing(:CA).must_be_instance_of(Nexmo::Response)
68
+ @client.get_country_pricing(:CA).must_equal(@json_response_object)
81
69
  end
82
70
  end
83
71
 
84
72
  describe 'get_prefix_pricing method' do
85
- it 'fetches the outbound pricing resource for the given prefix and returns a response object' do
86
- stub_request(:get, "#@base_url/account/get-prefix-pricing/outbound?api_key=key&api_secret=secret&prefix=44")
73
+ it 'fetches the outbound pricing resource for the given prefix and returns the response object' do
74
+ url = "#@base_url/account/get-prefix-pricing/outbound?api_key=key&api_secret=secret&prefix=44"
87
75
 
88
- @client.get_prefix_pricing(44).must_be_instance_of(Nexmo::Response)
76
+ stub_request(:get, url).to_return(@json_response_body)
77
+
78
+ @client.get_prefix_pricing(44).must_equal(@json_response_object)
89
79
  end
90
80
  end
91
81
 
92
82
  describe 'get_account_numbers method' do
93
- it 'fetches the account numbers resource with the given parameters and returns a response object' do
94
- stub_request(:get, "#@base_url/account/numbers?api_key=key&api_secret=secret&size=25&pattern=33")
83
+ it 'fetches the account numbers resource with the given parameters and returns the response object' do
84
+ url = "#@base_url/account/numbers?api_key=key&api_secret=secret&size=25&pattern=33"
85
+
86
+ stub_request(:get, url).to_return(@json_response_body)
95
87
 
96
- @client.get_account_numbers(:size => 25, :pattern => 33).must_be_instance_of(Nexmo::Response)
88
+ @client.get_account_numbers(:size => 25, :pattern => 33).must_equal(@json_response_object)
97
89
  end
98
90
  end
99
91
 
100
92
  describe 'number_search method' do
101
- it 'fetches the number search resource for the given country with the given parameters and returns a response object' do
102
- stub_request(:get, "#@base_url/number/search?api_key=key&api_secret=secret&country=CA&size=25")
93
+ it 'fetches the number search resource for the given country with the given parameters and returns the response object' do
94
+ url = "#@base_url/number/search?api_key=key&api_secret=secret&country=CA&size=25"
103
95
 
104
- @client.number_search(:CA, :size => 25).must_be_instance_of(Nexmo::Response)
96
+ stub_request(:get, url).to_return(@json_response_body)
97
+
98
+ @client.number_search(:CA, :size => 25).must_equal(@json_response_object)
105
99
  end
106
100
  end
107
101
 
108
102
  describe 'buy_number method' do
109
- it 'purchases the number requested with the given parameters and returns a response object' do
110
- stub_request(:post, "#@base_url/number/buy").with(@json_object)
103
+ it 'purchases the number requested with the given parameters and returns the response object' do
104
+ url = "#@base_url/number/buy"
105
+
106
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
111
107
 
112
- @client.buy_number(:country => 'US', :msisdn => 'number').must_be_instance_of(Nexmo::Response)
108
+ @client.buy_number(:country => 'US', :msisdn => 'number').must_equal(@json_response_object)
113
109
  end
114
110
  end
115
111
 
116
112
  describe 'cancel_number method' do
117
- it 'cancels the number requested with the given parameters and returns a response object' do
118
- stub_request(:post, "#@base_url/number/cancel").with(@json_object)
113
+ it 'cancels the number requested with the given parameters and returns the response object' do
114
+ url = "#@base_url/number/cancel"
119
115
 
120
- @client.cancel_number(:country => 'US', :msisdn => 'number').must_be_instance_of(Nexmo::Response)
116
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
117
+
118
+ @client.cancel_number(:country => 'US', :msisdn => 'number').must_equal(@json_response_object)
121
119
  end
122
120
  end
123
121
 
124
122
  describe 'update_number method' do
125
- it 'updates the number requested with the given parameters and returns a response object' do
126
- stub_request(:post, "#@base_url/number/update").with(@json_object)
123
+ it 'updates the number requested with the given parameters and returns the response object' do
124
+ url = "#@base_url/number/update"
125
+
126
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
127
127
 
128
- @client.update_number(:country => 'US', :msisdn => 'number', :moHttpUrl => 'callback').must_be_instance_of(Nexmo::Response)
128
+ @client.update_number(:country => 'US', :msisdn => 'number', :moHttpUrl => 'callback').must_equal(@json_response_object)
129
129
  end
130
130
  end
131
131
 
132
132
  describe 'get_message method' do
133
- it 'fetches the message search resource for the given message id and returns a response object' do
134
- stub_request(:get, "#@base_url/search/message?api_key=key&api_secret=secret&id=00A0B0C0")
133
+ it 'fetches the message search resource for the given message id and returns the response object' do
134
+ url = "#@base_url/search/message?api_key=key&api_secret=secret&id=00A0B0C0"
135
135
 
136
- @client.get_message('00A0B0C0').must_be_instance_of(Nexmo::Response)
136
+ stub_request(:get, url).to_return(@json_response_body)
137
+
138
+ @client.get_message('00A0B0C0').must_equal(@json_response_object)
137
139
  end
138
140
  end
139
141
 
140
142
  describe 'get_message_rejections method' do
141
- it 'fetches the message rejections resource with the given parameters and returns a response object' do
142
- stub_request(:get, "#@base_url/search/rejections?api_key=key&api_secret=secret&date=YYYY-MM-DD")
143
+ it 'fetches the message rejections resource with the given parameters and returns the response object' do
144
+ url = "#@base_url/search/rejections?api_key=key&api_secret=secret&date=YYYY-MM-DD"
145
+
146
+ stub_request(:get, url).to_return(@json_response_body)
143
147
 
144
- @client.get_message_rejections(:date => 'YYYY-MM-DD').must_be_instance_of(Nexmo::Response)
148
+ @client.get_message_rejections(:date => 'YYYY-MM-DD').must_equal(@json_response_object)
145
149
  end
146
150
  end
147
151
 
148
152
  describe 'search_messages method' do
149
- it 'fetches the search messages resource with the given parameters and returns a response object' do
150
- stub_request(:get, "#@base_url/search/messages?api_key=key&api_secret=secret&date=YYYY-MM-DD&to=1234567890")
153
+ it 'fetches the search messages resource with the given parameters and returns the response object' do
154
+ url = "#@base_url/search/messages?api_key=key&api_secret=secret&date=YYYY-MM-DD&to=1234567890"
151
155
 
152
- @client.search_messages(:date => 'YYYY-MM-DD', :to => 1234567890).must_be_instance_of(Nexmo::Response)
156
+ stub_request(:get, url).to_return(@json_response_body)
157
+
158
+ @client.search_messages(:date => 'YYYY-MM-DD', :to => 1234567890).must_equal(@json_response_object)
153
159
  end
154
160
 
155
161
  it 'should encode a non hash argument as a list of ids' do
156
- stub_request(:get, "#@base_url/search/messages?api_key=key&api_secret=secret&ids=id1&ids=id2")
162
+ url = "#@base_url/search/messages?api_key=key&api_secret=secret&ids=id1&ids=id2"
163
+
164
+ stub_request(:get, url).to_return(@json_response_body)
157
165
 
158
166
  @client.search_messages(%w(id1 id2))
159
167
  end
160
168
  end
161
169
 
162
- describe 'when initialized with an oauth access token' do
163
- before do
164
- @oauth_consumer = OAuth::Consumer.new('key', 'secret', {:site => 'https://rest.nexmo.com', :scheme => :header})
170
+ describe 'send_ussd_push_message method' do
171
+ it 'posts to the ussd json resource and returns the response object' do
172
+ url = "#@base_url/ussd/json"
165
173
 
166
- @oauth_access_token = OAuth::AccessToken.new(@oauth_consumer, 'access_token', 'access_token_secret')
174
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
167
175
 
168
- @client = Nexmo::Client.new
169
-
170
- @client.oauth_access_token = @oauth_access_token
171
- end
172
-
173
- it 'makes get requests through the access token and returns a response object' do
174
- stub_request(:get, "#@base_url/account/get-pricing/outbound?country=CA").with(:headers => @oauth_header)
175
-
176
- @client.get_country_pricing(:CA).must_be_instance_of(Nexmo::Response)
176
+ @client.send_ussd_push_message(from: 'MyCompany20', to: '447525856424', text: 'Hello')
177
177
  end
178
+ end
178
179
 
179
- it 'makes post requests through the access token and returns a response object' do
180
- @json_object[:headers].merge!(@oauth_header)
180
+ describe 'send_ussd_prompt_message method' do
181
+ it 'posts to the ussd prompt json resource and returns the response object' do
182
+ url = "#@base_url/ussd-prompt/json"
181
183
 
182
- stub_request(:post, "#@base_url/sms/json").with(@json_object)
184
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
183
185
 
184
- @client.send_message(@example_message_hash).must_be_instance_of(Nexmo::Response)
186
+ @client.send_ussd_prompt_message(from: 'Nexmo long virtual number', to: '447525856424', text: 'Hello')
185
187
  end
186
188
  end
187
189
 
188
- describe 'when initialized with a different json implementation' do
189
- it 'emits a deprecation warning' do
190
- Kernel.expects(:warn).with(regexp_matches(/:json option is deprecated/))
190
+ describe 'send_2fa_message method' do
191
+ it 'posts to the short code two factor authentication json resource and returns the response object' do
192
+ url = "#@base_url/sc/us/2fa/json"
191
193
 
192
- @client = Nexmo::Client.new('key', 'secret', :json => stub)
193
- end
194
-
195
- describe 'send_message method' do
196
- it 'encodes the request body using the alternative json implementation' do
197
- Kernel.stubs(:warn)
198
-
199
- @json = faux(JSON)
200
-
201
- @json.expects(:dump).with(instance_of(Hash))
194
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
202
195
 
203
- @client = Nexmo::Client.new('key', 'secret', :json => @json)
204
-
205
- @client.http.stubs(:post)
206
-
207
- @client.send_message(@example_message_hash)
208
- end
196
+ @client.send_2fa_message(to: '16365553226', pin: 1234)
209
197
  end
210
198
  end
211
199
 
212
- describe 'when initialized with a block' do
213
- it 'calls the block for each response and returns the return value of the block' do
214
- @client = Nexmo::Client.new('key', 'secret') do |response|
215
- response.must_be_instance_of(Nexmo::Response)
200
+ describe 'send_event_alert_message method' do
201
+ it 'posts to the short code alert json resource and returns the response object' do
202
+ url = "#@base_url/sc/us/alert/json"
216
203
 
217
- :return_value
218
- end
204
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
219
205
 
220
- @client.http.stubs(:get).returns(stub)
221
-
222
- @client.get_balance.must_equal(:return_value)
206
+ @client.send_event_alert_message(to: '16365553226', server: 'host', link: 'http://example.com/')
223
207
  end
224
208
  end
225
209
 
226
- it 'provides an option for specifying a different hostname to connect to' do
227
- @client = Nexmo::Client.new('key', 'secret', host: 'rest-sandbox.nexmo.com')
228
-
229
- @client.http.address.must_equal('rest-sandbox.nexmo.com')
230
- end
231
- end
232
-
233
- describe 'Nexmo::Response' do
234
- before do
235
- @http_response = mock()
236
-
237
- @response = Nexmo::Response.new(@http_response)
238
- end
210
+ describe 'send_marketing_message method' do
211
+ it 'posts to the short code marketing json resource and returns the response object' do
212
+ url = "#@base_url/sc/us/marketing/json"
239
213
 
240
- it 'delegates to the underlying http response' do
241
- @http_response.expects(:code).returns('200')
214
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
242
215
 
243
- @response.must_respond_to(:code) unless RUBY_VERSION == '1.8.7'
244
- @response.code.must_equal('200')
216
+ @client.send_marketing_message(from: '666', to: '16365553226', keyword: 'NEXMO', text: 'Hello')
217
+ end
245
218
  end
246
219
 
247
- describe 'ok query method' do
248
- it 'returns true if the status code is 200' do
249
- @http_response.expects(:code).returns('200')
250
-
251
- @response.ok?.must_equal(true)
252
- end
220
+ describe 'initiate_call method' do
221
+ it 'posts to the call json resource and returns the response object' do
222
+ url = "#@base_url/call/json"
253
223
 
254
- it 'returns false otherwise' do
255
- @http_response.expects(:code).returns('400')
224
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
256
225
 
257
- @response.ok?.must_equal(false)
226
+ @client.initiate_call(to: '16365553226', answer_url: 'http://example.com/answer')
258
227
  end
259
228
  end
260
229
 
261
- describe 'json query method' do
262
- it 'returns true if the response has a json content type' do
263
- @http_response.expects(:[]).with('Content-Type').returns('application/json;charset=utf-8')
230
+ describe 'initiate_tts_call method' do
231
+ it 'posts to the tts json resource and returns the response object' do
232
+ url = "#@base_url/tts/json"
264
233
 
265
- @response.json?.must_equal(true)
266
- end
267
-
268
- it 'returns false otherwise' do
269
- @http_response.expects(:[]).with('Content-Type').returns('text/html')
234
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
270
235
 
271
- @response.json?.must_equal(false)
236
+ @client.initiate_tts_call(to: '16365553226', text: 'Hello')
272
237
  end
273
238
  end
274
239
 
275
- describe 'object method' do
276
- it 'decodes the response body as json and returns a hash' do
277
- @http_response.expects(:body).returns('{"value":0.0}')
240
+ describe 'initiate_tts_prompt_call method' do
241
+ it 'posts to the tts prompt json resource and returns the response object' do
242
+ url = "#@base_url/tts-prompt/json"
278
243
 
279
- @response.object.must_equal({'value' => 0})
244
+ stub_request(:post, url).with(@form_urlencoded_data).to_return(@json_response_body)
245
+
246
+ @client.initiate_tts_prompt_call(to: '16365553226', text: 'Hello', max_digits: 4, bye_text: 'Goodbye')
280
247
  end
281
248
  end
282
249
 
283
- describe 'object equals method' do
284
- it 'sets the object to be returned by the object method' do
285
- @object = stub
286
-
287
- @response.object = @object
250
+ it 'raises an exception if the response code is not 2xx' do
251
+ stub_request(:post, "#@base_url/sms/json").with(@form_urlencoded_data).to_return(status: 500)
288
252
 
289
- @response.object.must_equal(@object)
290
- end
253
+ proc { @client.send_message(@example_message_hash) }.must_raise(Nexmo::Error)
291
254
  end
292
255
 
293
- describe 'when initialized with a different json implementation' do
294
- before do
295
- @json = faux(JSON)
296
-
297
- @response = Nexmo::Response.new(@http_response, :json => @json)
298
- end
256
+ it 'raises an authentication error exception if the response code is 401' do
257
+ stub_request(:post, "#@base_url/sms/json").with(@form_urlencoded_data).to_return(status: 401)
299
258
 
300
- describe 'object method' do
301
- it 'decodes the response body using the alternative json implementation' do
302
- @json.expects(:parse).with('{"value":0.0}')
259
+ proc { @client.send_message(@example_message_hash) }.must_raise(Nexmo::AuthenticationError)
260
+ end
303
261
 
304
- @http_response.stubs(:body).returns('{"value":0.0}')
262
+ it 'provides an option for specifying a different hostname to connect to' do
263
+ @client = Nexmo::Client.new(key: 'key', secret: 'secret', host: 'rest-sandbox.nexmo.com')
305
264
 
306
- @response.object
307
- end
308
- end
265
+ @client.http.address.must_equal('rest-sandbox.nexmo.com')
309
266
  end
310
267
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nexmo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Craft
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-22 00:00:00.000000000 Z
11
+ date: 2014-07-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -24,62 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.3
27
- - !ruby/object:Gem::Dependency
28
- name: mocha
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: 0.13.2
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: 0.13.2
41
- - !ruby/object:Gem::Dependency
42
- name: oauth
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: 0.4.7
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: 0.4.7
55
- - !ruby/object:Gem::Dependency
56
- name: faux
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: 1.1.0
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: 1.1.0
69
27
  - !ruby/object:Gem::Dependency
70
28
  name: webmock
71
29
  requirement: !ruby/object:Gem::Requirement
72
30
  requirements:
73
31
  - - "~>"
74
32
  - !ruby/object:Gem::Version
75
- version: 1.17.0
33
+ version: 1.18.0
76
34
  type: :development
77
35
  prerelease: false
78
36
  version_requirements: !ruby/object:Gem::Requirement
79
37
  requirements:
80
38
  - - "~>"
81
39
  - !ruby/object:Gem::Version
82
- version: 1.17.0
40
+ version: 1.18.0
83
41
  description: A Ruby wrapper for the Nexmo API
84
42
  email:
85
43
  - mail@timcraft.com