automation_test_no_submodules 1.0.1

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,436 @@
1
+ =begin
2
+ #Test Automation (No submodules)
3
+
4
+ #SDKs (no submodules) to test automation workflows.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+ =end
8
+
9
+ require 'date'
10
+ require 'json'
11
+ require 'logger'
12
+ require 'tempfile'
13
+ require 'time'
14
+ require_relative './api_client_custom'
15
+ require 'faraday'
16
+ require 'faraday/multipart' if Gem::Version.new(Faraday::VERSION) >= Gem::Version.new('2.0')
17
+
18
+ module AutomationTestNoSubmodules
19
+ class ApiClient
20
+ # The Configuration object holding settings to be used in the API client.
21
+ attr_accessor :config
22
+
23
+ # Defines the headers to be used in HTTP requests of all API calls by default.
24
+ #
25
+ # @return [Hash]
26
+ attr_accessor :default_headers
27
+
28
+ # Initializes the ApiClient
29
+ # @option config [Configuration] Configuration for initializing the object, default to Configuration.default
30
+ def initialize(config = Configuration.default)
31
+ @config = config
32
+ @user_agent = "Konfig/#{VERSION}/ruby"
33
+ @default_headers = {
34
+ 'Content-Type' => 'application/json',
35
+ 'User-Agent' => @user_agent
36
+ }
37
+ end
38
+
39
+ def self.default
40
+ @@default ||= ApiClient.new
41
+ end
42
+
43
+ # Call an API with given options.
44
+ #
45
+ # @return [Array<(Object, Integer, Hash)>] an array of 3 elements:
46
+ # the data deserialized from response body (could be nil), response status code and response headers.
47
+ def call_api(http_method, path, opts = {})
48
+ begin
49
+ response = connection(opts).public_send(http_method.to_sym.downcase) do |req|
50
+ build_request(http_method, path, req, opts)
51
+ end
52
+
53
+ if config.debugging
54
+ config.logger.debug "HTTP response body ~BEGIN~\n#{response.body}\n~END~\n"
55
+ end
56
+
57
+ unless response.success?
58
+ if response.status == 0
59
+ # Errors from libcurl will be made visible here
60
+ fail ApiError.new(code: 0,
61
+ message: response.return_message)
62
+ else
63
+ fail ApiError.new(code: response.status,
64
+ response_headers: response.headers,
65
+ response_body: response.body),
66
+ response.reason_phrase
67
+ end
68
+ end
69
+ rescue Faraday::TimeoutError
70
+ fail ApiError.new('Connection timed out')
71
+ end
72
+
73
+ if opts[:return_type]
74
+ data = deserialize(response, opts[:return_type])
75
+ else
76
+ data = nil
77
+ end
78
+ return data, response.status, response.headers, response
79
+ end
80
+
81
+ # Builds the HTTP request
82
+ #
83
+ # @param [String] http_method HTTP method/verb (e.g. POST)
84
+ # @param [String] path URL path (e.g. /account/new)
85
+ # @option opts [Hash] :header_params Header parameters
86
+ # @option opts [Hash] :query_params Query parameters
87
+ # @option opts [Hash] :form_params Query parameters
88
+ # @option opts [Object] :body HTTP body (JSON/XML)
89
+ # @return [Faraday::Request] A Faraday Request
90
+ def build_request(http_method, path, request, opts = {})
91
+ url = build_request_url(path, opts)
92
+ http_method = http_method.to_sym.downcase
93
+
94
+ header_params = @default_headers.merge(opts[:header_params] || {})
95
+ query_params = opts[:query_params] || {}
96
+ form_params = opts[:form_params] || {}
97
+
98
+ update_params_for_auth! header_params, query_params, opts[:auth_names]
99
+
100
+ if [:post, :patch, :put, :delete].include?(http_method)
101
+ req_body = build_request_body(header_params, form_params, opts[:body])
102
+ if config.debugging
103
+ config.logger.debug "HTTP request body param ~BEGIN~\n#{req_body}\n~END~\n"
104
+ end
105
+ end
106
+ request.headers = header_params
107
+ request.body = req_body
108
+
109
+ # Overload default options only if provided
110
+ request.options.params_encoder = config.params_encoder if config.params_encoder
111
+ request.options.timeout = config.timeout if config.timeout
112
+
113
+ request.url url
114
+ request.params = query_params
115
+ download_file(request) if opts[:return_type] == 'File' || opts[:return_type] == 'Binary'
116
+
117
+ ApiClientCustom.request_hook(request, @config)
118
+
119
+ request
120
+ end
121
+
122
+ # Builds the HTTP request body
123
+ #
124
+ # @param [Hash] header_params Header parameters
125
+ # @param [Hash] form_params Query parameters
126
+ # @param [Object] body HTTP body (JSON/XML)
127
+ # @return [String] HTTP body data in the form of string
128
+ def build_request_body(header_params, form_params, body)
129
+ # http form
130
+ if header_params['Content-Type'] == 'application/x-www-form-urlencoded'
131
+ data = URI.encode_www_form(form_params)
132
+ elsif header_params['Content-Type'] == 'multipart/form-data'
133
+ data = {}
134
+ form_params.each do |key, value|
135
+ case value
136
+ when ::File, ::Tempfile
137
+ # TODO hardcode to application/octet-stream, need better way to detect content type
138
+ data[key] = Faraday::FilePart.new(value.path, 'application/octet-stream', value.path)
139
+ when ::Array, nil
140
+ # let Faraday handle Array and nil parameters
141
+ data[key] = value
142
+ else
143
+ data[key] = value.to_s
144
+ end
145
+ end
146
+ elsif body
147
+ data = body.is_a?(String) ? body : body.to_json
148
+ else
149
+ data = nil
150
+ end
151
+ data
152
+ end
153
+
154
+ def download_file(request)
155
+ @stream = []
156
+
157
+ # handle streaming Responses
158
+ request.options.on_data = Proc.new do |chunk, overall_received_bytes|
159
+ @stream << chunk
160
+ end
161
+ end
162
+
163
+ def connection(opts)
164
+ opts[:header_params]['Content-Type'] == 'multipart/form-data' ? connection_multipart : connection_regular
165
+ end
166
+
167
+ def connection_multipart
168
+ @connection_multipart ||= build_connection do |conn|
169
+ conn.request :multipart
170
+ conn.request :url_encoded
171
+ end
172
+ end
173
+
174
+ def connection_regular
175
+ @connection_regular ||= build_connection
176
+ end
177
+
178
+ def build_connection
179
+ Faraday.new(url: config.base_url, ssl: ssl_options) do |conn|
180
+ config.configure_middleware(conn)
181
+ yield(conn) if block_given?
182
+ conn.adapter(Faraday.default_adapter)
183
+ end
184
+ end
185
+
186
+ def ssl_options
187
+ {
188
+ ca_file: config.ssl_ca_file,
189
+ verify: config.ssl_verify,
190
+ verify_mode: config.ssl_verify_mode,
191
+ client_cert: config.ssl_client_cert,
192
+ client_key: config.ssl_client_key
193
+ }
194
+ end
195
+
196
+ # Check if the given MIME is a JSON MIME.
197
+ # JSON MIME examples:
198
+ # application/json
199
+ # application/json; charset=UTF8
200
+ # APPLICATION/JSON
201
+ # */*
202
+ # @param [String] mime MIME
203
+ # @return [Boolean] True if the MIME is application/json
204
+ def json_mime?(mime)
205
+ (mime == '*/*') || !(mime =~ /Application\/.*json(?!p)(;.*)?/i).nil?
206
+ end
207
+
208
+ # Deserialize the response to the given return type.
209
+ #
210
+ # @param [Response] response HTTP response
211
+ # @param [String] return_type some examples: "User", "Array<User>", "Hash<String, Integer>"
212
+ def deserialize(response, return_type)
213
+ body = response.body
214
+
215
+ # handle file downloading - return the File instance processed in request callbacks
216
+ # note that response body is empty when the file is written in chunks in request on_body callback
217
+ if return_type == 'File'
218
+ if @config.return_binary_data == true
219
+ # return byte stream
220
+ encoding = body.encoding
221
+ return @stream.join.force_encoding(encoding)
222
+ else
223
+ # return file instead of binary data
224
+ content_disposition = response.headers['Content-Disposition']
225
+ if content_disposition && content_disposition =~ /filename=/i
226
+ filename = content_disposition[/filename=['"]?([^'"\s]+)['"]?/, 1]
227
+ prefix = sanitize_filename(filename)
228
+ else
229
+ prefix = 'download-'
230
+ end
231
+ prefix = prefix + '-' unless prefix.end_with?('-')
232
+ encoding = body.encoding
233
+ @tempfile = Tempfile.open(prefix, @config.temp_folder_path, encoding: encoding)
234
+ @tempfile.write(@stream.join.force_encoding(encoding))
235
+ @tempfile.close
236
+ @config.logger.info "Temp file written to #{@tempfile.path}, please copy the file to a proper folder "\
237
+ "with e.g. `FileUtils.cp(tempfile.path, '/new/file/path')` otherwise the temp file "\
238
+ "will be deleted automatically with GC. It's also recommended to delete the temp file "\
239
+ "explicitly with `tempfile.delete`"
240
+ return @tempfile
241
+ end
242
+ end
243
+
244
+ return nil if body.nil? || body.empty?
245
+
246
+ # return response body directly for String return type
247
+ return body if return_type == 'String'
248
+
249
+ # ensuring a default content type
250
+ content_type = response.headers['Content-Type'] || 'application/json'
251
+
252
+ fail "Content-Type is not supported: #{content_type}" unless json_mime?(content_type)
253
+
254
+ begin
255
+ data = JSON.parse("[#{body}]", :symbolize_names => true)[0]
256
+ rescue JSON::ParserError => e
257
+ if %w(String Date Time).include?(return_type)
258
+ data = body
259
+ else
260
+ raise e
261
+ end
262
+ end
263
+
264
+ convert_to_type data, return_type
265
+ end
266
+
267
+ # Convert data to the given return type.
268
+ # @param [Object] data Data to be converted
269
+ # @param [String] return_type Return type
270
+ # @return [Mixed] Data in a particular type
271
+ def convert_to_type(data, return_type)
272
+ return nil if data.nil?
273
+ case return_type
274
+ when 'String'
275
+ data.to_s
276
+ when 'Integer'
277
+ data.to_i
278
+ when 'Float'
279
+ data.to_f
280
+ when 'Boolean'
281
+ data == true
282
+ when 'Time'
283
+ # parse date time (expecting ISO 8601 format)
284
+ Time.parse data
285
+ when 'Date'
286
+ # parse date time (expecting ISO 8601 format)
287
+ Date.parse data
288
+ when 'Object'
289
+ # generic object (usually a Hash), return directly
290
+ data
291
+ when /\AArray<(.+)>\z/
292
+ # e.g. Array<Pet>
293
+ sub_type = $1
294
+ data.map { |item| convert_to_type(item, sub_type) }
295
+ when /\AHash\<String, (.+)\>\z/
296
+ # e.g. Hash<String, Integer>
297
+ sub_type = $1
298
+ {}.tap do |hash|
299
+ data.each { |k, v| hash[k] = convert_to_type(v, sub_type) }
300
+ end
301
+ else
302
+ # models (e.g. Pet) or oneOf
303
+ klass = AutomationTestNoSubmodules.const_get(return_type)
304
+ klass.respond_to?(:openapi_one_of) ? klass.build(data) : klass.build_from_hash(data)
305
+ end
306
+ end
307
+
308
+ # Sanitize filename by removing path.
309
+ # e.g. ../../sun.gif becomes sun.gif
310
+ #
311
+ # @param [String] filename the filename to be sanitized
312
+ # @return [String] the sanitized filename
313
+ def sanitize_filename(filename)
314
+ filename.gsub(/.*[\/\\]/, '')
315
+ end
316
+
317
+ def build_request_url(path, opts = {})
318
+ # Add leading and trailing slashes to path
319
+ path = "/#{path}".gsub(/\/+/, '/')
320
+ @config.base_url(opts[:operation]) + path
321
+ end
322
+
323
+ # Update header and query params based on authentication settings.
324
+ #
325
+ # @param [Hash] header_params Header parameters
326
+ # @param [Hash] query_params Query parameters
327
+ # @param [String] auth_names Authentication scheme name
328
+ def update_params_for_auth!(header_params, query_params, auth_names)
329
+ Array(auth_names).each do |auth_name|
330
+ auth_setting = @config.auth_settings[auth_name]
331
+ next unless auth_setting
332
+ value = auth_setting[:value]
333
+ next unless value
334
+ case auth_setting[:in]
335
+ when 'header' then header_params[auth_setting[:key]] = value
336
+ when 'query' then query_params[auth_setting[:key]] = value
337
+ else fail ArgumentError, 'Authentication token must be in `query` or `header`'
338
+ end
339
+ end
340
+ end
341
+
342
+ # Sets user agent in HTTP header
343
+ #
344
+ # @param [String] user_agent User agent (e.g. Konfig/ruby/1.0.0)
345
+ def user_agent=(user_agent)
346
+ @user_agent = user_agent
347
+ @default_headers['User-Agent'] = @user_agent
348
+ end
349
+
350
+ # Return Accept header based on an array of accepts provided.
351
+ # @param [Array] accepts array for Accept
352
+ # @return [String] the Accept header (e.g. application/json)
353
+ def select_header_accept(accepts)
354
+ return nil if accepts.nil? || accepts.empty?
355
+ # use JSON when present, otherwise use all of the provided
356
+ json_accept = accepts.find { |s| json_mime?(s) }
357
+ json_accept || accepts.join(',')
358
+ end
359
+
360
+ # Return Content-Type header based on an array of content types provided.
361
+ # @param [Array] content_types array for Content-Type
362
+ # @return [String] the Content-Type header (e.g. application/json)
363
+ def select_header_content_type(content_types)
364
+ # return nil by default
365
+ return if content_types.nil? || content_types.empty?
366
+ # use JSON when present, otherwise use the first one
367
+ json_content_type = content_types.find { |s| json_mime?(s) }
368
+ json_content_type || content_types.first
369
+ end
370
+
371
+ # Convert object (array, hash, object, etc) to JSON string.
372
+ # @param [Object] model object to be converted into JSON string
373
+ # @return [String] JSON string representation of the object
374
+ def object_to_http_body(model)
375
+ return model if model.nil? || model.is_a?(String)
376
+ local_body = nil
377
+ if model.is_a?(Array)
378
+ local_body = model.map { |m| object_to_hash(m) }
379
+ else
380
+ local_body = object_to_hash(model)
381
+ end
382
+ local_body.to_json
383
+ end
384
+
385
+ # Convert object(non-array) to hash.
386
+ # @param [Object] obj object to be converted into JSON string
387
+ # @return [String] JSON string representation of the object
388
+ def object_to_hash(obj)
389
+ if obj.respond_to?(:to_hash)
390
+ obj.to_hash
391
+ else
392
+ obj
393
+ end
394
+ end
395
+
396
+ # Build parameter value according to the given collection format.
397
+ # @param [String] collection_format one of :csv, :ssv, :tsv, :pipes and :multi
398
+ def build_collection_param(param, collection_format)
399
+ case collection_format
400
+ when :csv
401
+ param.join(',')
402
+ when :ssv
403
+ param.join(' ')
404
+ when :tsv
405
+ param.join("\t")
406
+ when :pipes
407
+ param.join('|')
408
+ when :multi
409
+ # return the array directly as typhoeus will handle it as expected
410
+ param
411
+ else
412
+ fail "unknown collection format: #{collection_format.inspect}"
413
+ end
414
+ end
415
+ end
416
+
417
+ # Represents an HTTP response for method that end with *_with_http_info
418
+ class APIResponse
419
+ # [Object] deserialized data
420
+ attr_reader :data
421
+ # [Integer] response status code
422
+ attr_reader :status_code
423
+ # [Hash] response headers
424
+ attr_reader :headers
425
+ # [Faraday::Response] the original Faraday response object
426
+ attr_reader :response
427
+
428
+ def initialize(data, status_code, headers, response)
429
+ @data = data
430
+ @status_code = status_code
431
+ @headers = headers
432
+ @response = response
433
+ end
434
+
435
+ end
436
+ end
@@ -0,0 +1,14 @@
1
+ =begin
2
+ #Test Automation (No submodules)
3
+
4
+ #SDKs (no submodules) to test automation workflows.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+ =end
8
+
9
+ module AutomationTestNoSubmodules
10
+ class ApiClientCustom
11
+ def self.request_hook(request, configuration)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,53 @@
1
+ =begin
2
+ #Test Automation (No submodules)
3
+
4
+ #SDKs (no submodules) to test automation workflows.
5
+
6
+ The version of the OpenAPI document: 1.0.0
7
+ =end
8
+
9
+ module AutomationTestNoSubmodules
10
+ class ApiError < StandardError
11
+ attr_reader :code, :response_headers, :response_body
12
+
13
+ # Usage examples:
14
+ # ApiError.new
15
+ # ApiError.new("message")
16
+ # ApiError.new(:code => 500, :response_headers => {}, :response_body => "")
17
+ # ApiError.new(:code => 404, :message => "Not Found")
18
+ def initialize(arg = nil)
19
+ if arg.is_a? Hash
20
+ if arg.key?(:message) || arg.key?('message')
21
+ super(arg[:message] || arg['message'])
22
+ else
23
+ super arg
24
+ end
25
+
26
+ arg.each do |k, v|
27
+ instance_variable_set "@#{k}", v
28
+ end
29
+ else
30
+ super arg
31
+ end
32
+ end
33
+
34
+ # Override to_s to display a friendly error message
35
+ def to_s
36
+ message
37
+ end
38
+
39
+ def message
40
+ if @message.nil?
41
+ msg = "Error message: the server returns an error"
42
+ else
43
+ msg = @message
44
+ end
45
+
46
+ msg += "\nHTTP status code: #{code}" if code
47
+ msg += "\nResponse headers: #{response_headers}" if response_headers
48
+ msg += "\nResponse body: #{response_body}" if response_body
49
+
50
+ msg
51
+ end
52
+ end
53
+ end