monobank 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a9e91f8a19ff3ec21d27e4665dc1b94b73fe69735621411340e5d56c83827e63
4
- data.tar.gz: '048ba2327b532c52be70e1ee376ac98c8003e5ab736ae49b06fdb8ee1c48a54d'
3
+ metadata.gz: 15be031b6729c65effbd0495c54824eea911e9162101b373f0b3cf35b598f851
4
+ data.tar.gz: e4c51fd2a95aab6bbe4313be5e5f65c6c45f0a0f8eb67a527d7e530519a10ded
5
5
  SHA512:
6
- metadata.gz: d3aa68afc8bcf9019ea4dcb1a55c41a91fa9f9a930c750797301197c24245e1730775f5016c09efddf86b1d7b0bf9c9955204c927cc948150811be25573117a1
7
- data.tar.gz: fab711e63c1d203afe8172dfc570578f6e74a7acc478fd9c2f21c69e7aa44167a9f32d03d56f6ab6d322be8c26cdb757ebbf8f6da9f18219fed41cdbabece532
6
+ metadata.gz: 7cdfec02d3d6c96ca18565af5db3e779b479b77722db0d170f3aa7ff144c4229112a57736809faec916010d96c474072911fbc7e1790299a52c4db50b6e40e90
7
+ data.tar.gz: c9cf70b27da7289cec013e577fe194feebfea8d9c05b09e2a690feba1036a04d582631cc774643cc32069f90347008db3311d3895bfbd16d74c6739e0d11c844
@@ -0,0 +1,35 @@
1
+ module Monobank
2
+ module Auth
3
+ class Corporate
4
+ def initialize(private_key:, key_id: nil, request_id: nil)
5
+ @private_key = init_key(private_key:)
6
+ @key_id = key_id
7
+ @request_id = request_id
8
+ end
9
+
10
+ def to_headers(pathname:)
11
+ time = Time.now.to_i
12
+
13
+ {
14
+ 'X-Time' => time.to_s,
15
+ 'X-Sign' => Base64.strict_encode64(sign(pathname:, time:))
16
+ }.tap do |headers|
17
+ headers['X-Key-Id'] = key_id unless key_id.nil?
18
+ headers['X-Request-Id'] = request_id unless request_id.nil?
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ attr_accessor :private_key, :key_id, :request_id
25
+
26
+ def init_key(private_key:)
27
+ OpenSSL::PKey::EC.new(private_key)
28
+ end
29
+
30
+ def sign(pathname:, time:)
31
+ private_key.sign(OpenSSL::Digest::SHA256.new, "#{time}#{request_id}#{pathname}")
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,17 @@
1
+ module Monobank
2
+ module Auth
3
+ class Private
4
+ def initialize(token:)
5
+ @token = token
6
+ end
7
+
8
+ def to_headers(*)
9
+ { 'X-Token' => token }
10
+ end
11
+
12
+ private
13
+
14
+ attr_reader :token
15
+ end
16
+ end
17
+ end
@@ -1,4 +1,5 @@
1
1
  require 'monobank/connection'
2
+ require 'monobank/auth/private'
2
3
  require 'monobank/bank/currency'
3
4
  require 'monobank/personal/client_info'
4
5
  require 'monobank/personal/statement'
@@ -11,15 +12,21 @@ module Monobank
11
12
  end
12
13
 
13
14
  def client_info(token:)
14
- Personal::ClientInfo.new(token: token).call
15
+ Personal::ClientInfo.new(auth: auth(token:)).call
15
16
  end
16
17
 
17
18
  def statement(token:, account_id:, from:, to: nil)
18
- Personal::Statement.new(token: token, account_id: account_id, from: from, to: to).call
19
+ Personal::Statement.new(account_id:, from:, to:, auth: auth(token:)).call
19
20
  end
20
21
 
21
22
  def set_webhook(token:, url:)
22
- Personal::Webhook.new(token: token, url: url).call
23
+ Personal::Webhook.new(url:, auth: auth(token:)).call
24
+ end
25
+
26
+ private
27
+
28
+ def auth(token:)
29
+ Auth::Private.new(token:)
23
30
  end
24
31
  end
25
32
  end
@@ -0,0 +1,60 @@
1
+ require 'monobank/auth/corporate'
2
+ require 'monobank/personal/registration'
3
+ require 'monobank/personal/registration_status'
4
+ require 'monobank/personal/corporate_webhook'
5
+ require 'monobank/personal/settings'
6
+ require 'monobank/personal/auth_request'
7
+ require 'monobank/personal/auth_check'
8
+ require 'monobank/personal/client_info'
9
+ require 'monobank/personal/statement'
10
+
11
+ module Monobank
12
+ module Corporate
13
+ class Client
14
+ def initialize(private_key:, key_id:)
15
+ @private_key = private_key
16
+ @key_id = key_id
17
+ end
18
+
19
+ def registration(public_key:, name:, description:, contact_person:, phone:, email:, logo:)
20
+ Personal::Registration.new(public_key:, name:, description:, contact_person:, phone:, email:, logo:, auth:).call
21
+ end
22
+
23
+ def registration_status(public_key:)
24
+ Personal::RegistrationStatus.new(public_key:, auth:).call
25
+ end
26
+
27
+ def set_webhook(url:)
28
+ Personal::CorporateWebhook.new(url: url, auth:).call
29
+ end
30
+
31
+ def settings
32
+ Personal::Settings.new(auth:).call
33
+ end
34
+
35
+ def auth_request(callback: nil)
36
+ Personal::AuthRequest.new(callback:, auth:).call
37
+ end
38
+
39
+ def auth_check(request_id:)
40
+ Personal::AuthCheck.new(auth: auth(request_id:)).call
41
+ end
42
+
43
+ def client_info(request_id:)
44
+ Personal::ClientInfo.new(auth: auth(request_id:)).call
45
+ end
46
+
47
+ def statement(request_id:, account_id:, from:, to: nil)
48
+ Personal::Statement.new(account_id:, from:, to:, auth: auth(request_id:)).call
49
+ end
50
+
51
+ private
52
+
53
+ attr_reader :private_key, :key_id
54
+
55
+ def auth(request_id: nil)
56
+ Auth::Corporate.new(private_key:, key_id:, request_id:)
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,21 @@
1
+ require 'forwardable'
2
+ require 'monobank/corporate/client'
3
+
4
+ module Monobank
5
+ module Corporate
6
+ extend SingleForwardable
7
+ def_delegators \
8
+ :client, :registration, :registration_status, :set_webhook, :settings,
9
+ :auth_request, :auth_check, :client_info, :statement
10
+
11
+ def self.configure(private_key:, key_id: nil)
12
+ @private_key = private_key
13
+ @key_id = key_id
14
+ @client = nil
15
+ end
16
+
17
+ def self.client
18
+ @client ||= Client.new(private_key: @private_key, key_id: @key_id)
19
+ end
20
+ end
21
+ end
@@ -3,6 +3,10 @@ require 'monobank/resources/error'
3
3
  module Monobank
4
4
  module Methods
5
5
  class Base
6
+ def initialize(auth: nil)
7
+ @auth = auth
8
+ end
9
+
6
10
  def call
7
11
  attributes = response
8
12
  return define_resources(attributes) if attributes.code == 200
@@ -12,7 +16,11 @@ module Monobank
12
16
 
13
17
  private
14
18
 
15
- attr_reader :token
19
+ attr_reader :auth
20
+
21
+ def pathname
22
+ raise NotImplementedError
23
+ end
16
24
 
17
25
  def response
18
26
  raise NotImplementedError
@@ -20,11 +28,15 @@ module Monobank
20
28
 
21
29
  def options
22
30
  {
23
- headers: { 'X-Token' => token.to_s },
31
+ headers: (headers || {}).merge(auth&.to_headers(pathname:) || {}),
24
32
  body: body.to_json
25
33
  }
26
34
  end
27
35
 
36
+ def headers
37
+ {}
38
+ end
39
+
28
40
  def body; end
29
41
 
30
42
  def connection
@@ -0,0 +1,22 @@
1
+ require 'monobank/methods/get'
2
+ require 'monobank/resources/personal/auth_check'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class AuthCheck < Methods::Get
7
+ ENDPOINT = '/personal/auth/request'.freeze
8
+
9
+ private
10
+
11
+ attr_reader :request_id
12
+
13
+ def pathname
14
+ ENDPOINT
15
+ end
16
+
17
+ def define_resources(attributes)
18
+ Monobank::Resources::Personal::AuthCheck.new(attributes)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,31 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/auth_request'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class AuthRequest < Methods::Post
7
+ ENDPOINT = '/personal/auth/request'.freeze
8
+
9
+ def initialize(callback: nil, **rest)
10
+ super(**rest)
11
+ @callback = callback
12
+ end
13
+
14
+ private
15
+
16
+ attr_reader :callback
17
+
18
+ def pathname
19
+ ENDPOINT
20
+ end
21
+
22
+ def headers
23
+ {'X-Callback' => callback} if callback
24
+ end
25
+
26
+ def define_resources(attributes)
27
+ Monobank::Resources::Personal::AuthRequest.new(attributes)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -6,10 +6,6 @@ module Monobank
6
6
  class ClientInfo < Methods::Get
7
7
  ENDPOINT = '/personal/client-info'.freeze
8
8
 
9
- def initialize(token:)
10
- @token = token
11
- end
12
-
13
9
  private
14
10
 
15
11
  def pathname
@@ -0,0 +1,15 @@
1
+ require 'monobank/personal/webhook'
2
+
3
+ module Monobank
4
+ module Personal
5
+ class CorporateWebhook < Webhook
6
+ ENDPOINT = '/personal/corp/webhook'.freeze
7
+
8
+ private
9
+
10
+ def pathname
11
+ ENDPOINT
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,46 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/registration'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class Registration < Methods::Post
7
+ ENDPOINT = '/personal/auth/registration'.freeze
8
+
9
+ def initialize(public_key:, name:, description:, contact_person:, phone:, email:, logo:, **rest)
10
+ super(**rest)
11
+
12
+ @public_key = public_key
13
+ @name = name
14
+ @description = description
15
+ @contact_person = contact_person
16
+ @phone = phone
17
+ @email = email
18
+ @logo = logo
19
+ end
20
+
21
+ def pathname
22
+ ENDPOINT
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :public_key, :name, :description, :contact_person, :phone, :email, :logo
28
+
29
+ def body
30
+ {
31
+ pubkey: public_key,
32
+ name:,
33
+ description:,
34
+ contactPerson: contact_person,
35
+ phone:,
36
+ email:,
37
+ logo:
38
+ }
39
+ end
40
+
41
+ def define_resources(attributes)
42
+ Resources::Personal::Registration.new(attributes)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/registration_status'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class RegistrationStatus < Methods::Post
7
+ ENDPOINT = '/personal/auth/registration/status'.freeze
8
+
9
+ def initialize(public_key:, **rest)
10
+ super(**rest)
11
+
12
+ @public_key = public_key
13
+ end
14
+
15
+ def pathname
16
+ ENDPOINT
17
+ end
18
+
19
+ private
20
+
21
+ attr_reader :public_key
22
+
23
+ def body
24
+ { pubkey: public_key }
25
+ end
26
+
27
+ def define_resources(attributes)
28
+ Resources::Personal::RegistrationStatus.new(attributes)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,20 @@
1
+ require 'monobank/methods/post'
2
+ require 'monobank/resources/personal/settings'
3
+
4
+ module Monobank
5
+ module Personal
6
+ class Settings < Methods::Post
7
+ ENDPOINT = '/personal/corp/settings'.freeze
8
+
9
+ def pathname
10
+ ENDPOINT
11
+ end
12
+
13
+ private
14
+
15
+ def define_resources(attributes)
16
+ Resources::Personal::Settings.new(attributes)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -6,8 +6,9 @@ module Monobank
6
6
  class Statement < Methods::Get
7
7
  ENDPOINT = '/personal/statement'.freeze
8
8
 
9
- def initialize(token:, account_id:, from:, to:)
10
- @token = token
9
+ def initialize(account_id:, from:, to:, **rest)
10
+ super(**rest)
11
+
11
12
  @account_id = account_id
12
13
  @from = from
13
14
  @to = to
@@ -30,4 +31,4 @@ module Monobank
30
31
  end
31
32
  end
32
33
  end
33
- end
34
+ end
@@ -6,8 +6,9 @@ module Monobank
6
6
  class Webhook < Methods::Post
7
7
  ENDPOINT = '/personal/webhook'.freeze
8
8
 
9
- def initialize(token:, url:)
10
- @token = token
9
+ def initialize(url:, **rest)
10
+ super(**rest)
11
+
11
12
  @url = url
12
13
  end
13
14
 
@@ -0,0 +1,11 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Personal
6
+ class AuthCheck < Base
7
+ define_fields %w[status]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Personal
6
+ class AuthRequest < Base
7
+ define_fields %w[accept_url]
8
+
9
+ def request_id
10
+ @attributes['token_request_id']
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,11 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Personal
6
+ class Registration < Base
7
+ define_fields %w[status]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Personal
6
+ class RegistrationStatus < Base
7
+ define_fields %w[key_id status]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'monobank/resources/base'
2
+
3
+ module Monobank
4
+ module Resources
5
+ module Personal
6
+ class Settings < Base
7
+ define_fields %w[name permissions webhook]
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module Monobank
2
- VERSION = "0.2.3"
2
+ VERSION = "0.3.0"
3
3
  end
data/lib/monobank.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  require 'monobank/version'
2
2
  require 'monobank/client'
3
+ require 'monobank/corporate'
3
4
  require 'forwardable'
4
5
 
5
6
  module Monobank
@@ -0,0 +1,290 @@
1
+ describe Monobank::Corporate do
2
+ let(:key_id) { nil }
3
+
4
+ before do
5
+ allow(Time).to receive(:now).and_return(Time.parse('2024-01-31'))
6
+
7
+ fake_private_key = OpenSSL::PKey::EC.new
8
+ allow(fake_private_key).to(receive(:sign)) { |_, args| "__SIGNED__#{args}" }
9
+ allow_any_instance_of(Monobank::Auth::Corporate).to receive(:init_key).and_return(fake_private_key)
10
+
11
+ allow(Base64).to(receive(:strict_encode64)) { |arg| "__BASE64__#{arg}" }
12
+
13
+ Monobank::Corporate.configure(private_key: 'FAKE PRIVATE KEY', key_id:)
14
+ end
15
+
16
+ context '.registration' do
17
+ before do
18
+ stub_request(:post, 'https://api.monobank.ua/personal/auth/registration').
19
+ with(
20
+ body: {
21
+ "pubkey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZZd0VBWUhLb1pJemow...",
22
+ "name": "ТОВ \"Ворона\"",
23
+ "description": "Ми робимо найрозумніший PFM з усіх можливих і нам потрібен доступ до виписка користувача, щоб створювати красиву статистику",
24
+ "contactPerson": "Роман Шевченко",
25
+ "phone": "380671234567",
26
+ "email": "etс@example.com",
27
+ "logo": "iVBORw0KGgoAAAANSUhEUgAAAUAAAACECAYAAADhnvK8AAAapElEQVR42..."
28
+ }.to_json,
29
+ headers: {
30
+ 'X-Sign'=>'__BASE64____SIGNED__1706652000/personal/auth/registration',
31
+ 'X-Time'=>'1706652000'
32
+ }).
33
+ to_return(status: 200, body: { status: 'New' }.to_json, headers: {'Content-Type' => 'application/json'})
34
+ end
35
+
36
+ it 'returns correct data' do
37
+ result = Monobank::Corporate.registration(
38
+ public_key: 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZZd0VBWUhLb1pJemow...',
39
+ name: 'ТОВ "Ворона"',
40
+ description: 'Ми робимо найрозумніший PFM з усіх можливих і нам потрібен доступ до виписка користувача, щоб створювати красиву статистику',
41
+ contact_person: 'Роман Шевченко',
42
+ phone: '380671234567',
43
+ email: 'etс@example.com',
44
+ logo: 'iVBORw0KGgoAAAANSUhEUgAAAUAAAACECAYAAADhnvK8AAAapElEQVR42...'
45
+ )
46
+
47
+ expect(result.status).to eq 'New'
48
+ end
49
+ end
50
+
51
+ context '.registration_status' do
52
+ before do
53
+ stub_request(:post, 'https://api.monobank.ua/personal/auth/registration/status').
54
+ with(
55
+ body: {
56
+ "pubkey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZZd0VBWUhLb1pJemow..."
57
+ }.to_json,
58
+ headers: {
59
+ 'X-Sign' => '__BASE64____SIGNED__1706652000/personal/auth/registration/status',
60
+ 'X-Time' => '1706652000'
61
+ }).
62
+ to_return(
63
+ status: 200,
64
+ body: { status: 'Approved', keyId: '28a75537175a018645e6f8b14be7681791e701e0' }.to_json,
65
+ headers: {'Content-Type' => 'application/json'}
66
+ )
67
+ end
68
+
69
+ it 'returns correct data' do
70
+ result = Monobank::Corporate.registration_status(public_key: 'LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZZd0VBWUhLb1pJemow...')
71
+
72
+ expect(result.status).to eq 'Approved'
73
+ expect(result.key_id).to eq '28a75537175a018645e6f8b14be7681791e701e0'
74
+ end
75
+ end
76
+
77
+ context 'with key_id' do
78
+ let(:key_id) { '28a75537175a018645e6f8b14be7681791e701e0' }
79
+
80
+ context '.set_webhook' do
81
+ before do
82
+ stub_request(:post, 'https://api.monobank.ua/personal/corp/webhook').
83
+ with(
84
+ body: {'webHookUrl': 'https://example.com/some_random_data_for_security'}.to_json,
85
+ headers: {
86
+ 'X-Key-Id' => '28a75537175a018645e6f8b14be7681791e701e0',
87
+ 'X-Sign' => '__BASE64____SIGNED__1706652000/personal/corp/webhook',
88
+ 'X-Time' => '1706652000'
89
+ }).
90
+ to_return(status: 200, body: {'status' => 'ok'}.to_json, headers: {'Content-Type' => 'application/json'})
91
+ end
92
+
93
+ it 'returns correct data' do
94
+ result = Monobank::Corporate.set_webhook(url: 'https://example.com/some_random_data_for_security')
95
+
96
+ expect(result.status).to eq 'ok'
97
+ end
98
+ end
99
+
100
+ context '.settings' do
101
+ before do
102
+ stub_request(:post, 'https://api.monobank.ua/personal/corp/settings').
103
+ with(
104
+ headers: {
105
+ 'X-Key-Id' => '28a75537175a018645e6f8b14be7681791e701e0',
106
+ 'X-Sign' => '__BASE64____SIGNED__1706652000/personal/corp/settings',
107
+ 'X-Time' => '1706652000'
108
+ }).
109
+ to_return(
110
+ status: 200,
111
+ body: {
112
+ "pubkey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUZZd0VBWUhLb1pJemow...",
113
+ "name": "Компанія",
114
+ "permission": "psf",
115
+ "logo": "iVBORw0KGgoAAAANSUhEUgAAAUAAAACECAYAAADhnvK8AAAapElEQVR42...",
116
+ "webhook": "https://example.com/mono/corp/webhook/maybesomegibberishuniquestringbutnotnecessarily"
117
+ }.to_json,
118
+ headers: {'Content-Type' => 'application/json'}
119
+ )
120
+ end
121
+
122
+ it 'returns correct data' do
123
+ result = Monobank::Corporate.settings
124
+
125
+ expect(result.name).to eq 'Компанія'
126
+ expect(result.webhook).to eq 'https://example.com/mono/corp/webhook/maybesomegibberishuniquestringbutnotnecessarily'
127
+ end
128
+ end
129
+
130
+ context '.auth_request' do
131
+ let(:headers) { {} }
132
+
133
+ before do
134
+ stub_request(:post, 'https://api.monobank.ua/personal/auth/request').
135
+ with(
136
+ headers: {
137
+ 'X-Key-Id' => '28a75537175a018645e6f8b14be7681791e701e0',
138
+ 'X-Sign' => '__BASE64____SIGNED__1706652000/personal/auth/request',
139
+ 'X-Time' => '1706652000',
140
+ **headers
141
+ }).
142
+ to_return(
143
+ status: 200,
144
+ body: {
145
+ "tokenRequestId": "uLkwh3NzFAfEkj7urj5C7AU_",
146
+ "acceptUrl": "https://mbnk.app/auth/uLkwh3NzFAfEkj7urj5C7AU_"
147
+ }.to_json,
148
+ headers: {'Content-Type' => 'application/json'}
149
+ )
150
+ end
151
+
152
+ it 'returns correct data' do
153
+ result = Monobank::Corporate.auth_request
154
+
155
+ expect(result.request_id).to eq 'uLkwh3NzFAfEkj7urj5C7AU_'
156
+ expect(result.accept_url).to eq 'https://mbnk.app/auth/uLkwh3NzFAfEkj7urj5C7AU_'
157
+ end
158
+
159
+ context 'when a callback is passed' do
160
+ let(:headers) { {'X-Callback' => 'https://example.com' }}
161
+
162
+ it 'returns passes it as headers' do
163
+ result = Monobank::Corporate.auth_request(callback: 'https://example.com')
164
+
165
+ expect(result.request_id).to eq 'uLkwh3NzFAfEkj7urj5C7AU_'
166
+ expect(result.accept_url).to eq 'https://mbnk.app/auth/uLkwh3NzFAfEkj7urj5C7AU_'
167
+ end
168
+ end
169
+ end
170
+
171
+ context 'with request_id' do
172
+ let(:request_id) { 'uLkwh3NzFAfEkj7urj5C7AU_' }
173
+
174
+ context '.auth_check' do
175
+ before do
176
+ stub_request(:get, 'https://api.monobank.ua/personal/auth/request').
177
+ with(
178
+ headers: {
179
+ 'X-Key-Id' => '28a75537175a018645e6f8b14be7681791e701e0',
180
+ 'X-Request-Id' => 'uLkwh3NzFAfEkj7urj5C7AU_',
181
+ 'X-Sign' => '__BASE64____SIGNED__1706652000uLkwh3NzFAfEkj7urj5C7AU_/personal/auth/request',
182
+ 'X-Time' => '1706652000'
183
+ }).
184
+ to_return(
185
+ status: 200,
186
+ body: { status: 'ok' }.to_json,
187
+ headers: {'Content-Type' => 'application/json'}
188
+ )
189
+ end
190
+
191
+ it 'returns correct data' do
192
+ result = Monobank::Corporate.auth_check(request_id:)
193
+
194
+ expect(result.status).to eq 'ok'
195
+ end
196
+ end
197
+
198
+ context '.client_info' do
199
+ before do
200
+ stub_request(:get, 'https://api.monobank.ua/personal/client-info').
201
+ with(
202
+ headers: {
203
+ 'X-Key-Id' => '28a75537175a018645e6f8b14be7681791e701e0',
204
+ 'X-Request-Id' => 'uLkwh3NzFAfEkj7urj5C7AU_',
205
+ 'X-Sign' => '__BASE64____SIGNED__1706652000uLkwh3NzFAfEkj7urj5C7AU_/personal/client-info',
206
+ 'X-Time' => '1706652000'
207
+ }).
208
+ to_return(
209
+ status: 200,
210
+ body: {
211
+ "clientId": "3MSaMMtczs",
212
+ "name": "Мазепа Іван",
213
+ "webHookUrl": "https://mysomesite.copm/some_random_data_for_security",
214
+ "permissions": "psf",
215
+ "accounts": [
216
+ {
217
+ "id": "kKGVoZuHWzqVoZuH",
218
+ "sendId": "uHWzqVoZuH",
219
+ "balance": 10000000,
220
+ "creditLimit": 10000000,
221
+ "type": "black",
222
+ "currencyCode": 980,
223
+ "cashbackType": "UAH",
224
+ "maskedPan": [
225
+ "537541******1234"
226
+ ],
227
+ "iban": "UA733220010000026201234567890"
228
+ }
229
+ ]
230
+ }.to_json,
231
+ headers: {'Content-Type' => 'application/json'}
232
+ )
233
+ end
234
+
235
+ it 'returns correct data' do
236
+ result = Monobank::Corporate.client_info(request_id:)
237
+
238
+ expect(result.name).to eq 'Мазепа Іван'
239
+ expect(result.accounts.length).to eq 1
240
+ end
241
+ end
242
+
243
+ context '.statement' do
244
+ before do
245
+ stub_request(:get, 'https://api.monobank.ua/personal/statement/0/1546304461').
246
+ with(
247
+ headers: {
248
+ 'X-Key-Id' => '28a75537175a018645e6f8b14be7681791e701e0',
249
+ 'X-Request-Id' => 'uLkwh3NzFAfEkj7urj5C7AU_',
250
+ 'X-Sign' => '__BASE64____SIGNED__1706652000uLkwh3NzFAfEkj7urj5C7AU_/personal/statement/0/1546304461',
251
+ 'X-Time' => '1706652000'
252
+ }).
253
+ to_return(
254
+ status: 200,
255
+ body: [
256
+ {
257
+ "id": "ZuHWzqkKGVo=",
258
+ "time": 1554466347,
259
+ "description": "Покупка щастя",
260
+ "mcc": 7997,
261
+ "originalMcc": 7997,
262
+ "hold": false,
263
+ "amount": -95000,
264
+ "operationAmount": -95000,
265
+ "currencyCode": 980,
266
+ "commissionRate": 0,
267
+ "cashbackAmount": 19000,
268
+ "balance": 10050000,
269
+ "comment": "За каву",
270
+ "receiptId": "XXXX-XXXX-XXXX-XXXX",
271
+ "counterEdrpou": "3096889974",
272
+ "counterIban": "UA898999980000355639201001404",
273
+ "counterName": "ТОВАРИСТВО З ОБМЕЖЕНОЮ ВІДПОВІДАЛЬНІСТЮ «ВОРОНА»"
274
+ }
275
+ ].to_json,
276
+ headers: {'Content-Type' => 'application/json'}
277
+ )
278
+ end
279
+
280
+ it 'returns correct data' do
281
+ result = Monobank::Corporate.statement(request_id:, account_id: 0, from: 1546304461)
282
+
283
+ expect(result.first.id).to eq 'ZuHWzqkKGVo='
284
+ expect(result.first.amount).to eq -95000
285
+ expect(result.first.currency_code).to eq 980
286
+ end
287
+ end
288
+ end
289
+ end
290
+ end
@@ -0,0 +1,138 @@
1
+ describe Monobank do
2
+ let(:token) { 'FAKE_TOKEN' }
3
+
4
+ context '.bank_currency' do
5
+ before do
6
+ stub_request(:get, "https://api.monobank.ua/bank/currency").
7
+ to_return(
8
+ status: 200,
9
+ body: [
10
+ {
11
+ 'currencyCodeA' => 840,
12
+ 'currencyCodeB' => 980,
13
+ 'date' => 1552392228,
14
+ 'rateSell' => 27,
15
+ 'rateBuy' => 27.2,
16
+ 'rateCross' => 27.1
17
+ }
18
+ ].to_json,
19
+ headers: {'Content-Type' => 'application/json'}
20
+ )
21
+ end
22
+
23
+ it 'returns correct data' do
24
+ result = Monobank.bank_currency
25
+ expect(result.first.currency_code_a).to eq 840
26
+ end
27
+ end
28
+
29
+ context '.client_info' do
30
+ before do
31
+ stub_request(:get, "https://api.monobank.ua/personal/client-info").
32
+ with(headers: {'X-Token' => 'FAKE_TOKEN'}).
33
+ to_return(
34
+ status: 200,
35
+ body: {
36
+ "clientId": "3MSaMMtczs",
37
+ "name": "Мазепа Іван",
38
+ "webHookUrl": "https://example.com/some_random_data_for_security",
39
+ "permissions": "psfj",
40
+ "accounts": [
41
+ {
42
+ "id": "kKGVoZuHWzqVoZuH",
43
+ "sendId": "uHWzqVoZuH",
44
+ "balance": 10000000,
45
+ "creditLimit": 10000000,
46
+ "type": "black",
47
+ "currencyCode": 980,
48
+ "cashbackType": "UAH",
49
+ "maskedPan": [
50
+ "537541******1234"
51
+ ],
52
+ "iban": "UA733220010000026201234567890"
53
+ }
54
+ ],
55
+ "jars": [
56
+ {
57
+ "id": "kKGVoZuHWzqVoZuH",
58
+ "sendId": "uHWzqVoZuH",
59
+ "title": "На тепловізор",
60
+ "description": "На тепловізор",
61
+ "currencyCode": 980,
62
+ "balance": 1000000,
63
+ "goal": 10000000
64
+ }
65
+ ]
66
+ }.to_json,
67
+ headers: {'Content-Type' => 'application/json'}
68
+ )
69
+ end
70
+
71
+ it 'returns correct data' do
72
+ result = Monobank.client_info(token:)
73
+ expect(result.name).to eq 'Мазепа Іван'
74
+ expect(result.accounts.length).to eq 1
75
+ end
76
+ end
77
+
78
+ context '.statement' do
79
+ before do
80
+ stub_request(:get, "https://api.monobank.ua/personal/statement/0/1546304461").
81
+ with(headers: {'X-Token' => 'FAKE_TOKEN'}).
82
+ to_return(
83
+ status: 200,
84
+ body: [
85
+ {
86
+ "id": "ZuHWzqkKGVo=",
87
+ "time": 1554466347,
88
+ "description": "Покупка щастя",
89
+ "mcc": 7997,
90
+ "originalMcc": 7997,
91
+ "hold": false,
92
+ "amount": -95000,
93
+ "operationAmount": -95000,
94
+ "currencyCode": 980,
95
+ "commissionRate": 0,
96
+ "cashbackAmount": 19000,
97
+ "balance": 10050000,
98
+ "comment": "За каву",
99
+ "receiptId": "XXXX-XXXX-XXXX-XXXX",
100
+ "invoiceId": "2103.в.27",
101
+ "counterEdrpou": "3096889974",
102
+ "counterIban": "UA898999980000355639201001404",
103
+ "counterName": "ТОВАРИСТВО З ОБМЕЖЕНОЮ ВІДПОВІДАЛЬНІСТЮ «ВОРОНА»"
104
+ }
105
+ ].to_json,
106
+ headers: {'Content-Type' => 'application/json'}
107
+ )
108
+ end
109
+
110
+ it 'returns correct data' do
111
+ result = Monobank.statement(token:, account_id: 0, from: 1546304461)
112
+ expect(result.first.id).to eq 'ZuHWzqkKGVo='
113
+ expect(result.first.amount).to eq -95000
114
+ expect(result.first.currency_code).to eq 980
115
+ end
116
+ end
117
+
118
+ context '.set_webhook' do
119
+ before do
120
+ stub_request(:post, "https://api.monobank.ua/personal/webhook").
121
+ with(
122
+ body: {'webHookUrl': 'https://example.com/some_random_data_for_security'}.to_json,
123
+ headers: {
124
+ 'Accept'=>'*/*',
125
+ 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
126
+ 'User-Agent'=>'Ruby',
127
+ 'X-Token'=>'FAKE_TOKEN'
128
+ }).
129
+ to_return(status: 200, body: {'status' => 'ok'}.to_json, headers: {'Content-Type' => 'application/json'})
130
+ end
131
+
132
+ it 'returns correct data' do
133
+ result = Monobank.set_webhook(token:, url: 'https://example.com/some_random_data_for_security')
134
+
135
+ expect(result.status).to eq 'ok'
136
+ end
137
+ end
138
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  ENV['RAILS_ENV'] ||= 'test'
2
2
 
3
+ require 'webmock/rspec'
4
+
3
5
  require 'monobank'
4
6
 
5
7
  ENGINE_RAILS_ROOT = File.join(File.dirname(__FILE__), '../')
metadata CHANGED
@@ -1,15 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monobank
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - vergilet
8
8
  - anatoliikryvishyn
9
+ - dreyks
9
10
  autorequire:
10
11
  bindir: bin
11
12
  cert_chain: []
12
- date: 2024-01-31 00:00:00.000000000 Z
13
+ date: 2024-02-23 00:00:00.000000000 Z
13
14
  dependencies:
14
15
  - !ruby/object:Gem::Dependency
15
16
  name: httparty
@@ -71,6 +72,20 @@ dependencies:
71
72
  - - ">="
72
73
  - !ruby/object:Gem::Version
73
74
  version: 3.8.0
75
+ - !ruby/object:Gem::Dependency
76
+ name: webmock
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
74
89
  description: Unofficial Ruby Gem for Monobank API.
75
90
  email:
76
91
  - osyaroslav@gmail.com
@@ -80,24 +95,41 @@ extra_rdoc_files: []
80
95
  files:
81
96
  - Rakefile
82
97
  - lib/monobank.rb
98
+ - lib/monobank/auth/corporate.rb
99
+ - lib/monobank/auth/private.rb
83
100
  - lib/monobank/bank/currency.rb
84
101
  - lib/monobank/client.rb
85
102
  - lib/monobank/connection.rb
103
+ - lib/monobank/corporate.rb
104
+ - lib/monobank/corporate/client.rb
86
105
  - lib/monobank/error.rb
87
106
  - lib/monobank/methods/base.rb
88
107
  - lib/monobank/methods/get.rb
89
108
  - lib/monobank/methods/post.rb
109
+ - lib/monobank/personal/auth_check.rb
110
+ - lib/monobank/personal/auth_request.rb
90
111
  - lib/monobank/personal/client_info.rb
112
+ - lib/monobank/personal/corporate_webhook.rb
113
+ - lib/monobank/personal/registration.rb
114
+ - lib/monobank/personal/registration_status.rb
115
+ - lib/monobank/personal/settings.rb
91
116
  - lib/monobank/personal/statement.rb
92
117
  - lib/monobank/personal/webhook.rb
93
118
  - lib/monobank/resources/bank/currency.rb
94
119
  - lib/monobank/resources/base.rb
95
120
  - lib/monobank/resources/error.rb
96
121
  - lib/monobank/resources/personal/accounts.rb
122
+ - lib/monobank/resources/personal/auth_check.rb
123
+ - lib/monobank/resources/personal/auth_request.rb
97
124
  - lib/monobank/resources/personal/client_info.rb
125
+ - lib/monobank/resources/personal/registration.rb
126
+ - lib/monobank/resources/personal/registration_status.rb
127
+ - lib/monobank/resources/personal/settings.rb
98
128
  - lib/monobank/resources/personal/statement.rb
99
129
  - lib/monobank/resources/personal/webhook.rb
100
130
  - lib/monobank/version.rb
131
+ - spec/monobank_corporate_spec.rb
132
+ - spec/monobank_spec.rb
101
133
  - spec/spec_helper.rb
102
134
  homepage: https://github.com/vergilet/monobank
103
135
  licenses:
@@ -126,4 +158,6 @@ signing_key:
126
158
  specification_version: 4
127
159
  summary: Unofficial Ruby Gem for Monobank API.
128
160
  test_files:
161
+ - spec/monobank_corporate_spec.rb
162
+ - spec/monobank_spec.rb
129
163
  - spec/spec_helper.rb