bsb 1.2.3 → 1.2.6

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,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require("faraday")
4
+
5
+ module BSB
6
+ module AusPayNet
7
+ module Client
8
+ class MissingSubscriptionKeyError < StandardError; end
9
+
10
+ OUTPUT_PARAM_WIDTH = 30
11
+ LEADER_WIDTH = OUTPUT_PARAM_WIDTH + 11
12
+
13
+ Response = Struct.new(:body, keyword_init: true)
14
+
15
+ def self.fetch_all_bsbs
16
+ subscription_key = ENV.fetch('AUSPAYNET_SUB_KEY', nil)
17
+ if subscription_key.nil?
18
+ raise MissingSubscriptionKeyError, "the environment variable 'AUSPAYNET_SUB_KEY' must be present"
19
+ end
20
+
21
+ conn = Faraday.new(
22
+ url: 'https://auspaynet-bicbsb-api-prod.azure-api.net',
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ 'Ocp-Apim-Subscription-Key': subscription_key
26
+ }
27
+ ) do |faraday|
28
+ faraday.response :raise_error
29
+ end
30
+
31
+ response = conn.post('/bsbquery/manual/paths/invoke') do |req|
32
+ req.body = { outputparam: ' ' * OUTPUT_PARAM_WIDTH }.to_json
33
+ end
34
+
35
+ Response.new(body: response.body[LEADER_WIDTH..])
36
+ end
37
+ end
38
+ end
39
+ end
@@ -4,6 +4,8 @@ require 'json'
4
4
 
5
5
  module BSB
6
6
  class BaseGenerator
7
+ attr_reader :hash
8
+
7
9
  def initialize(hash)
8
10
  @hash = hash
9
11
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bsb/base_generator'
4
+ require 'bsb/aus_pay_net/client'
4
5
 
5
6
  module BSB
6
7
  class DatabaseGenerator < BaseGenerator
@@ -16,5 +17,24 @@ module BSB
16
17
  end
17
18
  new(hash)
18
19
  end
20
+
21
+ def self.fetch_latest
22
+ response = BSB::AusPayNet::Client.fetch_all_bsbs
23
+
24
+ hash = {}
25
+ JSON.parse(response.body).each do |bsb_config|
26
+ bsb = bsb_config.fetch('BSBCode').delete('-')
27
+ hash[bsb] = [
28
+ bsb_config.fetch('FiMnemonic'),
29
+ bsb_config.fetch('BSBName'),
30
+ bsb_config.fetch('Address'),
31
+ bsb_config.fetch('Suburb'),
32
+ bsb_config.fetch('State'),
33
+ bsb_config.fetch('Postcode'),
34
+ 'PEH'.chars.map { bsb_config.fetch('StreamCode').include?(_1) ? _1 : ' ' }.join
35
+ ]
36
+ end
37
+ new(hash)
38
+ end
19
39
  end
20
40
  end
data/lib/bsb/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BSB
4
- VERSION = '1.2.3'
4
+ VERSION = '1.2.6'
5
5
  end
data/lib/bsb.rb CHANGED
@@ -5,6 +5,8 @@ require 'json'
5
5
  require 'bsb_number_validator'
6
6
 
7
7
  module BSB
8
+ DB_FILEPATH = 'config/bsb_db.json'
9
+ CHANGES_FILEPATH = 'config/latest_update.json'
8
10
  class << self
9
11
  def lookup(number)
10
12
  bsb = normalize(number)
@@ -42,7 +44,7 @@ module BSB
42
44
  protected
43
45
 
44
46
  def data_hash
45
- @data_hash ||= JSON.parse(File.read(File.expand_path('../config/bsb_db.json', __dir__)))
47
+ @data_hash ||= JSON.parse(File.read(File.expand_path("../#{DB_FILEPATH}", __dir__)))
46
48
  end
47
49
 
48
50
  def bank_list
@@ -4,6 +4,6 @@ require 'active_model'
4
4
 
5
5
  class BsbNumberValidator < ActiveModel::EachValidator
6
6
  def validate_each(record, attribute, value)
7
- record.errors.add(attribute, :invalid) unless BSB.lookup(value)
7
+ record.errors.add(attribute, :invalid) unless value.nil? || BSB.lookup(value)
8
8
  end
9
9
  end
@@ -1,26 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'bsb'
4
+ require 'bsb/database_generator'
5
+ require 'bsb/bank_list_generator'
6
+
3
7
  namespace :bsb do
4
8
  desc 'Sync config/*.json.'
5
- task :sync, [:keyfile, :bsbfile] do |_t, args|
6
- require 'bsb/base_generator'
7
- bank_list_filename = args[:keyfile]
9
+ task :sync_bsb_db_manual, [:bsbfile] do |_t, args|
8
10
  db_list_filename = args[:bsbfile]
9
11
 
12
+ if db_list_filename
13
+ bsb_db_gen = BSB::DatabaseGenerator.load_file(db_list_filename)
14
+ File.write(BSB::DB_FILEPATH, bsb_db_gen.json)
15
+ else
16
+ warn 'Missing bsb db "BSBDirectory"'
17
+ end
18
+ end
19
+
20
+ task :sync_bank_list, [:keyfile] do |_t, args|
21
+ bank_list_filename = args[:keyfile]
22
+
10
23
  if bank_list_filename
11
- require 'bsb/bank_list_generator'
12
24
  bsb_bl_gen = BSB::BankListGenerator.load_file(bank_list_filename)
13
25
  File.write('config/bsb_bank_list.json', bsb_bl_gen.json)
14
26
  else
15
27
  warn 'Missing bank list "KEY TO ABBREVIATIONS AND BSB NUMBERS"'
16
28
  end
17
-
18
- if db_list_filename
19
- require 'bsb/database_generator'
20
- bsb_db_gen = BSB::DatabaseGenerator.load_file(db_list_filename)
21
- File.write('config/bsb_db.json', bsb_db_gen.json)
22
- else
23
- warn 'Missing bsb db "BSBDirectory"'
24
- end
25
29
  end
26
30
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bsb'
4
+ require 'bsb/database_generator'
5
+
6
+ namespace :bsb do
7
+ desc 'Sync config/bsb_db.json with data provided by AusPayNet'
8
+ task :sync_bsb_db do
9
+ latest_db = BSB::DatabaseGenerator.fetch_latest
10
+ existing_db_hash = JSON.parse(File.read(BSB::DB_FILEPATH))
11
+ latest_db_hash = latest_db.hash
12
+
13
+ deletions = existing_db_hash.reject { |bsb, _| latest_db_hash.key?(bsb) }
14
+ additions = latest_db_hash.reject { |bsb, _| existing_db_hash.key?(bsb) }
15
+ modifications = {}
16
+
17
+ latest_db_hash.each do |bsb, data|
18
+ next unless existing_db_hash.key?(bsb) && existing_db_hash[bsb] != data
19
+
20
+ modifications[bsb] = data
21
+ end
22
+
23
+ changes_json = JSON.pretty_generate(
24
+ {
25
+ additions: additions,
26
+ deletions: deletions,
27
+ modifications: modifications
28
+ }
29
+ )
30
+
31
+ File.write(BSB::DB_FILEPATH, latest_db.json)
32
+ File.write(BSB::CHANGES_FILEPATH, changes_json)
33
+ end
34
+ end
@@ -0,0 +1,11 @@
1
+ {
2
+ "release-type": "ruby",
3
+ "bump-minor-pre-major": true,
4
+ "bump-patch-for-minor-pre-major": true,
5
+ "packages": {
6
+ ".": {
7
+ "release-type": "ruby",
8
+ "version-file": "lib/bsb/version.rb"
9
+ }
10
+ }
11
+ }
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bsb/aus_pay_net/client'
4
+ require 'test_helper'
5
+
6
+ describe BSB::AusPayNet::Client do
7
+ describe '.fetch_all_bsbs' do
8
+ before { ENV['AUSPAYNET_SUB_KEY'] = 'something' }
9
+
10
+ it 'returns the expected response' do
11
+ VCR.use_cassette('auspaynet_fetch_all_bsbs') do
12
+ response = BSB::AusPayNet::Client.fetch_all_bsbs
13
+ assert_equal(response.class, BSB::AusPayNet::Client::Response)
14
+ assert_equal(response.body.class, String)
15
+ assert_equal(JSON.parse(response.body).count, 2)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,20 @@
1
+ {
2
+ "333333": [
3
+ "AAA",
4
+ "Aviato3",
5
+ "123 Fakest Street",
6
+ "Canberra",
7
+ "ACT",
8
+ "1234",
9
+ "P H"
10
+ ],
11
+ "987654": [
12
+ "EST",
13
+ "Aviato2",
14
+ "123 Old Faker Street",
15
+ "Ballina",
16
+ "NSW",
17
+ "1234",
18
+ "P "
19
+ ]
20
+ }
@@ -0,0 +1,80 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://auspaynet-bicbsb-api-prod.azure-api.net/bsbquery/manual/paths/invoke
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"outputparam":" "}'
9
+ headers:
10
+ Content-type:
11
+ - application/json
12
+ Ocp-apim-subscription-key:
13
+ - "<AUSPAYNET_SUB_KEY>"
14
+ User-Agent:
15
+ - Faraday v2.10.1
16
+ response:
17
+ status:
18
+ code: 200
19
+ message: OK
20
+ headers:
21
+ cache-control:
22
+ - no-cache
23
+ pragma:
24
+ - no-cache
25
+ transfer-encoding:
26
+ - chunked
27
+ content-type:
28
+ - text/plain; charset=utf-8
29
+ content-encoding:
30
+ - gzip
31
+ expires:
32
+ - "-1"
33
+ vary:
34
+ - Accept-Encoding
35
+ set-cookie:
36
+ - ARRAffinity=0aa69915266871205a67096b40953eafb333722c9d662666b4ee1cbd3af96c28;Path=/;HttpOnly;Secure;Domain=prod-07.australiasoutheast.logic.azure.com,
37
+ ARRAffinitySameSite=0aa69915266871205a67096b40953eafb333722c9d662666b4ee1cbd3af96c28;Path=/;HttpOnly;SameSite=None;Secure;Domain=prod-07.australiasoutheast.logic.azure.com
38
+ strict-transport-security:
39
+ - max-age=31536000; includeSubDomains
40
+ x-ms-workflow-run-id:
41
+ - '08584759810780029358383571724CU01'
42
+ x-ms-correlation-id:
43
+ - 8d349630-46fe-44ae-9d3f-0dc53071b48e
44
+ x-ms-client-tracking-id:
45
+ - '08584759810780029358383571724CU01'
46
+ x-ms-trigger-history-name:
47
+ - '08584759810780029358383571724CU01'
48
+ x-ms-execution-location:
49
+ - australiasoutheast
50
+ x-ms-workflow-system-id:
51
+ - "/locations/australiasoutheast/scaleunits/prod-07/workflows/55b07bc2b01c48cea922b9673bb16c54"
52
+ x-ms-workflow-id:
53
+ - 55b07bc2b01c48cea922b9673bb16c54
54
+ x-ms-workflow-version:
55
+ - '08584793971872858901'
56
+ x-ms-workflow-name:
57
+ - logicapp-all-wildcardquery
58
+ x-ms-tracking-id:
59
+ - 8d349630-46fe-44ae-9d3f-0dc53071b48e
60
+ x-ms-ratelimit-burst-remaining-workflow-writes:
61
+ - '2999'
62
+ x-ms-ratelimit-remaining-workflow-download-contentsize:
63
+ - '210888995'
64
+ x-ms-ratelimit-remaining-workflow-upload-contentsize:
65
+ - '214748112'
66
+ x-ms-ratelimit-time-remaining-directapirequests:
67
+ - '19998471'
68
+ x-ms-request-id:
69
+ - australiasoutheast:8d349630-46fe-44ae-9d3f-0dc53071b48e
70
+ request-context:
71
+ - appId=cid-v1:62fce8e1-7550-4725-83ec-f11232c5768f
72
+ date:
73
+ - Fri, 06 Sep 2024 12:30:08 GMT
74
+ body:
75
+ encoding: UTF-8
76
+ string: '{"outputparam":"Query results returned "}[{"BSBCode":"012-002","BSBName":"ANZ
77
+ Smart Choice","FiMnemonic":"ANZ","Address":"115 Pitt Street","Suburb":"Sydney","State":"NSW","Postcode":"2000","StreamCode":"PEH","lastmodified":null,"BIC":"ANZBAU3R","BICINT":"","repair":"00"},{"BSBCode":"012-003","BSBName":"Merged","FiMnemonic":"ANZ","Address":"Refer
78
+ to BSB 012-019","Suburb":"Sydney","State":"NSW","Postcode":"2000","StreamCode":"PEH","lastmodified":null,"BIC":"ANZBAU3R","BICINT":"","repair":"00"}]'
79
+ recorded_at: Fri, 06 Sep 2024 12:30:09 GMT
80
+ recorded_with: VCR 6.3.1
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+ require 'rake'
5
+ require 'bsb/database_generator'
6
+
7
+ describe 'sync_bsb_db rake task' do # rubocop:disable Metrics/BlockLength
8
+ before do
9
+ ENV.update('AUSPAYNET_SUB_KEY' => 'something')
10
+ Rake.application.rake_require('../lib/tasks/sync_bsb_db')
11
+ Rake::Task['bsb:sync_bsb_db'].reenable
12
+ File.write('test/tmp/bsb_db.json', File.read('test/fixtures/bsb_db.json'))
13
+ end
14
+
15
+ let(:auspaynet_bsb_client_response) do
16
+ BSB::AusPayNet::Client::Response.new(
17
+ body: JSON.dump(
18
+ [
19
+ {
20
+ BSBCode: '123-456',
21
+ BSBName: 'Aviato',
22
+ FiMnemonic: 'TST',
23
+ Address: '123 Fake Street',
24
+ Suburb: 'Dubbo',
25
+ State: 'NSW',
26
+ Postcode: '1234',
27
+ StreamCode: 'EH',
28
+ lastmodified: nil,
29
+ BIC: 'TSTAAU2SSYD',
30
+ BICINT: '',
31
+ repair: '00'
32
+ },
33
+ {
34
+ BSBCode: '987-654',
35
+ BSBName: 'Aviato2',
36
+ FiMnemonic: 'EST',
37
+ Address: '123 Faker Street',
38
+ Suburb: 'Ballina',
39
+ State: 'NSW',
40
+ Postcode: '1234',
41
+ StreamCode: 'P',
42
+ lastmodified: nil,
43
+ BIC: 'TSTAAU2SSYD',
44
+ BICINT: '',
45
+ repair: '00'
46
+ }
47
+ ]
48
+ )
49
+ )
50
+ end
51
+
52
+ let(:expected_db) do
53
+ JSON.pretty_generate(
54
+ {
55
+ '123456': [
56
+ 'TST',
57
+ 'Aviato',
58
+ '123 Fake Street',
59
+ 'Dubbo',
60
+ 'NSW',
61
+ '1234',
62
+ ' EH'
63
+ ],
64
+ '987654': [
65
+ 'EST',
66
+ 'Aviato2',
67
+ '123 Faker Street',
68
+ 'Ballina',
69
+ 'NSW',
70
+ '1234',
71
+ 'P '
72
+ ]
73
+ }
74
+ )
75
+ end
76
+
77
+ let(:expected_changes) do
78
+ JSON.pretty_generate(
79
+ {
80
+ additions: {
81
+ '123456': [
82
+ 'TST',
83
+ 'Aviato',
84
+ '123 Fake Street',
85
+ 'Dubbo',
86
+ 'NSW',
87
+ '1234',
88
+ ' EH'
89
+ ]
90
+ },
91
+ deletions: {
92
+ '333333': [
93
+ 'AAA',
94
+ 'Aviato3',
95
+ '123 Fakest Street',
96
+ 'Canberra',
97
+ 'ACT',
98
+ '1234',
99
+ 'P H'
100
+ ]
101
+ },
102
+ modifications: {
103
+ '987654': [
104
+ 'EST',
105
+ 'Aviato2',
106
+ '123 Faker Street',
107
+ 'Ballina',
108
+ 'NSW',
109
+ '1234',
110
+ 'P '
111
+ ]
112
+ }
113
+ }
114
+ )
115
+ end
116
+
117
+ it 'generates the expected bsb_db and changes file' do
118
+ BSB.stub_consts(DB_FILEPATH: 'test/tmp/bsb_db.json', CHANGES_FILEPATH: 'test/tmp/latest_update.json') do
119
+ BSB::AusPayNet::Client.stub(:fetch_all_bsbs, auspaynet_bsb_client_response) do
120
+ Rake::Task['bsb:sync_bsb_db'].invoke
121
+ end
122
+
123
+ resultant_db = File.read(BSB::DB_FILEPATH).strip
124
+ resultant_changes = File.read(BSB::CHANGES_FILEPATH).strip
125
+ assert_equal(resultant_db, expected_db)
126
+ assert_equal(resultant_changes, expected_changes)
127
+ end
128
+ end
129
+
130
+ describe 'when the AUSPAYNET_SUB_KEY env var is not set' do
131
+ before do
132
+ ENV.delete('AUSPAYNET_SUB_KEY')
133
+ end
134
+
135
+ it 'raises the expected error' do
136
+ assert_raises BSB::AusPayNet::Client::MissingSubscriptionKeyError do
137
+ Rake::Task['bsb:sync_bsb_db'].invoke
138
+ end
139
+ end
140
+ end
141
+ end
data/test/test_helper.rb CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  require 'bsb'
4
4
  require 'minitest/autorun'
5
+ require 'minitest/stub_const'
6
+ require 'vcr'
7
+
8
+ Minitest.after_run do
9
+ Dir.glob('test/tmp/**/*.json').each { File.delete(_1) }
10
+ end
11
+
12
+ VCR.configure do |config|
13
+ config.cassette_library_dir = 'test/fixtures/vcr_cassettes'
14
+ config.hook_into :faraday
15
+ config.filter_sensitive_data('<AUSPAYNET_SUB_KEY>') do |interaction|
16
+ interaction.request.headers['Ocp-apim-subscription-key'][0]
17
+ end
18
+ end
5
19
 
6
20
  class Account
7
21
  include ActiveModel::API
data/test/tmp/.keep ADDED
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bsb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Zhou
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-01 00:00:00.000000000 Z
11
+ date: 2024-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -32,7 +32,9 @@ extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
34
  - ".github/workflows/ci.yml"
35
+ - ".github/workflows/publish.yml"
35
36
  - ".github/workflows/release.yml"
37
+ - ".github/workflows/update_bsb_db.yml"
36
38
  - ".gitignore"
37
39
  - ".release-please-manifest.json"
38
40
  - ".rubocop.yml"
@@ -46,15 +48,23 @@ files:
46
48
  - config/bsb_bank_list.json
47
49
  - config/bsb_db.json
48
50
  - lib/bsb.rb
51
+ - lib/bsb/aus_pay_net/client.rb
49
52
  - lib/bsb/bank_list_generator.rb
50
53
  - lib/bsb/base_generator.rb
51
54
  - lib/bsb/database_generator.rb
52
55
  - lib/bsb/version.rb
53
56
  - lib/bsb_number_validator.rb
54
57
  - lib/tasks/bsb_tasks.rake
58
+ - lib/tasks/sync_bsb_db.rake
59
+ - release-please-config.json
60
+ - test/bsb/aus_pay_net/client_test.rb
55
61
  - test/bsb_number_validator_test.rb
56
62
  - test/bsb_test.rb
63
+ - test/fixtures/bsb_db.json
64
+ - test/fixtures/vcr_cassettes/auspaynet_fetch_all_bsbs.yml
65
+ - test/tasks/sync_bsb_db_test.rb
57
66
  - test/test_helper.rb
67
+ - test/tmp/.keep
58
68
  homepage: https://github.com/zhoutong/bsb
59
69
  licenses:
60
70
  - MIT