# encoding: UTF-8 require 'thor' require 'colorize' require_relative './mockserver-client' # CLI for this gem # @author Nayyara Samuel(nayyara.samuel@opower.com) # module CLIHelpers include MockServer LOGGER = LoggingFactory::DEFAULT_FACTORY.log('MockServerClient') # Prints out the parameters passed to it # @param options [Hash] a hash of parameters def print_parameters(options) puts "\nRunning with parameters:".bold options.each { |k, v| puts "\t#{k}: #{v}".yellow } puts '' end # Create a mockserver client # @param options [Struct] with host and port set # @return [MockServerClient] the mockserver client with the host and port def mockserver_client(options) client = MockServerClient.new(options.host, options.port) client.logger = LOGGER client end # Create a proxy client # @param options [Struct] with host and port set # @return [ProxyClient] the proxy client with the host and port def proxy_client(options) client = ProxyClient.new(options.host, options.port) client.logger = LOGGER client end # Convert a hash to a struct # @param hash [Hash] a hash # @return [Struct] a struct constructed from the hash def to_struct(hash) hash = symbolize_keys(hash) Struct.new(*hash.keys).new(*hash.values) end # Process a block using options extracted into a struct # @param mockserver [Boolean] true to use mockserver, false to use proxy # @yieldparam [AbstractClient] a mockserver or a proxy client # @yieldparam [Struct] a struct created from options hash def execute_command(mockserver = false, data_required = false, error_msg = '--data option must be provided', &_) print_parameters(options) struct_options = to_struct({ data: nil }.merge(options)) if data_required && !options['data'] error(error_msg) else client = mockserver ? mockserver_client(struct_options) : proxy_client(struct_options) yield client, struct_options if block_given? end end # Prints an error message # @param message [String] an error message def error(message) puts message.red end # Read a file # @param file [String] a file to read def read_file(file) YAML.load_file(file) end end # CLI for mock server and proxy clients class MockServerCLI < Thor include CLIHelpers include MockServer::UtilityMethods include MockServer::Model::DSL class_option :host, type: :string, aliases: '-h', required: true, default: 'localhost', desc: 'The host for the MockServer client.' class_option :port, type: :numeric, aliases: '-p', required: true, default: 8080, desc: 'The port for the MockServer client.' class_option :data, type: :string, aliases: '-d', desc: 'A JSON or YAML file containing the request payload.' desc 'retrieve', 'Retrieve the list of requests that have been made to the mock/proxy server.' def retrieve execute_command do |client, _| result = options.data ? client.retrieve(read_file(options.data)) : client.retrieve puts "RESULT:\n".bold + "#{result.to_json}".green end end desc 'register', 'Register an expectation with the mock server.' def register execute_command(true, true) do |client, options| payload = read_file(options.data) mock_expectation = expectation do |expectation| expectation.populate_from_payload(payload) end client.register(mock_expectation) end end desc 'dump_log', 'Dumps the matching request to the mock server logs.' option :java, type: :boolean, aliases: '-j', default: false, desc: 'A switch to turn Java format for logs on/off.' def dump_log execute_command do |client, options| options.data ? client.dump_log(read_file(options.data), options.java) : client.dump_log(nil, options.java) end end desc 'clear', 'Clears all stored mock request/responses from server.' def clear error_message = 'ERROR: No request provided. HINT: Use `clear` to selectively clear requests. Use `reset` to clear all.' execute_command(false, true, error_message) do |client, _| payload = read_file(options.data) client.clear(payload) end end desc 'reset', 'Resets the server clearing all data.' def reset execute_command do |client, _| client.reset end end desc 'verify', 'Verify that a request has been made the specified number of times to the server.' def verify execute_command(false, true) do |client, _| payload = read_file(options.data) mock_request = payload[HTTP_REQUEST] mock_times = payload[HTTP_TIMES] error 'No request found for verifying against' unless mock_request mock_times ? client.verify(mock_request, mock_times) : client.verify(mock_request) end end end