ibandit 1.0.0 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -95,7 +95,7 @@ BE:
95
95
  :national_id_length: 3
96
96
  :bban_format: "\\d{3}\\d{7}\\d{2}"
97
97
  :bank_code_format: "\\d{3}"
98
- :account_number_format: "\\d{7}\\d{2}"
98
+ :account_number_format: "\\d{7}\\d{2}\\d{3}"
99
99
  :local_check_digit_position: 15
100
100
  :local_check_digit_length: 2
101
101
  BG:
@@ -902,7 +902,7 @@ US:
902
902
  :branch_code_length: 0
903
903
  :account_number_length: 17
904
904
  :bank_code_format: "\\d{9}"
905
- :account_number_format: "\\A_*\\d{1,17}\\z"
905
+ :account_number_format: "_*\\d{1,17}"
906
906
  :national_id_length: 9
907
907
  :pseudo_iban_bank_code_length: 9
908
908
  :pseudo_iban_branch_code_length: 0
@@ -3,13 +3,14 @@
3
3
  require File.expand_path("lib/ibandit/version", __dir__)
4
4
 
5
5
  Gem::Specification.new do |gem|
6
+ gem.add_development_dependency "gc_ruboconfig", "~> 2.17.0"
6
7
  gem.add_development_dependency "nokogiri", "~> 1.6"
7
8
  gem.add_development_dependency "pry", "~> 0.10"
8
9
  gem.add_development_dependency "pry-nav", "~> 0.2"
9
10
  gem.add_development_dependency "rspec", "~> 3.3"
10
11
  gem.add_development_dependency "rspec-its", "~> 1.2"
11
- gem.add_development_dependency "rubocop", "~> 0.70.0"
12
- gem.add_development_dependency "sax-machine", "~> 1.3"
12
+ gem.add_development_dependency "rspec_junit_formatter", "~> 0.4.1"
13
+ gem.add_development_dependency "sax-machine", "~> 1.3"
13
14
 
14
15
  gem.add_runtime_dependency "i18n"
15
16
 
@@ -36,7 +36,7 @@ module Ibandit
36
36
  end
37
37
 
38
38
  def translate(key, options = {})
39
- I18n.translate(key, { scope: [:ibandit] }.merge(options))
39
+ I18n.translate(key, scope: [:ibandit], **options)
40
40
  end
41
41
  end
42
42
  end
@@ -23,7 +23,7 @@ module Ibandit
23
23
  end
24
24
  end
25
25
  remainder = digits.join.to_i % 97
26
- sprintf("%02d", 98 - remainder)
26
+ sprintf("%<check_digit>02d", check_digit: 98 - remainder)
27
27
  end
28
28
 
29
29
  def self.italian(string)
@@ -517,7 +517,7 @@ module Ibandit
517
517
  updated_account_number =
518
518
  case unpadded_account_number.size
519
519
  when 5, 6 then unpadded_account_number + "00"
520
- when 7 then
520
+ when 7
521
521
  if Check63.new(unpadded_account_number + "00").valid?
522
522
  unpadded_account_number + "00"
523
523
  else
@@ -957,6 +957,23 @@ module Ibandit
957
957
  end
958
958
  end
959
959
 
960
+ # New version of Rule004200 but with another range:
961
+ # For 10-digit Account Numbers, only the following Account Numbers are
962
+ # applicable to be issued / created into an IBAN with the
963
+ # standard-IBAN rule: nnn4400001 to nnn4499999
964
+ class Rule004201 < Rule004200
965
+ def converted_details
966
+ unpadded_account_number = @account_number.gsub(/\A0+/, "")
967
+
968
+ if unpadded_account_number.size == 10 &&
969
+ %w[4400001 4499999].include?(unpadded_account_number.slice(3, 10))
970
+ { bank_code: @bank_code, account_number: @account_number }
971
+ else
972
+ super
973
+ end
974
+ end
975
+ end
976
+
960
977
  class Rule004301 < BaseRule
961
978
  def converted_details
962
979
  { bank_code: "66650085", account_number: @account_number }
@@ -1028,6 +1045,10 @@ module Ibandit
1028
1045
  end
1029
1046
  end
1030
1047
 
1048
+ class Rule004901 < Rule000000
1049
+ # Rule 0049 01 is actually about modulus checking, not IBAN construction
1050
+ end
1051
+
1031
1052
  class Rule005000 < BaseRule
1032
1053
  def converted_details
1033
1054
  { bank_code: "28550000", account_number: @account_number }
@@ -9,7 +9,8 @@ module Ibandit
9
9
  :swift_account_number, :source
10
10
 
11
11
  def initialize(argument)
12
- if argument.is_a?(String)
12
+ case argument
13
+ when String
13
14
  input = argument.to_s.gsub(/\s+/, "").upcase
14
15
 
15
16
  pseudo_iban_splitter = PseudoIBANSplitter.new(input)
@@ -24,7 +25,7 @@ module Ibandit
24
25
  @iban = input
25
26
  extract_swift_details_from_iban!
26
27
  end
27
- elsif argument.is_a?(Hash)
28
+ when Hash
28
29
  @source = :local_details
29
30
  build_iban_from_local_details(argument)
30
31
  else
@@ -225,7 +226,7 @@ module Ibandit
225
226
  return unless valid_country_code?
226
227
  return unless structure[:bban_format]
227
228
 
228
- if bban =~ Regexp.new(structure[:bban_format])
229
+ if bban&.match?(entire_string_regex(structure[:bban_format]))
229
230
  true
230
231
  else
231
232
  @errors[:format] = Ibandit.translate(:invalid_format,
@@ -238,7 +239,9 @@ module Ibandit
238
239
  return unless valid_bank_code_length?
239
240
  return true if structure[:bank_code_length]&.zero?
240
241
 
241
- if swift_bank_code =~ Regexp.new(structure[:bank_code_format])
242
+ if swift_bank_code&.match?(
243
+ entire_string_regex(structure[:bank_code_format]),
244
+ )
242
245
  true
243
246
  else
244
247
  @errors[:bank_code] = Ibandit.translate(:is_invalid)
@@ -250,7 +253,9 @@ module Ibandit
250
253
  return unless valid_branch_code_length?
251
254
  return true unless structure[:branch_code_format]
252
255
 
253
- if swift_branch_code =~ Regexp.new(structure[:branch_code_format])
256
+ if swift_branch_code&.match?(
257
+ entire_string_regex(structure[:branch_code_format]),
258
+ )
254
259
  true
255
260
  else
256
261
  @errors[:branch_code] = Ibandit.translate(:is_invalid)
@@ -261,7 +266,9 @@ module Ibandit
261
266
  def valid_account_number_format?
262
267
  return unless valid_account_number_length?
263
268
 
264
- if swift_account_number =~ Regexp.new(structure[:account_number_format])
269
+ if swift_account_number&.match?(
270
+ entire_string_regex(structure[:account_number_format]),
271
+ )
265
272
  true
266
273
  else
267
274
  @errors[:account_number] = Ibandit.translate(:is_invalid)
@@ -460,12 +467,12 @@ module Ibandit
460
467
  @swift_branch_code = try_dup(local_details[:swift_branch_code])
461
468
  @swift_bank_code = try_dup(local_details[:swift_bank_code])
462
469
 
463
- @iban = IBANAssembler.assemble(swift_details)
470
+ @iban = IBANAssembler.assemble(swift_details)
464
471
 
465
472
  if source == :pseudo_iban
466
- @check_digits = try_dup(local_details[:check_digits])
473
+ @check_digits = try_dup(local_details[:check_digits])
467
474
  else
468
- @check_digits = @iban.slice(2, 2) unless @iban.nil?
475
+ @check_digits = @iban.slice(2, 2) unless @iban.nil?
469
476
  end
470
477
  end
471
478
 
@@ -497,6 +504,10 @@ module Ibandit
497
504
  Ibandit.structures[country_code]
498
505
  end
499
506
 
507
+ def entire_string_regex(pattern)
508
+ Regexp.new("\\A#{pattern}\\z")
509
+ end
510
+
500
511
  def formatted
501
512
  iban.to_s.gsub(/(.{4})/, '\1 ').strip
502
513
  end
@@ -89,7 +89,9 @@ module Ibandit
89
89
  end
90
90
 
91
91
  def self.clean_ca_details(local_details)
92
- return {} if local_details[:account_number].length < 7 # minimum length
92
+ account_number = local_details[:account_number].tr("-", "")
93
+
94
+ return {} if account_number.length < 7 # minimum length
93
95
 
94
96
  bank_code = if local_details[:bank_code].length == 3
95
97
  local_details[:bank_code].rjust(4, "0")
@@ -98,7 +100,7 @@ module Ibandit
98
100
  end
99
101
 
100
102
  {
101
- account_number: local_details[:account_number].rjust(12, "0"),
103
+ account_number: account_number.rjust(12, "0"),
102
104
  bank_code: bank_code,
103
105
  }
104
106
  end
@@ -198,7 +200,7 @@ module Ibandit
198
200
  bank_code, account_number = local_details[:account_number].split("-", 2)
199
201
  elsif local_details[:account_number].gsub(/\s/, "").length == 14
200
202
  cleaned_account_number = local_details[:account_number].gsub(/\s/, "")
201
- bank_code = cleaned_account_number.slice(0, 4)
203
+ bank_code = cleaned_account_number.slice(0, 4)
202
204
  account_number = cleaned_account_number.slice(4, 10)
203
205
  else
204
206
  return {}
@@ -512,7 +514,7 @@ module Ibandit
512
514
  bank_code = local_details[:bank_code]
513
515
  account_number = local_details[:account_number]
514
516
  else
515
- cleaned_acct_number = local_details[:account_number].gsub(/[\s]/, "")
517
+ cleaned_acct_number = local_details[:account_number].gsub(/\s/, "")
516
518
 
517
519
  bank_code = cleaned_acct_number.slice(2, 8)
518
520
  account_number = cleaned_acct_number[10..-1]
@@ -573,7 +575,7 @@ module Ibandit
573
575
  ken_1 = parts[2].nil? ? "" : parts[2].rjust(6, "0")
574
576
  ken_2 = parts[3].nil? ? "" : parts[3].rjust(4, "0")
575
577
 
576
- kennitala = ken_1.empty? ? "" : (ken_1 + ken_2).rjust(10, "0")
578
+ kennitala = ken_1.empty? ? "" : (ken_1 + ken_2).rjust(10, "0")
577
579
 
578
580
  hufo + reikningsnumer + kennitala
579
581
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ibandit
4
- VERSION = "1.0.0"
4
+ VERSION = "1.2.1"
5
5
  end
@@ -22,15 +22,15 @@
22
22
  { "bank_code": "72020700", "account_number" : "1111111611" }
23
23
  ]
24
24
  },
25
- {
26
- "convertor": "000300",
27
- "valid": [
28
- { "bank_code": "51010800", "account_number" : "1" }
29
- ],
30
- "invalid": [
31
- { "bank_code": "51010800", "account_number" : "6161604670" }
32
- ]
33
- },
25
+ // {
26
+ // "convertor": "000300",
27
+ // "valid": [
28
+ // { "bank_code": "51010800", "account_number" : "1" }
29
+ // ],
30
+ // "invalid": [
31
+ // { "bank_code": "51010800", "account_number" : "6161604670" }
32
+ // ]
33
+ // },
34
34
  {
35
35
  "convertor": "000400",
36
36
  "valid": [
@@ -101,12 +101,12 @@
101
101
  {"bank_code":"51020000","account_number":"30009963","converted_bank_code":"50020200","converted_account_number":"30009963"}
102
102
  ]
103
103
  },
104
- {
105
- "convertor": "000900",
106
- "valid": [
107
- {"bank_code":"68351976","account_number":"1116232594","converted_bank_code":"68351557","converted_account_number":"3047232594"}
108
- ]
109
- },
104
+ // {
105
+ // "convertor": "000900",
106
+ // "valid": [
107
+ // {"bank_code":"68351976","account_number":"1116232594","converted_bank_code":"68351557","converted_account_number":"3047232594"}
108
+ // ]
109
+ // },
110
110
  {
111
111
  "convertor": "001001",
112
112
  "valid": [
@@ -162,9 +162,15 @@
162
162
  ]
163
163
  },
164
164
  {
165
- "convertor": "001900",
165
+ "convertor": "004901",
166
166
  "valid": [
167
- { "bank_code": "50130100", "account_number": "556", "converted_bank_code": "50120383" }
167
+ { "bank_code": "30060010", "account_number": "12345678", "converted_account_number": "12345678" }
168
168
  ]
169
169
  }
170
+ // {
171
+ // "convertor": "001900",
172
+ // "valid": [
173
+ // { "bank_code": "50130100", "account_number": "556", "converted_bank_code": "50120383" }
174
+ // ]
175
+ // }
170
176
  ]
@@ -136,12 +136,12 @@
136
136
  { "bank_code": "10010010", "account_number" : "556", "converted_account_number": "0120440110" }
137
137
  ]
138
138
  },
139
- {
140
- "convertor": "001900",
141
- "valid": [
142
- { "bank_code": "10010010", "account_number" : "1234567890", "converted_bank_code": "50120383" }
143
- ]
144
- },
139
+ // {
140
+ // "convertor": "001900",
141
+ // "valid": [
142
+ // { "bank_code": "10010010", "account_number" : "1234567890", "converted_bank_code": "50120383" }
143
+ // ]
144
+ // },
145
145
  {
146
146
  "convertor": "002002",
147
147
  "valid": [
@@ -318,6 +318,20 @@
318
318
  { "bank_code": "10010010", "account_number" : "0040400000" },
319
319
  { "bank_code": "10010010", "account_number" : "0040412000" }
320
320
  ]
321
+ },
322
+ {
323
+ "convertor": "004201",
324
+ "valid": [
325
+ { "bank_code": "10010010", "account_number" : "0050462000" },
326
+ { "bank_code": "70020001", "account_number" : "0040402000" },
327
+ { "bank_code": "70020001", "account_number" : "1004400001" }
328
+ ],
329
+ "invalid": [
330
+ { "bank_code": "10010010", "account_number" : "504620001" },
331
+ { "bank_code": "10010010", "account_number" : "0040400000" },
332
+ { "bank_code": "10010010", "account_number" : "0040412000" },
333
+ { "bank_code": "70020001", "account_number" : "1035400001" }
334
+ ]
321
335
  },
322
336
  {
323
337
  "convertor": "004301",
@@ -421,5 +435,16 @@
421
435
  "valid": [
422
436
  { "bank_code": "10010010", "account_number" : "1234567890", "converted_bank_code": "66010200" }
423
437
  ]
438
+ },
439
+ {
440
+ "convertor": "004901",
441
+ "valid": [
442
+ {
443
+ "bank_code": "30060010",
444
+ "account_number": "1234567890",
445
+ "converted_bank_code": "30060010",
446
+ "converted_account_number": "1234567890"
447
+ }
448
+ ]
424
449
  }
425
450
  ]
@@ -112,6 +112,22 @@ describe Ibandit::IBAN do
112
112
  its(:local_check_digits) { is_expected.to be_nil }
113
113
  end
114
114
 
115
+ context "when the IBAN was created from a Belgian IBAN" do
116
+ let(:iban_code) { "BE62510007547061" }
117
+
118
+ its(:country_code) { is_expected.to eq("BE") }
119
+ its(:bank_code) { is_expected.to eq("510") }
120
+ its(:branch_code) { is_expected.to be_nil }
121
+ its(:account_number) { is_expected.to eq("510007547061") }
122
+ its(:account_number_suffix) { is_expected.to be_nil }
123
+ its(:swift_bank_code) { is_expected.to eq("510") }
124
+ its(:swift_branch_code) { is_expected.to be_nil }
125
+ its(:swift_account_number) { is_expected.to eq("510007547061") }
126
+ its(:swift_national_id) { is_expected.to eq("510") }
127
+ its(:local_check_digits) { is_expected.to eq("61") }
128
+ its(:bban) { is_expected.to eq("510007547061") }
129
+ end
130
+
115
131
  context "when the IBAN was created with local details" do
116
132
  let(:arg) do
117
133
  {
@@ -452,6 +468,13 @@ describe Ibandit::IBAN do
452
468
  its(:to_s) { is_expected.to eq("") }
453
469
  end
454
470
 
471
+ context "and account number has invalid characters in" do
472
+ let(:account_number) { "123456XX789" }
473
+ let(:bank_code) { "0036" }
474
+
475
+ its(:valid?) { is_expected.to be false }
476
+ end
477
+
455
478
  context "and a 12 digit account number" do
456
479
  let(:account_number) { "012345678900" }
457
480
  let(:bank_code) { "0036" }
@@ -2247,16 +2270,16 @@ describe Ibandit::IBAN do
2247
2270
 
2248
2271
  context "with an invalid branch code" do
2249
2272
  let(:iban_code) { "GB60BARC20000055779911" }
2273
+ let(:valid_bank_code) { true }
2274
+ let(:valid_branch_code) { false }
2275
+ let(:valid_account_number) { true }
2276
+
2250
2277
  before { Ibandit.bic_finder = double(call: "BARCGB22XXX") }
2251
2278
 
2252
2279
  after { Ibandit.bic_finder = nil }
2253
2280
 
2254
2281
  before { iban.valid_local_modulus_check? }
2255
2282
 
2256
- let(:valid_bank_code) { true }
2257
- let(:valid_branch_code) { false }
2258
- let(:valid_account_number) { true }
2259
-
2260
2283
  it "calls valid_branch_code? with an IBAN object" do
2261
2284
  expect(Ibandit.modulus_checker).
2262
2285
  to receive(:valid_branch_code?).
@@ -167,6 +167,12 @@ describe Ibandit::LocalDetailsCleaner do
167
167
  its([:country_code]) { is_expected.to eq(country_code) }
168
168
  its([:bank_code]) { is_expected.to eq("0036") }
169
169
  its([:branch_code]) { is_expected.to eq("00063") }
170
+
171
+ context "with a hyphen" do
172
+ let(:account_number) { "0123456-789" }
173
+
174
+ its([:account_number]) { is_expected.to eq("000123456789") }
175
+ end
170
176
  end
171
177
 
172
178
  context "Cyprus" do
@@ -286,7 +292,7 @@ describe Ibandit::LocalDetailsCleaner do
286
292
 
287
293
  context "with unsupported account details" do
288
294
  let(:account_number) { "7955791111" }
289
- let(:bank_code) { "20000000" }
295
+ let(:bank_code) { "99999999" }
290
296
 
291
297
  it { is_expected.to eq(local_details_with_swift) }
292
298
  end
@@ -3,7 +3,7 @@
3
3
  require "spec_helper"
4
4
 
5
5
  describe Ibandit::PseudoIBANAssembler do
6
- subject(:pseudo_iban) { described_class.new(local_details).assemble }
6
+ subject(:pseudo_iban) { described_class.new(**local_details).assemble }
7
7
 
8
8
  context "for Sweden" do
9
9
  context "with valid parameters" do
@@ -9,7 +9,7 @@ describe "structures.yml" do
9
9
  structures.each do |country, rules|
10
10
  context country do
11
11
  rules.each do |rule, value|
12
- next unless rule =~ /_format$/
12
+ next unless rule.to_s.end_with?("_format")
13
13
 
14
14
  it "builds #{rule} rule" do
15
15
  expect { Regexp.new(value) }.to_not raise_exception