wire_tap 0.0.2 → 0.0.3
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.
- data/.gitignore +1 -0
- data/lib/wire_tap/listener.rb +25 -1
- data/lib/wire_tap/parsers/request_parser.rb +19 -0
- data/lib/wire_tap/version.rb +1 -1
- data/sample_output.md +50 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/support/basic_web_app.rb +3 -0
- data/spec/wire_tap/listener_spec.rb +44 -5
- data/spec/wire_tap/parsers/request_parser_spec.rb +19 -0
- data/wire_tap.gemspec +7 -5
- metadata +57 -11
- data/spec/factories.rb +0 -5
data/lib/wire_tap/listener.rb
CHANGED
@@ -1,10 +1,34 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
require 'wire_tap/parsers/request_parser'
|
1
3
|
module WireTap
|
2
4
|
class Listener
|
5
|
+
attr_reader :transactions
|
3
6
|
def initialize app
|
4
7
|
@app = app
|
8
|
+
@transactions = []
|
5
9
|
end
|
6
10
|
def call(env)
|
7
|
-
@app.call(env)
|
11
|
+
response = @app.call(env)
|
12
|
+
@transactions << parse_transaction(env, response)
|
13
|
+
response
|
14
|
+
end
|
15
|
+
def parse_request(request)
|
16
|
+
RequestParser.parse(request)
|
17
|
+
end
|
18
|
+
def parse_response(response)
|
19
|
+
status,headers,body = response
|
20
|
+
{
|
21
|
+
:status => status,
|
22
|
+
:content_type => headers["Content-Type"],
|
23
|
+
:body => body
|
24
|
+
}
|
25
|
+
end
|
26
|
+
def parse_transaction(env, response)
|
27
|
+
{
|
28
|
+
:method=>env["REQUEST_METHOD"],
|
29
|
+
:path=>env["PATH_INFO"],
|
30
|
+
:request => parse_request(env["rack.input"].read)
|
31
|
+
}.merge(parse_response(response))
|
8
32
|
end
|
9
33
|
end
|
10
34
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'cgi'
|
2
|
+
module WireTap
|
3
|
+
class RequestParser
|
4
|
+
class << self
|
5
|
+
def parse request
|
6
|
+
clean(CGI.parse(request))
|
7
|
+
end
|
8
|
+
def clean kv_pairs
|
9
|
+
kv_pairs.reduce({}) do |result, kv|
|
10
|
+
key,value = kv
|
11
|
+
value = value.first if value.length <=1
|
12
|
+
result[key] = value
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/wire_tap/version.rb
CHANGED
data/sample_output.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
Sample API documentation
|
2
|
+
========================
|
3
|
+
|
4
|
+
Todo: review content. layout probably unimportant at this stage.
|
5
|
+
We will probably need one feature per API call. The feature description can provide the heading. Would probably need one scenario covering the 200 'happy' path and a scenario for each error code.
|
6
|
+
|
7
|
+
I don't think we should document the authentication failures for every API call - maybe just for the authentication docs.
|
8
|
+
|
9
|
+
|
10
|
+
Retrieving all child records
|
11
|
+
----------------------------
|
12
|
+
|
13
|
+
* Path: /children/
|
14
|
+
* Method: GET
|
15
|
+
* Accept headers: application/json
|
16
|
+
* Parameters:
|
17
|
+
* imei_number: Handset identifier
|
18
|
+
* Status code: 200
|
19
|
+
|
20
|
+
Sample response:
|
21
|
+
|
22
|
+
```json
|
23
|
+
[
|
24
|
+
{
|
25
|
+
"ID" : 1234,
|
26
|
+
"Location" : "UK"
|
27
|
+
}
|
28
|
+
]
|
29
|
+
```
|
30
|
+
|
31
|
+
* Alternative status codes:
|
32
|
+
* 403: Not authenticated
|
33
|
+
* 401: User account is blocked
|
34
|
+
|
35
|
+
Updating a child record
|
36
|
+
-----------------------
|
37
|
+
|
38
|
+
* Path: /children/:id
|
39
|
+
* Method: POST
|
40
|
+
* Accept headers: application/json
|
41
|
+
* Parameters:
|
42
|
+
* id : ID of the record to be updated
|
43
|
+
* Return status code: 204
|
44
|
+
|
45
|
+
Sample request:
|
46
|
+
|
47
|
+
```
|
48
|
+
location=UK
|
49
|
+
has_siblings=TRUE
|
50
|
+
```
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require 'rspec'
|
2
2
|
require "factory_girl"
|
3
|
-
require
|
3
|
+
require 'rack/test'
|
4
4
|
require 'wire_tap'
|
5
5
|
|
6
|
+
Dir['./lib/**/*.rb'].map {|f| require f}
|
7
|
+
Dir['./spec/support/**/*.rb'].map {|f| require f}
|
8
|
+
|
6
9
|
class FakeRackApp
|
7
10
|
def call(env)
|
11
|
+
[200, {"Content-Type" => "text/plain"}, ["Hello world!"]]
|
8
12
|
end
|
9
13
|
end
|
10
14
|
|
@@ -1,9 +1,48 @@
|
|
1
|
+
|
1
2
|
require 'spec_helper'
|
2
3
|
describe WireTap::Listener do
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
context "saving request details" do
|
5
|
+
include Rack::Test::Methods
|
6
|
+
let(:app){
|
7
|
+
WireTap::Listener.new(wrapped_app)
|
8
|
+
}
|
9
|
+
context "for a get request" do
|
10
|
+
before(:each) do
|
11
|
+
get "/foo"
|
12
|
+
end
|
13
|
+
let(:wrapped_app){
|
14
|
+
class SinatraApp < BasicWebApp
|
15
|
+
get("/foo") { "Hello world"}
|
16
|
+
end
|
17
|
+
SinatraApp.new
|
18
|
+
}
|
19
|
+
describe "the recorded transaction" do
|
20
|
+
subject {app.transactions.last}
|
21
|
+
its([:method]) { should == "GET"}
|
22
|
+
its([:path]) { should == "/foo"}
|
23
|
+
its([:request]) { should be_empty}
|
24
|
+
its([:status]) { should == 200}
|
25
|
+
its([:content_type]) { should match /^text\/html/}
|
26
|
+
its([:body]) { should==["Hello world"]}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
context "for a post request" do
|
30
|
+
before(:each) do
|
31
|
+
post "/bar",{:id=>123, :name=>"bob"}
|
32
|
+
end
|
33
|
+
let(:wrapped_app) {
|
34
|
+
class SinatraApp < BasicWebApp
|
35
|
+
post("/bar") do
|
36
|
+
"#{params[:id]} : Hello, #{params[:name]}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
SinatraApp.new
|
40
|
+
}
|
41
|
+
describe "the recorded transaction" do
|
42
|
+
subject{app.transactions.last}
|
43
|
+
its([:method]){ should == "POST"}
|
44
|
+
its([:request]){ should == {"id"=>"123", "name"=>"bob"}}
|
45
|
+
end
|
46
|
+
end
|
8
47
|
end
|
9
48
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
module WireTap
|
3
|
+
describe RequestParser do
|
4
|
+
subject {RequestParser.parse(request)}
|
5
|
+
context "parsing an empty request" do
|
6
|
+
let(:request) {""}
|
7
|
+
it { should be_empty}
|
8
|
+
end
|
9
|
+
context "parsing a request with two strings" do
|
10
|
+
let(:request) {"foo=bar&bob=bill"}
|
11
|
+
its(["foo"]){ should == "bar"}
|
12
|
+
its(["bob"]){ should == "bill"}
|
13
|
+
end
|
14
|
+
context "parsing a request with two values for the same key" do
|
15
|
+
let(:request) {"foo=bar&foo=bob"}
|
16
|
+
its(["foo"]){ should == ["bar", "bob"]}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/wire_tap.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |s|
|
|
6
6
|
s.name = "wire_tap"
|
7
7
|
s.version = WireTap::VERSION
|
8
8
|
s.authors = ["Jennifer Smith"]
|
9
|
-
s.email = ["
|
9
|
+
s.email = ["jensmith@thoughtworks.com"]
|
10
10
|
s.homepage = "https://github.com/jennifersmith/wire_tap"
|
11
11
|
s.summary = "Rack middleware that logs API calls made to a file for documentation"
|
12
12
|
s.description = "Rack middleware that logs API calls made to a file for documentation. This gem is being developed for the RapidFTR project - www.rapidftr.com"
|
@@ -20,9 +20,11 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
22
|
s.add_runtime_dependency "rack"
|
23
|
-
|
24
|
-
|
23
|
+
s.add_runtime_dependency "contracted"
|
24
|
+
|
25
|
+
s.add_development_dependency "rspec"
|
26
|
+
s.add_development_dependency "rack-test"
|
25
27
|
s.add_development_dependency "factory_girl"
|
26
|
-
|
27
|
-
|
28
|
+
s.add_development_dependency "i18n"
|
29
|
+
s.add_development_dependency "sinatra"
|
28
30
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wire_tap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jennifer Smith
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-11-08 00:00:00 -06:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -33,7 +33,7 @@ dependencies:
|
|
33
33
|
type: :runtime
|
34
34
|
version_requirements: *id001
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
|
-
name:
|
36
|
+
name: contracted
|
37
37
|
prerelease: false
|
38
38
|
requirement: &id002 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
@@ -44,10 +44,10 @@ dependencies:
|
|
44
44
|
segments:
|
45
45
|
- 0
|
46
46
|
version: "0"
|
47
|
-
type: :
|
47
|
+
type: :runtime
|
48
48
|
version_requirements: *id002
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
50
|
+
name: rspec
|
51
51
|
prerelease: false
|
52
52
|
requirement: &id003 !ruby/object:Gem::Requirement
|
53
53
|
none: false
|
@@ -61,7 +61,7 @@ dependencies:
|
|
61
61
|
type: :development
|
62
62
|
version_requirements: *id003
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
|
-
name:
|
64
|
+
name: rack-test
|
65
65
|
prerelease: false
|
66
66
|
requirement: &id004 !ruby/object:Gem::Requirement
|
67
67
|
none: false
|
@@ -74,9 +74,51 @@ dependencies:
|
|
74
74
|
version: "0"
|
75
75
|
type: :development
|
76
76
|
version_requirements: *id004
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: factory_girl
|
79
|
+
prerelease: false
|
80
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
hash: 3
|
86
|
+
segments:
|
87
|
+
- 0
|
88
|
+
version: "0"
|
89
|
+
type: :development
|
90
|
+
version_requirements: *id005
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: i18n
|
93
|
+
prerelease: false
|
94
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
hash: 3
|
100
|
+
segments:
|
101
|
+
- 0
|
102
|
+
version: "0"
|
103
|
+
type: :development
|
104
|
+
version_requirements: *id006
|
105
|
+
- !ruby/object:Gem::Dependency
|
106
|
+
name: sinatra
|
107
|
+
prerelease: false
|
108
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ">="
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
hash: 3
|
114
|
+
segments:
|
115
|
+
- 0
|
116
|
+
version: "0"
|
117
|
+
type: :development
|
118
|
+
version_requirements: *id007
|
77
119
|
description: Rack middleware that logs API calls made to a file for documentation. This gem is being developed for the RapidFTR project - www.rapidftr.com
|
78
120
|
email:
|
79
|
-
-
|
121
|
+
- jensmith@thoughtworks.com
|
80
122
|
executables: []
|
81
123
|
|
82
124
|
extensions: []
|
@@ -90,10 +132,13 @@ files:
|
|
90
132
|
- Rakefile
|
91
133
|
- lib/wire_tap.rb
|
92
134
|
- lib/wire_tap/listener.rb
|
135
|
+
- lib/wire_tap/parsers/request_parser.rb
|
93
136
|
- lib/wire_tap/version.rb
|
94
|
-
-
|
137
|
+
- sample_output.md
|
95
138
|
- spec/spec_helper.rb
|
139
|
+
- spec/support/basic_web_app.rb
|
96
140
|
- spec/wire_tap/listener_spec.rb
|
141
|
+
- spec/wire_tap/parsers/request_parser_spec.rb
|
97
142
|
- spec/wire_tap_spec.rb
|
98
143
|
- wire_tap.gemspec
|
99
144
|
has_rdoc: true
|
@@ -131,7 +176,8 @@ signing_key:
|
|
131
176
|
specification_version: 3
|
132
177
|
summary: Rack middleware that logs API calls made to a file for documentation
|
133
178
|
test_files:
|
134
|
-
- spec/factories.rb
|
135
179
|
- spec/spec_helper.rb
|
180
|
+
- spec/support/basic_web_app.rb
|
136
181
|
- spec/wire_tap/listener_spec.rb
|
182
|
+
- spec/wire_tap/parsers/request_parser_spec.rb
|
137
183
|
- spec/wire_tap_spec.rb
|