robust_client_socket 0.5.2

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,137 @@
1
+ require 'spec_helper'
2
+ require 'httparty'
3
+ require './lib/version.rb'
4
+ require './lib/robust_client_socket/http/helpers'
5
+ require './lib/robust_client_socket/http/httparty_overrides'
6
+ require './lib/robust_client_socket/http/client'
7
+
8
+ RSpec.describe RobustClientSocket::HTTP::Client do
9
+ let(:credentials) do
10
+ {
11
+ base_uri: 'https://example.com',
12
+ public_key: OpenSSL::PKey::RSA.new(2048).public_key.to_s
13
+ }
14
+ end
15
+ let(:client_name) { 'test_client' }
16
+ let(:header_name) { 'Custom-Token' }
17
+
18
+ after(:each) do
19
+ # Reset HTTParty default_options to avoid test pollution
20
+ described_class.default_options.delete(:verify)
21
+ described_class.default_options.delete(:verify_mode)
22
+ described_class.default_options.delete(:ssl_version)
23
+ described_class.default_options.delete(:ciphers)
24
+ end
25
+
26
+ describe '.init' do
27
+ context 'with valid HTTPS credentials' do
28
+ it 'sets credentials' do
29
+ described_class.init(credentials: credentials, client_name: client_name)
30
+ expect(described_class.credentials).to eq(credentials)
31
+ end
32
+
33
+ it 'sets client_name' do
34
+ described_class.init(credentials: credentials, client_name: client_name)
35
+ expect(described_class.client_name).to eq(client_name)
36
+ end
37
+
38
+ it 'sets custom header_name' do
39
+ described_class.init(credentials: credentials, client_name: client_name, header_name: header_name)
40
+ expect(described_class.header_name).to eq(header_name)
41
+ end
42
+
43
+ it 'sets base_uri' do
44
+ described_class.init(credentials: credentials, client_name: client_name)
45
+ expect(described_class.base_uri).to eq('https://example.com')
46
+ end
47
+
48
+ it 'configures SSL verification when ssl_verify is enabled' do
49
+ ssl_credentials = credentials.merge(ssl_verify: true)
50
+ described_class.init(credentials: ssl_credentials, client_name: client_name)
51
+ expect(described_class.default_options[:verify]).to be true
52
+ expect(described_class.default_options[:verify_mode]).to eq(OpenSSL::SSL::VERIFY_PEER)
53
+ end
54
+
55
+ it 'does not configure SSL verification when ssl_verify is not set' do
56
+ described_class.init(credentials: credentials, client_name: client_name)
57
+ expect(described_class.default_options[:verify]).to be_nil
58
+ end
59
+ end
60
+
61
+ context 'in production with non-HTTPS base_uri and ssl_verify enabled' do
62
+ let(:http_credentials) { credentials.merge(base_uri: 'http://example.com', ssl_verify: true) }
63
+
64
+ before do
65
+ allow(described_class).to receive(:production?).and_return(true)
66
+ end
67
+
68
+ it 'raises InsecureConnectionError' do
69
+ expect {
70
+ described_class.init(credentials: http_credentials, client_name: client_name)
71
+ }.to raise_error(RobustClientSocket::HTTP::Client::InsecureConnectionError, /HTTPS required in production/)
72
+ end
73
+ end
74
+
75
+ context 'in production with non-HTTPS base_uri and ssl_verify disabled' do
76
+ let(:http_credentials) { credentials.merge(base_uri: 'http://example.com', ssl_verify: false) }
77
+
78
+ before do
79
+ allow(described_class).to receive(:production?).and_return(true)
80
+ end
81
+
82
+ it 'allows HTTP when ssl_verify is false' do
83
+ expect {
84
+ described_class.init(credentials: http_credentials, client_name: client_name)
85
+ }.not_to raise_error
86
+ end
87
+ end
88
+
89
+ context 'in development with HTTP base_uri' do
90
+ let(:http_credentials) { credentials.merge(base_uri: 'http://example.com') }
91
+
92
+ before do
93
+ allow(described_class).to receive(:production?).and_return(false)
94
+ end
95
+
96
+ it 'allows HTTP' do
97
+ expect {
98
+ described_class.init(credentials: http_credentials, client_name: client_name)
99
+ }.not_to raise_error
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ RSpec.describe RobustClientSocket::HTTP::Client do
106
+ describe '.production?' do
107
+ context 'when Rails is defined' do
108
+ let(:rails_stub) { double('Rails') }
109
+ let(:rails_env) { double('env', production?: true) }
110
+
111
+ before do
112
+ stub_const('Rails', rails_stub)
113
+ allow(rails_stub).to receive(:env).and_return(rails_env)
114
+ end
115
+
116
+ it 'delegates to Rails.env.production?' do
117
+ expect(described_class.send(:production?)).to be true
118
+ end
119
+ end
120
+
121
+ context 'when Rails is not defined' do
122
+ before do
123
+ hide_const('Rails') if defined?(Rails)
124
+ end
125
+
126
+ it 'checks RACK_ENV for production' do
127
+ allow(ENV).to receive(:fetch).with('RACK_ENV', 'development').and_return('production')
128
+ expect(described_class.send(:production?)).to be true
129
+ end
130
+
131
+ it 'defaults to development' do
132
+ allow(ENV).to receive(:fetch).with('RACK_ENV', 'development').and_return('development')
133
+ expect(described_class.send(:production?)).to be false
134
+ end
135
+ end
136
+ end
137
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+ require 'openssl'
3
+ require 'base64'
4
+ require './lib/version.rb'
5
+ require './lib/robust_client_socket/http/helpers.rb'
6
+
7
+ RSpec.describe RobustClientSocket::HTTP::Helpers do
8
+ let(:dummy_class) do
9
+ Class.new do
10
+ include RobustClientSocket::HTTP::Helpers
11
+
12
+ singleton_class.attr_accessor :credentials, :client_name
13
+
14
+ def self.service_uri
15
+ end
16
+
17
+ def self.public_key
18
+ end
19
+ end
20
+ end
21
+
22
+ describe 'PrivateClassMethods' do
23
+ describe '.robust_headers' do
24
+ it 'returns the correct headers' do
25
+ expected_headers = {
26
+ 'Content-Type' => 'application/json',
27
+ 'Accept' => 'application/json',
28
+ 'User-Agent' => "RobustClientSocket/#{RobustClientSocket::VERSION}"
29
+ }
30
+
31
+ expect(dummy_class.send(:robust_headers)).to eq(expected_headers)
32
+ end
33
+ end
34
+
35
+ describe '.secure_token' do
36
+ it 'returns the encrypted token' do
37
+ rsa_key = OpenSSL::PKey::RSA.new(2048)
38
+ allow(dummy_class).to receive(:public_key).and_return(rsa_key.public_key.to_s)
39
+ allow(dummy_class).to receive(:app_token).and_return('app_token')
40
+
41
+ result = dummy_class.send(:secure_token)
42
+ expect(result).to be_a(String)
43
+ expect { Base64.strict_decode64(result) }.not_to raise_error
44
+ end
45
+ end
46
+
47
+ describe '.app_token' do
48
+ it 'fetches the app token from configuration' do
49
+ allow(dummy_class).to receive(:client_name).and_return('client_name')
50
+
51
+ expect(dummy_class.send(:app_token)).to match(/client_name_+\d/)
52
+ end
53
+ end
54
+
55
+ describe '.public_key' do
56
+ it 'extracts public_key from credentials' do
57
+ dummy_class.credentials = { public_key: 'test_key' }
58
+ expect(dummy_class.send(:credentials)[:public_key]).to eq('test_key')
59
+ end
60
+ end
61
+
62
+ describe '.time_now_in_utc' do
63
+ it 'returns current UTC timestamp' do
64
+ allow(Time).to receive_message_chain(:now, :utc, :to_i).and_return(1234567890)
65
+ expect(dummy_class.send(:time_now_in_utc)).to eq(1234567890)
66
+ end
67
+ end
68
+
69
+ describe '.encrypted_data' do
70
+ it 'encrypts and base64 encodes data' do
71
+ rsa_key = OpenSSL::PKey::RSA.new(2048)
72
+ allow(dummy_class).to receive(:public_key).and_return(rsa_key.public_key.to_s)
73
+
74
+ result = dummy_class.send(:encrypted_data, 'test_data')
75
+ expect(result).to be_a(String)
76
+ expect { Base64.strict_decode64(result) }.not_to raise_error
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+ require 'webmock/rspec'
3
+ require 'httparty'
4
+ require './lib/robust_client_socket/http/httparty_overrides'
5
+ require './lib/robust_client_socket/http/helpers'
6
+
7
+ RSpec.describe RobustClientSocket::HTTP::HTTPartyOverrides do
8
+ let(:test_class) do
9
+ Class.new do
10
+ include HTTParty
11
+ include RobustClientSocket::HTTP::Helpers
12
+ include RobustClientSocket::HTTP::HTTPartyOverrides
13
+
14
+ class << self
15
+ attr_accessor :credentials, :client_name, :header_name
16
+ end
17
+ end
18
+ end
19
+
20
+ describe '.perform_request' do
21
+ before do
22
+ test_class.credentials = { public_key: OpenSSL::PKey::RSA.new(2048).public_key.to_s }
23
+ test_class.client_name = 'test_client'
24
+ allow(Time).to receive_message_chain(:now, :utc, :to_i).and_return(12345)
25
+ end
26
+
27
+ context 'with custom header_name' do
28
+ before do
29
+ test_class.header_name = 'Custom-Auth'
30
+ test_class.base_uri 'https://example.com'
31
+ test_class.headers({}) # Initialize headers
32
+ end
33
+
34
+ it 'sets custom header with secure token' do
35
+ stub = stub_request(:get, 'https://example.com/test')
36
+ .with { |req| req.headers['Custom-Auth'] }
37
+ test_class.get('/test')
38
+
39
+ expect(stub).to have_been_requested
40
+ end
41
+ end
42
+
43
+ context 'without custom header_name' do
44
+ before do
45
+ test_class.header_name = nil
46
+ test_class.base_uri 'https://example.com'
47
+ test_class.headers({}) # Initialize headers
48
+ end
49
+
50
+ it 'uses default Secure-Token header' do
51
+ stub = stub_request(:get, 'https://example.com/test')
52
+ .with { |req| req.headers['Secure-Token'] }
53
+ test_class.get('/test')
54
+
55
+ expect(stub).to have_been_requested
56
+ end
57
+ end
58
+ end
59
+
60
+ describe 'DEFAULT_HEADER_NAME' do
61
+ it 'is set to Secure-Token' do
62
+ expect(described_class::DEFAULT_HEADER_NAME).to eq('Secure-Token')
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,99 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
4
+ # this file to always be loaded, without a need to explicitly require it in any
5
+ # files.
6
+ #
7
+ # Given that it is always loaded, you are encouraged to keep this file as
8
+ # light-weight as possible. Requiring heavyweight dependencies from this file
9
+ # will add to the boot time of your test suite on EVERY test run, even for an
10
+ # individual file that may not need all of that loaded. Instead, consider making
11
+ # a separate helper file that requires the additional dependencies and performs
12
+ # the additional setup, and require it from the spec files that actually need
13
+ # it.
14
+ #
15
+ # See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
16
+
17
+ RSpec.configure do |config|
18
+ # rspec-expectations config goes here. You can use an alternate
19
+ # assertion/expectation library such as wrong or the stdlib/minitest
20
+ # assertions if you prefer.
21
+ config.expect_with :rspec do |expectations|
22
+ # This option will default to `true` in RSpec 4. It makes the `description`
23
+ # and `failure_message` of custom matchers include text for helper methods
24
+ # defined using `chain`, e.g.:
25
+ # be_bigger_than(2).and_smaller_than(4).description
26
+ # # => "be bigger than 2 and smaller than 4"
27
+ # ...rather than:
28
+ # # => "be bigger than 2"
29
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
30
+ end
31
+
32
+ # rspec-mocks config goes here. You can use an alternate test double
33
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
34
+ config.mock_with :rspec do |mocks|
35
+ # Prevents you from mocking or stubbing a method that does not exist on
36
+ # a real object. This is generally recommended, and will default to
37
+ # `true` in RSpec 4.
38
+ mocks.verify_partial_doubles = true
39
+ end
40
+
41
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
42
+ # have no way to turn it off -- the option exists only for backwards
43
+ # compatibility in RSpec 3). It causes shared context metadata to be
44
+ # inherited by the metadata hash of host groups and examples, rather than
45
+ # triggering implicit auto-inclusion in groups with matching metadata.
46
+ config.shared_context_metadata_behavior = :apply_to_host_groups
47
+
48
+ # The settings below are suggested to provide a good initial experience
49
+ # with RSpec, but feel free to customize to your heart's content.
50
+ =begin
51
+ # This allows you to limit a spec run to individual examples or groups
52
+ # you care about by tagging them with `:focus` metadata. When nothing
53
+ # is tagged with `:focus`, all examples get run. RSpec also provides
54
+ # aliases for `it`, `describe`, and `context` that include `:focus`
55
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
56
+ config.filter_run_when_matching :focus
57
+
58
+ # Allows RSpec to persist some state between runs in order to support
59
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
60
+ # you configure your source control system to ignore this file.
61
+ config.example_status_persistence_file_path = "spec/examples.txt"
62
+
63
+ # Limits the available syntax to the non-monkey patched syntax that is
64
+ # recommended. For more details, see:
65
+ # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/
66
+ config.disable_monkey_patching!
67
+
68
+ # This setting enables warnings. It's recommended, but in some cases may
69
+ # be too noisy due to issues in dependencies.
70
+ config.warnings = true
71
+
72
+ # Many RSpec users commonly either run the entire suite or an individual
73
+ # file, and it's useful to allow more verbose output when running an
74
+ # individual spec file.
75
+ if config.files_to_run.one?
76
+ # Use the documentation formatter for detailed output,
77
+ # unless a formatter has already been configured
78
+ # (e.g. via a command-line flag).
79
+ config.default_formatter = "doc"
80
+ end
81
+
82
+ # Print the 10 slowest examples and example groups at the
83
+ # end of the spec run, to help surface which specs are running
84
+ # particularly slow.
85
+ config.profile_examples = 10
86
+
87
+ # Run specs in random order to surface order dependencies. If you find an
88
+ # order dependency and want to debug it, you can fix the order by providing
89
+ # the seed, which is printed after each run.
90
+ # --seed 1234
91
+ config.order = :random
92
+
93
+ # Seed global randomization in this process using the `--seed` CLI option.
94
+ # Setting this allows you to use `--seed` to deterministically reproduce
95
+ # test failures related to randomization by passing the same `--seed` value
96
+ # as the one that triggered the failure.
97
+ Kernel.srand config.seed
98
+ =end
99
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: robust_client_socket
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.2
5
+ platform: ruby
6
+ authors:
7
+ - Taras Zhuk
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: oj
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: httparty
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rspec
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: rake
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ type: :runtime
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ description: Methods that should be used to interact with Robust inner ecosystem.
69
+ email:
70
+ - tee0zed@gmail.com
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - ".rspec"
76
+ - CODE_OF_CONDUCT.md
77
+ - LICENSE.txt
78
+ - README.md
79
+ - Rakefile
80
+ - lib/robust_client_socket.rb
81
+ - lib/robust_client_socket/configuration.rb
82
+ - lib/robust_client_socket/http/client.rb
83
+ - lib/robust_client_socket/http/helpers.rb
84
+ - lib/robust_client_socket/http/httparty_overrides.rb
85
+ - lib/version.rb
86
+ - robust_client_socket.gemspec
87
+ - spec/lib/payrent_client_socket.rb
88
+ - spec/lib/payrent_client_socket/http/client_spec.rb
89
+ - spec/lib/robust_client_socket/configuration_spec.rb
90
+ - spec/lib/robust_client_socket/http/client_spec.rb
91
+ - spec/lib/robust_client_socket/http/helpers_spec.rb
92
+ - spec/lib/robust_client_socket/http/httparty_overrides_spec.rb
93
+ - spec/spec_helper.rb
94
+ licenses: []
95
+ metadata: {}
96
+ rdoc_options: []
97
+ require_paths:
98
+ - lib
99
+ - config
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: 2.7.7
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubygems_version: 3.6.9
112
+ specification_version: 4
113
+ summary: Robust Client Socket
114
+ test_files: []