client-api 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 354bd06d34542ca2e3010787df486062955a1bed02e442085dad030bb93fa8fd
4
+ data.tar.gz: 7992b72abafc9da352d16ae1a8e47f84daaa21b41b79b6954b3bea5ec1f3fc97
5
+ SHA512:
6
+ metadata.gz: 5efb106c06984cc6544c846dc66eacca7af085576b285ca71f00802498f9fd75057fa4ffc299e1238f7ee7adb5d75162014f81db5fa6283c325740cdf26324b4
7
+ data.tar.gz: 9d9132ed137314a0b828fa56073efdca4a437abeda66731faecea9ada65dbabe23d822bc34b9a3a7cfa0f92d6533c0e1ef396ae63e8606277803337ea2bf129e
@@ -0,0 +1,17 @@
1
+ require "client-api/version"
2
+ require "client-api/settings"
3
+ require "client-api/base"
4
+ require "client-api/request"
5
+ require "client-api/validator"
6
+ require "client-api/loggers"
7
+
8
+ RSpec.configure do |config|
9
+ config.add_setting :base_url
10
+ config.add_setting :headers
11
+ config.add_setting :basic_auth
12
+ config.add_setting :json_output
13
+ config.add_setting :time_out
14
+ config.include ClientApi
15
+ end
16
+
17
+ include Loggers
@@ -0,0 +1,72 @@
1
+ require_relative 'request'
2
+
3
+ module ClientApi
4
+
5
+ class Api < ClientApi::Request
6
+
7
+ include ClientApi
8
+
9
+ def get(url, headers = nil)
10
+ @output = get_request(url, :headers => headers)
11
+ post_logger if $logger
12
+ end
13
+
14
+ def post(url, body, headers = nil)
15
+ @output = post_request(url, :body => body, :headers => headers)
16
+ post_logger if $logger
17
+ end
18
+
19
+ def delete(url, headers = nil)
20
+ @output = delete_request(url, :headers => headers)
21
+ post_logger if $logger
22
+ end
23
+
24
+ def put(url, body, headers = nil)
25
+ @output = put_request(url, :body => body, :headers => headers)
26
+ post_logger if $logger
27
+ end
28
+
29
+ def patch(url, body, headers = nil)
30
+ @output = patch_request(url, :body => body, :headers => headers)
31
+ post_logger if $logger
32
+ end
33
+
34
+ def status
35
+ @output.code.to_i
36
+ end
37
+
38
+ def body
39
+ if [200, 201, 204].include? status
40
+ unless json_output['Dirname'] == nil
41
+ FileUtils.mkdir_p "#{json_output['Dirname']}"
42
+ File.open("./output/#{json_output['Filename']}.json", "wb") {|file| file.puts JSON.pretty_generate(JSON.parse(@output.body))}
43
+ end
44
+ JSON.parse(@output.body)
45
+ else
46
+ JSON.parse(@output.message)
47
+ end
48
+ end
49
+
50
+ def message
51
+ @output.message
52
+ end
53
+
54
+ def post_logger
55
+ (@output.body.nil? || @output.body == "{}") ? res_body = 'empty response body' : res_body = body
56
+
57
+ $logger.debug("Response code == #{@output.code.to_i}")
58
+ $logger.debug("Response body == #{res_body}")
59
+ $logger.debug("=====================================================================================")
60
+ end
61
+
62
+ alias :code :status
63
+ alias :resp :body
64
+ end
65
+
66
+ def payload(path)
67
+ JSON.parse(File.read(path))
68
+ end
69
+
70
+ alias :schema_from_json :payload
71
+
72
+ end
@@ -0,0 +1,22 @@
1
+ require 'logger'
2
+
3
+ module Loggers
4
+
5
+ def logger=(logs)
6
+ output_logs_dir = logs['Dirname']
7
+ output_logs_filename = logs['Filename']
8
+
9
+ now = (Time.now.to_f * 1000).to_i
10
+ $logger = Logger.new(STDOUT)
11
+ $logger.datetime_format = '%Y-%m-%d %H:%M:%S'
12
+ Dir.mkdir("./#{output_logs_dir}") unless File.exist?("./#{output_logs_dir}")
13
+
14
+ if logs['StoreFilesCount'] && (logs['StoreFilesCount'] != nil || logs['StoreFilesCount'] != {} || logs['StoreFilesCount'] != empty)
15
+ file_count = Dir["./#{output_logs_dir}/*.log"].length
16
+ Dir["./#{output_logs_dir}/*.log"].sort_by {|f| File.ctime(f)}.reverse.last(file_count - "#{logs['StoreFilesCount']}".to_i).map {|junk_file| File.delete(junk_file)} if file_count > logs['StoreFilesCount']
17
+ end
18
+
19
+ $logger = Logger.new(File.new("#{output_logs_dir}/#{output_logs_filename}_#{now}.log", 'w'))
20
+ $logger.level = Logger::DEBUG
21
+ end
22
+ end
@@ -0,0 +1,74 @@
1
+ module ClientApi
2
+
3
+ class Request
4
+
5
+ include ClientApi
6
+
7
+ def get_request(url, options = {})
8
+ connect(url)
9
+ pre_logger(:log_url => uri(url), :log_header => header(options), :log_method => 'GET') if $logger
10
+ @http.get(uri(url).request_uri, initheader = header(options))
11
+ end
12
+
13
+ def post_request(url, options = {})
14
+ body = options[:body] || {}
15
+ connect(url)
16
+ pre_logger(:log_url => uri(url), :log_header => header(options), :log_body => body, :log_method => 'POST') if $logger
17
+ @http.post(uri(url).path, body.to_json, initheader = header(options))
18
+ end
19
+
20
+ def delete_request(url, options = {})
21
+ connect(url)
22
+ pre_logger(:log_url => uri(url), :log_header => header(options), :log_method => 'DELETE') if $logger
23
+ @http.delete(uri(url).path, initheader = header(options))
24
+ end
25
+
26
+ def put_request(url, options = {})
27
+ body = options[:body] || {}
28
+ connect(url)
29
+ pre_logger(:log_url => uri(url), :log_header => header(options), :log_body => body, :log_method => 'PUT') if $logger
30
+ @http.put(uri(url).path, body.to_json, initheader = header(options))
31
+ end
32
+
33
+ def patch_request(url, options = {})
34
+ body = options[:body] || {}
35
+ connect(url)
36
+ pre_logger(:log_url => uri(url), :log_header => header(options), :log_body => body, :log_method => 'PATCH') if $logger
37
+ @http.patch(uri(url).path, body.to_json, initheader = header(options))
38
+ end
39
+
40
+ def uri(args)
41
+ %w[http://, https://].any? {|protocol| args.include? protocol} ? URI.parse(args) : URI.parse(base_url + args)
42
+ end
43
+
44
+ def connect(args)
45
+ http = Net::HTTP.new(uri(args).host, uri(args).port)
46
+
47
+ if uri(args).scheme == "https"
48
+ http.use_ssl = true
49
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
50
+ http.read_timeout = time_out.to_i
51
+ @http = http
52
+ end
53
+ end
54
+
55
+ def basic_encode(options = {})
56
+ 'Basic ' + ["#{options[:username]}:#{options[:password]}"].pack('m0')
57
+ end
58
+
59
+ def header(options = {})
60
+ mod_headers = options[:headers] || {}
61
+ headers['Authorization'] = basic_encode(:username => basic_auth['Username'], :password => basic_auth['Password'])
62
+ headers.merge(mod_headers)
63
+ end
64
+
65
+ def pre_logger(options = {})
66
+ options[:log_body] = 'not available' if options[:log_body].nil?
67
+ $logger.debug("Requested method == #{options[:log_method]}")
68
+ $logger.debug("Requested url == #{options[:log_url]}")
69
+ $logger.debug("Requested headers == #{options[:log_header]}")
70
+ $logger.debug("Requested body == #{options[:log_body]}")
71
+ end
72
+ end
73
+
74
+ end
@@ -0,0 +1,35 @@
1
+ require 'logger'
2
+
3
+ module ClientApi
4
+
5
+ def self.configure
6
+ RSpec.configure do |config|
7
+ yield config
8
+ end
9
+ end
10
+
11
+ def self.configuration
12
+ RSpec.configuration
13
+ end
14
+
15
+ def base_url
16
+ ClientApi.configuration.base_url || ''
17
+ end
18
+
19
+ def headers
20
+ ClientApi.configuration.headers || ''
21
+ end
22
+
23
+ def basic_auth
24
+ ClientApi.configuration.basic_auth || ''
25
+ end
26
+
27
+ def json_output
28
+ ClientApi.configuration.json_output || ''
29
+ end
30
+
31
+ def time_out
32
+ ClientApi.configuration.time_out || ''
33
+ end
34
+
35
+ end
@@ -0,0 +1,180 @@
1
+ require "json-schema"
2
+
3
+ module ClientApi
4
+
5
+ def validate(res, *options)
6
+ options.map do |data|
7
+ raise_error('key (or) operator is not given!') if data[:key].nil? && data[:operator].nil?
8
+ raise_error('value (or) type is not given!') if data[:value].nil? && data[:type].nil?
9
+
10
+ @resp = res
11
+ key = data[:key].split("->")
12
+
13
+ key.map do |method|
14
+ method = method.to_i if is_num?(method)
15
+ @resp = @resp.send(:[], method)
16
+ end
17
+
18
+ value ||= data[:value]
19
+ operator = data[:operator]
20
+ type = data[:type] if data[:type] || data[:type] != {} || !data[:type].empty?
21
+
22
+ case operator
23
+ when '=', '==', 'eql?', 'equal', 'equal?'
24
+ # value validation
25
+ expect(value).to eq(@resp) if value != nil
26
+
27
+ # datatype validation
28
+ if (type == "boolean" || type == "bool") && value.nil?
29
+ expect(%w[TrueClass, FalseClass].any? {|bool| @resp.class.to_s.include? bool}).to be true
30
+ else
31
+ expect(datatype(type, value)).to eq(@resp.class)
32
+ end
33
+
34
+ when '!', '!=', '!eql?', 'not equal', '!equal?'
35
+ # value validation
36
+ expect(value).not_to eq(@resp) if value != nil
37
+
38
+ # datatype validation
39
+ if (type == "boolean" || type == "bool") && value.nil?
40
+ expect(%w[TrueClass, FalseClass].any? {|bool| @resp.class.to_s.include? bool}).not_to be true
41
+ else
42
+ expect(datatype(type, value)).not_to eq(@resp.class)
43
+ end
44
+ else
45
+ raise_error('operator not matching')
46
+ end
47
+ end
48
+ end
49
+
50
+ def validate_schema(param1, param2)
51
+ expected_schema = JSON::Validator.validate(param1, param2)
52
+ expect(expected_schema).to be true
53
+ end
54
+
55
+ def datatype(type, value)
56
+ if (type.downcase == 'string') || (type.downcase.== 'str')
57
+ String
58
+ elsif (type.downcase.== 'integer') || (type.downcase.== 'int')
59
+ Integer
60
+ elsif (type.downcase == 'symbol') || (type.downcase == 'sym')
61
+ Symbol
62
+ elsif (type.downcase == 'array') || (type.downcase == 'arr')
63
+ Array
64
+ elsif (type.downcase == 'object') || (type.downcase == 'obj')
65
+ Object
66
+ elsif (type.downcase == 'boolean') || (type.downcase == 'bool')
67
+ value === true ? TrueClass : FalseClass
68
+ elsif type.downcase == 'float'
69
+ Float
70
+ elsif type.downcase == 'hash'
71
+ Hash
72
+ elsif type.downcase == 'complex'
73
+ Complex
74
+ elsif type.downcase == 'rational'
75
+ Rational
76
+ elsif type.downcase == 'fixnum'
77
+ Fixnum
78
+ elsif type.downcase == 'falseclass'
79
+ FalseClass
80
+ elsif type.downcase == 'trueclass'
81
+ TrueClass
82
+ elsif type.downcase == 'bignum'
83
+ Bignum
84
+ else
85
+ end
86
+ end
87
+
88
+ def is_num?(str)
89
+ if Float(str)
90
+ true
91
+ end
92
+ rescue ArgumentError, TypeError
93
+ false
94
+ end
95
+
96
+ def validate_json(actual, expected)
97
+ param1 = JSON.parse(actual.to_json)
98
+ param2 = JSON.parse(expected.to_json)
99
+
100
+ @actual_key, @actual_value = [], []
101
+ deep_traverse(param2) do |path, value|
102
+ if !value.is_a?(Hash)
103
+ key_path = path.map! {|k| k}
104
+ @actual_key << key_path.join("->").to_s
105
+ @actual_value << value
106
+ end
107
+ end
108
+
109
+ Hash[@actual_key.zip(@actual_value)].map do |data|
110
+ @resp = param1
111
+ key = data[0].split("->")
112
+
113
+ key.map do |method|
114
+ method = method.to_i if is_num?(method)
115
+ @resp = @resp.send(:[], method)
116
+ end
117
+
118
+ value = data[1]
119
+ @assert, @final_assert, @overall = [], [], []
120
+
121
+ if !value.is_a?(Array)
122
+ expect(value).to eq(@resp)
123
+ else
124
+ @resp.each_with_index do |resp, i|
125
+ value.to_a.each_with_index do |val1, j|
126
+ val1.to_a.each_with_index do |val2, k|
127
+ if resp.to_a.include? val2
128
+ @assert << true
129
+ else
130
+ @assert << false
131
+ end
132
+ end
133
+ @final_assert << @assert
134
+ @assert = []
135
+
136
+ if @resp.count == @final_assert.count
137
+ @final_assert.each_with_index do |result, i|
138
+ if result.count(true) == val1.count
139
+ @overall << true
140
+ break
141
+ elsif @final_assert.count == i+1
142
+ expect(value).to eq(@resp)
143
+ end
144
+ end
145
+ @final_assert = []
146
+ end
147
+
148
+ end
149
+ end
150
+
151
+ if @overall.count(true) == value.count
152
+ return
153
+ else
154
+ expect(value).to eq(@resp)
155
+ end
156
+
157
+ end
158
+ end
159
+ end
160
+
161
+ def deep_traverse(hash, &block)
162
+ stack = hash.map {|k, v| [[k], v]}
163
+
164
+ while not stack.empty?
165
+ key, value = stack.pop
166
+ yield(key, value)
167
+ if value.is_a? Hash
168
+ value.each do |k, v|
169
+ if v.is_a?(String) then
170
+ if v.empty? then
171
+ v = nil
172
+ end
173
+ end
174
+ stack.push [key.dup << k, v]
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ end
@@ -0,0 +1,3 @@
1
+ module ClientApi
2
+ VERSION = "0.1.0".freeze
3
+ end
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: client-api
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - prashanth-sams
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-10-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json-schema
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '2.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '2.0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: logger
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.0'
83
+ description: client-api helps you write api tests quickly using rspec with different
84
+ levels of validations
85
+ email:
86
+ - sams.prashanth@gmail.com
87
+ executables: []
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - lib/client-api.rb
92
+ - lib/client-api/base.rb
93
+ - lib/client-api/loggers.rb
94
+ - lib/client-api/request.rb
95
+ - lib/client-api/settings.rb
96
+ - lib/client-api/validator.rb
97
+ - lib/client-api/version.rb
98
+ homepage: https://github.com/prashanth-sams/client-api
99
+ licenses:
100
+ - MIT
101
+ metadata:
102
+ homepage_uri: https://github.com/prashanth-sams/client-api
103
+ source_code_uri: https://github.com/prashanth-sams/client-api
104
+ documentation_uri: https://www.rubydoc.info/github/prashanth-sams/client-api/master
105
+ bug_tracker_uri: https://github.com/prashanth-sams/client-api/issues
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubygems_version: 3.0.4
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: HTTP Rest API client for RSpec Api Test framework
125
+ test_files: []