require 'aws-eventstream' module Aws module Stubbing module Protocols class Rest include Seahorse::Model::Shapes def stub_data(api, operation, data) resp = new_http_response apply_status_code(operation, resp, data) apply_headers(operation, resp, data) apply_body(api, operation, resp, data) resp end private def new_http_response resp = Seahorse::Client::Http::Response.new resp.status_code = 200 resp.headers["x-amzn-RequestId"] = "stubbed-request-id" resp end def apply_status_code(operation, resp, data) operation.output.shape.members.each do |member_name, member_ref| if member_ref.location == 'statusCode' resp.status_code = data[member_name] if data.key?(member_name) end end end def apply_headers(operation, resp, data) Aws::Rest::Request::Headers.new(operation.output).apply(resp, data) end def apply_body(api, operation, resp, data) resp.body = build_body(api, operation, data) end def build_body(api, operation, data) rules = operation.output if head_operation(operation) "" elsif streaming?(rules) data[rules[:payload]] elsif rules[:payload] body_for(api, operation, rules[:payload_member], data[rules[:payload]]) else filtered = Seahorse::Model::Shapes::ShapeRef.new( shape: Seahorse::Model::Shapes::StructureShape.new.tap do |s| rules.shape.members.each do |member_name, member_ref| s.add_member(member_name, member_ref) if member_ref.location.nil? end end ) body_for(api, operation, filtered, data) end end def streaming?(ref) if ref[:payload] case ref[:payload_member].shape when StringShape then true when BlobShape then true else false end else false end end def head_operation(operation) operation.http_method == "HEAD" end def eventstream?(rules) rules.eventstream end def encode_eventstream_response(rules, data, builder) data.inject('') do |stream, event_data| # construct message headers and payload opts = {headers: {}} case event_data.delete(:message_type) when 'event' encode_event(opts, rules, event_data, builder) when 'error' # errors are unmodeled encode_error(opts, event_data) when 'exception' # Pending raise 'Stubbing :exception event is not supported' end stream << Aws::EventStream::Encoder.new.encode( Aws::EventStream::Message.new(opts)) stream end end def encode_error(opts, event_data) opts[:headers][':error-message'] = Aws::EventStream::HeaderValue.new( value: event_data[:error_message], type: 'string' ) opts[:headers][':error-code'] = Aws::EventStream::HeaderValue.new( value: event_data[:error_code], type: 'string' ) opts[:headers][':message-type'] = Aws::EventStream::HeaderValue.new( value: 'error', type: 'string' ) opts end def encode_event(opts, rules, event_data, builder) event_ref = rules.shape.member(event_data.delete(:event_type)) explicit_payload = false implicit_payload_members = {} event_ref.shape.members.each do |name, ref| if ref.eventpayload explicit_payload = true else implicit_payload_members[name] = ref end end if !explicit_payload && !implicit_payload_members.empty? unless implicit_payload_members.size > 1 m_name, _ = implicit_payload_members.first value = {} value[m_name] = event_data[m_name] opts[:payload] = StringIO.new(builder.new(event_ref).serialize(value)) end end event_data.each do |k, v| member_ref = event_ref.shape.member(k) if member_ref.eventheader opts[:headers][member_ref.location_name] = Aws::EventStream::HeaderValue.new( value: v, type: member_ref.eventheader_type ) elsif member_ref.eventpayload case member_ref.eventpayload_type when 'string' opts[:payload] = StringIO.new(v) when 'blob' opts[:payload] = v when 'structure' opts[:payload] = StringIO.new(builder.new(member_ref).serialize(v)) end end end opts[:headers][':event-type'] = Aws::EventStream::HeaderValue.new( value: event_ref.location_name, type: 'string' ) opts[:headers][':message-type'] = Aws::EventStream::HeaderValue.new( value: 'event', type: 'string' ) opts end end end end end