response_mate 0.1.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.
- checksums.yaml +15 -0
- data/.gitignore +15 -0
- data/.travis.yml +10 -0
- data/Gemfile +5 -0
- data/Gemfile.lock +107 -0
- data/LICENSE +20 -0
- data/README.md +107 -0
- data/Rakefile +12 -0
- data/bin/response_mate +5 -0
- data/environment.yml.sample +4 -0
- data/lib/response_mate.rb +43 -0
- data/lib/response_mate/cli.rb +58 -0
- data/lib/response_mate/commands.rb +1 -0
- data/lib/response_mate/commands/base.rb +12 -0
- data/lib/response_mate/commands/clear.rb +24 -0
- data/lib/response_mate/commands/export.rb +29 -0
- data/lib/response_mate/commands/inspect.rb +42 -0
- data/lib/response_mate/commands/list.rb +48 -0
- data/lib/response_mate/commands/record.rb +27 -0
- data/lib/response_mate/commands/setup.rb +24 -0
- data/lib/response_mate/connection.rb +36 -0
- data/lib/response_mate/core.rb +29 -0
- data/lib/response_mate/environment.rb +22 -0
- data/lib/response_mate/exporter.rb +18 -0
- data/lib/response_mate/exporters/postman.rb +61 -0
- data/lib/response_mate/helpers/application.rb +3 -0
- data/lib/response_mate/http.rb +41 -0
- data/lib/response_mate/inspector.rb +54 -0
- data/lib/response_mate/manifest.rb +68 -0
- data/lib/response_mate/manifest_parser.rb +7 -0
- data/lib/response_mate/oauth.rb +17 -0
- data/lib/response_mate/recorder.rb +39 -0
- data/lib/response_mate/request.rb +2 -0
- data/lib/response_mate/tape.rb +18 -0
- data/lib/response_mate/version.rb +3 -0
- data/oauth.yml.sample +12 -0
- data/requests.yml.sample +16 -0
- data/response_mate.gemspec +41 -0
- data/roadmap.md +24 -0
- data/spec/fixtures/two_keys.yml.erb +8 -0
- data/spec/lib/response_mate/cli_spec.rb +108 -0
- data/spec/lib/response_mate/core_spec.rb +65 -0
- data/spec/lib/response_mate/recorder_spec.rb +103 -0
- data/spec/lib/response_mate_spec.rb +7 -0
- data/spec/spec_helper.rb +32 -0
- metadata +336 -0
@@ -0,0 +1,68 @@
|
|
1
|
+
class ResponseMate::Manifest
|
2
|
+
include ResponseMate::ManifestParser
|
3
|
+
|
4
|
+
attr_accessor :filename, :requests, :requests_text, :base_url, :oauth,
|
5
|
+
:default_headers, :environment
|
6
|
+
|
7
|
+
def initialize(filename, environment = nil)
|
8
|
+
@filename = filename || ResponseMate.configuration.requests_manifest
|
9
|
+
@oauth = ResponseMate::Oauth.new
|
10
|
+
@environment = environment
|
11
|
+
parse
|
12
|
+
end
|
13
|
+
|
14
|
+
def preprocess_manifest
|
15
|
+
begin
|
16
|
+
@requests_text = File.read filename
|
17
|
+
rescue Errno::ENOENT
|
18
|
+
puts filename.red << ' does not seem to exist'
|
19
|
+
exit 1
|
20
|
+
end
|
21
|
+
|
22
|
+
@requests_text = Mustache.render(@requests_text, environment.try(:env) || {})
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse
|
26
|
+
preprocess_manifest
|
27
|
+
@request_hashes = YAML.load(requests_text)
|
28
|
+
@base_url = @request_hashes['base_url']
|
29
|
+
@requests = @request_hashes['requests'].map { |rh| ResponseMate::Request.new(rh) }
|
30
|
+
@default_headers = @request_hashes['default_headers']
|
31
|
+
add_oauth_to_requests
|
32
|
+
end
|
33
|
+
|
34
|
+
def add_oauth_to_requests
|
35
|
+
@requests.each do |req|
|
36
|
+
if req[:params].present?
|
37
|
+
req[:params].merge!('oauth_token' => oauth.token)
|
38
|
+
else
|
39
|
+
req[:params] = { 'oauth_token' => oauth.token }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
class << self
|
45
|
+
def parse_request(request)
|
46
|
+
return parse_request_string(request) if request.is_a? String
|
47
|
+
parse_request_hash(request) if request.is_a? Hash
|
48
|
+
end
|
49
|
+
|
50
|
+
def parse_request_hash(hash)
|
51
|
+
self::DEFAULT_REQUEST.merge(hash.symbolize_keys)
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_request_string(request_string)
|
55
|
+
raise ArgumentError if request_string !~ self::REQUEST_MATCHER
|
56
|
+
{ verb: $~[:verb] || self::DEFAULT_REQUEST[:verb] }
|
57
|
+
.merge(extract_path_query($~[:path]))
|
58
|
+
end
|
59
|
+
|
60
|
+
def extract_path_query(str)
|
61
|
+
parsed = Addressable::URI.parse(str)
|
62
|
+
{
|
63
|
+
path: parsed.path,
|
64
|
+
params: parsed.query_values
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module ResponseMate
|
4
|
+
class Oauth
|
5
|
+
attr_accessor :manifest
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@manifest = YAML.load_file(ResponseMate.configuration.oauth_manifest)
|
9
|
+
rescue Errno::ENOENT
|
10
|
+
@manifest = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def token
|
14
|
+
manifest['token']
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module ResponseMate
|
4
|
+
# Handles recording requests
|
5
|
+
class Recorder
|
6
|
+
include ResponseMate::ManifestParser
|
7
|
+
|
8
|
+
attr_accessor :base_url, :conn, :manifest, :oauth, :keys
|
9
|
+
|
10
|
+
def initialize(args = {})
|
11
|
+
@manifest = args[:manifest]
|
12
|
+
|
13
|
+
@keys = args[:keys]
|
14
|
+
@base_url = args[:base_url] || manifest.base_url
|
15
|
+
|
16
|
+
@conn = ResponseMate::Connection.new(base_url)
|
17
|
+
@conn.set_headers_from_manifest(manifest)
|
18
|
+
end
|
19
|
+
|
20
|
+
def record
|
21
|
+
requests = manifest.requests
|
22
|
+
requests.select! { |r| keys.include? r.key } if keys.present?
|
23
|
+
requests.each do |request|
|
24
|
+
process request.key, request
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def process(key, request)
|
31
|
+
meta = request.meta
|
32
|
+
request = ResponseMate::Manifest.parse_request(request.request)
|
33
|
+
|
34
|
+
puts "[#{key}] #{request[:verb]}".cyan_on_black.bold << " #{request[:path]}"
|
35
|
+
puts "\tparams #{request[:params]}" if request[:params].present?
|
36
|
+
ResponseMate::Tape.new.write(key, request, conn.fetch(request), meta)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class ResponseMate::Tape
|
2
|
+
def write(key, request, response, meta = {})
|
3
|
+
File.open("#{ResponseMate.configuration.output_dir}#{key}.yml", 'w') do |f|
|
4
|
+
file_content = {
|
5
|
+
request: request.select { |_, v| !v.nil? },
|
6
|
+
status: response.status,
|
7
|
+
headers: response.headers.to_hash,
|
8
|
+
body: response.body
|
9
|
+
}
|
10
|
+
|
11
|
+
file_content.merge!(meta: meta) if meta.present?
|
12
|
+
|
13
|
+
f << file_content.to_yaml
|
14
|
+
end
|
15
|
+
rescue Errno::ENOENT
|
16
|
+
raise ResponseMate::OutputDirError
|
17
|
+
end
|
18
|
+
end
|
data/oauth.yml.sample
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
---
|
2
|
+
token: Vr/AzbfQt3ywQlKUonZk25VqRg2ILFAFV/voi69FD9xlJl5Yp9DmDWb6PAEsVwuI1KckH3aa1/vxRaj/Mbwg==
|
3
|
+
application_token: false
|
4
|
+
expires_at: 2013-12-16 15:27:33.304654000 Z
|
5
|
+
user_id: 147606
|
6
|
+
oauth2_client_id: 1330
|
7
|
+
:permissions:
|
8
|
+
- favorites
|
9
|
+
- notifications
|
10
|
+
- easy
|
11
|
+
- public
|
12
|
+
- current_user_profile
|
data/requests.yml.sample
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
base_url: http://localhost:3000/api
|
2
|
+
default_headers:
|
3
|
+
accept: 'application/vnd.github.beta+json'
|
4
|
+
requests:
|
5
|
+
-
|
6
|
+
key: user_repos
|
7
|
+
request: 'GET /user/repos'
|
8
|
+
-
|
9
|
+
key: user_issues
|
10
|
+
request:
|
11
|
+
path: '/user/issues'
|
12
|
+
params:
|
13
|
+
sort: 'updated'
|
14
|
+
-
|
15
|
+
key: users_repos
|
16
|
+
request: 'GET /users/{{some_user_id}}/repos'
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'response_mate/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "response_mate"
|
8
|
+
spec.version = ResponseMate::VERSION
|
9
|
+
spec.authors = ["Dimitris Zorbas"]
|
10
|
+
spec.email = ["zorbash@skroutz.gr"]
|
11
|
+
spec.description = <<-DESC
|
12
|
+
Cli tool to make inspecting and recording HTTP requests fun again
|
13
|
+
DESC
|
14
|
+
spec.summary = %q{}
|
15
|
+
spec.homepage = ""
|
16
|
+
spec.license = "MIT"
|
17
|
+
|
18
|
+
spec.files = `git ls-files`.split($/)
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "pry-remote"
|
27
|
+
spec.add_development_dependency "pry-nav"
|
28
|
+
spec.add_development_dependency "rspec", "~> 2.14"
|
29
|
+
spec.add_development_dependency 'fakefs'
|
30
|
+
spec.add_development_dependency 'rubocop'
|
31
|
+
|
32
|
+
spec.add_dependency "thor", "~> 0.18.1"
|
33
|
+
spec.add_dependency "awesome_print"
|
34
|
+
spec.add_dependency "activesupport"
|
35
|
+
spec.add_dependency "colored"
|
36
|
+
spec.add_dependency "faraday"
|
37
|
+
spec.add_dependency "faraday_middleware"
|
38
|
+
spec.add_dependency "addressable"
|
39
|
+
spec.add_dependency "highline"
|
40
|
+
spec.add_dependency "mustache"
|
41
|
+
end
|
data/roadmap.md
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
## Milestone 0.1.0
|
2
|
+
- Make the list command prompt you to perform any of the listed requests ✓
|
3
|
+
- Recording is optional, you may just perform requests to inspect their
|
4
|
+
- output. [Done]
|
5
|
+
- Support mustache templates in favor of erb ✓
|
6
|
+
- Extract Manifest to a separate class ✓
|
7
|
+
- Add usage instructions in README.md [Done]
|
8
|
+
- Remove support for .yml.erb request manifests [Done]
|
9
|
+
- Export Connection as a separate class [Done]
|
10
|
+
- Export Tape as a separate class [Done]
|
11
|
+
|
12
|
+
## Milestone 0.2.0
|
13
|
+
- Request helpers (random ids, uuids).
|
14
|
+
- Paraller requests.
|
15
|
+
- Expectations, a expectations.yml file will contain a list of keys and
|
16
|
+
- status codes to match against the recordings.
|
17
|
+
- response_mate server command that serves the recorded responses when
|
18
|
+
- requests matching requests.yml are replayed.
|
19
|
+
- Curl exporter.
|
20
|
+
- Export environment.yml to postman format
|
21
|
+
- Accept extra params/headers from cli
|
22
|
+
- Support request types: [:raw, urlencoded]
|
23
|
+
- read manifest file from url
|
24
|
+
- Allow multiline input for inspect
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ResponseMate::CLI do
|
4
|
+
describe '.package_name' do
|
5
|
+
it 'names the tool response_mate' do
|
6
|
+
content = capture(:stdout) { ResponseMate::CLI.start %w[help] }
|
7
|
+
expect(content).to match(/response_mate commands:/m)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:command) { double(run: 'yay') }
|
12
|
+
|
13
|
+
describe '#record' do
|
14
|
+
before do
|
15
|
+
allow(ResponseMate::Commands::Record).to receive(:new).and_return(command)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'initializes ResponseMate::Commands::Record' do
|
19
|
+
expect(ResponseMate::Commands::Record).to receive(:new)
|
20
|
+
capture(:stdout) { ResponseMate::CLI.start %w[record] }
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'runs the command passing any given options, arguments' do
|
24
|
+
expect(command).to receive(:run)
|
25
|
+
capture(:stdout) { ResponseMate::CLI.start %w[record] }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe'#inspect' do
|
30
|
+
before do
|
31
|
+
allow(ResponseMate::Commands::Inspect).to receive(:new).and_return(command)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'initializes ResponseMate::Commands::Inspect' do
|
35
|
+
expect(ResponseMate::Commands::Inspect).to receive(:new)
|
36
|
+
capture(:stdout) { ResponseMate::CLI.start %w[inspect] }
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'runs the command passing any given options, arguments' do
|
40
|
+
expect(command).to receive(:run)
|
41
|
+
capture(:stdout) { ResponseMate::CLI.start %w[inspect] }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#setup' do
|
46
|
+
before do
|
47
|
+
allow(ResponseMate::Commands::Setup).to receive(:new).and_return(command)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'initializes ResponseMate::Commands::setup' do
|
51
|
+
expect(ResponseMate::Commands::Setup).to receive(:new)
|
52
|
+
capture(:stdout) { ResponseMate::CLI.start %w[setup] }
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'runs the command passing any given options, arguments' do
|
56
|
+
expect(command).to receive(:run)
|
57
|
+
capture(:stdout) { ResponseMate::CLI.start %w[setup] }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#clear' do
|
62
|
+
before do
|
63
|
+
allow(ResponseMate::Commands::Clear).to receive(:new).and_return(command)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'initializes ResponseMate::Commands::Clear' do
|
67
|
+
expect(ResponseMate::Commands::Clear).to receive(:new)
|
68
|
+
capture(:stdout) { ResponseMate::CLI.start %w[clear] }
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'runs the command passing any given options, arguments' do
|
72
|
+
expect(command).to receive(:run)
|
73
|
+
capture(:stdout) { ResponseMate::CLI.start %w[clear] }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe '#list' do
|
78
|
+
before do
|
79
|
+
allow(ResponseMate::Commands::List).to receive(:new).and_return(command)
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'initializes ResponseMate::Commands::List' do
|
83
|
+
expect(ResponseMate::Commands::List).to receive(:new)
|
84
|
+
capture(:stdout) { ResponseMate::CLI.start %w[list] }
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'runs the command passing any given options, arguments' do
|
88
|
+
expect(command).to receive(:run)
|
89
|
+
capture(:stdout) { ResponseMate::CLI.start %w[list] }
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#export' do
|
94
|
+
before do
|
95
|
+
allow(ResponseMate::Commands::Export).to receive(:new).and_return(command)
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'initializes ResponseMate::Commands::Export' do
|
99
|
+
expect(ResponseMate::Commands::Export).to receive(:new)
|
100
|
+
capture(:stdout) { ResponseMate::CLI.start %w[export] }
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'runs the command passing any given options, arguments' do
|
104
|
+
expect(command).to receive(:run)
|
105
|
+
capture(:stdout) { ResponseMate::CLI.start %w[export] }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ResponseMate::Configuration do
|
4
|
+
describe '.initialize' do
|
5
|
+
let(:subject) { ResponseMate::Configuration.new }
|
6
|
+
|
7
|
+
it 'assigns @output_dir' do
|
8
|
+
expect(subject.output_dir).to be_present
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'assigns @requests_manifest' do
|
12
|
+
expect(subject.requests_manifest).to be_present
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'assigns @oauth_manifest' do
|
16
|
+
expect(subject.oauth_manifest).to be_present
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ResponseMate do
|
22
|
+
describe '.setup' do
|
23
|
+
context '@configuration is nil' do
|
24
|
+
before { ResponseMate.configuration = nil }
|
25
|
+
|
26
|
+
it 'assigns @configuration to a new ResponseMate::Configuration' do
|
27
|
+
expect(ResponseMate::Configuration).to receive(:new)
|
28
|
+
ResponseMate.setup
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context '@configuration is not nil' do
|
33
|
+
before { ResponseMate.configuration = ResponseMate::Configuration.new }
|
34
|
+
|
35
|
+
it 'does not assign @configuration to a new ResponseMate::Configuration' do
|
36
|
+
ResponseMate::Configuration.should_not_receive(:new)
|
37
|
+
ResponseMate.setup
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'configuration block' do
|
42
|
+
before do
|
43
|
+
ResponseMate.setup do |config|
|
44
|
+
config.output_dir = 'foo'
|
45
|
+
config.requests_manifest = 'bar'
|
46
|
+
config.oauth_manifest = 'koko'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
after do
|
51
|
+
ResponseMate.setup do |config|
|
52
|
+
config.output_dir = './output/responses/'
|
53
|
+
config.requests_manifest = './requests.yml.erb'
|
54
|
+
config.oauth_manifest = './oauth.yml'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'properly assigns ivars' do
|
59
|
+
expect(ResponseMate.configuration.output_dir).to eq('foo')
|
60
|
+
expect(ResponseMate.configuration.requests_manifest).to eq('bar')
|
61
|
+
expect(ResponseMate.configuration.oauth_manifest).to eq('koko')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|