Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Make it actually work with the service and fix specs accordingly.

  • Loading branch information...
commit dbe25b1d40c32b143e27557871cf0668e92bb753 1 parent 4170ec6
Eloy Durán alloy authored
Showing with 147 additions and 47 deletions.
  1. +63 −15 lib/mollie/sms.rb
  2. +84 −32 spec/sms_spec.rb
78 lib/mollie/sms.rb
View
@@ -1,6 +1,6 @@
require "digest/md5"
require "uri"
-require "net/http"
+require "net/https"
begin
require "rubygems"
@@ -10,17 +10,20 @@
module Mollie
class SMS
- GATEWAY_URI = URI.parse("http://www.mollie.nl/xml/sms")
+ GATEWAY_URI = URI.parse("https://secure.mollie.nl/xml/sms")
GATEWAYS = {
- :basic => '2',
- :business => '4',
- :business_plus => '1',
- :landline => '8'
+ 'basic' => '2',
+ 'business' => '4',
+ 'business+' => '1',
+ 'landline' => '8'
}
+ class MissingRequiredParam < StandardError; end
+ REQUIRED_PARAMS = %w{ username md5_password originator gateway charset type recipients message }
+
class << self
- attr_accessor :username, :password, :charset, :type, :gateway
+ attr_accessor :username, :password, :originator, :charset, :type, :gateway
def password=(password)
@password = Digest::MD5.hexdigest(password)
@@ -30,6 +33,7 @@ def request_params
{
'username' => @username,
'md5_password' => @password,
+ 'originator' => @originator,
'gateway' => @gateway,
'charset' => @charset,
'type' => @type
@@ -39,16 +43,49 @@ def request_params
self.charset = 'UTF-8'
self.type = 'normal'
- self.gateway = GATEWAYS[:basic]
+ self.gateway = GATEWAYS['basic']
+
+ attr_reader :params
+
+ def initialize(telephone_number = nil, body = nil, extra_params = {})
+ @params = self.class.request_params.merge(extra_params)
+ self.telephone_number = telephone_number if telephone_number
+ self.body = body if body
+ end
+
+ def telephone_number
+ @params['recipients']
+ end
- attr_accessor :telephone_number, :body
+ def telephone_number=(telephone_number)
+ @params['recipients'] = telephone_number
+ end
- def request_params
- self.class.request_params.merge('recipients' => @telephone_number, 'message' => @body)
+ def body
+ @params['message']
+ end
+
+ def body=(body)
+ @params['message'] = body
+ end
+
+ def inspect
+ "#<#{self.class.name} from: <#{@params['originator']}> to: <#{telephone_number}> body: \"#{body}\" >"
end
def deliver
- Response.new(Net::HTTP.post_form(GATEWAY_URI, request_params))
+ params.slice(*REQUIRED_PARAMS).each do |key, value|
+ raise MissingRequiredParam, "The required parameter `#{key}' is missing." if value.blank?
+ end
+
+ post = Net::HTTP::Post.new(GATEWAY_URI.path)
+ post.form_data = params
+ request = Net::HTTP.new(GATEWAY_URI.host, GATEWAY_URI.port)
+ request.use_ssl = true
+ request.start do |http|
+ response = http.request(post)
+ Response.new(response)
+ end
end
class Response
@@ -59,11 +96,12 @@ def initialize(http_response)
end
def params
- @params ||= Hash.from_xml(@http_response.read_body)['response']['item']
+ @params ||= http_request_succeeded? ?
+ Hash.from_xml(@http_response.read_body)['response']['item'] : {}
end
def result_code
- params['resultcode'].to_i
+ params['resultcode'].to_i if http_request_succeeded?
end
def message
@@ -71,7 +109,17 @@ def message
end
def success?
- @http_response.is_a?(Net::HTTPSuccess) && params['success'] == 'true'
+ http_request_succeeded? && params['success'] == 'true'
+ end
+
+ def inspect
+ "#<#{self.class.name} #{ success? ? 'succeeded' : 'failed' } (#{result_code}) `#{message}'>"
+ end
+
+ private
+
+ def http_request_succeeded?
+ @http_response.is_a?(Net::HTTPSuccess)
end
end
end
116 spec/sms_spec.rb
View
@@ -3,10 +3,11 @@
Mollie::SMS.username = 'AstroRadio'
Mollie::SMS.password = 'secret'
+Mollie::SMS.originator = 'Fingertips'
describe "Mollie::SMS" do
it "holds the gateway uri" do
- Mollie::SMS::GATEWAY_URI.should == URI.parse("http://www.mollie.nl/xml/sms")
+ Mollie::SMS::GATEWAY_URI.should == URI.parse("https://secure.mollie.nl/xml/sms")
end
it "holds the service username" do
@@ -17,6 +18,10 @@
Mollie::SMS.password.should == Digest::MD5.hexdigest('secret')
end
+ it "holds the originator" do
+ Mollie::SMS.originator.should == 'Fingertips'
+ end
+
it "returns the default charset" do
Mollie::SMS.charset.should == 'UTF-8'
end
@@ -26,25 +31,40 @@
end
it "holds a list of available gateways" do
- Mollie::SMS::GATEWAYS[:basic].should == '2'
- Mollie::SMS::GATEWAYS[:business].should == '4'
- Mollie::SMS::GATEWAYS[:business_plus].should == '1'
- Mollie::SMS::GATEWAYS[:landline].should == '8'
+ Mollie::SMS::GATEWAYS['basic'].should == '2'
+ Mollie::SMS::GATEWAYS['business'].should == '4'
+ Mollie::SMS::GATEWAYS['business+'].should == '1'
+ Mollie::SMS::GATEWAYS['landline'].should == '8'
end
it "returns the default gateway to use" do
- Mollie::SMS.gateway.should == Mollie::SMS::GATEWAYS[:basic]
+ Mollie::SMS.gateway.should == Mollie::SMS::GATEWAYS['basic']
end
it "returns a hash of params for a request" do
Mollie::SMS.request_params.should == {
'username' => 'AstroRadio',
- 'md5_password' => Mollie::SMS.password,
+ 'md5_password' => Digest::MD5.hexdigest('secret'),
+ 'originator' => 'Fingertips',
'gateway' => '2',
'charset' => 'UTF-8',
'type' => 'normal'
}
end
+
+ it "initializes, optionally, with a telephone number, body, and params" do
+ sms1 = Mollie::SMS.new
+ sms1.telephone_number = '+31612345678'
+ sms1.body = "The stars tell me you will have chicken noodle soup for breakfast."
+
+ sms2 = Mollie::SMS.new('+31612345678', "The stars tell me you will have chicken noodle soup for breakfast.", 'originator' => 'Eloy')
+ sms2.params['originator'].should == 'Eloy'
+
+ [sms1, sms2].each do |sms|
+ sms.telephone_number.should == '+31612345678'
+ sms.body.should == "The stars tell me you will have chicken noodle soup for breakfast."
+ end
+ end
end
describe "A Mollie::SMS instance" do
@@ -67,28 +87,32 @@
'recipients' => '+31612345678',
'message' => "The stars tell me you will have chicken noodle soup for breakfast."
)
- @sms.request_params.should == params
+ @sms.params.should == params
end
end
module Net
class HTTP
class << self
- attr_accessor :stubbed_response
+ attr_accessor :posted, :stubbed_response
def reset!
@posted = nil
@stubbed_response = nil
end
+ end
- def post_form(url, params)
- @posted = { 'url' => url, 'params' => params }
- @stubbed_response
- end
+ def host
+ @address
+ end
- def posted
- @posted ||= {}
- end
+ def start
+ yield self
+ end
+
+ def request(request)
+ self.class.posted = [self, request]
+ self.class.stubbed_response
end
end
end
@@ -96,6 +120,17 @@ def posted
class ResponseStub
end
+SUCCESS_BODY = %{
+<?xml version="1.0" ?>
+<response>
+ <item type="sms">
+ <recipients>1</recipients>
+ <success>true</success>
+ <resultcode>10</resultcode>
+ <resultmessage>Message successfully sent.</resultmessage>
+ </item>
+</response>}
+
describe "When sending a Mollie::SMS message" do
before do
@sms = Mollie::SMS.new
@@ -108,33 +143,27 @@ class ResponseStub
end
it "posts the post body to the gateway" do
+ @sms.stubs(:params).returns('a key' => 'a value')
@sms.deliver
- Net::HTTP.posted.should == {
- 'url' => Mollie::SMS::GATEWAY_URI,
- 'params' => @sms.request_params
- }
+
+ request, post = Net::HTTP.posted
+ request.should.use_ssl
+ request.host.should == Mollie::SMS::GATEWAY_URI.host
+ request.port.should == Mollie::SMS::GATEWAY_URI.port
+ post.path.should == Mollie::SMS::GATEWAY_URI.path
+ post.body.should == "a%20key=a%20value"
end
it "returns a Mollie::SMS::Response object, with the Net::HTTP response" do
Net::HTTP.stubbed_response = Net::HTTPOK.new('1.1', '200', 'OK')
+ Net::HTTP.stubbed_response.stubs(:read_body).returns(SUCCESS_BODY)
response = @sms.deliver
response.should.be.instance_of Mollie::SMS::Response
response.http_response.should == Net::HTTP.stubbed_response
end
end
-SUCCESS_BODY = %{
-<?xml version="1.0" ?>
-<response>
- <item type="sms">
- <recipients>1</recipients>
- <success>true</success>
- <resultcode>10</resultcode>
- <resultmessage>Message successfully sent.</resultmessage>
- </item>
-</response>}
-
-describe "A Mollie::SMS::Response instance" do
+describe "A Mollie::SMS::Response instance, for a succeeded request" do
before do
@http_response = Net::HTTPOK.new('1.1', '200', 'OK')
@http_response.stubs(:read_body).returns(SUCCESS_BODY)
@@ -165,3 +194,26 @@ class ResponseStub
@response.message.should == "Message successfully sent."
end
end
+
+describe "A Mollie::SMS::Response instance, for a failed request" do
+ before do
+ @http_response = Net::HTTPBadRequest.new('1.1', '400', 'Bad request')
+ @response = Mollie::SMS::Response.new(@http_response)
+ end
+
+ it "returns an empty hash as the params" do
+ @response.params.should == {}
+ end
+
+ it "returns that the request was not a success" do
+ @response.should.not.be.success
+ end
+
+ it "returns nil as the result_code" do
+ @response.result_code.should == nil
+ end
+
+ it "returns nil as the message" do
+ @response.message.should == nil
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.