ibandit 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,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