response_mate 0.3.3 → 0.4.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +41 -0
- data/CONTRIBUTING.md +42 -0
- data/Gemfile +1 -2
- data/Guardfile +4 -4
- data/README.md +126 -37
- data/Rakefile +1 -1
- data/bin/response_mate +18 -1
- data/lib/response_mate.rb +1 -1
- data/lib/response_mate/cli.rb +8 -4
- data/lib/response_mate/commands/inspect.rb +5 -6
- data/lib/response_mate/commands/list.rb +10 -7
- data/lib/response_mate/commands/record.rb +2 -3
- data/lib/response_mate/connection.rb +2 -4
- data/lib/response_mate/core.rb +3 -2
- data/lib/response_mate/environment.rb +10 -10
- data/lib/response_mate/exporter.rb +3 -2
- data/lib/response_mate/exporters/postman/environment.rb +1 -1
- data/lib/response_mate/manifest.rb +58 -19
- data/lib/response_mate/request.rb +7 -5
- data/lib/response_mate/tape.rb +11 -10
- data/lib/response_mate/version.rb +1 -1
- data/response_mate.gemspec +1 -1
- data/spec/lib/response_mate/commands/list_spec.rb +44 -1
- data/spec/lib/response_mate/commands/record_spec.rb +13 -14
- data/spec/lib/response_mate/core_spec.rb +7 -10
- data/spec/lib/response_mate/environment_spec.rb +67 -0
- data/spec/lib/response_mate/manifest_spec.rb +175 -0
- data/spec/lib/response_mate/recorder_spec.rb +1 -1
- data/spec/spec_helper.rb +34 -1
- metadata +13 -8
- data/roadmap.md +0 -24
@@ -2,15 +2,14 @@ class ResponseMate::Commands::Inspect < ResponseMate::Commands::Base
|
|
2
2
|
attr_reader :inspector
|
3
3
|
attr_accessor :history
|
4
4
|
|
5
|
-
def
|
6
|
-
|
5
|
+
def run # rubocop:disable Metrics/AbcSize
|
6
|
+
environment = ResponseMate::Environment.new(options[:environment])
|
7
|
+
options[:manifest] = ResponseMate::Manifest.new(options[:requests_manifest],
|
8
|
+
environment)
|
7
9
|
|
8
|
-
@
|
9
|
-
@inspector = ResponseMate::Inspector.new(@options)
|
10
|
+
@inspector = ResponseMate::Inspector.new(options)
|
10
11
|
@history = []
|
11
|
-
end
|
12
12
|
|
13
|
-
def run
|
14
13
|
if args.empty?
|
15
14
|
return $stderr.puts 'At least one key has to be specified'.red
|
16
15
|
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
# Command which performs the operations required by `response_mate list`
|
2
2
|
class ResponseMate::Commands::List < ResponseMate::Commands::Base
|
3
3
|
# Run the command based on args, options provided
|
4
|
-
def run
|
4
|
+
def run # rubocop:disable Metrics/AbcSize
|
5
5
|
environment = ResponseMate::Environment.new(options[:environment])
|
6
|
-
|
7
|
-
|
8
|
-
available_keys = @manifest.requests.map { |r| r.key.to_sym }
|
6
|
+
options[:manifest] = ResponseMate::Manifest.new(options[:requests_manifest],
|
7
|
+
environment)
|
9
8
|
|
10
9
|
puts available_keys.join("\n") << "\n\n"
|
11
|
-
|
12
10
|
action = ask_action
|
11
|
+
|
13
12
|
return if action == :no
|
14
13
|
|
15
14
|
perform_action(action, ask_key(available_keys))
|
@@ -17,6 +16,10 @@ class ResponseMate::Commands::List < ResponseMate::Commands::Base
|
|
17
16
|
|
18
17
|
private
|
19
18
|
|
19
|
+
def available_keys
|
20
|
+
options[:manifest].requests.map { |r| r.key.to_sym }
|
21
|
+
end
|
22
|
+
|
20
23
|
def ask_action
|
21
24
|
choose do |menu|
|
22
25
|
menu.prompt = 'Want to perform any of the actions above?'
|
@@ -34,9 +37,9 @@ class ResponseMate::Commands::List < ResponseMate::Commands::Base
|
|
34
37
|
def perform_action(action, key)
|
35
38
|
case action
|
36
39
|
when :record
|
37
|
-
ResponseMate::Recorder.new(
|
40
|
+
ResponseMate::Recorder.new(options).record([key])
|
38
41
|
when :inspect
|
39
|
-
ResponseMate::Inspector.new(
|
42
|
+
ResponseMate::Inspector.new(options).inspect_key(key)
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
@@ -3,9 +3,8 @@ class ResponseMate::Commands::Record < ResponseMate::Commands::Base
|
|
3
3
|
# Run the command based on args, options provided
|
4
4
|
def run
|
5
5
|
environment = ResponseMate::Environment.new(options[:environment])
|
6
|
-
manifest = ResponseMate::Manifest.new(options[:requests_manifest],
|
7
|
-
|
8
|
-
options[:manifest] = manifest
|
6
|
+
options[:manifest] = ResponseMate::Manifest.new(options[:requests_manifest],
|
7
|
+
environment)
|
9
8
|
|
10
9
|
recorder = ResponseMate::Recorder.new(options)
|
11
10
|
|
@@ -14,7 +14,7 @@ class ResponseMate::Connection
|
|
14
14
|
|
15
15
|
# Performs the supplied request
|
16
16
|
# @param {ResponseMate::Request} The request to be performed
|
17
|
-
def fetch(request)
|
17
|
+
def fetch(request) # rubocop:disable Metrics/AbcSize
|
18
18
|
uri = URI.parse(request[:url])
|
19
19
|
|
20
20
|
if request[:params]
|
@@ -23,10 +23,8 @@ class ResponseMate::Connection
|
|
23
23
|
uri.query = query
|
24
24
|
end
|
25
25
|
|
26
|
-
verb = request[:verb] || 'GET'
|
27
|
-
|
28
26
|
client.headers = request[:headers] if request[:headers]
|
29
|
-
client.send verb.downcase.to_sym, uri.to_s
|
27
|
+
client.send request[:verb].downcase.to_sym, uri.to_s
|
30
28
|
rescue Faraday::Error::ConnectionFailed
|
31
29
|
puts "Is a server up and running at #{request[:path]}?".red
|
32
30
|
exit 1
|
data/lib/response_mate/core.rb
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
# The main module of the tool contains configuration code and some constants
|
2
2
|
module ResponseMate
|
3
3
|
class OutputDirError < StandardError; end
|
4
|
+
class ManifestMissing < StandardError; end
|
4
5
|
class KeysNotFound < StandardError; end
|
5
6
|
|
6
7
|
# Methods handled by response_mate
|
7
|
-
HTTP_METHODS =
|
8
|
+
HTTP_METHODS = Faraday::Connection::METHODS
|
8
9
|
|
9
10
|
# Responsible for keeping initialization configuration values
|
10
11
|
class Configuration
|
11
12
|
attr_accessor :output_dir, :requests_manifest, :environment
|
12
13
|
|
13
14
|
def initialize
|
14
|
-
@output_dir = './
|
15
|
+
@output_dir = './'
|
15
16
|
@requests_manifest = './requests.yml'
|
16
17
|
@environment = './environment.yml'
|
17
18
|
end
|
@@ -3,26 +3,26 @@
|
|
3
3
|
# is a Hash which will be used for the rendering of the requests manifest as a
|
4
4
|
# [Mustace template](http://mustache.github.io/mustache.5.html).
|
5
5
|
class ResponseMate::Environment
|
6
|
-
attr_accessor :filename, :env
|
6
|
+
attr_accessor :filename, :env
|
7
7
|
|
8
8
|
delegate :[], to: :env
|
9
9
|
|
10
10
|
def initialize(filename)
|
11
11
|
@filename = filename || ResponseMate.configuration.environment
|
12
|
-
@env = {}
|
13
12
|
parse
|
14
13
|
end
|
15
14
|
|
15
|
+
# Check for environment file existence
|
16
|
+
# @return [TrueClass|FalseClass]
|
17
|
+
def exists?
|
18
|
+
File.exist? filename
|
19
|
+
end
|
20
|
+
|
16
21
|
private
|
17
22
|
|
23
|
+
# Set the env to the parsed YAML environment file
|
18
24
|
def parse
|
19
|
-
|
20
|
-
|
21
|
-
rescue Errno::ENOENT
|
22
|
-
puts filename.red << ' does not seem to exist'
|
23
|
-
exit 1
|
24
|
-
end
|
25
|
-
|
26
|
-
@env = ::YAML.load(environment_text)
|
25
|
+
return @env = {} unless exists?
|
26
|
+
@env = ::YAML.load_file(filename)
|
27
27
|
end
|
28
28
|
end
|
@@ -13,8 +13,9 @@ module ResponseMate
|
|
13
13
|
|
14
14
|
# Returns the compatible transformed resource
|
15
15
|
def export
|
16
|
-
@handler = "ResponseMate::Exporters::#{format.capitalize}".safe_constantize.
|
17
|
-
|
16
|
+
@handler = "ResponseMate::Exporters::#{format.capitalize}".safe_constantize.new manifest,
|
17
|
+
environment,
|
18
|
+
resource
|
18
19
|
handler.export
|
19
20
|
end
|
20
21
|
end
|
@@ -10,29 +10,17 @@ class ResponseMate::Manifest
|
|
10
10
|
parse
|
11
11
|
end
|
12
12
|
|
13
|
-
# Parse the requests manifest
|
14
|
-
# @return [Array] of requests
|
15
|
-
def parse
|
16
|
-
preprocess_manifest
|
17
|
-
@request_hashes = YAML.load(requests_text).deep_symbolize_keys
|
18
|
-
@name = @request_hashes[:name] || filename
|
19
|
-
@description = @request_hashes[:description] || ''
|
20
|
-
@requests = @request_hashes[:requests].
|
21
|
-
map(&:deep_symbolize_keys!).
|
22
|
-
map { |rh| ResponseMate::Request.new(rh).normalize! }
|
23
|
-
end
|
24
|
-
|
25
13
|
# Filters requests based on the supplied Array of keys
|
26
14
|
# @param [Array] keys The keys to lookup for matching requests
|
27
15
|
# @return [Array] of matching requests
|
28
16
|
def requests_for_keys(keys)
|
29
|
-
return [] if keys.
|
17
|
+
return [] if keys.blank?
|
30
18
|
|
31
19
|
existing_keys = requests.map(&:key)
|
32
20
|
missing_keys = keys - existing_keys
|
33
21
|
|
34
22
|
if missing_keys.present?
|
35
|
-
fail ResponseMate::KeysNotFound.new(missing_keys.join(','))
|
23
|
+
fail ResponseMate::KeysNotFound.new(missing_keys.join(', '))
|
36
24
|
end
|
37
25
|
|
38
26
|
requests.select! do |r|
|
@@ -42,18 +30,69 @@ class ResponseMate::Manifest
|
|
42
30
|
|
43
31
|
private
|
44
32
|
|
33
|
+
# Parse the requests manifest
|
34
|
+
# @return [Array] of requests
|
35
|
+
def parse
|
36
|
+
preprocess_manifest
|
37
|
+
parsed_manifest = YAML.load(@requests_text).deep_symbolize_keys
|
38
|
+
@name = parsed_manifest.fetch(:name, filename)
|
39
|
+
@description = parsed_manifest.fetch(:description, '')
|
40
|
+
check_requests(parsed_manifest)
|
41
|
+
@requests = parsed_manifest.
|
42
|
+
fetch(:requests, []). # rubocop:disable Style/MultilineOperationIndentation
|
43
|
+
map(&:deep_symbolize_keys!). # rubocop:disable Style/MultilineOperationIndentation
|
44
|
+
map { |rh| ResponseMate::Request.new(rh).normalize! } # rubocop:disable Style/MultilineOperationIndentation
|
45
|
+
end
|
46
|
+
|
45
47
|
# Parse the manifest file as a template
|
46
48
|
# @return [String] The manifest text parsed as a template
|
47
49
|
def preprocess_manifest
|
48
50
|
begin
|
49
51
|
@requests_text = File.read filename
|
50
52
|
rescue Errno::ENOENT
|
51
|
-
|
52
|
-
exit 1
|
53
|
+
raise ResponseMate::ManifestMissing.new(filename)
|
53
54
|
end
|
54
55
|
|
55
|
-
if environment.present?
|
56
|
-
|
57
|
-
|
56
|
+
process_mustache! if environment.present? && mustache?
|
57
|
+
end
|
58
|
+
|
59
|
+
# Check if the manifest file is a Mustache template
|
60
|
+
def mustache?
|
61
|
+
requests_text =~ /{{.*}}/
|
62
|
+
end
|
63
|
+
|
64
|
+
# Evaluate Mustache template
|
65
|
+
def process_mustache!
|
66
|
+
check_environment
|
67
|
+
|
68
|
+
@requests_text = Mustache.render(requests_text, environment.env)
|
69
|
+
end
|
70
|
+
|
71
|
+
def check_environment
|
72
|
+
return if environment.exists?
|
73
|
+
|
74
|
+
warning = 'The specified requests file is a template, but no environment file is found.'
|
75
|
+
guide = <<-GUIDE
|
76
|
+
The environment file holds any variables you wish to be interpolated.
|
77
|
+
You may specify a different environment file using the -e [file.yml] option.
|
78
|
+
Default: environment.yml
|
79
|
+
GUIDE
|
80
|
+
|
81
|
+
STDERR.puts warning.yellow, guide
|
82
|
+
end
|
83
|
+
|
84
|
+
def check_requests(parsed_manifest)
|
85
|
+
return if parsed_manifest.key? :requests
|
86
|
+
|
87
|
+
gemspec = Gem::Specification.find_by_name('response_mate')
|
88
|
+
example_manifest = "#{gemspec.homepage}/blob/master/requests.yml.sample"
|
89
|
+
|
90
|
+
warning = 'The specified requests file contains no requests.'
|
91
|
+
guide = <<-GUIDE
|
92
|
+
To declare requests place them under the :requests key.
|
93
|
+
Example manifest: #{example_manifest}
|
94
|
+
GUIDE
|
95
|
+
|
96
|
+
STDERR.puts warning.yellow, guide
|
58
97
|
end
|
59
98
|
end
|
@@ -5,9 +5,10 @@ class ResponseMate::Request < OpenStruct
|
|
5
5
|
|
6
6
|
# Make sure all defined requests in the manifest have complete
|
7
7
|
# information for {ResponseMate::Connection#fetch}
|
8
|
-
def normalize!
|
9
|
-
|
10
|
-
request
|
8
|
+
def normalize! # rubocop:disable Metrics/AbcSize
|
9
|
+
request[:verb] = begin
|
10
|
+
(ResponseMate::HTTP_METHODS & [request.fetch(:verb, 'GET').downcase.to_sym]).first ||
|
11
|
+
'GET'
|
11
12
|
end
|
12
13
|
|
13
14
|
if request[:url] !~ /{{.*?}}/ # Avoid encoding unprocessed mustache tags
|
@@ -18,8 +19,9 @@ class ResponseMate::Request < OpenStruct
|
|
18
19
|
end
|
19
20
|
|
20
21
|
# @return [String] Output string suitable for a terminal
|
21
|
-
def to_cli_format
|
22
|
-
out = "[#{key}]
|
22
|
+
def to_cli_format # rubocop:disable Metrics/AbcSize
|
23
|
+
out = ["[#{key.yellow}] ", request[:verb].to_s.upcase.colorize(:cyan).on_black.bold,
|
24
|
+
" #{request[:url]}"].join
|
23
25
|
out << "\tparams #{request[:params]}" if request[:params].present?
|
24
26
|
out
|
25
27
|
end
|
data/lib/response_mate/tape.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Responsible for the recorded responses as files
|
2
2
|
class ResponseMate::Tape
|
3
3
|
# Writes the tape as a file
|
4
|
-
def write(key, request, response, meta = {}, output_dir = nil)
|
4
|
+
def write(key, request, response, meta = {}, output_dir = nil) # rubocop:disable Metrics/AbcSize
|
5
5
|
output_dir ||= ResponseMate.configuration.output_dir
|
6
6
|
|
7
7
|
output_path = File.join output_dir, "#{key}.yml"
|
@@ -22,21 +22,22 @@ class ResponseMate::Tape
|
|
22
22
|
f << file_content.to_yaml
|
23
23
|
end
|
24
24
|
rescue Errno::ENOENT
|
25
|
-
raise ResponseMate::OutputDirError
|
25
|
+
raise ResponseMate::OutputDirError.new(output_dir)
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
30
|
def _utf8_encode(object)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
31
|
+
if object.respond_to? :force_encoding
|
32
|
+
object.force_encoding('UTF-8').encode!
|
33
|
+
elsif object.is_a? Hash
|
34
|
+
object.reduce({}) do |h, (k, v)|
|
35
|
+
key = k.dup unless k.is_a? Symbol
|
36
|
+
|
37
|
+
h[_utf8_encode(key)] = _utf8_encode(v)
|
38
|
+
h
|
38
39
|
end
|
39
|
-
|
40
|
+
elsif object.respond_to? :each
|
40
41
|
object.each { |v| _utf8_encode(v) }
|
41
42
|
end
|
42
43
|
end
|
data/response_mate.gemspec
CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_dependency 'thor', '~> 0.19'
|
27
27
|
spec.add_dependency 'awesome_print'
|
28
28
|
spec.add_dependency 'activesupport'
|
29
|
-
spec.add_dependency '
|
29
|
+
spec.add_dependency 'colorize', '> 0.7.5'
|
30
30
|
spec.add_dependency 'faraday'
|
31
31
|
spec.add_dependency 'faraday_middleware'
|
32
32
|
spec.add_dependency 'addressable'
|
@@ -3,9 +3,11 @@ require 'spec_helper'
|
|
3
3
|
describe ResponseMate::Commands::List do
|
4
4
|
include_context 'stubbed_requests'
|
5
5
|
|
6
|
-
|
6
|
+
let(:options) { {} }
|
7
7
|
let(:cmd_output) { capture(:stdout) { subject.run } }
|
8
8
|
|
9
|
+
subject(:command) { ResponseMate::Commands::List.new([], options) }
|
10
|
+
|
9
11
|
describe '#run' do
|
10
12
|
before { subject.stub(:ask_action).and_return(:no) }
|
11
13
|
|
@@ -23,6 +25,47 @@ describe ResponseMate::Commands::List do
|
|
23
25
|
quietly { cmd_output }
|
24
26
|
expect(File.basename(output_files.call.last)).to eq('user_friends.yml')
|
25
27
|
end
|
28
|
+
|
29
|
+
describe 'output directory' do
|
30
|
+
context 'when the output_dir option is specified' do
|
31
|
+
let(:custom_output_dir) do
|
32
|
+
File.expand_path('spec/source/other_output_dir')
|
33
|
+
end
|
34
|
+
|
35
|
+
let(:options) { { output_dir: custom_output_dir } }
|
36
|
+
|
37
|
+
context 'and it exists' do
|
38
|
+
let(:output_files) { -> { Dir[custom_output_dir + '/*'] } }
|
39
|
+
|
40
|
+
after { output_files.call.each { |file| File.delete(file) } }
|
41
|
+
|
42
|
+
it 'places the tapes in the specified directory' do
|
43
|
+
quietly { command.run }
|
44
|
+
|
45
|
+
expect(output_files.call.size).to eq(1)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context 'and it does not exist' do
|
50
|
+
let(:custom_output_dir) do
|
51
|
+
File.expand_path('spec/source/i_do_not_exist')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'raises ResponeMate::OutputDirError' do
|
55
|
+
expect { quietly { command.run } }.to raise_error(ResponseMate::OutputDirError,
|
56
|
+
/#{custom_output_dir}/)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when the output_dir options is not specified' do
|
62
|
+
it 'places the tapes in the default output directory' do
|
63
|
+
quietly { command.run }
|
64
|
+
|
65
|
+
expect(output_files.call.size).to eq(1)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
26
69
|
end
|
27
70
|
end
|
28
71
|
|
@@ -10,8 +10,10 @@ describe ResponseMate::Commands::Record do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe 'output files' do
|
13
|
+
subject { output_files.call }
|
14
|
+
|
13
15
|
it 'creates on for each request' do
|
14
|
-
expect(
|
16
|
+
expect(subject.size).to eq(2)
|
15
17
|
end
|
16
18
|
end
|
17
19
|
end
|
@@ -24,7 +26,7 @@ describe ResponseMate::Commands::Record do
|
|
24
26
|
let(:cmd_with_output_dir) do
|
25
27
|
quietly do
|
26
28
|
ResponseMate::Commands::Record.new([], keys: [],
|
27
|
-
output_dir:
|
29
|
+
output_dir: other_output_dir).run
|
28
30
|
end
|
29
31
|
end
|
30
32
|
|
@@ -34,8 +36,8 @@ describe ResponseMate::Commands::Record do
|
|
34
36
|
before { cmd_with_output_dir }
|
35
37
|
after { output_files.call.each { |file| File.delete(file) } }
|
36
38
|
|
37
|
-
it '
|
38
|
-
expect(output_files.call).to
|
39
|
+
it 'creates the tapes in the specified directory' do
|
40
|
+
expect(output_files.call.size).to eq(2)
|
39
41
|
end
|
40
42
|
end
|
41
43
|
|
@@ -45,7 +47,8 @@ describe ResponseMate::Commands::Record do
|
|
45
47
|
end
|
46
48
|
|
47
49
|
it 'raises ResponeMate::OutputDirError' do
|
48
|
-
expect { cmd_with_output_dir }.to raise_error(ResponseMate::OutputDirError
|
50
|
+
expect { cmd_with_output_dir }.to raise_error(ResponseMate::OutputDirError,
|
51
|
+
/#{other_output_dir}/)
|
49
52
|
end
|
50
53
|
end
|
51
54
|
end
|
@@ -54,7 +57,7 @@ describe ResponseMate::Commands::Record do
|
|
54
57
|
it 'creates the tapes in the default output directory' do
|
55
58
|
quietly { ResponseMate::Commands::Record.new([], keys: []).run }
|
56
59
|
|
57
|
-
expect(output_files.call).to
|
60
|
+
expect(output_files.call.size).to eq(2)
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
@@ -67,7 +70,7 @@ describe ResponseMate::Commands::Record do
|
|
67
70
|
end
|
68
71
|
|
69
72
|
it 'creates an output response file' do
|
70
|
-
expect(output_files.call).to
|
73
|
+
expect(output_files.call.size).to eq(1)
|
71
74
|
end
|
72
75
|
|
73
76
|
describe 'output response file' do
|
@@ -76,7 +79,7 @@ describe ResponseMate::Commands::Record do
|
|
76
79
|
end
|
77
80
|
|
78
81
|
it 'has the right file extension' do
|
79
|
-
expect(File.exist?(output_filename)).to
|
82
|
+
expect(File.exist?(output_filename)).to be(true)
|
80
83
|
end
|
81
84
|
|
82
85
|
describe 'YAML content' do
|
@@ -91,13 +94,9 @@ describe ResponseMate::Commands::Record do
|
|
91
94
|
expect(subject[:request][:verb]).to be_present
|
92
95
|
end
|
93
96
|
|
94
|
-
|
95
|
-
pending
|
96
|
-
end
|
97
|
+
xit 'contains the original request path'
|
97
98
|
|
98
|
-
|
99
|
-
pending
|
100
|
-
end
|
99
|
+
xit 'contains the original request params'
|
101
100
|
|
102
101
|
it 'contains the response status' do
|
103
102
|
expect(subject[:response][:status]).
|