mollie 0.1.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,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Arie
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,18 @@
1
+ = mollie
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but
13
+ bump version in a commit by itself I can ignore when I pull)
14
+ * Send me a pull request. Bonus points for topic branches.
15
+
16
+ == Copyright
17
+
18
+ Copyright (c) 2009 Arie. See LICENSE for details.
@@ -0,0 +1,45 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "mollie"
8
+ gem.summary = "Interface to SMS gateway Mollie.nl"
9
+ gem.description = gem.summary
10
+ gem.email = "github@ariekanarie.nl"
11
+ gem.homepage = "http://github.com/arie/mollie"
12
+ gem.authors = ["Arie", "iain"]
13
+ gem.add_development_dependency "rspec", ">= 1.2.9"
14
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
15
+ end
16
+ Jeweler::GemcutterTasks.new
17
+ rescue LoadError
18
+ puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
19
+ end
20
+
21
+ require 'spec/rake/spectask'
22
+ Spec::Rake::SpecTask.new(:spec) do |spec|
23
+ spec.libs << 'lib' << 'spec'
24
+ spec.spec_files = FileList['spec/**/*_spec.rb']
25
+ end
26
+
27
+ Spec::Rake::SpecTask.new(:rcov) do |spec|
28
+ spec.libs << 'lib' << 'spec'
29
+ spec.pattern = 'spec/**/*_spec.rb'
30
+ spec.rcov = true
31
+ end
32
+
33
+ task :spec => :check_dependencies
34
+
35
+ task :default => :spec
36
+
37
+ require 'rake/rdoctask'
38
+ Rake::RDocTask.new do |rdoc|
39
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
40
+
41
+ rdoc.rdoc_dir = 'rdoc'
42
+ rdoc.title = "mollie #{version}"
43
+ rdoc.rdoc_files.include('README*')
44
+ rdoc.rdoc_files.include('lib/**/*.rb')
45
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,147 @@
1
+ require 'uri'
2
+ require 'net/http'
3
+ require 'nokogiri'
4
+
5
+ module Mollie
6
+
7
+ module RequestOptions
8
+
9
+ DEFAULT_URI = "http://www.mollie.nl/xml/sms/"
10
+
11
+ def self.query_attributes
12
+ [:username, :password, :recipients, :originator, :gateway, :md5_password, :udh, :receipt, :deliverydate, :message, :message_type, :delivery_url]
13
+ end
14
+
15
+ def self.included(klass)
16
+ klass.__send__(:attr_accessor, *(query_attributes + [ :uri ]))
17
+ end
18
+
19
+ def uri
20
+ @uri || DEFAULT_URI
21
+ end
22
+
23
+ end
24
+
25
+ class SMS
26
+
27
+ include RequestOptions
28
+
29
+ attr_accessor :deliver_at, :message_type, :delivery_url
30
+
31
+ def initialize(options = {})
32
+ options.each_pair do |key,value|
33
+ send("#{key}=", value)
34
+ end
35
+ end
36
+
37
+ def uri
38
+ @uri || RequestOptions::DEFAULT_URI
39
+ end
40
+
41
+ def recipient=(recipient)
42
+ self.recipients = [recipient]
43
+ end
44
+
45
+ end
46
+
47
+ class Send
48
+
49
+ attr_reader :query
50
+
51
+ def self.send(query)
52
+ new(query).send!
53
+ end
54
+
55
+ def initialize(query)
56
+ @query = query
57
+ end
58
+
59
+ def send!
60
+ raise MollieException.new(self) unless success?
61
+ self
62
+ end
63
+
64
+ def success?
65
+ resultcode == 10
66
+ end
67
+
68
+ def resultcode
69
+ $1.to_i if response.body =~ /<resultcode>(.*)<\/resultcode>/m
70
+ end
71
+
72
+ def response
73
+ @response ||= Net::HTTP.get_response(query.request_uri)
74
+ end
75
+
76
+ end
77
+
78
+ class Query
79
+
80
+ # Let's provide some friendly names instead of Mollie's weird short names
81
+ QUERY_ALIASES = { :message_type => :type, :delivery_url => :dlrurl, :receipt => :return }
82
+
83
+ attr_reader :sms
84
+
85
+ def initialize(sms)
86
+ @sms = sms
87
+ end
88
+
89
+ def deliverydate
90
+ DateTime.parse(value(:deliver_at)).strftime("%Y%m%d%H%M%S")
91
+ rescue TypeError
92
+ nil
93
+ end
94
+
95
+ def request_uri
96
+ request_uri = URI.parse(value(:uri))
97
+ request_uri.query = query
98
+ request_uri
99
+ end
100
+
101
+ def recipients
102
+ sms.recipients.join(',')
103
+ end
104
+
105
+ private
106
+
107
+ def attribute_name(attribute)
108
+ QUERY_ALIASES.has_key?(attribute) ? QUERY_ALIASES[attribute] : attribute
109
+ end
110
+
111
+ def value(attribute)
112
+ (respond_to?(attribute) ? self : sms).__send__(attribute)
113
+ end
114
+
115
+ def query_format
116
+ lambda { |attribute| "#{attribute_name(attribute)}=#{URI.encode(value(attribute))}" }
117
+ end
118
+
119
+ def empty_attribute?
120
+ lambda { |attribute| value(attribute).nil? }
121
+ end
122
+
123
+ def query
124
+ query_attributes.reject(&empty_attribute?).map(&query_format).join("&")
125
+ end
126
+
127
+ def query_attributes
128
+ RequestOptions.query_attributes
129
+ end
130
+
131
+ end
132
+
133
+ class MollieException < ::Exception
134
+
135
+ attr_reader :response
136
+
137
+ def initialize(response)
138
+ @response = response
139
+ end
140
+
141
+ def resultcode
142
+ response.resultcode
143
+ end
144
+
145
+ end
146
+
147
+ end
@@ -0,0 +1,107 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe Mollie do
4
+
5
+ describe Mollie::SMS do
6
+
7
+ def accepts(attribute, checked_attribute = nil)
8
+ checked_attribute ||= attribute
9
+ subject = Mollie::SMS.new(attribute => 'xxx')
10
+ subject.__send__(checked_attribute).should == 'xxx'
11
+ subject.__send__("#{attribute}=", 'yyy')
12
+ subject.__send__(checked_attribute).should == 'yyy'
13
+ end
14
+
15
+ def self.should_accept(attribute, checked_attribute = nil)
16
+ it "should accept #{attribute} #{checked_attribute ? "and store it as #{checked_attribute}" : ""}" do
17
+ accepts(attribute, checked_attribute)
18
+ end
19
+ end
20
+
21
+ should_accept :username
22
+ should_accept :password
23
+ should_accept :message
24
+ should_accept :originator
25
+ should_accept :gateway
26
+ should_accept :md5_password
27
+ should_accept :delivery_url
28
+ should_accept :message_type
29
+ should_accept :udh
30
+ should_accept :receipt
31
+ should_accept :uri
32
+ should_accept :deliver_at
33
+
34
+ it "should know a default gateway" do
35
+ Mollie::SMS.new.uri.should == Mollie::RequestOptions::DEFAULT_URI
36
+ end
37
+
38
+ it "should accept a single recipient" do
39
+ subject = Mollie::SMS.new(:recipients => ['x', 'y'])
40
+ subject.recipient = 'z'
41
+ subject.recipients.should == ['z']
42
+ end
43
+
44
+ end
45
+
46
+ describe Mollie::Query do
47
+
48
+ it "should format deliverydate as yyyymmddhhmmss" do
49
+ date = DateTime.civil(2009, 3, 8, 1, 3, 4).to_s
50
+ Mollie::Query.new(Mollie::SMS.new(:deliver_at => date)).deliverydate.should == "20090308010304"
51
+ end
52
+
53
+ it "should get a comma seperated list of recipients" do
54
+ subject = Mollie::Query.new(Mollie::SMS.new(:recipients => [ "alice", "bob" ]))
55
+ subject.recipients.should == "alice,bob"
56
+ end
57
+
58
+ it "should return an uri to get" do
59
+ subject = Mollie::Query.new(Mollie::SMS.new(:username => 'un', :password => 'pw', :message => 'msg', :recipients => ['alice','charles'], :originator => 'bob', :uri => 'http://gateway', :gateway => "4", :udh => "bla", :receipt => "yesplease", :message_type => "123")).request_uri.to_s
60
+ subject.should =~ /\busername=un\b/
61
+ subject.should =~ /\Ahttp:\/\/gateway\?/
62
+ subject.should =~ /\bpassword=pw\b/
63
+ subject.should =~ /\bmessage=msg\b/
64
+ subject.should =~ /\brecipients=alice,charles\b/
65
+ subject.should =~ /\boriginator=bob\b/
66
+ subject.should =~ /\bgateway=4\b/
67
+ subject.should =~ /\breturn=yesplease\b/
68
+ subject.should =~ /\btype=123\b/
69
+ subject.should =~ /\budh=bla\b/
70
+ end
71
+
72
+ end
73
+
74
+ describe Mollie::Send do
75
+
76
+ it "should accept a result code 10 as success" do
77
+ query = mock("query")
78
+ query.stub!(:request_uri).and_return(URI.parse("http://blah"))
79
+ FakeWeb.register_uri(:get, /.*/, :body => xml_ellende(10))
80
+ Mollie::Send.send(query).should be_success
81
+ end
82
+
83
+
84
+ it "should raise an exception when resultcode is not 10" do
85
+ query = mock("query")
86
+ query.stub!(:request_uri).and_return(URI.parse("http://blash"))
87
+ FakeWeb.register_uri(:get, /.*/, :body => xml_ellende(20))
88
+ lambda { Mollie::Send.send(query) }.should raise_error(Mollie::MollieException)
89
+ end
90
+
91
+ end
92
+
93
+ def xml_ellende(resultcode=10)
94
+ %Q|
95
+ <?xml version="1.0" ?>
96
+ <response>
97
+ <item type="sms">
98
+ <recipients>1</recipients>
99
+ <success>true</success>
100
+ <resultcode>#{resultcode}</resultcode>
101
+ <resultmessage>Message successfully sent.</resultmessage>
102
+ </item>
103
+ </response>
104
+ |
105
+ end
106
+
107
+ end
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,11 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'rubygems'
4
+ require 'mollie'
5
+ require 'spec'
6
+ require 'spec/autorun'
7
+ require 'fakeweb'
8
+
9
+ Spec::Runner.configure do |config|
10
+
11
+ end
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mollie
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Arie
8
+ - iain
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-11-09 00:00:00 +01:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: rspec
18
+ type: :development
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 1.2.9
25
+ version:
26
+ description: Interface to SMS gateway Mollie.nl
27
+ email: github@ariekanarie.nl
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files:
33
+ - LICENSE
34
+ - README.rdoc
35
+ files:
36
+ - .document
37
+ - .gitignore
38
+ - LICENSE
39
+ - README.rdoc
40
+ - Rakefile
41
+ - VERSION
42
+ - lib/mollie.rb
43
+ - spec/mollie_spec.rb
44
+ - spec/spec.opts
45
+ - spec/spec_helper.rb
46
+ has_rdoc: true
47
+ homepage: http://github.com/arie/mollie
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Interface to SMS gateway Mollie.nl
74
+ test_files:
75
+ - spec/mollie_spec.rb
76
+ - spec/spec_helper.rb