docdata 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.
- checksums.yaml +4 -4
- data/.coveralls.yml +2 -0
- data/.gitignore +4 -1
- data/.travis.yml +10 -0
- data/LICENSE +1 -1
- data/README.md +173 -7
- data/Rakefile +8 -0
- data/docdata.gemspec +18 -11
- data/lib/docdata.rb +74 -1
- data/lib/docdata/bank.rb +27 -0
- data/lib/docdata/config.rb +41 -0
- data/lib/docdata/docdata_error.rb +8 -0
- data/lib/docdata/engine.rb +13 -0
- data/lib/docdata/ideal.rb +40 -0
- data/lib/docdata/line_item.rb +99 -0
- data/lib/docdata/payment.rb +196 -0
- data/lib/docdata/response.rb +173 -0
- data/lib/docdata/shopper.rb +112 -0
- data/lib/docdata/version.rb +1 -1
- data/lib/docdata/xml/bank-list.xml +39 -0
- data/lib/docdata/xml/cancel.xml.erb +9 -0
- data/lib/docdata/xml/create.xml.erb +98 -0
- data/lib/docdata/xml/start.xml.erb +67 -0
- data/lib/docdata/xml/status.xml.erb +9 -0
- data/php-example/create.xml.erb +140 -0
- data/php-example/index.html +78 -0
- data/php-example/process.php +182 -0
- data/php-example/return.php +36 -0
- data/php-example/soap.rb +21 -0
- data/spec/config_spec.rb +53 -0
- data/spec/ideal_spec.rb +19 -0
- data/spec/line_item_spec.rb +55 -0
- data/spec/payment_spec.rb +162 -0
- data/spec/response_spec.rb +206 -0
- data/spec/shopper_spec.rb +50 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/xml/status-canceled-creditcard.xml +34 -0
- data/spec/xml/status-canceled-ideal.xml +29 -0
- data/spec/xml/status-new.xml +20 -0
- data/spec/xml/status-paid-creditcard.xml +33 -0
- data/spec/xml/status-paid-ideal.xml +33 -0
- data/spec/xml/status-paid-sofort.xml +33 -0
- metadata +145 -13
- data/LICENSE.txt +0 -22
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Docdata::Payment do
|
4
|
+
before(:each) do
|
5
|
+
@shopper = Docdata::Shopper.create_valid_shopper
|
6
|
+
@payment = Docdata::Payment.new
|
7
|
+
@payment.amount = 500
|
8
|
+
@payment.profile = ENV["DOCDATA_PAYMENT_PROFILE"]
|
9
|
+
@payment.order_reference = rand(500)
|
10
|
+
@payment.currency = "EUR"
|
11
|
+
@payment.description = "Description of my order"
|
12
|
+
@payment.shopper = @shopper
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "initialisation" do
|
16
|
+
|
17
|
+
it "ititializes a new object through a hash" do
|
18
|
+
payment = Docdata::Payment.new(amount: 500)
|
19
|
+
expect(payment.amount).to eq(500)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "validations" do
|
25
|
+
it "validates amount" do
|
26
|
+
expect(@payment).to be_valid
|
27
|
+
@payment.amount = nil
|
28
|
+
expect(@payment).not_to be_valid
|
29
|
+
expect(@payment.errors.count).to eq(2)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "validates amount with message" do
|
33
|
+
@payment.amount = nil
|
34
|
+
expect(@payment).not_to be_valid
|
35
|
+
expect(@payment.errors.full_messages).to eq(["amount is not present", "amount is not a number"])
|
36
|
+
end
|
37
|
+
|
38
|
+
it "validates precense and format of currency" do
|
39
|
+
@payment.currency = nil
|
40
|
+
expect(@payment).not_to be_valid
|
41
|
+
expect(@payment.errors.full_messages).to include("currency is not valid")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "has a shopper" do
|
45
|
+
expect(@payment.shopper).to be_kind_of(Docdata::Shopper)
|
46
|
+
expect(@payment.shopper.first_name).to eq("John")
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "#create" do
|
51
|
+
|
52
|
+
it "raises error when credentials are wrong" do
|
53
|
+
# puts @payment.xml
|
54
|
+
Docdata.password = "1234"
|
55
|
+
VCR.use_cassette("payments-xml-create-without-credentials") do
|
56
|
+
expect { @payment.create }.to raise_error(DocdataError, "Login failed.")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
it "raises error when password is blank" do
|
61
|
+
Docdata.password = ""
|
62
|
+
VCR.use_cassette("payments-xml-create-without-password") do
|
63
|
+
expect { @payment.create }.to raise_error(DocdataError, /The value '' of attribute 'password' on element '_1:merchant' is not valid with respect to its type/)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
it "raises error when blank xml is sent" do
|
68
|
+
Docdata.set_credentials_from_environment
|
69
|
+
VCR.use_cassette("payments-successful-create") do
|
70
|
+
response = @payment.create
|
71
|
+
expect(response).to be_kind_of(Docdata::Response)
|
72
|
+
expect(response).to be_success
|
73
|
+
expect(response.key).to match /[A-Z0-9]{32}/
|
74
|
+
expect(@payment.key).to be_present
|
75
|
+
expect(@payment.key).to eq(response.key)
|
76
|
+
# expect { @payment.create }.to raise_error(Savon::SOAPFault, "(S:Server) Not a number: ?")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
it "has a redirect_url" do
|
81
|
+
Docdata.set_credentials_from_environment
|
82
|
+
VCR.use_cassette("payments-successful-create") do
|
83
|
+
@payment.create
|
84
|
+
# puts @payment.redirect_url
|
85
|
+
expect(@payment.redirect_url).to include("https://test.docdatapayments.com/ps/menu?command=show_payment_cluster")
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
it "redirect directly to the bank if bank_id && default_act is given" do
|
91
|
+
Docdata.set_credentials_from_environment
|
92
|
+
@payment.bank_id = "0031" # ABN AMRO
|
93
|
+
@payment.default_act = true
|
94
|
+
VCR.use_cassette("payments-successful-create") do
|
95
|
+
@payment.create
|
96
|
+
# puts @payment.redirect_url
|
97
|
+
expect(@payment.redirect_url).to include("&default_act=true&ideal_issuer_id=0031&default_pm=IDEAL")
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
describe "#find" do
|
104
|
+
it "returns a Payment object if correct key is given" do
|
105
|
+
Docdata.set_credentials_from_environment
|
106
|
+
VCR.use_cassette("payments-successful-create") do
|
107
|
+
@payment.create
|
108
|
+
end
|
109
|
+
expect(@payment.key).to be_present
|
110
|
+
VCR.use_cassette("perform-valid-status-call") do
|
111
|
+
@new_payment = Docdata::Payment.find(@payment.key)
|
112
|
+
end
|
113
|
+
expect(@new_payment).to be_kind_of(Docdata::Payment)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "raises error if order is not found" do
|
117
|
+
VCR.use_cassette("perform-invalid-status-call") do
|
118
|
+
Docdata.set_credentials_from_environment
|
119
|
+
expect { @new_payment = Docdata::Payment.find("THISWILLPRODUC3AN3RROR") }.
|
120
|
+
to raise_error(DocdataError, "Order could not be found with the given key.")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#status" do
|
126
|
+
it "returns 'success'" do
|
127
|
+
Docdata.set_credentials_from_environment
|
128
|
+
VCR.use_cassette("payments-successful-create") do
|
129
|
+
@payment.create
|
130
|
+
end
|
131
|
+
VCR.use_cassette("perform-valid-status-call") do
|
132
|
+
@new_payment = Docdata::Payment.find(@payment.key)
|
133
|
+
end
|
134
|
+
VCR.use_cassette("status-call") do
|
135
|
+
@response = @new_payment.status
|
136
|
+
end
|
137
|
+
expect(@response).to be_kind_of(Docdata::Response)
|
138
|
+
expect(@response).to be_success
|
139
|
+
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it "returns paid == false by default" do
|
144
|
+
Docdata.set_credentials_from_environment
|
145
|
+
VCR.use_cassette("payments-successful-create") do
|
146
|
+
@payment.create
|
147
|
+
end
|
148
|
+
VCR.use_cassette("perform-valid-status-call") do
|
149
|
+
@new_payment = Docdata::Payment.find(@payment.key)
|
150
|
+
end
|
151
|
+
VCR.use_cassette("status-call") do
|
152
|
+
@response = @new_payment.status
|
153
|
+
end
|
154
|
+
expect(@response).not_to be_paid
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#new" do
|
158
|
+
it "returns a Payment object" do
|
159
|
+
expect(@payment).to be_kind_of(Docdata::Payment)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,206 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Docdata::Response do
|
4
|
+
context ":status, new unpaid payment" do
|
5
|
+
before(:each) do
|
6
|
+
file = "#{File.dirname(__FILE__)}/xml/status-new.xml"
|
7
|
+
@xml = open(file)
|
8
|
+
@response = Docdata::Response.parse(:status, @xml)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "is not paid" do
|
12
|
+
expect(@response).to be_success
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has xml attribute with raw data" do
|
16
|
+
expect(@response.xml).to be_present
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "different payment methods" do
|
21
|
+
context ":status, paid iDeal" do
|
22
|
+
before(:each) do
|
23
|
+
file = "#{File.dirname(__FILE__)}/xml/status-paid-ideal.xml"
|
24
|
+
@xml = open(file)
|
25
|
+
@response = Docdata::Response.parse(:status, @xml)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "has 'total_registered' method" do
|
29
|
+
expect(@response.total_registered).to eq(500)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "returns 0 for empty values" do
|
33
|
+
expect(@response.total_shopper_pending).to eq(0)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "returns amount" do
|
37
|
+
expect(@response.amount).to eq(500)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "returns payment_method" do
|
41
|
+
expect(@response.payment_method).to eq("IDEAL")
|
42
|
+
end
|
43
|
+
|
44
|
+
it "is paid" do
|
45
|
+
expect(@response).to be_success
|
46
|
+
expect(@response).to be_paid
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
it "has currency EUR" do
|
52
|
+
expect(@response.xml).to be_present
|
53
|
+
expect(@response.currency).to eq("EUR")
|
54
|
+
end
|
55
|
+
|
56
|
+
it "is NOT canceled" do
|
57
|
+
expect(@response).to be_success
|
58
|
+
expect(@response).not_to be_canceled
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
context ":status, canceled iDeal" do
|
64
|
+
before(:each) do
|
65
|
+
file = "#{File.dirname(__FILE__)}/xml/status-canceled-ideal.xml"
|
66
|
+
@xml = open(file)
|
67
|
+
@response = Docdata::Response.parse(:status, @xml)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "has 'total_registered' method" do
|
71
|
+
expect(@response.total_registered).to eq(500)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "returns 0 for empty values" do
|
75
|
+
expect(@response.total_shopper_pending).to eq(0)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returns amount" do
|
79
|
+
# puts "xml: #{@response.xml}"
|
80
|
+
expect(@response.amount).to eq(500)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "returns payment_method" do
|
84
|
+
expect(@response.payment_method).to eq("IDEAL")
|
85
|
+
end
|
86
|
+
|
87
|
+
it "is NOT paid" do
|
88
|
+
expect(@response).to be_success
|
89
|
+
expect(@response).not_to be_paid
|
90
|
+
end
|
91
|
+
|
92
|
+
it "is canceled" do
|
93
|
+
expect(@response).to be_success
|
94
|
+
expect(@response).to be_canceled
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
context ":status, paid creditcard" do
|
100
|
+
before(:each) do
|
101
|
+
file = "#{File.dirname(__FILE__)}/xml/status-paid-creditcard.xml"
|
102
|
+
@xml = open(file)
|
103
|
+
@response = Docdata::Response.parse(:status, @xml)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "has 'total_registered' method" do
|
107
|
+
expect(@response.total_registered).to eq(500)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "returns amount" do
|
111
|
+
expect(@response.amount).to eq(500)
|
112
|
+
end
|
113
|
+
|
114
|
+
it "returns payment_method" do
|
115
|
+
expect(@response.payment_method).to eq("MASTERCARD")
|
116
|
+
end
|
117
|
+
|
118
|
+
it "is paid" do
|
119
|
+
expect(@response).to be_success
|
120
|
+
expect(@response).to be_paid
|
121
|
+
end
|
122
|
+
|
123
|
+
it "is NOT canceled" do
|
124
|
+
expect(@response).to be_success
|
125
|
+
expect(@response).not_to be_canceled
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context ":status, canceled creditcard" do
|
130
|
+
before(:each) do
|
131
|
+
file = "#{File.dirname(__FILE__)}/xml/status-canceled-creditcard.xml"
|
132
|
+
@xml = open(file)
|
133
|
+
@response = Docdata::Response.parse(:status, @xml)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "returns amount" do
|
137
|
+
expect(@response.amount).to eq(500)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "is NOT paid" do
|
141
|
+
expect(@response).to be_success
|
142
|
+
expect(@response).not_to be_paid
|
143
|
+
end
|
144
|
+
|
145
|
+
it "is canceled" do
|
146
|
+
expect(@response).to be_success
|
147
|
+
expect(@response).to be_canceled
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
context ":status, paid sofort" do
|
153
|
+
before(:each) do
|
154
|
+
file = "#{File.dirname(__FILE__)}/xml/status-paid-sofort.xml"
|
155
|
+
@xml = open(file)
|
156
|
+
@response = Docdata::Response.parse(:status, @xml)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "has 'total_registered' method" do
|
160
|
+
expect(@response.total_registered).to eq(500)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "returns amount" do
|
164
|
+
expect(@response.amount).to eq(500)
|
165
|
+
end
|
166
|
+
|
167
|
+
it "returns payment_method" do
|
168
|
+
expect(@response.payment_method).to eq("SOFORT_UEBERWEISUNG")
|
169
|
+
end
|
170
|
+
|
171
|
+
it "is paid" do
|
172
|
+
expect(@response).to be_success
|
173
|
+
expect(@response).to be_paid
|
174
|
+
end
|
175
|
+
|
176
|
+
it "is NOT canceled" do
|
177
|
+
expect(@response).to be_success
|
178
|
+
expect(@response).not_to be_canceled
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
# context ":status, canceled sofort" do
|
183
|
+
# before(:each) do
|
184
|
+
# file = "#{File.dirname(__FILE__)}/xml/status-canceled-sofort.xml"
|
185
|
+
# @xml = open(file)
|
186
|
+
# @response = Docdata::Response.parse(:status, @xml)
|
187
|
+
# end
|
188
|
+
|
189
|
+
# it "returns amount" do
|
190
|
+
# expect(@response.amount).to eq(500)
|
191
|
+
# end
|
192
|
+
|
193
|
+
# it "is NOT paid" do
|
194
|
+
# expect(@response).to be_success
|
195
|
+
# expect(@response).not_to be_paid
|
196
|
+
# end
|
197
|
+
|
198
|
+
# it "is canceled" do
|
199
|
+
# expect(@response).to be_success
|
200
|
+
# expect(@response).to be_canceled
|
201
|
+
# end
|
202
|
+
|
203
|
+
# end
|
204
|
+
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Docdata::Shopper do
|
4
|
+
before(:each) do
|
5
|
+
@shopper = Docdata::Shopper.new
|
6
|
+
@shopper.first_name = "John"
|
7
|
+
@shopper.last_name = "Doe"
|
8
|
+
end
|
9
|
+
|
10
|
+
context "validations" do
|
11
|
+
it "validates attributes" do
|
12
|
+
shopper = Docdata::Shopper.new
|
13
|
+
expect(shopper).not_to be_valid
|
14
|
+
expect(shopper.errors.count).to eq(1)
|
15
|
+
expect(shopper.errors.full_messages).to include("id is not present")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "creates a valid shopper" do
|
19
|
+
shopper = Docdata::Shopper.create_valid_shopper
|
20
|
+
expect(shopper).to be_valid
|
21
|
+
end
|
22
|
+
|
23
|
+
it "sets up proper defaults" do
|
24
|
+
shopper = Docdata::Shopper.new
|
25
|
+
expect(shopper.first_name).to eq("First Name")
|
26
|
+
expect(shopper.last_name).to eq("Last Name")
|
27
|
+
expect(shopper.street).to eq("Main Street")
|
28
|
+
expect(shopper.house_number).to eq("123")
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
it "has a name" do
|
34
|
+
expect(@shopper.first_name).to eq("John")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "has a full name" do
|
38
|
+
expect(@shopper.name).to eq("John Doe")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "belongs to a payment" do
|
42
|
+
@payment = Docdata::Payment.new
|
43
|
+
@payment.amount = 500
|
44
|
+
@payment.currency = "EUR"
|
45
|
+
@payment.shopper = @shopper
|
46
|
+
expect(@payment.shopper).to be_kind_of(Docdata::Shopper)
|
47
|
+
expect(@payment.shopper.first_name).to eq("John")
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.setup(:default, :development)
|
3
|
+
|
4
|
+
require 'simplecov'
|
5
|
+
require 'coveralls'
|
6
|
+
|
7
|
+
Coveralls.wear!
|
8
|
+
# SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
9
|
+
# SimpleCov::Formatter::HTMLFormatter,
|
10
|
+
# Coveralls::SimpleCov::Formatter
|
11
|
+
# ]
|
12
|
+
# SimpleCov.start
|
13
|
+
|
14
|
+
require 'rubygems'
|
15
|
+
require 'bundler/setup'
|
16
|
+
require 'vcr'
|
17
|
+
require 'cgi'
|
18
|
+
require 'docdata'
|
19
|
+
|
20
|
+
VCR.configure do |c|
|
21
|
+
c.cassette_library_dir = 'spec/vcr_cassettes'
|
22
|
+
c.hook_into :fakeweb
|
23
|
+
c.register_request_matcher :ignore_query_param_ordering do |r1, r2|
|
24
|
+
uri1 = URI(r1.uri)
|
25
|
+
uri2 = URI(r2.uri)
|
26
|
+
|
27
|
+
uri1.scheme == uri2.scheme &&
|
28
|
+
uri1.host == uri2.host &&
|
29
|
+
uri1.path == uri2.path &&
|
30
|
+
CGI.parse(uri1.query) == CGI.parse(uri2.query)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
RSpec.configure do |config|
|
35
|
+
config.order = "random"
|
36
|
+
end
|