mollie-sms 0.2.1 → 1.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.
@@ -0,0 +1,104 @@
1
+ A Ruby client that allows you to send SMS messages via
2
+ {http://www.mollie.nl/sms-diensten/sms-gateway Mollie.nl}.
3
+
4
+ See {Mollie::SMS} for the API documentation. Or, if you are reading this as
5
+ plain text, on {http://rdoc.info/projects/Fingertips/Mollie-SMS rdoc.info}.
6
+
7
+ See the Mollie.nl API
8
+ {http://www.mollie.nl/support/documentatie/sms-diensten/sms/http/en documentation}
9
+ for more info.
10
+
11
+ *Note* that it currently only does what we need, for our app, at this point in
12
+ time. Which means that it connects to the webservice via SSL, and only sends a
13
+ message to *one* recipient at a time. Finally, it assumes ActiveSupport is
14
+ available for XML parsing. (A patch that adds a fallback, to REXML, is much
15
+ appreciated.)
16
+
17
+ = Install
18
+
19
+ $ gem install mollie-sms
20
+
21
+ Or if you have a checkout of the source and have installed Jeweler:
22
+
23
+ $ rake install
24
+
25
+ = Configuration
26
+
27
+ The minimum required settings are:
28
+ * {Mollie::SMS.username username}
29
+ * {Mollie::SMS.password password}
30
+ * {Mollie::SMS.originator originator}
31
+
32
+ For example, a Rails initializer might look like:
33
+
34
+ module Mollie
35
+ SMS.username = 'Fingertips'
36
+ SMS.password = 'secret'
37
+ SMS.originator = 'fngtps.nl'
38
+ end
39
+
40
+ = Examples
41
+
42
+ == Normal usage
43
+
44
+ require 'mollie/sms'
45
+
46
+ sms = Mollie::SMS.new('+31681664814', 'You have won a bowl of chicken noodle soup!')
47
+ => #<Mollie::SMS from: <fngtps.nl> to: <+31681664814> body: "You have won a bowl of chicken noodle soup!">
48
+
49
+ response = sms.deliver # => #<Mollie::SMS::Response succeeded (10) `Message successfully sent.'>
50
+
51
+ response.success? # => true
52
+ response.result_code # => 10
53
+ response.message # => "Message successfully sent."
54
+
55
+ == Test usage
56
+
57
+ require 'mollie/sms'
58
+ require 'mollie/sms/test_helper'
59
+
60
+ Mollie::SMS.http_failure!
61
+
62
+ response = sms.deliver # => #<Mollie::SMS::Response failed (400) `[HTTP: 400] Bad request'>
63
+ response.success? # => false
64
+ response.result_code # => 400
65
+ response.message # => "[HTTP: 400] Bad request"
66
+
67
+ Mollie::SMS.gateway_failure! # => #<Mollie::SMS::Response failed (20) `No username given.'>
68
+
69
+ response = sms.deliver # => #<Mollie::SMS::Response failed (20) `No username given.'>
70
+ response.success? # => false
71
+ response.result_code # => 20
72
+ response.message # => "No username given."
73
+
74
+ Mollie::SMS.deliveries
75
+ => [#<Mollie::SMS from: <fngtps.nl> to: <+31681664814> body: "You have won a bowl of chicken noodle soup!">,
76
+ #<Mollie::SMS from: <fngtps.nl> to: <+31681664814> body: "You have won a bowl of chicken noodle soup!">]
77
+
78
+ = Rails
79
+
80
+ If you are using Rails and load the Mollie::SMS gem, it will automatically
81
+ require the test helper in test mode.
82
+
83
+ It also requires the test helper in development mode, so no actual SMS
84
+ messages can be send. Instead, the messages are logged to the
85
+ development.log.
86
+
87
+ = Contributing
88
+
89
+ Once you've made your great commits:
90
+
91
+ 1. {http://help.github.com/forking Fork} Mollie-SMS
92
+ 2. Create a topic branch
93
+ git checkout -b my_branch
94
+ 3. Push to your branch
95
+ git push origin my_branch
96
+ 4. Create an {http://github.com/Fingertips/Mollie-SMS/issues issue} with a link
97
+ to your branch
98
+ 5. That's it!
99
+
100
+ = Copyright
101
+
102
+ Copyright (c) 2010 Eloy Duran, Fingertips <eloy@fngtps.com>
103
+
104
+ This software is MIT licensed. See {file:LICENSE} for more info.
data/Rakefile CHANGED
@@ -5,8 +5,18 @@ task :spec do
5
5
  sh "ruby ./spec/functional_sms_deliver_spec.rb"
6
6
  end
7
7
 
8
+ desc "Run the specs with Kicker"
9
+ task :kick do
10
+ sh "kicker -c -e rake"
11
+ end
12
+
8
13
  task :default => :spec
9
14
 
15
+ desc "Generate the docs with YARD"
16
+ task :doc do ||
17
+ sh "yardoc - README.rdoc LICENSE"
18
+ end
19
+
10
20
  begin
11
21
  require 'rubygems'
12
22
  require 'jeweler'
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.1
1
+ 1.0.0
@@ -8,10 +8,56 @@ rescue LoadError
8
8
  end
9
9
  require "active_support"
10
10
 
11
+ # The namespace for the Mollie.nl webservices.
12
+ #
13
+ # @see Mollie::SMS
11
14
  module Mollie
15
+ # A class that allows you to send SMS messages through the Mollie.nl SMS
16
+ # webservice.
17
+ #
18
+ # See the {file:README.rdoc README} for examples on how to use this.
19
+ #
12
20
  class SMS
21
+ # A collection of exception classes raised by Mollie::SMS.
22
+ module Exceptions
23
+ # The base class for Mollie::SMS exceptions.
24
+ class StandardError < ::StandardError; end
25
+
26
+ # The exception class which is used to indicate a validation error of one
27
+ # of the {SMS#params parameters} that would be send to the gateway.
28
+ class ValidationError < StandardError; end
29
+
30
+ # The exception class which is used to indicate a delivery failure, when
31
+ # the {SMS#deliver!} method is used and delivery fails.
32
+ class DeliveryFailure < StandardError
33
+ # @return [SMS] The Mollie::SMS instance.
34
+ attr_reader :sms
35
+
36
+ # @return [Response] The Mollie::SMS::Response instance.
37
+ attr_reader :response
38
+
39
+ # @param [SMS] sms The Mollie::SMS instance.
40
+ # @param [Response] response The Mollie::SMS::Response instance.
41
+ def initialize(sms, response)
42
+ @sms, @response = sms, response
43
+ end
44
+
45
+ # @return [String] A string representation of the exception.
46
+ def message
47
+ "(#{@response.message}) #{@sms.to_s}"
48
+ end
49
+ end
50
+ end
51
+
52
+ # The SSL URI to which the parameters of a SMS are posted.
53
+ #
54
+ # Note that the certificate is *not* verified.
13
55
  GATEWAY_URI = URI.parse("https://secure.mollie.nl/xml/sms")
14
56
 
57
+ # The possible values that indicate which {SMS.gateway= SMS gateway} should
58
+ # be used.
59
+ #
60
+ # @see http://www.mollie.nl/sms-diensten/sms-gateway/gateways
15
61
  GATEWAYS = {
16
62
  'basic' => '2',
17
63
  'business' => '4',
@@ -19,31 +65,69 @@ module Mollie
19
65
  'landline' => '8'
20
66
  }
21
67
 
22
- class StandardError < ::StandardError; end
23
- class ValidationError < StandardError; end
24
- class MissingRequiredParam < StandardError; end
25
-
26
- class DeliveryFailure < StandardError
27
- attr_reader :sms, :response
28
-
29
- def initialize(sms, response)
30
- @sms, @response = sms, response
31
- end
32
-
33
- def message
34
- "(#{@response.message}) #{@sms.to_s}"
35
- end
36
- end
37
-
68
+ # A list of paramaters that *must* to be included in the
69
+ # {SMS#params parameters} send to the gateway.
38
70
  REQUIRED_PARAMS = %w{ username md5_password originator gateway charset type recipients message }
39
71
 
40
72
  class << self
41
- attr_accessor :username, :password, :originator, :charset, :type, :gateway
73
+ # @return [String] Your username for the Mollie.nl SMS webservice.
74
+ attr_accessor :username
42
75
 
76
+ # @return [String] A MD5 hashed version of your password for the
77
+ # Mollie.nl SMS webservice.
78
+ attr_reader :password
43
79
  def password=(password)
44
80
  @password = Digest::MD5.hexdigest(password)
45
81
  end
46
82
 
83
+ # The number, or display name, that will be used to indicate the
84
+ # originator of a message.
85
+ #
86
+ # It should be upto either fourteen numerical characters, or eleven
87
+ # alphanumerical characters.
88
+ #
89
+ # @see SMS#validate_params!
90
+ #
91
+ # @return [String] The originator
92
+ attr_accessor :originator
93
+
94
+ # @return [String] A character set name, describing the message’s body
95
+ # encoding. Defaults to ‘UTF-8’.
96
+ attr_accessor :charset
97
+
98
+ # The type of messages that will be send. Possible values are:
99
+ # * normal
100
+ # * wappush
101
+ # * vcard
102
+ # * flash
103
+ # * binary
104
+ # * long
105
+ #
106
+ # Defaults to ‘normal’
107
+ #
108
+ # @return [String] The message type.
109
+ attr_accessor :type
110
+
111
+ # The gateway that should be used to send messages. Possible values are:
112
+ # * {GATEWAYS GATEWAYS['basic']}
113
+ # * {GATEWAYS GATEWAYS['business']}
114
+ # * {GATEWAYS GATEWAYS['business+']}
115
+ # * {GATEWAYS GATEWAYS['landline']}
116
+ #
117
+ # Defaults to ‘basic’.
118
+ #
119
+ # @see http://www.mollie.nl/sms-diensten/sms-gateway/gateways
120
+ #
121
+ # @return [String] The gateway ID.
122
+ attr_accessor :gateway
123
+
124
+ # Returns the default parameters that will be we merged with each
125
+ # instance’s params.
126
+ #
127
+ # This includes +username+, +md5_password+, +originator+, +gateway+,
128
+ # +charset+, and +type+.
129
+ #
130
+ # @return [Hash]
47
131
  def default_params
48
132
  {
49
133
  'username' => @username,
@@ -60,42 +144,78 @@ module Mollie
60
144
  self.type = 'normal'
61
145
  self.gateway = GATEWAYS['basic']
62
146
 
147
+ # @return [Hash] The parameters that will be send to the gateway.
63
148
  attr_reader :params
64
149
 
150
+ # Initializes a new Mollie::SMS instance.
151
+ #
152
+ # You can either specify the recipient’s telephone number and message
153
+ # body here, or later on through the accessors for these attributes.
154
+ #
155
+ # @param [String] telephone_number The recipient’s telephone number.
156
+ #
157
+ # @param [String] body The message body.
158
+ #
159
+ # @param [Hash] extra_params Optional parameters that are to be merged with
160
+ # the {SMS.default_params default parameters}.
65
161
  def initialize(telephone_number = nil, body = nil, extra_params = {})
66
162
  @params = self.class.default_params.merge(extra_params)
67
163
  self.telephone_number = telephone_number if telephone_number
68
164
  self.body = body if body
69
165
  end
70
166
 
167
+ # @return [String] The recipient’s telephone number.
71
168
  def telephone_number
72
169
  @params['recipients']
73
170
  end
74
171
 
172
+ # Assigns the recipient’s telephone number.
173
+ #
174
+ # @param [String] telephone_number The recipient’s telephone number.
175
+ # @return [String] The recipient’s telephone number.
75
176
  def telephone_number=(telephone_number)
76
177
  @params['recipients'] = telephone_number
77
178
  end
78
179
 
180
+ # @return [String] The message body.
79
181
  def body
80
182
  @params['message']
81
183
  end
82
184
 
185
+ # Assigns the message’s body.
186
+ #
187
+ # @param [String] body The message’s body.
188
+ # @return [String] The message’s body.
83
189
  def body=(body)
84
190
  @params['message'] = body
85
191
  end
86
192
 
193
+ # Compares whether or not this and the +other+ Mollie::SMS instance are
194
+ # equal in recipient, body, and other parameters.
195
+ #
196
+ # @param [SMS] other The Mollie::SMS instance to compare against.
197
+ # @return [Boolean]
87
198
  def ==(other)
88
199
  other.is_a?(SMS) && other.params == params
89
200
  end
90
201
 
202
+ # @return [String] A string representation of this instance.
91
203
  def to_s
92
204
  %{from: <#{params['originator']}> to: <#{telephone_number}> body: "#{body}"}
93
205
  end
94
206
 
207
+ # @return [String] A `inspect' string representation of this instance.
95
208
  def inspect
96
209
  %{#<#{self.class.name} #{to_s}>}
97
210
  end
98
211
 
212
+ # Posts the {#params parameters} to the gateway, through SSL.
213
+ #
214
+ # The params are validated before attempting to post them.
215
+ # @see #validate_params!
216
+ #
217
+ # @return [Response] A response object which encapsulates the result of the
218
+ # request.
99
219
  def deliver
100
220
  validate_params!
101
221
 
@@ -103,60 +223,120 @@ module Mollie
103
223
  post.form_data = params
104
224
  request = Net::HTTP.new(GATEWAY_URI.host, GATEWAY_URI.port)
105
225
  request.use_ssl = true
226
+ request.verify_mode = OpenSSL::SSL::VERIFY_NONE
106
227
  request.start do |http|
107
228
  response = http.request(post)
108
229
  Response.new(response)
109
230
  end
110
231
  end
111
232
 
233
+ # Posts the {#params parameters} through {#deliver}, but raises a
234
+ # DeliveryFailure in case the request fails.
235
+ #
236
+ # This happens if an HTTP error occurs, or the gateway didn’t accept the
237
+ # {#params parameters}.
238
+ #
239
+ # @return [Response] Upon success, a response object which encapsulates the
240
+ # result of the request.
241
+ #
242
+ # @raise [DeliveryFailure] An exception which encapsulates this {SMS SMS}
243
+ # instance and the {Response} object.
112
244
  def deliver!
113
245
  response = deliver
114
- raise DeliveryFailure.new(self, response) unless response.success?
246
+ raise Exceptions::DeliveryFailure.new(self, response) unless response.success?
115
247
  response
116
248
  end
117
249
 
250
+ # Checks if all {REQUIRED_PARAMS required parameters} are present and if
251
+ # the {SMS.originator} is of the right size.
252
+ #
253
+ # @see SMS.originator
254
+ #
255
+ # @raise [ValidationError] If any of the validations fail.
256
+ #
257
+ # @return [nil]
118
258
  def validate_params!
119
259
  params.slice(*REQUIRED_PARAMS).each do |key, value|
120
- raise MissingRequiredParam, "The required parameter `#{key}' is missing." if value.blank?
260
+ raise Exceptions::ValidationError, "The required parameter `#{key}' is missing." if value.blank?
121
261
  end
122
262
 
123
263
  originator = params['originator']
124
264
  if originator =~ /^\d+$/
125
265
  if originator.size > 14
126
- raise ValidationError, "Originator may have a maximimun of 14 numerical characters."
266
+ raise Exceptions::ValidationError, "Originator may have a maximimun of 14 numerical characters."
127
267
  end
128
268
  elsif originator.size > 11
129
- raise ValidationError, "Originator may have a maximimun of 11 alphanumerical characters."
269
+ raise Exceptions::ValidationError, "Originator may have a maximimun of 11 alphanumerical characters."
130
270
  end
131
271
  end
132
272
 
273
+ # This class encapsulates the HTTP response and the response from the
274
+ # gateway. Put shortly, instances of this class return whether or not a SMS
275
+ # message has been delivered.
133
276
  class Response
277
+ # @return [Net::HTTPResponse] The raw HTTP response object.
134
278
  attr_reader :http_response
135
279
 
280
+ # Initializes a new Mollie::SMS::Response instance.
281
+ #
282
+ # @param [Net::HTTPResponse] http_response The HTTP response object.
136
283
  def initialize(http_response)
137
284
  @http_response = http_response
138
285
  end
139
286
 
287
+ # @return [Hash] The response parameters from the gateway. Or an empty
288
+ # Hash if a HTTP error occurred.
140
289
  def params
141
290
  @params ||= http_failure? ? {} : Hash.from_xml(@http_response.read_body)['response']['item']
142
291
  end
143
292
 
293
+ # Upon success, returns the result code from the gateway. Otherwise the
294
+ # HTTP response code.
295
+ #
296
+ # The possible gateway result codes are:
297
+ # * 10 - message sent
298
+ # * 20 - no ‘username’
299
+ # * 21 - no ‘password’
300
+ # * 22 - no, or incorrect, ‘originator’
301
+ # * 23 - no ‘recipients’
302
+ # * 24 - no ‘message’
303
+ # * 25 - incorrect ‘recipients’
304
+ # * 26 - incorrect ‘originator’
305
+ # * 27 - incorrect ‘message’
306
+ # * 28 - charset failure
307
+ # * 29 - parameter failure
308
+ # * 30 - incorrect ‘username’ or ‘password’
309
+ # * 31 - not enough credits to send message
310
+ # * 38 - binary UDH parameter misformed
311
+ # * 39 - ‘deliverydate’ format is not correct
312
+ # * 98 - gateway unreachable
313
+ # * 99 - unknown error
314
+ #
315
+ # @return [Integer] The result code from the gateway or HTTP response
316
+ # code.
144
317
  def result_code
145
318
  (http_failure? ? @http_response.code : params['resultcode']).to_i
146
319
  end
147
320
 
321
+ # @return [String] The message from the gateway, or the HTTP message in
322
+ # case of a HTTP error.
323
+ #
324
+ # @see #result_code #result_code for a list of possible messages.
148
325
  def message
149
326
  http_failure? ? "[HTTP: #{@http_response.code}] #{@http_response.message}" : params['resultmessage']
150
327
  end
151
328
 
329
+ # @return [Boolean] Whether or not the SMS message has been delivered.
152
330
  def success?
153
331
  !http_failure? && params['success'] == 'true'
154
332
  end
155
333
 
334
+ # @return [Boolean] Whether or not the HTTP request was a success.
156
335
  def http_failure?
157
336
  !@http_response.is_a?(Net::HTTPSuccess)
158
337
  end
159
338
 
339
+ # @return [String] A `inspect' string representation of this instance.
160
340
  def inspect
161
341
  "#<#{self.class.name} #{ success? ? 'succeeded' : 'failed' } (#{result_code}) `#{message}'>"
162
342
  end
@@ -1,44 +1,13 @@
1
1
  module Mollie
2
2
  class SMS
3
- def self.deliveries
4
- @deliveries ||= []
5
- end
6
-
7
- def self.reset!
8
- @deliveries = []
9
- success!
10
- end
11
-
12
- def self.success!
13
- http_response = Net::HTTPOK.new('1.1', '200', 'OK')
14
- http_response.add_field('Content-type', 'application/xml')
15
- def http_response.read_body; TestHelper::SUCCESS_BODY; end
16
- @stubbed_response = Mollie::SMS::Response.new(http_response)
17
- end
18
-
19
- def self.gateway_failure!
20
- http_response = Net::HTTPOK.new('1.1', '200', 'OK')
21
- http_response.add_field('Content-type', 'application/xml')
22
- def http_response.read_body; TestHelper::FAILURE_BODY; end
23
- @stubbed_response = Mollie::SMS::Response.new(http_response)
24
- end
25
-
26
- def self.http_failure!
27
- @stubbed_response = Mollie::SMS::Response.new(Net::HTTPBadRequest.new('1.1', '400', 'Bad request'))
28
- end
29
-
30
- def self.stubbed_response
31
- @stubbed_response || success!
32
- end
33
-
34
- def deliver
35
- validate_params!
36
- self.class.deliveries << self
37
- self.class.stubbed_response
38
- end
39
-
3
+ # A collection of helpers for testing the delivery of SMS messages.
4
+ #
5
+ # This includes:
6
+ # * a couple of Test::Unit {Mollie::SMS::TestHelper::Assertions assertions}
7
+ # * {Mollie::SMS::TestHelper::SMSExt Mollie::SMS} class extensions and
8
+ # overrides
40
9
  module TestHelper
41
- SUCCESS_BODY = %{
10
+ SUCCESS_BODY = %{
42
11
  <?xml version="1.0" ?>
43
12
  <response>
44
13
  <item type="sms">
@@ -49,7 +18,7 @@ module Mollie
49
18
  </item>
50
19
  </response>}
51
20
 
52
- FAILURE_BODY = %{
21
+ FAILURE_BODY = %{
53
22
  <?xml version="1.0"?>
54
23
  <response>
55
24
  <item type="sms">
@@ -60,17 +29,175 @@ module Mollie
60
29
  </item>
61
30
  </response>}
62
31
 
63
- def assert_sms_messages(number_of_messages)
64
- before = Mollie::SMS.deliveries.length
65
- yield
66
- diff = Mollie::SMS.deliveries.length - before
67
- assert(diff == number_of_messages, "expected `#{number_of_messages}' SMS messages to be sent, actually sent `#{diff}'")
32
+ # A couple of Test::Unit assertions, to test the amount of sent messages.
33
+ module Assertions
34
+ # Asserts that a specific number of SMS messages have been sent, for the
35
+ # duration of the given block.
36
+ #
37
+ # def test_invitation_message_is_sent
38
+ # assert_sms_messages(1) do
39
+ # Account.create(:telephone_number => "+31621212121")
40
+ # end
41
+ # end
42
+ #
43
+ # @yield The context that will be used to check the number of sent
44
+ # messages.
45
+ #
46
+ # @return [nil]
47
+ #
48
+ # @see Mollie::SMS::TestHelper::SMSExt::ClassMethods#deliveries
49
+ # Mollie::SMS.deliveries
50
+ def assert_sms_messages(number_of_messages)
51
+ before = Mollie::SMS.deliveries.length
52
+ yield
53
+ diff = Mollie::SMS.deliveries.length - before
54
+ assert(diff == number_of_messages, "expected `#{number_of_messages}' SMS messages to be sent, actually sent `#{diff}'")
55
+ end
56
+
57
+ # Asserts that *no* SMS messages have been sent, for the duration of the
58
+ # given block.
59
+ #
60
+ # def test_no_invitation_message_is_sent_when_account_is_invalid
61
+ # assert_no_sms_messages do
62
+ # Account.create(:telephone_number => "invalid")
63
+ # end
64
+ # end
65
+ #
66
+ # @yield The context that will be used to check the number of sent
67
+ # messages.
68
+ #
69
+ # @return [nil]
70
+ #
71
+ # @see Mollie::SMS::TestHelper::SMSExt::ClassMethods#deliveries
72
+ # Mollie::SMS.deliveries
73
+ def assert_no_sms_messages
74
+ assert_sms_messages(0) { yield }
75
+ end
68
76
  end
69
77
 
70
- def assert_no_sms_messages
71
- assert_sms_messages(0) { yield }
78
+ # Extensions and overrides of the Mollie::SMS class for testing purposes.
79
+ #
80
+ # The class method extensions are defined on the
81
+ # {Mollie::SMS::TestHelper::SMSExt::ClassMethods ClassMethods} module.
82
+ module SMSExt
83
+ # @private
84
+ def self.included(klass)
85
+ klass.class_eval do
86
+ undef_method :deliver
87
+ alias_method :deliver, :test_deliver
88
+ extend ClassMethods
89
+ end
90
+ end
91
+
92
+ # Overrides the normal {Mollie::SMS#deliver deliver} method to *never*
93
+ # make an actual request.
94
+ #
95
+ # Instead, the SMS message, that’s to be delivered, is added to the
96
+ # {Mollie::SMS::TestHelper::SMSExt::ClassMethods#deliveries
97
+ # Mollie::SMS.deliveries} list for later inspection.
98
+ #
99
+ # The parameters are still validated.
100
+ #
101
+ # @return [Response] The stubbed Response instance.
102
+ #
103
+ # @see Mollie::SMS::TestHelper::SMSExt::ClassMethods#stubbed_response
104
+ # Mollie::SMS.stubbed_response
105
+ def deliver
106
+ validate_params!
107
+ self.class.deliveries << self
108
+ self.class.stubbed_response
109
+ end
110
+
111
+ alias_method :test_deliver, :deliver
112
+
113
+ module ClassMethods
114
+ # @return [Array<Mollie::SMS>] A list of sent SMS messages.
115
+ #
116
+ # @see Mollie::SMS::TestHelper::SMSExt#deliver
117
+ # Mollie::SMS#deliver
118
+ def deliveries
119
+ @deliveries ||= []
120
+ end
121
+
122
+ # Clears the {#deliveries deliveries} list and stubs a {#success!
123
+ # ‘success’} Response instance.
124
+ #
125
+ # @return [Response] The stubbed ‘success’ Response instance.
126
+ def reset!
127
+ @deliveries = []
128
+ success!
129
+ end
130
+
131
+ # Stubs a ‘success’ Response instance.
132
+ #
133
+ # This means that any following calls to {Mollie::SMS#deliver} will
134
+ # succeed and return the stubbed ‘success’ Response instance.
135
+ #
136
+ # Mollie::SMS.success!
137
+ # response = Mollie::SMS.new(number, body).deliver
138
+ # response.success? # => true
139
+ # response.result_code # => 10
140
+ # response.message # => "Message successfully sent."
141
+ #
142
+ # @return [Response] The stubbed ‘success’ Response instance.
143
+ def success!
144
+ http_response = Net::HTTPOK.new('1.1', '200', 'OK')
145
+ http_response.add_field('Content-type', 'application/xml')
146
+ # @private
147
+ def http_response.read_body; TestHelper::SUCCESS_BODY; end
148
+ @stubbed_response = Mollie::SMS::Response.new(http_response)
149
+ end
150
+
151
+ # Stubs a ‘gateway failure’ Response instance.
152
+ #
153
+ # This means that any following calls to {Mollie::SMS#deliver} will
154
+ # fail at the gateway and return the stubbed ‘gateway failure’
155
+ # Response instance.
156
+ #
157
+ # Mollie::SMS.gateway_failure!
158
+ # response = Mollie::SMS.new(number, body).deliver
159
+ # response.success? # => false
160
+ # response.result_code # => 20
161
+ # response.message # => "No username given."
162
+ #
163
+ # @return [Response] The stubbed ‘gateway failure’ Response
164
+ # instance.
165
+ def gateway_failure!
166
+ http_response = Net::HTTPOK.new('1.1', '200', 'OK')
167
+ http_response.add_field('Content-type', 'application/xml')
168
+ # @private
169
+ def http_response.read_body; TestHelper::FAILURE_BODY; end
170
+ @stubbed_response = Mollie::SMS::Response.new(http_response)
171
+ end
172
+
173
+ # Stubs a ‘HTTP failure’ Response instance.
174
+ #
175
+ # This means that any following calls to {Mollie::SMS#deliver} will
176
+ # fail at the HTTP level and return the stubbed ‘HTTP failure’
177
+ # Response instance.
178
+ #
179
+ # Mollie::SMS.http_failure!
180
+ # response = Mollie::SMS.new(number, body).deliver
181
+ # response.success? # => false
182
+ # response.result_code # => 400
183
+ # response.message # => "[HTTP: 400] Bad request"
184
+ #
185
+ # @return [Response] The stubbed ‘HTTP failure’ Response
186
+ # instance.
187
+ def http_failure!
188
+ @stubbed_response = Mollie::SMS::Response.new(Net::HTTPBadRequest.new('1.1', '400', 'Bad request'))
189
+ end
190
+
191
+ # @return [Response] The stubbed Response instance that will be
192
+ # returned for all requests from
193
+ # {Mollie::SMS#deliver}.
194
+ def stubbed_response
195
+ @stubbed_response || success!
196
+ end
197
+ end
72
198
  end
73
199
  end
74
200
  end
75
201
  end
76
202
 
203
+ Mollie::SMS.send(:include, Mollie::SMS::TestHelper::SMSExt)
@@ -5,20 +5,20 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{mollie-sms}
8
- s.version = "0.2.1"
8
+ s.version = "1.0.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Eloy Duran"]
12
- s.date = %q{2010-08-03}
12
+ s.date = %q{2010-08-06}
13
13
  s.description = %q{Send SMS text messages via the Mollie.nl SMS gateway.}
14
14
  s.email = ["eloy@fngtps.com"]
15
15
  s.extra_rdoc_files = [
16
16
  "LICENSE",
17
- "README"
17
+ "README.rdoc"
18
18
  ]
19
19
  s.files = [
20
20
  "LICENSE",
21
- "README",
21
+ "README.rdoc",
22
22
  "Rakefile",
23
23
  "VERSION",
24
24
  "lib/mollie/sms.rb",
@@ -2,7 +2,7 @@ case Rails.env
2
2
  when "test"
3
3
  require 'mollie/sms/test_helper'
4
4
  require 'active_support/test_case'
5
- ActiveSupport::TestCase.send(:include, Mollie::SMS::TestHelper)
5
+ ActiveSupport::TestCase.send(:include, Mollie::SMS::TestHelper::Assertions)
6
6
  when "development"
7
7
  require 'mollie/sms/test_helper'
8
8
  class Mollie::SMS
@@ -110,7 +110,7 @@ describe "When sending a Mollie::SMS message" do
110
110
  exception = nil
111
111
  begin
112
112
  @sms.deliver!
113
- rescue Mollie::SMS::DeliveryFailure => exception
113
+ rescue Mollie::SMS::Exceptions::DeliveryFailure => exception
114
114
  end
115
115
 
116
116
  exception.message.should == "(No username given.) #{@sms.to_s}"
@@ -210,7 +210,7 @@ describe "Mollie::SMS, concerning validation" do
210
210
  @sms.params['originator'] = "000000000011112"
211
211
  lambda do
212
212
  @sms.deliver
213
- end.should.raise(Mollie::SMS::ValidationError, "Originator may have a maximimun of 14 numerical characters.")
213
+ end.should.raise(Mollie::SMS::Exceptions::ValidationError, "Originator may have a maximimun of 14 numerical characters.")
214
214
  end
215
215
 
216
216
  it "accepts an originator of upto 11 alphanumerical characters" do
@@ -222,6 +222,6 @@ describe "Mollie::SMS, concerning validation" do
222
222
  @sms.params['originator'] = "0123456789AB"
223
223
  lambda do
224
224
  @sms.deliver
225
- end.should.raise(Mollie::SMS::ValidationError, "Originator may have a maximimun of 11 alphanumerical characters.")
225
+ end.should.raise(Mollie::SMS::Exceptions::ValidationError, "Originator may have a maximimun of 11 alphanumerical characters.")
226
226
  end
227
227
  end
@@ -44,8 +44,8 @@ describe "Mollie::SMS ext" do
44
44
  end
45
45
  end
46
46
 
47
- describe "Mollie::SMS::TestHelper" do
48
- extend Mollie::SMS::TestHelper
47
+ describe "Mollie::SMS::TestHelper::Assertions" do
48
+ extend Mollie::SMS::TestHelper::Assertions
49
49
 
50
50
  before do
51
51
  Mollie::SMS.reset!
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mollie-sms
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 23
5
5
  prerelease: false
6
6
  segments:
7
- - 0
8
- - 2
9
7
  - 1
10
- version: 0.2.1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Eloy Duran
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-03 00:00:00 +02:00
18
+ date: 2010-08-06 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -43,10 +43,10 @@ extensions: []
43
43
 
44
44
  extra_rdoc_files:
45
45
  - LICENSE
46
- - README
46
+ - README.rdoc
47
47
  files:
48
48
  - LICENSE
49
- - README
49
+ - README.rdoc
50
50
  - Rakefile
51
51
  - VERSION
52
52
  - lib/mollie/sms.rb
data/README DELETED
@@ -1,7 +0,0 @@
1
- A Ruby client that allows you to send SMS messages via http://mollie.nl.
2
-
3
- It does only what we need, for our app, at this point in time. Which means that
4
- connects to the webservice via SSL, and only sends a message to one recipient
5
- at a time.
6
-
7
- Patches are accepted.