mollie-bank 0.0.1 → 0.0.2
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/.gitignore +3 -0
- data/.rspec +2 -0
- data/.travis.yml +11 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +5 -0
- data/README.md +5 -15
- data/Rakefile +8 -0
- data/lib/mollie-bank.rb +1 -3
- data/lib/mollie-bank/application/app.rb +100 -70
- data/lib/mollie-bank/application/storage.rb +23 -0
- data/lib/mollie-bank/application/views/check.haml +1 -1
- data/lib/mollie-bank/application/views/info.haml +5 -4
- data/lib/mollie-bank/application/views/layout.haml +2 -2
- data/lib/mollie-bank/version.rb +2 -1
- data/mollie-bank.gemspec +10 -6
- data/spec/backend_spec.rb +61 -0
- data/spec/errors_spec.rb +170 -0
- data/spec/frontend_spec.rb +62 -0
- data/spec/spec_helper.rb +20 -0
- metadata +94 -30
data/.gitignore
CHANGED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
-
# Mollie-Bank
|
1
|
+
# Mollie-Bank [][travis] [][gemnasium]
|
2
|
+
|
3
|
+
[travis]: http://travis-ci.org/manuelvanrijn/mollie-bank
|
4
|
+
[gemnasium]: https://gemnasium.com/manuelvanrijn/mollie-bank
|
2
5
|
|
3
6
|
A simple implementation of the "TM Bank" by [Mollie](http://www.mollie.nl), but without the portforward stuff to test your iDeal transactions localy.
|
4
7
|
|
@@ -12,19 +15,6 @@ To install the gem you should execute
|
|
12
15
|
gem install mollie-bank
|
13
16
|
```
|
14
17
|
|
15
|
-
Or if you are implementing this into a Rails project you could add the gem into your `Gemfile`.
|
16
|
-
|
17
|
-
```
|
18
|
-
gem 'mollie-bank'
|
19
|
-
```
|
20
|
-
|
21
|
-
Finally, if you don’t dig any of that gemming that’s so popular nowadays, you can install it as a plugin for you Rails project:
|
22
|
-
|
23
|
-
```
|
24
|
-
cd vendor/plugins
|
25
|
-
git clone --depth 1 git://github.com/manuelvanrijn/mollie-bank.git mollie-bank
|
26
|
-
```
|
27
|
-
|
28
18
|
### Running the Mollie Bank
|
29
19
|
|
30
20
|
After installation you can simple run:
|
@@ -37,7 +27,7 @@ Check if it works by browsing to: [http://localhost:4567/](http://localhost:4567
|
|
37
27
|
|
38
28
|
## Howto implement
|
39
29
|
|
40
|
-
By default all communication for iDeal transactions is through [https://secure.mollie.nl/xml/ideal](https://secure.mollie.nl/xml/ideal). To use the "Mollie Bank" gem, you have to change this path into http://localhost:4567/xml/ideal](http://localhost:4567/xml/ideal).
|
30
|
+
By default all communication for iDeal transactions is through [https://secure.mollie.nl/xml/ideal](https://secure.mollie.nl/xml/ideal). To use the "Mollie Bank" gem, you have to change this path into [http://localhost:4567/xml/ideal](http://localhost:4567/xml/ideal).
|
41
31
|
|
42
32
|
Of course you only want to use this in development mode, so you have to create some code to change this path only when it isn't in production mode.
|
43
33
|
|
data/Rakefile
CHANGED
data/lib/mollie-bank.rb
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
# EXTERNAL DEPS
|
2
2
|
require 'sinatra'
|
3
|
-
require 'sinatra/content_for'
|
4
|
-
require 'sinatra/namespace'
|
5
|
-
require 'sinatra/reloader'
|
6
3
|
require 'haml'
|
7
4
|
require 'net/http'
|
8
5
|
require 'uuid'
|
9
6
|
|
10
7
|
# LOCAL DEPS
|
11
8
|
require 'mollie-bank/version'
|
9
|
+
require 'mollie-bank/application/storage'
|
12
10
|
require 'mollie-bank/application/app'
|
@@ -1,20 +1,21 @@
|
|
1
|
+
# MollieBank Module
|
1
2
|
module MollieBank
|
3
|
+
# The Sinatra Application
|
2
4
|
class Application < Sinatra::Base
|
3
|
-
helpers Sinatra::ContentFor
|
4
|
-
register Sinatra::Namespace
|
5
|
-
register Sinatra::Reloader
|
6
|
-
|
7
5
|
set :static, true
|
8
6
|
set :public_folder, File.expand_path('..', __FILE__)
|
9
7
|
|
10
8
|
set :views, File.expand_path('../views/', __FILE__)
|
11
9
|
set :haml, { :format => :html5 }
|
12
10
|
|
13
|
-
|
11
|
+
set :storage, MollieBank::Storage
|
14
12
|
|
13
|
+
# Displays a information page of the Mollie-Bank gem
|
15
14
|
get '/' do
|
16
15
|
haml :info
|
17
16
|
end
|
17
|
+
|
18
|
+
# Displays a bank page for finishing the transaction
|
18
19
|
get '/ideal' do
|
19
20
|
transaction_id = params[:transaction_id]
|
20
21
|
description = params[:description]
|
@@ -25,11 +26,16 @@ module MollieBank
|
|
25
26
|
if transaction_id.nil? or description.nil? or reporturl.nil? or returnurl.nil? or amount.nil?
|
26
27
|
haml :html_error, :locals => { :message => "To few params have been supplied (expected to retrieve 'transaction_id', 'description', 'reporturl', 'returnurl' and 'amount')" }
|
27
28
|
else
|
29
|
+
cent_amount = amount
|
28
30
|
int, frac = ("%.2f" % (amount.to_f/100)).split('.')
|
29
31
|
amount = "#{int},#{frac}"
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
+
transaction = settings.storage.get(transaction_id)
|
34
|
+
transaction[:reporturl] = reporturl
|
35
|
+
transaction[:returnurl] = returnurl
|
36
|
+
transaction[:amount] = cent_amount
|
37
|
+
|
38
|
+
settings.storage.set(transaction_id, transaction)
|
33
39
|
|
34
40
|
url_path = request.url.split('/ideal?transaction_id=')[0]
|
35
41
|
|
@@ -43,83 +49,107 @@ module MollieBank
|
|
43
49
|
}
|
44
50
|
end
|
45
51
|
end
|
52
|
+
|
53
|
+
# Background page that sends the paid = true or paid = false to the report url
|
46
54
|
get '/payment' do
|
47
55
|
transaction_id = params[:transaction_id]
|
48
56
|
paid = params[:paid] == "true" ? true : false
|
49
57
|
|
50
58
|
if transaction_id.nil? or paid.nil?
|
51
59
|
haml :html_error, :locals => { :message => "To few params have been supplied" }
|
52
|
-
|
60
|
+
else
|
61
|
+
transaction = settings.storage.get(transaction_id)
|
62
|
+
reporturl = transaction[:reporturl]
|
63
|
+
returnurl = transaction[:returnurl]
|
64
|
+
transaction[:paid] = paid
|
53
65
|
|
54
|
-
|
55
|
-
reporturl = @@storage["#{transaction_id}"]['reporturl']
|
56
|
-
returnurl = @@storage["#{transaction_id}"]['returnurl']
|
66
|
+
settings.storage.set(transaction_id, transaction)
|
57
67
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
68
|
+
begin
|
69
|
+
reporturl = URI("#{reporturl}?transaction_id=#{transaction_id}")
|
70
|
+
res = Net::HTTP.get(reporturl)
|
71
|
+
rescue
|
72
|
+
end
|
63
73
|
|
64
|
-
|
74
|
+
redirect returnurl
|
75
|
+
end
|
65
76
|
end
|
66
77
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
transaction_id
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
78
|
+
# Displays the xml depending on the specified action
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# # returns a list of banks
|
82
|
+
# http://localhost:4567/xml/ideal?a=banklist
|
83
|
+
#
|
84
|
+
# @example
|
85
|
+
# # creates a new order
|
86
|
+
# http://localhost:4567/xml/ideal?a=fetch
|
87
|
+
#
|
88
|
+
# @example
|
89
|
+
# # checks if a order was paid
|
90
|
+
# http://localhost:4567/xml/ideal?a=check
|
91
|
+
post '/xml/ideal' do
|
92
|
+
content_type 'text/xml'
|
93
|
+
case params[:a]
|
94
|
+
when "banklist"
|
95
|
+
haml :banklist, :layout => false
|
96
|
+
when "fetch"
|
97
|
+
return error(-2) unless params.has_key?("partnerid")
|
98
|
+
return error(-7) unless params.has_key?("description")
|
99
|
+
return error(-3) unless params.has_key?("reporturl")
|
100
|
+
return error(-12) unless params.has_key?("returnurl")
|
101
|
+
return error(-4) unless params.has_key?("amount")
|
102
|
+
return error(-14) unless params[:amount].to_i > 118
|
103
|
+
return error(-6) unless params.has_key?("bank_id")
|
104
|
+
|
105
|
+
partnerid = params[:partnerid]
|
106
|
+
description = params[:description]
|
107
|
+
reporturl = params[:reporturl]
|
108
|
+
returnurl = params[:returnurl]
|
109
|
+
amount = params[:amount]
|
110
|
+
bank_id = params[:bank_id]
|
111
|
+
|
112
|
+
transaction_id = UUID.new.generate.gsub('-', '')
|
113
|
+
|
114
|
+
settings.storage.set(transaction_id, {:paid => false})
|
115
|
+
|
116
|
+
url_path = request.url.split('/xml/ideal')[0]
|
117
|
+
|
118
|
+
haml :fetch, :layout => false, :locals => {
|
119
|
+
:transaction_id => transaction_id,
|
120
|
+
:amount => amount,
|
121
|
+
:reporturl => reporturl,
|
122
|
+
:returnurl => returnurl,
|
123
|
+
:description => description,
|
124
|
+
:url_path => url_path
|
125
|
+
}
|
126
|
+
when "check"
|
127
|
+
return error(-11) unless params.has_key?("partnerid")
|
128
|
+
return error(-8) unless params.has_key?("transaction_id")
|
129
|
+
|
130
|
+
transaction_id = params[:transaction_id]
|
131
|
+
transaction = settings.storage.get(transaction_id)
|
132
|
+
return error(-10) if transaction.nil?
|
133
|
+
|
134
|
+
is_paid = transaction[:paid]
|
135
|
+
amount = transaction[:amount]
|
136
|
+
transaction[:paid] = false
|
137
|
+
|
138
|
+
settings.storage.set(transaction_id, transaction)
|
139
|
+
|
140
|
+
haml :check, :layout => false, :locals => {
|
141
|
+
:transaction_id => transaction_id,
|
142
|
+
:amount => amount,
|
143
|
+
:is_paid => is_paid
|
144
|
+
}
|
145
|
+
else
|
146
|
+
error(-1)
|
120
147
|
end
|
121
148
|
end
|
122
149
|
|
150
|
+
# Render the XML error for a specific code
|
151
|
+
#
|
152
|
+
# @param [int] error code
|
123
153
|
def error(code)
|
124
154
|
# Mollie codes taken from https://www.mollie.nl/support/documentatie/betaaldiensten/ideal/en/
|
125
155
|
errors = []
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module MollieBank
|
2
|
+
# The Storage class for storing a key value pair (without a database)
|
3
|
+
class Storage
|
4
|
+
@@_storage_object = {}
|
5
|
+
|
6
|
+
# Retrieve the value of the +key+
|
7
|
+
#
|
8
|
+
# @param [Object] key
|
9
|
+
# @return [Object] value
|
10
|
+
def self.get(key)
|
11
|
+
return nil unless @@_storage_object.has_key?key
|
12
|
+
@@_storage_object[key]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Retrieve the value of the +key+
|
16
|
+
#
|
17
|
+
# @param [Object] key
|
18
|
+
# @param [Object] value
|
19
|
+
def self.set(key, value)
|
20
|
+
@@_storage_object[key] = value
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
.hero-unit
|
2
|
-
%h1 Mollie Bank
|
3
|
-
%p
|
2
|
+
%h1 Mollie Bank <small>v#{MollieBank::VERSION}</small>
|
3
|
+
%p Test your transactions on your local machine
|
4
4
|
|
5
5
|
.row
|
6
6
|
.span4
|
@@ -10,7 +10,8 @@
|
|
10
10
|
.span4
|
11
11
|
%h1 Step 2
|
12
12
|
%p Make sure the <code>returnurl</code> and the <code>reporturl</code> are set to your local address. So for example you would have:
|
13
|
-
<code>http://localhost
|
13
|
+
<code>http://localhost/report.php</code> and<br /><br />
|
14
|
+
<code>http://localhost/return.php</code>
|
14
15
|
.span4
|
15
16
|
%h1 Step 3
|
16
|
-
|
17
|
+
Go to the bank selection page of your application and you'll now see <strong>"Mollie Bank"</strong> in the bank selection.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
!!! 5
|
2
2
|
%html(lang="en")
|
3
3
|
%head
|
4
|
-
%title Mollie Bank
|
4
|
+
%title Mollie Bank v#{MollieBank::VERSION}
|
5
5
|
%link(rel="stylesheet" href="bootstrap/css/bootstrap.min.css")
|
6
6
|
%link(rel="stylesheet" href="bootstrap/css/bootstrap.min.responsive")
|
7
7
|
%link(rel="stylesheet" href="css/style.css")
|
@@ -13,7 +13,7 @@
|
|
13
13
|
%span.i-bar
|
14
14
|
%span.i-bar
|
15
15
|
%span.i-bar
|
16
|
-
%a.brand(href="#") Mollie
|
16
|
+
%a.brand(href="#") Mollie Bank
|
17
17
|
|
18
18
|
.container
|
19
19
|
|
data/lib/mollie-bank/version.rb
CHANGED
data/mollie-bank.gemspec
CHANGED
@@ -19,12 +19,16 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.default_executable = 'mollie-bank'
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
|
23
|
-
s.add_development_dependency "
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "nokogiri"
|
24
|
+
s.add_development_dependency "webrat"
|
25
|
+
s.add_development_dependency "redcarpet"
|
26
|
+
s.add_development_dependency "yard"
|
27
|
+
s.add_development_dependency "yard-sinatra"
|
28
|
+
s.add_development_dependency "simplecov"
|
24
29
|
|
25
|
-
s.add_dependency "rake", "
|
26
|
-
s.add_dependency "uuid", "
|
27
|
-
s.add_dependency "haml", "
|
30
|
+
s.add_dependency "rake", "> 0.9.0"
|
31
|
+
s.add_dependency "uuid", "> 1.0"
|
32
|
+
s.add_dependency "haml", "> 3.0"
|
28
33
|
s.add_dependency "sinatra", "~> 1.3.0"
|
29
|
-
s.add_dependency "sinatra-contrib", "~> 1.3.1"
|
30
34
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "backend" do
|
4
|
+
it "should return the Mollie Bank when requesting /xml/ideal?a=banklist" do
|
5
|
+
post '/xml/ideal', {
|
6
|
+
:a => 'banklist'
|
7
|
+
}
|
8
|
+
|
9
|
+
last_response.should be_ok
|
10
|
+
xml = Nokogiri::Slop(last_response.body)
|
11
|
+
xml.response.bank.bank_id.content.should == "0001"
|
12
|
+
xml.response.bank.bank_name.content.should == "Mollie Bank"
|
13
|
+
end
|
14
|
+
it "should return the correct xml for /xml/ideal?a=fetch" do
|
15
|
+
post '/xml/ideal', {
|
16
|
+
:a => 'fetch',
|
17
|
+
:partnerid => '1234',
|
18
|
+
:description => 'description',
|
19
|
+
:reporturl => 'http://example.org/report',
|
20
|
+
:returnurl => 'http://example.org/return',
|
21
|
+
:amount => '1000',
|
22
|
+
:bank_id => '0001'
|
23
|
+
}
|
24
|
+
last_response.should be_ok
|
25
|
+
|
26
|
+
xml = Nokogiri::Slop(last_response.body)
|
27
|
+
xml.response.order.transaction_id.content.should_not be_blank
|
28
|
+
xml.response.order.amount.content.should == "1000"
|
29
|
+
xml.response.order.currency.content.should == "EUR"
|
30
|
+
xml.response.order.URL.content.should contain "http://example.org/ideal?transaction_id="
|
31
|
+
xml.response.order.message.content.should == "Your iDEAL-payment has successfully been setup. Your customer should visit the given URL to make the payment"
|
32
|
+
end
|
33
|
+
it "should return the true if paid" do
|
34
|
+
MollieBank::Storage.set('987654', {
|
35
|
+
:paid => true
|
36
|
+
})
|
37
|
+
post '/xml/ideal', {
|
38
|
+
:a => 'check',
|
39
|
+
:partnerid => '1234',
|
40
|
+
:transaction_id => '987654'
|
41
|
+
}
|
42
|
+
|
43
|
+
last_response.should be_ok
|
44
|
+
xml = Nokogiri::Slop(last_response.body)
|
45
|
+
xml.response.order.payed.content.should == "true"
|
46
|
+
end
|
47
|
+
it "should return the false not paid" do
|
48
|
+
MollieBank::Storage.set('987654', {
|
49
|
+
:paid => false
|
50
|
+
})
|
51
|
+
post '/xml/ideal', {
|
52
|
+
:a => 'check',
|
53
|
+
:partnerid => '1234',
|
54
|
+
:transaction_id => '987654'
|
55
|
+
}
|
56
|
+
|
57
|
+
last_response.should be_ok
|
58
|
+
xml = Nokogiri::Slop(last_response.body)
|
59
|
+
xml.response.order.payed.content.should == "false"
|
60
|
+
end
|
61
|
+
end
|
data/spec/errors_spec.rb
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "errors" do
|
4
|
+
describe "invalid /xml/ideal?a=" do
|
5
|
+
it "should return an error -1" do
|
6
|
+
post '/xml/ideal', {
|
7
|
+
:a => 'unknown'
|
8
|
+
}
|
9
|
+
xml = Nokogiri::Slop(last_response.body)
|
10
|
+
xml.response.item["type"].should == "error"
|
11
|
+
|
12
|
+
xml.response.item.errorcode.content.should == "-1"
|
13
|
+
xml.response.item.message.content.should == "Did not receive a proper input value."
|
14
|
+
end
|
15
|
+
end
|
16
|
+
describe "/xml/ideal?a=fetch" do
|
17
|
+
it "should return error -2 if partnerid isn't provided" do
|
18
|
+
post '/xml/ideal', {
|
19
|
+
:a => 'fetch',
|
20
|
+
:description => 'description',
|
21
|
+
:reporturl => 'http://example.org/report',
|
22
|
+
:returnurl => 'http://example.org/return',
|
23
|
+
:amount => '1000',
|
24
|
+
:bank_id => '0001'
|
25
|
+
}
|
26
|
+
last_response.should be_ok
|
27
|
+
xml = Nokogiri::Slop(last_response.body)
|
28
|
+
xml.response.item["type"].should == "error"
|
29
|
+
|
30
|
+
xml.response.item.errorcode.content.should == "-2"
|
31
|
+
xml.response.item.message.content.should == "A fetch was issued without specification of 'partnerid'."
|
32
|
+
end
|
33
|
+
it "should return error -7 if description isn't provided" do
|
34
|
+
post '/xml/ideal', {
|
35
|
+
:a => 'fetch',
|
36
|
+
:partnerid => '1234',
|
37
|
+
:reporturl => 'http://example.org/report',
|
38
|
+
:returnurl => 'http://example.org/return',
|
39
|
+
:amount => '1000',
|
40
|
+
:bank_id => '0001'
|
41
|
+
}
|
42
|
+
last_response.should be_ok
|
43
|
+
xml = Nokogiri::Slop(last_response.body)
|
44
|
+
xml.response.item["type"].should == "error"
|
45
|
+
|
46
|
+
xml.response.item.errorcode.content.should == "-7"
|
47
|
+
xml.response.item.message.content.should == "A fetch was issued without specification of 'description'."
|
48
|
+
end
|
49
|
+
it "should return error -3 if reporturl isn't provided" do
|
50
|
+
post '/xml/ideal', {
|
51
|
+
:a => 'fetch',
|
52
|
+
:partnerid => '1234',
|
53
|
+
:description => 'description',
|
54
|
+
:returnurl => 'http://example.org/return',
|
55
|
+
:amount => '1000',
|
56
|
+
:bank_id => '0001'
|
57
|
+
}
|
58
|
+
last_response.should be_ok
|
59
|
+
xml = Nokogiri::Slop(last_response.body)
|
60
|
+
xml.response.item["type"].should == "error"
|
61
|
+
|
62
|
+
xml.response.item.errorcode.content.should == "-3"
|
63
|
+
xml.response.item.message.content.should == "A fetch was issued without (proper) specification of 'reporturl'."
|
64
|
+
end
|
65
|
+
it "should return error -12 if returnurl isn't provided" do
|
66
|
+
post '/xml/ideal', {
|
67
|
+
:a => 'fetch',
|
68
|
+
:partnerid => '1234',
|
69
|
+
:description => 'description',
|
70
|
+
:reporturl => 'http://example.org/report',
|
71
|
+
:amount => '1000',
|
72
|
+
:bank_id => '0001'
|
73
|
+
}
|
74
|
+
last_response.should be_ok
|
75
|
+
xml = Nokogiri::Slop(last_response.body)
|
76
|
+
xml.response.item["type"].should == "error"
|
77
|
+
|
78
|
+
xml.response.item.errorcode.content.should == "-12"
|
79
|
+
xml.response.item.message.content.should == "A fetch was issued without (proper) specification of 'returnurl'."
|
80
|
+
end
|
81
|
+
it "should return error -4 if amount isn't provided" do
|
82
|
+
post '/xml/ideal', {
|
83
|
+
:a => 'fetch',
|
84
|
+
:partnerid => '1234',
|
85
|
+
:description => 'description',
|
86
|
+
:reporturl => 'http://example.org/report',
|
87
|
+
:returnurl => 'http://example.org/return',
|
88
|
+
:bank_id => '0001'
|
89
|
+
}
|
90
|
+
last_response.should be_ok
|
91
|
+
xml = Nokogiri::Slop(last_response.body)
|
92
|
+
xml.response.item["type"].should == "error"
|
93
|
+
|
94
|
+
xml.response.item.errorcode.content.should == "-4"
|
95
|
+
xml.response.item.message.content.should == "A fetch was issued without specification of 'amount'."
|
96
|
+
end
|
97
|
+
it "should return error -14 if amount is to low" do
|
98
|
+
post '/xml/ideal', {
|
99
|
+
:a => 'fetch',
|
100
|
+
:partnerid => '1234',
|
101
|
+
:description => 'description',
|
102
|
+
:reporturl => 'http://example.org/report',
|
103
|
+
:returnurl => 'http://example.org/return',
|
104
|
+
:amount => '100',
|
105
|
+
:bank_id => '0001'
|
106
|
+
}
|
107
|
+
last_response.should be_ok
|
108
|
+
xml = Nokogiri::Slop(last_response.body)
|
109
|
+
xml.response.item["type"].should == "error"
|
110
|
+
|
111
|
+
xml.response.item.errorcode.content.should == "-14"
|
112
|
+
xml.response.item.message.content.should == "Minimum amount for an ideal transaction is 1,18 EUR."
|
113
|
+
end
|
114
|
+
it "should return error -6 if bank_id isn't provided" do
|
115
|
+
post '/xml/ideal', {
|
116
|
+
:a => 'fetch',
|
117
|
+
:partnerid => '1234',
|
118
|
+
:description => 'description',
|
119
|
+
:reporturl => 'http://example.org/report',
|
120
|
+
:returnurl => 'http://example.org/return',
|
121
|
+
:amount => '1000'
|
122
|
+
}
|
123
|
+
last_response.should be_ok
|
124
|
+
xml = Nokogiri::Slop(last_response.body)
|
125
|
+
xml.response.item["type"].should == "error"
|
126
|
+
|
127
|
+
xml.response.item.errorcode.content.should == "-6"
|
128
|
+
xml.response.item.message.content.should == "A fetch was issues without specification of a known 'bank_id'."
|
129
|
+
end
|
130
|
+
end
|
131
|
+
describe "/xml/ideal?a=check" do
|
132
|
+
it "should return error -11 if partnerid isn't provided" do
|
133
|
+
post '/xml/ideal', {
|
134
|
+
:a => 'check',
|
135
|
+
:transaction_id => '1'
|
136
|
+
}
|
137
|
+
last_response.should be_ok
|
138
|
+
xml = Nokogiri::Slop(last_response.body)
|
139
|
+
xml.response.item["type"].should == "error"
|
140
|
+
|
141
|
+
xml.response.item.errorcode.content.should == "-11"
|
142
|
+
xml.response.item.message.content.should == "A check was issued without specification of your partner_id."
|
143
|
+
end
|
144
|
+
it "should return error -8 if transaction_id isn't provided" do
|
145
|
+
post '/xml/ideal', {
|
146
|
+
:a => 'check',
|
147
|
+
:partnerid => '1'
|
148
|
+
}
|
149
|
+
last_response.should be_ok
|
150
|
+
xml = Nokogiri::Slop(last_response.body)
|
151
|
+
xml.response.item["type"].should == "error"
|
152
|
+
|
153
|
+
xml.response.item.errorcode.content.should == "-8"
|
154
|
+
xml.response.item.message.content.should == "A check was issued without specification of transaction_id."
|
155
|
+
end
|
156
|
+
it "should return error -10 if transaction_id is unknown" do
|
157
|
+
post '/xml/ideal', {
|
158
|
+
:a => 'check',
|
159
|
+
:partnerid => '1234',
|
160
|
+
:transaction_id => '1234'
|
161
|
+
}
|
162
|
+
last_response.should be_ok
|
163
|
+
xml = Nokogiri::Slop(last_response.body)
|
164
|
+
xml.response.item["type"].should == "error"
|
165
|
+
|
166
|
+
xml.response.item.errorcode.content.should == "-10"
|
167
|
+
xml.response.item.message.content.should == "This is an unknown order."
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "frontend" do
|
4
|
+
it "should show the home page when browsing to /" do
|
5
|
+
get '/'
|
6
|
+
last_response.should be_ok
|
7
|
+
last_response.body.should contain "Test your transactions on your local machine"
|
8
|
+
last_response.body.should contain "Step 1"
|
9
|
+
last_response.body.should contain "Step 2"
|
10
|
+
last_response.body.should contain "Step 3"
|
11
|
+
end
|
12
|
+
it "should who me an error when browsing to /ideal without parameters" do
|
13
|
+
get '/ideal'
|
14
|
+
last_response.should be_ok
|
15
|
+
last_response.body.should contain "Oh snap! You got an error!"
|
16
|
+
last_response.body.should contain "To few params have been supplied"
|
17
|
+
end
|
18
|
+
it "should show me the Mollie Bank page to make payment or not when browsing to /ideal with parameters" do
|
19
|
+
session = {"987654" => {"paid" => false}}
|
20
|
+
MollieBank::Storage.set('987654', {
|
21
|
+
:paid => false
|
22
|
+
})
|
23
|
+
get '/ideal', {
|
24
|
+
:transaction_id => '987654',
|
25
|
+
:amount => '1000',
|
26
|
+
:reporturl => 'http://example.org/report',
|
27
|
+
:returnurl => 'http://example.org/return',
|
28
|
+
:description => 'a_description'
|
29
|
+
}
|
30
|
+
|
31
|
+
last_response.should be_ok
|
32
|
+
last_response.body.should contain "Pay time!"
|
33
|
+
last_response.body.should contain "YES, I wish to pay"
|
34
|
+
last_response.body.should contain "NO, I do not want to pay"
|
35
|
+
last_response.body.should contain "10,00 EUR"
|
36
|
+
last_response.body.should contain "a_description"
|
37
|
+
last_response.body.should contain "http://example.org/report"
|
38
|
+
last_response.body.should contain "http://example.org/return"
|
39
|
+
last_response.body.should contain "987654"
|
40
|
+
end
|
41
|
+
it "should show an html error when not all parameter are supplied for /payment" do
|
42
|
+
get '/payment'
|
43
|
+
last_response.should be_ok
|
44
|
+
last_response.body.should contain "Oh snap! You got an error!"
|
45
|
+
last_response.body.should contain "To few params have been supplied"
|
46
|
+
end
|
47
|
+
it "should store the correct values" do
|
48
|
+
MollieBank::Storage.set('987654', {
|
49
|
+
:paid => false,
|
50
|
+
:reporturl => 'http://example.org/report.html',
|
51
|
+
:returnurl => 'http://example.org/return.html'
|
52
|
+
})
|
53
|
+
get '/payment', {
|
54
|
+
:transaction_id => '987654',
|
55
|
+
:paid => 'true'
|
56
|
+
}
|
57
|
+
|
58
|
+
last_response.should be_redirect
|
59
|
+
follow_redirect!
|
60
|
+
last_request.url.should == 'http://example.org/return.html'
|
61
|
+
end
|
62
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
4
|
+
# Load the Sinatra app
|
5
|
+
require 'mollie-bank'
|
6
|
+
|
7
|
+
require 'rspec'
|
8
|
+
require 'webrat'
|
9
|
+
require 'rack/test'
|
10
|
+
require 'nokogiri'
|
11
|
+
|
12
|
+
RSpec.configure do |conf|
|
13
|
+
conf.include Rack::Test::Methods
|
14
|
+
conf.include Webrat::Methods
|
15
|
+
conf.include Webrat::Matchers
|
16
|
+
end
|
17
|
+
|
18
|
+
def app
|
19
|
+
MollieBank::Application
|
20
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mollie-bank
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-02-
|
12
|
+
date: 2012-02-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement: &
|
15
|
+
name: rspec
|
16
|
+
requirement: &24437360 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,43 +21,109 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *24437360
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: nokogiri
|
27
|
+
requirement: &24436620 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *24436620
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: webrat
|
38
|
+
requirement: &24436060 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *24436060
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: redcarpet
|
49
|
+
requirement: &24435380 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *24435380
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: yard
|
60
|
+
requirement: &24434740 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *24434740
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: yard-sinatra
|
71
|
+
requirement: &24433980 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *24433980
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: simplecov
|
82
|
+
requirement: &24432620 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *24432620
|
25
91
|
- !ruby/object:Gem::Dependency
|
26
92
|
name: rake
|
27
|
-
requirement: &
|
93
|
+
requirement: &24431580 !ruby/object:Gem::Requirement
|
28
94
|
none: false
|
29
95
|
requirements:
|
30
|
-
- -
|
96
|
+
- - ! '>'
|
31
97
|
- !ruby/object:Gem::Version
|
32
98
|
version: 0.9.0
|
33
99
|
type: :runtime
|
34
100
|
prerelease: false
|
35
|
-
version_requirements: *
|
101
|
+
version_requirements: *24431580
|
36
102
|
- !ruby/object:Gem::Dependency
|
37
103
|
name: uuid
|
38
|
-
requirement: &
|
104
|
+
requirement: &24446720 !ruby/object:Gem::Requirement
|
39
105
|
none: false
|
40
106
|
requirements:
|
41
|
-
- -
|
107
|
+
- - ! '>'
|
42
108
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
109
|
+
version: '1.0'
|
44
110
|
type: :runtime
|
45
111
|
prerelease: false
|
46
|
-
version_requirements: *
|
112
|
+
version_requirements: *24446720
|
47
113
|
- !ruby/object:Gem::Dependency
|
48
114
|
name: haml
|
49
|
-
requirement: &
|
115
|
+
requirement: &24444400 !ruby/object:Gem::Requirement
|
50
116
|
none: false
|
51
117
|
requirements:
|
52
|
-
- -
|
118
|
+
- - ! '>'
|
53
119
|
- !ruby/object:Gem::Version
|
54
120
|
version: '3.0'
|
55
121
|
type: :runtime
|
56
122
|
prerelease: false
|
57
|
-
version_requirements: *
|
123
|
+
version_requirements: *24444400
|
58
124
|
- !ruby/object:Gem::Dependency
|
59
125
|
name: sinatra
|
60
|
-
requirement: &
|
126
|
+
requirement: &24443540 !ruby/object:Gem::Requirement
|
61
127
|
none: false
|
62
128
|
requirements:
|
63
129
|
- - ~>
|
@@ -65,18 +131,7 @@ dependencies:
|
|
65
131
|
version: 1.3.0
|
66
132
|
type: :runtime
|
67
133
|
prerelease: false
|
68
|
-
version_requirements: *
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: sinatra-contrib
|
71
|
-
requirement: &14768560 !ruby/object:Gem::Requirement
|
72
|
-
none: false
|
73
|
-
requirements:
|
74
|
-
- - ~>
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: 1.3.1
|
77
|
-
type: :runtime
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: *14768560
|
134
|
+
version_requirements: *24443540
|
80
135
|
description: A small sinatra server that supports all the actions Mollie iDeal API
|
81
136
|
needs to make a payment. Now you can test your transactions on you local machine
|
82
137
|
without having to make portforwards
|
@@ -88,6 +143,9 @@ extensions: []
|
|
88
143
|
extra_rdoc_files: []
|
89
144
|
files:
|
90
145
|
- .gitignore
|
146
|
+
- .rspec
|
147
|
+
- .travis.yml
|
148
|
+
- .yardopts
|
91
149
|
- CHANGELOG.md
|
92
150
|
- Gemfile
|
93
151
|
- LICENSE.md
|
@@ -106,6 +164,7 @@ files:
|
|
106
164
|
- lib/mollie-bank/application/bootstrap/js/bootstrap.min.js
|
107
165
|
- lib/mollie-bank/application/css/style.css
|
108
166
|
- lib/mollie-bank/application/javascript/script.js
|
167
|
+
- lib/mollie-bank/application/storage.rb
|
109
168
|
- lib/mollie-bank/application/views/bank_page.haml
|
110
169
|
- lib/mollie-bank/application/views/banklist.haml
|
111
170
|
- lib/mollie-bank/application/views/check.haml
|
@@ -116,6 +175,10 @@ files:
|
|
116
175
|
- lib/mollie-bank/application/views/layout.haml
|
117
176
|
- lib/mollie-bank/version.rb
|
118
177
|
- mollie-bank.gemspec
|
178
|
+
- spec/backend_spec.rb
|
179
|
+
- spec/errors_spec.rb
|
180
|
+
- spec/frontend_spec.rb
|
181
|
+
- spec/spec_helper.rb
|
119
182
|
homepage: https://github.com/manuelvanrijn/mollie-bank
|
120
183
|
licenses: []
|
121
184
|
post_install_message:
|
@@ -130,7 +193,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
130
193
|
version: '0'
|
131
194
|
segments:
|
132
195
|
- 0
|
133
|
-
hash:
|
196
|
+
hash: 4653816000511860
|
134
197
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
135
198
|
none: false
|
136
199
|
requirements:
|
@@ -139,7 +202,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
139
202
|
version: '0'
|
140
203
|
segments:
|
141
204
|
- 0
|
142
|
-
hash:
|
205
|
+
hash: 4653816000511860
|
143
206
|
requirements: []
|
144
207
|
rubyforge_project: mollie-bank
|
145
208
|
rubygems_version: 1.8.11
|
@@ -147,3 +210,4 @@ signing_key:
|
|
147
210
|
specification_version: 3
|
148
211
|
summary: Mollie Bank server to make Mollie iDeal payments on your local machine
|
149
212
|
test_files: []
|
213
|
+
has_rdoc:
|