mockserver-client 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +23 -0
- data/.rubocop.yml +13 -0
- data/.travis.yml +7 -0
- data/Gemfile +4 -0
- data/README.md +200 -0
- data/Rakefile +11 -0
- data/lib/mockserver-client.rb +4 -0
- data/lib/mockserver/abstract_client.rb +112 -0
- data/lib/mockserver/mock_server_client.rb +50 -0
- data/lib/mockserver/model/array_of.rb +85 -0
- data/lib/mockserver/model/body.rb +56 -0
- data/lib/mockserver/model/delay.rb +34 -0
- data/lib/mockserver/model/enum.rb +47 -0
- data/lib/mockserver/model/expectation.rb +60 -0
- data/lib/mockserver/model/forward.rb +41 -0
- data/lib/mockserver/model/parameter.rb +46 -0
- data/lib/mockserver/model/request.rb +52 -0
- data/lib/mockserver/model/response.rb +39 -0
- data/lib/mockserver/model/times.rb +53 -0
- data/lib/mockserver/proxy_client.rb +9 -0
- data/lib/mockserver/utility_methods.rb +44 -0
- data/lib/mockserver/version.rb +5 -0
- data/mockserver-client.gemspec +31 -0
- data/spec/fixtures/forward_mockserver.json +7 -0
- data/spec/fixtures/incorrect_login_response.json +20 -0
- data/spec/fixtures/post_login_request.json +22 -0
- data/spec/fixtures/register_expectation.json +52 -0
- data/spec/fixtures/search_request.json +6 -0
- data/spec/fixtures/times_once.json +6 -0
- data/spec/mockserver/builder_spec.rb +83 -0
- data/spec/mockserver/mock_client_spec.rb +77 -0
- data/spec/mockserver/proxy_client_spec.rb +37 -0
- data/spec/spec_helper.rb +61 -0
- metadata +240 -0
@@ -0,0 +1,85 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# The ArrayOf class stores instances of a given class only.
|
4
|
+
# It enforces this by intercepting the methods :<<, :[]= and :insert on the Array class
|
5
|
+
# and casts objects to the allowed type first. To use in your code, create a subclass of ArrayOf and override the child_class() method to return
|
6
|
+
# the class associated with the array.
|
7
|
+
#
|
8
|
+
# NOTE: You should use this class internally with the contract that you only call :<<. :[]= and :insert method
|
9
|
+
# to manipulate the array in use. Can easily be changed to have stricter rules, suffices for internal use in this gem.
|
10
|
+
#
|
11
|
+
# @author:: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
12
|
+
#
|
13
|
+
module MockServer::Model
|
14
|
+
DEFAULT_MISSING_INDEX = -1_000_000_000
|
15
|
+
|
16
|
+
# The ArrayOf class stores instances of a given class only.
|
17
|
+
class ArrayOf < Array
|
18
|
+
alias_method :add_element, :<<
|
19
|
+
alias_method :set_element, :[]=
|
20
|
+
alias_method :insert_element, :insert
|
21
|
+
|
22
|
+
# Create an array from the elements passed in
|
23
|
+
def initialize(items)
|
24
|
+
items.each do |item|
|
25
|
+
self << item
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# The class/type that this array stores
|
30
|
+
def child_class
|
31
|
+
fail 'Subclass should override method :child_class'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Add the item to the array
|
35
|
+
# @param item [Object] an item of the type/class supported by this array
|
36
|
+
# @raise [Exception] if the item cannot be converted to the allowed class
|
37
|
+
def <<(item)
|
38
|
+
add_element(convert_to_child_class(item))
|
39
|
+
end
|
40
|
+
|
41
|
+
# Set the given item at the index
|
42
|
+
# @param index [Integer] the index for the new element
|
43
|
+
# @param item [Object] an item of the type/class supported by this array
|
44
|
+
# @raise [Exception] if the item cannot be converted to the allowed class
|
45
|
+
def []=(index, item)
|
46
|
+
set_element(index, convert_to_child_class(item))
|
47
|
+
end
|
48
|
+
|
49
|
+
# Adds the given item at the index and shifts elements forward
|
50
|
+
# @param index [Integer] the index for the new element
|
51
|
+
# @param item [Object] an item of the type/class supported by this array
|
52
|
+
# @raise [Exception] if the item cannot be converted to the allowed class
|
53
|
+
def insert(index, item)
|
54
|
+
insert_element(index, convert_to_child_class(item))
|
55
|
+
end
|
56
|
+
|
57
|
+
# Method to set the element at the specified index.
|
58
|
+
# Will insert at index if there is another object at the index; otherwise will update.
|
59
|
+
# If the special DEFAULT_MISSING_INDEX value is given, will insert at the end.
|
60
|
+
# @param index [Integer] the index for the new element
|
61
|
+
# @param item [Object] an item of the type/class supported by this array
|
62
|
+
# @raise [Exception] if the item cannot be converted to the allowed class
|
63
|
+
def set(index, item)
|
64
|
+
if index == DEFAULT_MISSING_INDEX
|
65
|
+
self << item
|
66
|
+
elsif self[index]
|
67
|
+
insert(index, item)
|
68
|
+
else
|
69
|
+
self[index] = item
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Cast item to target class
|
74
|
+
def convert_to_child_class(item)
|
75
|
+
if item && item.class != child_class
|
76
|
+
begin
|
77
|
+
item = child_class.new(item)
|
78
|
+
rescue e
|
79
|
+
raise "Failed to convert element: #{item} to required type #{child_class}. Error: #{e.message}"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
item
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'hashie'
|
3
|
+
require_relative './parameter'
|
4
|
+
require_relative './enum'
|
5
|
+
|
6
|
+
#
|
7
|
+
# A model for a a body in a request object.
|
8
|
+
# @author: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
9
|
+
#
|
10
|
+
module MockServer::Model
|
11
|
+
# An enum for body type
|
12
|
+
class BodyType < SymbolizedEnum
|
13
|
+
def allowed_values
|
14
|
+
[:EXACT, :REGEX, :XPATH, :PARAMETERS]
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# A model for a a body in a request object.
|
19
|
+
class Body < Hashie::Dash
|
20
|
+
include Hashie::Extensions::MethodAccess
|
21
|
+
include Hashie::Extensions::IgnoreUndeclared
|
22
|
+
include Hashie::Extensions::Coercion
|
23
|
+
|
24
|
+
property :type, required: true
|
25
|
+
property :value
|
26
|
+
property :parameters
|
27
|
+
|
28
|
+
coerce_key :type, BodyType
|
29
|
+
coerce_key :value, String
|
30
|
+
coerce_key :parameters, Parameters
|
31
|
+
end
|
32
|
+
|
33
|
+
# DSL methods related to body
|
34
|
+
module DSL
|
35
|
+
# For response object where body can only be a string
|
36
|
+
def body(value)
|
37
|
+
value
|
38
|
+
end
|
39
|
+
|
40
|
+
def exact(value)
|
41
|
+
Body.new(type: :EXACT, value: value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def regex(value)
|
45
|
+
Body.new(type: :REGEX, value: value)
|
46
|
+
end
|
47
|
+
|
48
|
+
def xpath(value)
|
49
|
+
Body.new(type: :XPATH, value: value)
|
50
|
+
end
|
51
|
+
|
52
|
+
def parameterized(*parameters)
|
53
|
+
Body.new(type: :PARAMETERS, parameters: parameters)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative './enum'
|
3
|
+
|
4
|
+
#
|
5
|
+
# A model for a delay in a response.
|
6
|
+
# @author: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
7
|
+
#
|
8
|
+
module MockServer::Model
|
9
|
+
# Enum for time unit
|
10
|
+
class TimeUnit < SymbolizedEnum
|
11
|
+
def allowed_values
|
12
|
+
[:NANOSECONDS, :MICROSECONDS, :MILLISECONDS, :SECONDS, :MINUTES, :HOURS, :DAYS]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# Model a delay object
|
17
|
+
class Delay < Hashie::Dash
|
18
|
+
include Hashie::Extensions::MethodAccess
|
19
|
+
include Hashie::Extensions::IgnoreUndeclared
|
20
|
+
include Hashie::Extensions::Coercion
|
21
|
+
|
22
|
+
property :time_unit, default: 'SECONDS'
|
23
|
+
property :value, required: true
|
24
|
+
|
25
|
+
coerce_key :time_unit, TimeUnit
|
26
|
+
end
|
27
|
+
|
28
|
+
# DSL methods related to delay model
|
29
|
+
module DSL
|
30
|
+
def delay_by(time_unit, value)
|
31
|
+
Delay.new(time_unit: time_unit, value: value)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# A class to model a Java-like Enum.
|
4
|
+
# To create an Enum extend this class and override :allowed_values method with allowed enum values.
|
5
|
+
#
|
6
|
+
# @author:: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
7
|
+
#
|
8
|
+
module MockServer::Model
|
9
|
+
# Enum generic class
|
10
|
+
class Enum
|
11
|
+
# Create an instance of the enum from the value supplied
|
12
|
+
# @param supplied_value [Object] value used to create instance of an enum
|
13
|
+
# @raise [Exception] if the supplied value is not valid for this enum
|
14
|
+
def initialize(supplied_value)
|
15
|
+
supplied_value = pre_process_value(supplied_value)
|
16
|
+
fail "Supplied value: #{supplied_value} is not valid. Allowed values are: #{supplied_value}" unless allowed_values.include?(supplied_value)
|
17
|
+
@value = supplied_value
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Array] a list of values allowed by this enum
|
21
|
+
def allowed_values
|
22
|
+
fail 'Override :allowed_values in Enum class'
|
23
|
+
end
|
24
|
+
|
25
|
+
# A pre-process hook for a value before it is stored
|
26
|
+
# @param value [Object] a value used to instantiate the enum
|
27
|
+
# @return [Object] the processed value. By default, a no-op implementation.
|
28
|
+
def pre_process_value(value)
|
29
|
+
value
|
30
|
+
end
|
31
|
+
|
32
|
+
# Override this for JSON representation
|
33
|
+
def to_s
|
34
|
+
@value.to_s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Subclass of Enum that has a list of symbols as allowed values.
|
39
|
+
class SymbolizedEnum < Enum
|
40
|
+
# Pre-process the value passed in and convert to a symbol
|
41
|
+
# @param value [Object] a value used to instantiate the enum
|
42
|
+
# @return [Symbol] a symbolized version of the value passed in (first calls to_s)
|
43
|
+
def pre_process_value(value)
|
44
|
+
value.to_s.to_sym
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative './request'
|
3
|
+
require_relative './response'
|
4
|
+
require_relative './forward'
|
5
|
+
require_relative './times'
|
6
|
+
|
7
|
+
#
|
8
|
+
# A class to model an expectation sent to the Mockserver instance.
|
9
|
+
# See http://www.mock-server.com/#create-expectations for details.
|
10
|
+
#
|
11
|
+
# @author:: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
12
|
+
#
|
13
|
+
module MockServer::Model
|
14
|
+
# Expectation model
|
15
|
+
class Expectation
|
16
|
+
attr_accessor :times
|
17
|
+
|
18
|
+
# Method to setup the request on the expectation object
|
19
|
+
# @yieldparam [Request] the request that this expectation references
|
20
|
+
# @return [Expectation] this object according to the the builder pattern
|
21
|
+
def request(&_)
|
22
|
+
if block_given?
|
23
|
+
@request ||= Request.new
|
24
|
+
yield @request
|
25
|
+
end
|
26
|
+
@request
|
27
|
+
end
|
28
|
+
|
29
|
+
# Method to setup the response on the expectation object
|
30
|
+
# @yieldparam [Response] the response that this expectation references
|
31
|
+
# @return [Expectation] this object according to the the builder pattern
|
32
|
+
def response(&_)
|
33
|
+
if block_given?
|
34
|
+
@response ||= Response.new
|
35
|
+
yield @response
|
36
|
+
end
|
37
|
+
@response
|
38
|
+
end
|
39
|
+
|
40
|
+
# Method to setup the request on the expectation object
|
41
|
+
# @yieldparam [Forward] the forward object that this expectation references
|
42
|
+
# @return [Expectation] this object according to the the builder pattern
|
43
|
+
def forward(&_)
|
44
|
+
if block_given?
|
45
|
+
@forward ||= Forward.new
|
46
|
+
yield @forward
|
47
|
+
end
|
48
|
+
@forward
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# DSL methods related to expectation
|
53
|
+
module DSL
|
54
|
+
def expectation(&_)
|
55
|
+
expectation = Expectation.new
|
56
|
+
yield expectation if block_given?
|
57
|
+
expectation
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'hashie'
|
3
|
+
require_relative './enum'
|
4
|
+
|
5
|
+
#
|
6
|
+
# A class to model a forwarding on a request.
|
7
|
+
# @author:: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
8
|
+
#
|
9
|
+
module MockServer::Model
|
10
|
+
# Enum for a scheme used in a forward request
|
11
|
+
class Scheme < SymbolizedEnum
|
12
|
+
def allowed_values
|
13
|
+
[:HTTP, :HTTPS]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Model for forwarding
|
18
|
+
class Forward < Hashie::Dash
|
19
|
+
include Hashie::Extensions::MethodAccess
|
20
|
+
include Hashie::Extensions::IgnoreUndeclared
|
21
|
+
include Hashie::Extensions::Coercion
|
22
|
+
|
23
|
+
property :host, default: 'localhost'
|
24
|
+
property :port, default: 80
|
25
|
+
property :scheme, default: 'HTTP'
|
26
|
+
|
27
|
+
coerce_key :host, String
|
28
|
+
coerce_key :scheme, Scheme
|
29
|
+
end
|
30
|
+
|
31
|
+
# DSL methods for forward
|
32
|
+
module DSL
|
33
|
+
def forward(&_)
|
34
|
+
obj = Forward.new
|
35
|
+
yield obj if block_given?
|
36
|
+
obj
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :http_forward, :forward
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'hashie'
|
3
|
+
require_relative './array_of'
|
4
|
+
|
5
|
+
#
|
6
|
+
# A class to model parameters in payloads.
|
7
|
+
# @author:: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
8
|
+
#
|
9
|
+
module MockServer::Model
|
10
|
+
# A class that only stores strings
|
11
|
+
class Strings < ArrayOf
|
12
|
+
def child_class
|
13
|
+
String
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Model for parameter
|
18
|
+
class Parameter < Hashie::Dash
|
19
|
+
include Hashie::Extensions::MethodAccess
|
20
|
+
include Hashie::Extensions::IgnoreUndeclared
|
21
|
+
include Hashie::Extensions::Coercion
|
22
|
+
|
23
|
+
property :name, required: true
|
24
|
+
property :values, default: Strings.new([])
|
25
|
+
|
26
|
+
coerce_key :name, String
|
27
|
+
coerce_key :values, Strings
|
28
|
+
end
|
29
|
+
|
30
|
+
# A collection that only stores parameters
|
31
|
+
class Parameters < ArrayOf
|
32
|
+
def child_class
|
33
|
+
Parameter
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# DSL methods for parameter
|
38
|
+
module DSL
|
39
|
+
def parameter(key, *value)
|
40
|
+
Parameter.new(name: key, values: value)
|
41
|
+
end
|
42
|
+
|
43
|
+
alias_method :cookie, :parameter
|
44
|
+
alias_method :header, :parameter
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'hashie'
|
3
|
+
require_relative './parameter'
|
4
|
+
require_relative './body'
|
5
|
+
require_relative './enum'
|
6
|
+
|
7
|
+
#
|
8
|
+
# A class to model a request in an expectation.
|
9
|
+
# @author:: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
10
|
+
#
|
11
|
+
module MockServer::Model
|
12
|
+
# Enum for HTTP methods
|
13
|
+
class HTTPMethod < SymbolizedEnum
|
14
|
+
def allowed_values
|
15
|
+
[:GET, :POST, :PUT, :DELETE]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# Request model
|
20
|
+
class Request < Hashie::Dash
|
21
|
+
include Hashie::Extensions::MethodAccess
|
22
|
+
include Hashie::Extensions::IgnoreUndeclared
|
23
|
+
include Hashie::Extensions::Coercion
|
24
|
+
|
25
|
+
ALLOWED_METHODS = [:GET, :POST, :PUT, :DELETE]
|
26
|
+
|
27
|
+
property :method, required: true, default: :GET
|
28
|
+
property :path, required: true, default: ''
|
29
|
+
property :query_parameters, default: Parameters.new([])
|
30
|
+
property :cookies, default: Parameters.new([])
|
31
|
+
property :headers, default: Parameters.new([])
|
32
|
+
property :body
|
33
|
+
|
34
|
+
coerce_key :method, HTTPMethod
|
35
|
+
coerce_key :path, String
|
36
|
+
coerce_key :query_parameters, Parameters
|
37
|
+
coerce_key :cookies, Parameters
|
38
|
+
coerce_key :headers, Parameters
|
39
|
+
coerce_key :body, Body
|
40
|
+
end
|
41
|
+
|
42
|
+
# DSL methods related to requests
|
43
|
+
module DSL
|
44
|
+
def request(method, path, &_)
|
45
|
+
obj = Request.new(method: method, path: path)
|
46
|
+
yield obj if block_given?
|
47
|
+
obj
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :http_request, :request
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require_relative './body'
|
3
|
+
require_relative './delay'
|
4
|
+
require_relative './parameter'
|
5
|
+
|
6
|
+
#
|
7
|
+
# A class to model a response in an expectation.
|
8
|
+
# @author:: Nayyara Samuel (mailto: nayyara.samuel@opower.com)
|
9
|
+
#
|
10
|
+
module MockServer::Model
|
11
|
+
# Model for a mock response
|
12
|
+
class Response < Hashie::Dash
|
13
|
+
include Hashie::Extensions::MethodAccess
|
14
|
+
include Hashie::Extensions::IgnoreUndeclared
|
15
|
+
include Hashie::Extensions::Coercion
|
16
|
+
|
17
|
+
property :status_code, default: 200
|
18
|
+
property :cookies, default: Parameters.new([])
|
19
|
+
property :headers, default: Parameters.new([])
|
20
|
+
property :delay
|
21
|
+
property :body
|
22
|
+
|
23
|
+
coerce_key :cookies, Parameters
|
24
|
+
coerce_key :headers, Parameters
|
25
|
+
coerce_key :delay, Delay
|
26
|
+
coerce_key :body, String
|
27
|
+
end
|
28
|
+
|
29
|
+
# DSL Methods for a response
|
30
|
+
module DSL
|
31
|
+
def response(&_)
|
32
|
+
obj = Response.new
|
33
|
+
yield obj if block_given?
|
34
|
+
obj
|
35
|
+
end
|
36
|
+
|
37
|
+
alias_method :http_response, :response
|
38
|
+
end
|
39
|
+
end
|