ibandit 1.0.0 → 1.2.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.
@@ -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.0"
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