ibandit 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ module Ibandit
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,130 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ibandit::CheckDigit do
4
+ describe '.mod_97_10' do
5
+ subject { described_class.mod_97_10(account_number) }
6
+
7
+ context 'with a non-numeric character' do
8
+ let(:account_number) { 'hhhh' }
9
+ specify { expect { subject }.to raise_error(/non-alphanumeric/) }
10
+ end
11
+ end
12
+
13
+ describe '.spanish' do
14
+ subject { described_class.spanish(account_number) }
15
+
16
+ context 'sequence that should give a check digit of 0' do
17
+ let(:account_number) { '12345678' }
18
+ it { is_expected.to eq('0') }
19
+ end
20
+
21
+ context 'sequence that should give a check digit of 8' do
22
+ let(:account_number) { '0000012345' }
23
+ it { is_expected.to eq('8') }
24
+ end
25
+
26
+ context 'with a non-numeric character' do
27
+ let(:account_number) { '000001234A' }
28
+ it 'raises an error' do
29
+ expect { subject }.to raise_error(Ibandit::InvalidCharacterError)
30
+ end
31
+ end
32
+ end
33
+
34
+ describe '.lund' do
35
+ subject { described_class.lund(account_number) }
36
+
37
+ let(:account_number) { '1200300002088' }
38
+ it { is_expected.to eq('3') }
39
+
40
+ context 'with another account number (double checking!)' do
41
+ let(:account_number) { '1428350017114' }
42
+ it { is_expected.to eq('1') }
43
+ end
44
+
45
+ context 'with a non-numeric character' do
46
+ let(:account_number) { '1BAD2014' }
47
+ specify { expect { subject }.to raise_error(/non-numeric character/) }
48
+ end
49
+ end
50
+
51
+ describe '.estonian' do
52
+ subject { described_class.estonian(account_number) }
53
+
54
+ context "with an account_number that doesn't start with a zero" do
55
+ let(:account_number) { '22102014568' }
56
+ it { is_expected.to eq('5') }
57
+ end
58
+
59
+ context 'with leading zeros' do
60
+ let(:account_number) { '0022102014568' }
61
+ it { is_expected.to eq('5') }
62
+ end
63
+
64
+ context 'with a non-numeric character' do
65
+ let(:account_number) { '1BAD2014' }
66
+ specify { expect { subject }.to raise_error(/non-numeric character/) }
67
+ end
68
+ end
69
+
70
+ describe '.dutch' do
71
+ subject { described_class.dutch(account_number) }
72
+
73
+ let(:account_number) { '041716430' }
74
+ it { is_expected.to eq('0') }
75
+
76
+ context 'with another account number (double checking!)' do
77
+ let(:account_number) { '030006526' }
78
+ it { is_expected.to eq('4') }
79
+ end
80
+
81
+ context 'with a non-numeric character' do
82
+ let(:account_number) { '1BAD2014' }
83
+ specify { expect { subject }.to raise_error(/non-numeric character/) }
84
+ end
85
+ end
86
+
87
+ describe '.slovakian_prefix' do
88
+ subject { described_class.slovakian_prefix(account_number) }
89
+
90
+ let(:account_number) { '00001' }
91
+ it { is_expected.to eq('9') }
92
+
93
+ context 'with a non-numeric character' do
94
+ let(:account_number) { '1BAD2014' }
95
+ specify { expect { subject }.to raise_error(/non-numeric character/) }
96
+ end
97
+ end
98
+
99
+ describe '.slovakian_basic' do
100
+ subject { described_class.slovakian_basic(account_number) }
101
+
102
+ let(:account_number) { '874263754' }
103
+ it { is_expected.to eq('1') }
104
+
105
+ context 'with a non-numeric character' do
106
+ let(:account_number) { '1BAD2014' }
107
+ specify { expect { subject }.to raise_error(/non-numeric character/) }
108
+ end
109
+ end
110
+
111
+ describe '.rib' do
112
+ subject { described_class.rib(bank_code, branch_code, account_number) }
113
+
114
+ context 'with some non-numeric characters' do
115
+ let(:bank_code) { '12BD4' }
116
+ let(:branch_code) { '367WX' }
117
+ let(:account_number) { '12345678912' }
118
+
119
+ it { is_expected.to eq('20') }
120
+ end
121
+
122
+ context 'with numeric characters' do
123
+ let(:bank_code) { '12244' }
124
+ let(:branch_code) { '36767' }
125
+ let(:account_number) { '12345678912' }
126
+
127
+ it { is_expected.to eq('20') }
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,853 @@
1
+ require 'spec_helper'
2
+
3
+ describe Ibandit::IBANBuilder do
4
+ shared_examples_for 'allows round trips' do |iban_code|
5
+ let(:iban) { Ibandit::IBAN.new(iban_code) }
6
+ let(:args) do
7
+ {
8
+ country_code: iban.country_code,
9
+ account_number: iban.account_number,
10
+ branch_code: iban.branch_code,
11
+ bank_code: iban.bank_code
12
+ }
13
+ end
14
+
15
+ it 'successfully reconstructs the IBAN' do
16
+ expect(described_class.build(args).iban).to eq(iban.iban)
17
+ end
18
+ end
19
+
20
+ describe '.build' do
21
+ subject(:build) { described_class.build(args) }
22
+ let(:args) { { country_code: 'ES' } }
23
+
24
+ context 'without a country_code' do
25
+ let(:args) { { bank_code: 1 } }
26
+
27
+ it 'raises a helpful error message' do
28
+ expect { build }.to raise_error(ArgumentError, /provide a country_code/)
29
+ end
30
+ end
31
+
32
+ context 'with an unsupported country_code' do
33
+ let(:args) { { country_code: 'FU' } }
34
+
35
+ it 'raises a helpful error message' do
36
+ expect { build }.to raise_error(Ibandit::UnsupportedCountryError)
37
+ end
38
+ end
39
+
40
+ context 'with AT as the country_code' do
41
+ let(:args) do
42
+ {
43
+ country_code: 'AT',
44
+ account_number: '00234573201',
45
+ bank_code: '19043'
46
+ }
47
+ end
48
+
49
+ its(:iban) { is_expected.to eq('AT611904300234573201') }
50
+
51
+ it_behaves_like 'allows round trips', 'AT61 1904 3002 3457 3201'
52
+
53
+ context "with an account number that hasn't been zero-padded" do
54
+ before { args[:account_number] = '234573201' }
55
+ its(:iban) { is_expected.to eq('AT611904300234573201') }
56
+ end
57
+
58
+ context 'without an account_number' do
59
+ before { args.delete(:account_number) }
60
+
61
+ it 'raises a helpful error message' do
62
+ expect { build }.
63
+ to raise_error(ArgumentError, /account_number is a required field/)
64
+ end
65
+ end
66
+
67
+ context 'without an bank_code' do
68
+ before { args.delete(:bank_code) }
69
+
70
+ it 'raises a helpful error message' do
71
+ expect { build }.
72
+ to raise_error(ArgumentError, /bank_code is a required field/)
73
+ end
74
+ end
75
+ end
76
+
77
+ context 'with BE as the country_code' do
78
+ let(:args) { { country_code: 'BE', account_number: '510007547061' } }
79
+
80
+ its(:iban) { is_expected.to eq('BE62510007547061') }
81
+
82
+ it_behaves_like 'allows round trips', 'BE62 5100 0754 7061'
83
+
84
+ context 'with dashes' do
85
+ before { args[:account_number] = '510-0075470-61' }
86
+ its(:iban) { is_expected.to eq('BE62510007547061') }
87
+ end
88
+
89
+ context 'without an account_number' do
90
+ before { args.delete(:account_number) }
91
+
92
+ it 'raises a helpful error message' do
93
+ expect { build }.
94
+ to raise_error(ArgumentError, /account_number is a required field/)
95
+ end
96
+ end
97
+ end
98
+
99
+ context 'with CY as the country_code' do
100
+ let(:args) do
101
+ {
102
+ country_code: 'CY',
103
+ account_number: '0000001200527600',
104
+ bank_code: '002',
105
+ branch_code: '00128'
106
+ }
107
+ end
108
+
109
+ its(:iban) { is_expected.to eq('CY17002001280000001200527600') }
110
+
111
+ it_behaves_like 'allows round trips', 'CY17 0020 0128 0000 0012 0052 7600'
112
+
113
+ context "with an account number that hasn't been zero-padded" do
114
+ before { args[:account_number] = '1200527600' }
115
+ its(:iban) { is_expected.to eq('CY17002001280000001200527600') }
116
+ end
117
+
118
+ context 'without an branch_code' do
119
+ before { args.delete(:branch_code) }
120
+ its(:iban) { is_expected.to eq('CY040020000001200527600') }
121
+ end
122
+
123
+ context 'without an account_number' do
124
+ before { args.delete(:account_number) }
125
+
126
+ it 'raises a helpful error message' do
127
+ expect { build }.
128
+ to raise_error(ArgumentError, /account_number is a required field/)
129
+ end
130
+ end
131
+
132
+ context 'without an bank_code' do
133
+ before { args.delete(:bank_code) }
134
+
135
+ it 'raises a helpful error message' do
136
+ expect { build }.
137
+ to raise_error(ArgumentError, /bank_code is a required field/)
138
+ end
139
+ end
140
+ end
141
+
142
+ context 'with DE as the country_code' do
143
+ let(:args) do
144
+ { country_code: 'DE',
145
+ bank_code: '37040044',
146
+ account_number: '0532013000' }
147
+ end
148
+
149
+ its(:iban) { is_expected.to eq('DE89370400440532013000') }
150
+
151
+ it_behaves_like 'allows round trips', 'DE89 3704 0044 0532 0130 00'
152
+
153
+ context 'without a bank_code' do
154
+ before { args.delete(:bank_code) }
155
+
156
+ specify do
157
+ expect { build }.
158
+ to raise_error(ArgumentError, /bank_code is a required field/)
159
+ end
160
+ end
161
+
162
+ context 'without an account_number' do
163
+ before { args.delete(:account_number) }
164
+
165
+ specify do
166
+ expect { build }.
167
+ to raise_error(ArgumentError, /account_number is a required field/)
168
+ end
169
+ end
170
+ end
171
+
172
+ context 'with EE as the country_code' do
173
+ let(:args) { { country_code: 'EE', account_number: '0221020145685' } }
174
+
175
+ its(:iban) { is_expected.to eq('EE382200221020145685') }
176
+
177
+ it_behaves_like 'allows round trips', 'EE38 2200 2210 2014 5685'
178
+
179
+ context 'with an account number that needs translating' do
180
+ before { args[:account_number] = '111020145685' }
181
+ its(:iban) { is_expected.to eq('EE412200111020145685') }
182
+ end
183
+
184
+ context 'without an account_number' do
185
+ before { args.delete(:account_number) }
186
+
187
+ it 'raises a helpful error message' do
188
+ expect { build }.
189
+ to raise_error(ArgumentError, /account_number is a required field/)
190
+ end
191
+ end
192
+ end
193
+
194
+ context 'with ES as the country_code' do
195
+ let(:args) do
196
+ {
197
+ country_code: 'ES',
198
+ bank_code: '2310',
199
+ branch_code: '0001',
200
+ account_number: '180000012345'
201
+ }
202
+ end
203
+
204
+ its(:iban) { is_expected.to eq('ES8023100001180000012345') }
205
+
206
+ it_behaves_like 'allows round trips', 'ES80 2310 0001 1800 0001 2345'
207
+
208
+ context 'without a bank_code or branch code' do
209
+ before { args.delete(:bank_code) }
210
+ before { args.delete(:branch_code) }
211
+ before { args[:account_number] = '23100001180000012345' }
212
+
213
+ its(:iban) { is_expected.to eq('ES8023100001180000012345') }
214
+ end
215
+
216
+ context 'without an account_number' do
217
+ before { args.delete(:account_number) }
218
+
219
+ it 'raises a helpful error message' do
220
+ expect { build }.
221
+ to raise_error(ArgumentError, /account_number is a required field/)
222
+ end
223
+ end
224
+ end
225
+
226
+ context 'with FI as the country_code' do
227
+ let(:args) do
228
+ { country_code: 'FI', bank_code: '123456', account_number: '785' }
229
+ end
230
+
231
+ its(:iban) { is_expected.to eq('FI2112345600000785') }
232
+
233
+ it_behaves_like 'allows round trips', 'FI21 1234 5600 0007 85'
234
+
235
+ context 'with a savings bank account_number in traditional format' do
236
+ before { args[:account_number] = '78510' }
237
+ before { args[:bank_code] = '423456' }
238
+
239
+ its(:iban) { is_expected.to eq('FI3442345670008510') }
240
+ end
241
+
242
+ context 'without an account_number' do
243
+ before { args.delete(:account_number) }
244
+
245
+ it 'raises a helpful error message' do
246
+ expect { build }.
247
+ to raise_error(ArgumentError, /account_number is a required field/)
248
+ end
249
+ end
250
+
251
+ context 'without a bank_code' do
252
+ before { args.delete(:bank_code) }
253
+
254
+ it 'raises a helpful error message' do
255
+ expect { build }.
256
+ to raise_error(ArgumentError, /bank_code is a required field/)
257
+ end
258
+ end
259
+ end
260
+
261
+ context 'with FR as the country_code' do
262
+ let(:args) do
263
+ {
264
+ country_code: 'FR',
265
+ bank_code: '20041',
266
+ branch_code: '01005',
267
+ account_number: '0500013M02606'
268
+ }
269
+ end
270
+
271
+ its(:iban) { is_expected.to eq('FR1420041010050500013M02606') }
272
+
273
+ it_behaves_like 'allows round trips', 'FR14 2004 1010 0505 0001 3M02 606'
274
+
275
+ context 'without the rib key in the account number' do
276
+ before { args[:account_number] = '0500013M026' }
277
+ its(:valid?) { is_expected.to be_falsey }
278
+ end
279
+
280
+ context 'without a bank_code' do
281
+ before { args.delete(:bank_code) }
282
+
283
+ it 'raises a helpful error message' do
284
+ expect { build }.
285
+ to raise_error(ArgumentError, /bank_code is a required field/)
286
+ end
287
+ end
288
+
289
+ context 'without a branch_code' do
290
+ before { args.delete(:branch_code) }
291
+
292
+ it 'raises a helpful error message' do
293
+ expect { build }.
294
+ to raise_error(ArgumentError, /branch_code is a required field/)
295
+ end
296
+ end
297
+
298
+ context 'without an account_number' do
299
+ before { args.delete(:account_number) }
300
+
301
+ it 'raises a helpful error message' do
302
+ expect { build }.
303
+ to raise_error(ArgumentError, /account_number is a required field/)
304
+ end
305
+ end
306
+ end
307
+
308
+ context 'with GB as the country_code' do
309
+ let(:args) do
310
+ { country_code: 'GB',
311
+ bank_code: 'BARC',
312
+ branch_code: '200000',
313
+ account_number: '579135' }
314
+ end
315
+
316
+ its(:iban) { is_expected.to eq('GB07BARC20000000579135') }
317
+
318
+ it_behaves_like 'allows round trips', 'GB07 BARC 2000 0000 5791 35'
319
+
320
+ context 'when the sort code is hyphenated' do
321
+ before { args[:branch_code] = '20-00-00' }
322
+ its(:iban) { is_expected.to eq('GB07BARC20000000579135') }
323
+ end
324
+
325
+ context 'when the sort code is spaced' do
326
+ before { args[:branch_code] = '20 00 00' }
327
+ its(:iban) { is_expected.to eq('GB07BARC20000000579135') }
328
+ end
329
+
330
+ context 'when the account number is spaced' do
331
+ before { args[:account_number] = '579 135' }
332
+ its(:iban) { is_expected.to eq('GB07BARC20000000579135') }
333
+ end
334
+
335
+ context 'when the account number is hyphenated' do
336
+ before { args[:account_number] = '5577-9911' }
337
+ its(:iban) { is_expected.to eq('GB60BARC20000055779911') }
338
+ end
339
+
340
+ context 'with the bank_code supplied manually' do
341
+ before { args.merge!(bank_code: 'BARC') }
342
+ its(:iban) { is_expected.to eq('GB07BARC20000000579135') }
343
+ end
344
+
345
+ context 'without a branch_code' do
346
+ before { args.delete(:branch_code) }
347
+
348
+ specify do
349
+ expect { build }.
350
+ to raise_error(ArgumentError, /branch_code is a required field/)
351
+ end
352
+ end
353
+
354
+ context 'without an account_number' do
355
+ before { args.delete(:account_number) }
356
+
357
+ specify do
358
+ expect { build }.
359
+ to raise_error(ArgumentError, /account_number is a required field/)
360
+ end
361
+ end
362
+
363
+ context 'without a bank_code' do
364
+ before { args.delete(:bank_code) }
365
+
366
+ context 'when a bic_finder is not defined' do
367
+ specify do
368
+ expect { build }.
369
+ to raise_error(ArgumentError, /bank_code is a required field/)
370
+ end
371
+ end
372
+
373
+ context 'with a bic_finder' do
374
+ let(:bic_finder) { double }
375
+ before do
376
+ allow(bic_finder).to receive(:find).with('GB', '200000').
377
+ and_return('BARCGB22XXX')
378
+ Ibandit.bic_finder = ->(cc, id) { bic_finder.find(cc, id) }
379
+ end
380
+ after { Ibandit.bic_finder = nil }
381
+
382
+ its(:iban) { is_expected.to eq('GB07BARC20000000579135') }
383
+
384
+ context "when the BIC can't be found" do
385
+ before { Ibandit.bic_finder = ->(_cc, _id) { nil } }
386
+
387
+ it 'raises an Ibandit::BicNotFoundError' do
388
+ expect { build }.to raise_error(Ibandit::BicNotFoundError)
389
+ end
390
+ end
391
+ end
392
+ end
393
+
394
+ context 'with both a bank_code and a bic_finder' do
395
+ let(:bic_finder) { double }
396
+ before do
397
+ allow(bic_finder).to receive(:find).with('GB', '200000').
398
+ and_return('BANKGB22XXX')
399
+ Ibandit.bic_finder = ->(cc, id) { bic_finder.find(cc, id) }
400
+ end
401
+ after { Ibandit.bic_finder = nil }
402
+
403
+ it 'uses the explicitly provided bank_code' do
404
+ expect(subject.iban).to eq('GB07BARC20000000579135')
405
+ end
406
+ end
407
+ end
408
+
409
+ context 'with IE as the country_code' do
410
+ let(:args) do
411
+ { country_code: 'IE',
412
+ bank_code: 'AIBK',
413
+ branch_code: '931152',
414
+ account_number: '12345678' }
415
+ end
416
+
417
+ its(:iban) { is_expected.to eq('IE29AIBK93115212345678') }
418
+
419
+ it_behaves_like 'allows round trips', 'IE29 AIBK 9311 5212 3456 78'
420
+
421
+ context 'with hyphens in the sort code' do
422
+ before { args[:branch_code] = '93-11-52' }
423
+ its(:iban) { is_expected.to eq('IE29AIBK93115212345678') }
424
+ end
425
+
426
+ context 'without a branch_code' do
427
+ before { args.delete(:branch_code) }
428
+
429
+ it 'raises a helpful error message' do
430
+ expect { build }.
431
+ to raise_error(ArgumentError, /branch_code is a required field/)
432
+ end
433
+ end
434
+
435
+ context 'without an account_number' do
436
+ before { args.delete(:account_number) }
437
+
438
+ it 'raises a helpful error message' do
439
+ expect { build }.
440
+ to raise_error(ArgumentError, /account_number is a required field/)
441
+ end
442
+ end
443
+
444
+ context 'without a bank_code' do
445
+ before { args.delete(:bank_code) }
446
+
447
+ context 'when a bic_finder is not defined' do
448
+ specify do
449
+ expect { build }.
450
+ to raise_error(ArgumentError, /bank_code is a required field/)
451
+ end
452
+ end
453
+
454
+ context 'with a bic_finder' do
455
+ let(:bic_finder) { double }
456
+ before do
457
+ allow(bic_finder).to receive(:find).with('IE', '931152').
458
+ and_return('AIBK1234XXX')
459
+ Ibandit.bic_finder = ->(cc, id) { bic_finder.find(cc, id) }
460
+ end
461
+ after { Ibandit.bic_finder = nil }
462
+
463
+ its(:iban) { is_expected.to eq('IE29AIBK93115212345678') }
464
+
465
+ context "when the BIC can't be found" do
466
+ before { Ibandit.bic_finder = ->(_cc, _id) { nil } }
467
+
468
+ it 'raises an Ibandit::BicNotFoundError' do
469
+ expect { build }.to raise_error(Ibandit::BicNotFoundError)
470
+ end
471
+ end
472
+ end
473
+ end
474
+
475
+ context 'with both a bank_code and a bic_finder' do
476
+ let(:bic_finder) { double }
477
+ before do
478
+ allow(bic_finder).to receive(:find).with('IE', '931152').
479
+ and_return('BANK1234XXX')
480
+ Ibandit.bic_finder = ->(cc, id) { bic_finder.find(cc, id) }
481
+ end
482
+ after { Ibandit.bic_finder = nil }
483
+
484
+ it 'uses the explicitly provided bank_code' do
485
+ expect(subject.iban).to eq('IE29AIBK93115212345678')
486
+ end
487
+ end
488
+ end
489
+
490
+ context 'with IT as the country_code' do
491
+ let(:args) do
492
+ {
493
+ country_code: 'IT',
494
+ bank_code: '05428',
495
+ branch_code: '11101',
496
+ account_number: '0000123456'
497
+ }
498
+ end
499
+
500
+ its(:iban) { is_expected.to eq('IT60X0542811101000000123456') }
501
+
502
+ it_behaves_like 'allows round trips', 'IT60 X054 2811 1010 0000 0123 456'
503
+
504
+ context 'with an explicitly passed check digit' do
505
+ before { args[:check_digit] = 'Y' }
506
+ its(:iban) { is_expected.to eq('IT64Y0542811101000000123456') }
507
+ end
508
+
509
+ context 'without a bank_code' do
510
+ before { args.delete(:bank_code) }
511
+
512
+ it 'raises a helpful error message' do
513
+ expect { build }.
514
+ to raise_error(ArgumentError, /bank_code is a required field/)
515
+ end
516
+ end
517
+
518
+ context 'without a branch_code' do
519
+ before { args.delete(:branch_code) }
520
+
521
+ it 'raises a helpful error message' do
522
+ expect { build }.
523
+ to raise_error(ArgumentError, /branch_code is a required field/)
524
+ end
525
+ end
526
+
527
+ context 'without an account_number' do
528
+ before { args.delete(:account_number) }
529
+
530
+ it 'raises a helpful error message' do
531
+ expect { build }.
532
+ to raise_error(ArgumentError, /account_number is a required field/)
533
+ end
534
+ end
535
+ end
536
+
537
+ context 'with LU as the country_code' do
538
+ let(:args) do
539
+ {
540
+ country_code: 'LU',
541
+ account_number: '9400644750000',
542
+ bank_code: '001'
543
+ }
544
+ end
545
+
546
+ its(:iban) { is_expected.to eq('LU280019400644750000') }
547
+
548
+ it_behaves_like 'allows round trips', 'LU28 0019 4006 4475 0000'
549
+
550
+ context 'without an account_number' do
551
+ before { args.delete(:account_number) }
552
+
553
+ it 'raises a helpful error message' do
554
+ expect { build }.
555
+ to raise_error(ArgumentError, /account_number is a required field/)
556
+ end
557
+ end
558
+
559
+ context 'without a bank_code' do
560
+ before { args.delete(:bank_code) }
561
+
562
+ it 'raises a helpful error message' do
563
+ expect { build }.
564
+ to raise_error(ArgumentError, /bank_code is a required field/)
565
+ end
566
+ end
567
+ end
568
+
569
+ context 'with LV as the country_code' do
570
+ let(:args) do
571
+ {
572
+ country_code: 'LV',
573
+ account_number: '1234567890123',
574
+ bank_code: 'BANK'
575
+ }
576
+ end
577
+
578
+ its(:iban) { is_expected.to eq('LV72BANK1234567890123') }
579
+
580
+ it_behaves_like 'allows round trips', 'LV72 BANK 1234 5678 9012 3'
581
+
582
+ context 'without an account_number' do
583
+ before { args.delete(:account_number) }
584
+
585
+ it 'raises a helpful error message' do
586
+ expect { build }.
587
+ to raise_error(ArgumentError, /account_number is a required field/)
588
+ end
589
+ end
590
+
591
+ context 'without a bank_code' do
592
+ before { args.delete(:bank_code) }
593
+
594
+ it 'raises a helpful error message' do
595
+ expect { build }.
596
+ to raise_error(ArgumentError, /bank_code is a required field/)
597
+ end
598
+ end
599
+ end
600
+
601
+ context 'with MC as the country_code' do
602
+ let(:args) do
603
+ {
604
+ country_code: 'MC',
605
+ bank_code: '20041',
606
+ branch_code: '01005',
607
+ account_number: '0500013M02606'
608
+ }
609
+ end
610
+
611
+ its(:iban) { is_expected.to eq('MC9320041010050500013M02606') }
612
+
613
+ it_behaves_like 'allows round trips', 'MC93 2004 1010 0505 0001 3M02 606'
614
+
615
+ context 'without the rib key in the account number' do
616
+ before { args[:account_number] = '0500013M026' }
617
+ its(:valid?) { is_expected.to be_falsey }
618
+ end
619
+
620
+ context 'without a bank_code' do
621
+ before { args.delete(:bank_code) }
622
+
623
+ it 'raises a helpful error message' do
624
+ expect { build }.
625
+ to raise_error(ArgumentError, /bank_code is a required field/)
626
+ end
627
+ end
628
+
629
+ context 'without a branch_code' do
630
+ before { args.delete(:branch_code) }
631
+
632
+ it 'raises a helpful error message' do
633
+ expect { build }.
634
+ to raise_error(ArgumentError, /branch_code is a required field/)
635
+ end
636
+ end
637
+
638
+ context 'without an account_number' do
639
+ before { args.delete(:account_number) }
640
+
641
+ it 'raises a helpful error message' do
642
+ expect { build }.
643
+ to raise_error(ArgumentError, /account_number is a required field/)
644
+ end
645
+ end
646
+ end
647
+
648
+ context 'with NL as the country_code' do
649
+ let(:args) do
650
+ {
651
+ country_code: 'NL',
652
+ account_number: '0417164300',
653
+ bank_code: 'ABNA'
654
+ }
655
+ end
656
+
657
+ its(:iban) { is_expected.to eq('NL91ABNA0417164300') }
658
+
659
+ it_behaves_like 'allows round trips', 'NL91 ABNA 0417 1643 00'
660
+
661
+ context "with an account number that hasn't been zero-padded" do
662
+ before { args[:account_number] = '417164300' }
663
+ its(:iban) { is_expected.to eq('NL91ABNA0417164300') }
664
+ end
665
+
666
+ context 'without an account_number' do
667
+ before { args.delete(:account_number) }
668
+
669
+ it 'raises a helpful error message' do
670
+ expect { build }.
671
+ to raise_error(ArgumentError, /account_number is a required field/)
672
+ end
673
+ end
674
+
675
+ context 'without an bank_code' do
676
+ before { args.delete(:bank_code) }
677
+
678
+ it 'raises a helpful error message' do
679
+ expect { build }.
680
+ to raise_error(ArgumentError, /bank_code is a required field/)
681
+ end
682
+ end
683
+ end
684
+
685
+ context 'with PT as the country_code' do
686
+ let(:args) do
687
+ {
688
+ country_code: 'PT',
689
+ bank_code: '0002',
690
+ branch_code: '0023',
691
+ account_number: '0023843000578'
692
+ }
693
+ end
694
+
695
+ its(:iban) { is_expected.to eq('PT50000200230023843000578') }
696
+
697
+ it_behaves_like 'allows round trips', 'PT50 0002 0023 0023 8430 0057 8'
698
+
699
+ context 'without a bank_code' do
700
+ before { args.delete(:bank_code) }
701
+
702
+ it 'raises a helpful error message' do
703
+ expect { build }.
704
+ to raise_error(ArgumentError, /bank_code is a required field/)
705
+ end
706
+ end
707
+
708
+ context 'without a branch_code' do
709
+ before { args.delete(:branch_code) }
710
+
711
+ it 'raises a helpful error message' do
712
+ expect { build }.
713
+ to raise_error(ArgumentError, /branch_code is a required field/)
714
+ end
715
+ end
716
+
717
+ context 'without an account_number' do
718
+ before { args.delete(:account_number) }
719
+
720
+ it 'raises a helpful error message' do
721
+ expect { build }.
722
+ to raise_error(ArgumentError, /account_number is a required field/)
723
+ end
724
+ end
725
+ end
726
+
727
+ context 'with SI as the country_code' do
728
+ let(:args) do
729
+ {
730
+ country_code: 'SI',
731
+ bank_code: '19100',
732
+ account_number: '0000123438'
733
+ }
734
+ end
735
+
736
+ its(:iban) { is_expected.to eq('SI56191000000123438') }
737
+
738
+ it_behaves_like 'allows round trips', 'SI56 1910 0000 0123 438'
739
+
740
+ context 'with an account number that needs padding' do
741
+ before { args[:account_number] = '123438' }
742
+ its(:iban) { is_expected.to eq('SI56191000000123438') }
743
+ end
744
+
745
+ context 'without a bank_code' do
746
+ before { args.delete(:bank_code) }
747
+
748
+ it 'raises a helpful error message' do
749
+ expect { build }.
750
+ to raise_error(ArgumentError, /bank_code is a required field/)
751
+ end
752
+ end
753
+
754
+ context 'without an account_number' do
755
+ before { args.delete(:account_number) }
756
+
757
+ it 'raises a helpful error message' do
758
+ expect { build }.
759
+ to raise_error(ArgumentError, /account_number is a required field/)
760
+ end
761
+ end
762
+ end
763
+
764
+ context 'with SK as the country_code' do
765
+ let(:args) do
766
+ {
767
+ country_code: 'SK',
768
+ bank_code: '1200',
769
+ account_number_prefix: '000019',
770
+ account_number: '8742637541'
771
+ }
772
+ end
773
+
774
+ its(:iban) { is_expected.to eq('SK3112000000198742637541') }
775
+
776
+ it_behaves_like 'allows round trips', 'SK31 1200 0000 1987 4263 7541'
777
+
778
+ context 'with an account number prefix that needs padding' do
779
+ before { args[:account_number_prefix] = '19' }
780
+ its(:iban) { is_expected.to eq('SK3112000000198742637541') }
781
+ end
782
+
783
+ context 'without a bank_code' do
784
+ before { args.delete(:bank_code) }
785
+
786
+ it 'raises a helpful error message' do
787
+ expect { build }.
788
+ to raise_error(ArgumentError, /bank_code is a required field/)
789
+ end
790
+ end
791
+
792
+ context 'without an account_number' do
793
+ before { args.delete(:account_number) }
794
+
795
+ it 'raises a helpful error message' do
796
+ expect { build }.
797
+ to raise_error(ArgumentError, /account_number is a required field/)
798
+ end
799
+ end
800
+
801
+ context 'without an account_number_prefix' do
802
+ before { args.delete(:account_number) }
803
+
804
+ it 'raises a helpful error message' do
805
+ expect { build }.
806
+ to raise_error(ArgumentError, /account_number is a required field/)
807
+ end
808
+ end
809
+ end
810
+
811
+ context 'with SM as the country_code' do
812
+ let(:args) do
813
+ {
814
+ country_code: 'SM',
815
+ bank_code: '05428',
816
+ branch_code: '11101',
817
+ account_number: '000000123456'
818
+ }
819
+ end
820
+
821
+ its(:iban) { is_expected.to eq('SM88X0542811101000000123456') }
822
+
823
+ it_behaves_like 'allows round trips', 'SM88 X054 2811 1010 0000 0123 456'
824
+
825
+ context 'without a bank_code' do
826
+ before { args.delete(:bank_code) }
827
+
828
+ it 'raises a helpful error message' do
829
+ expect { build }.
830
+ to raise_error(ArgumentError, /bank_code is a required field/)
831
+ end
832
+ end
833
+
834
+ context 'without a branch_code' do
835
+ before { args.delete(:branch_code) }
836
+
837
+ it 'raises a helpful error message' do
838
+ expect { build }.
839
+ to raise_error(ArgumentError, /branch_code is a required field/)
840
+ end
841
+ end
842
+
843
+ context 'without an account_number' do
844
+ before { args.delete(:account_number) }
845
+
846
+ it 'raises a helpful error message' do
847
+ expect { build }.
848
+ to raise_error(ArgumentError, /account_number is a required field/)
849
+ end
850
+ end
851
+ end
852
+ end
853
+ end