api_hammer 0.19.0 → 0.19.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +0 -2
- data/api_hammer.gemspec +14 -14
- data/lib/api_hammer/body.rb +1 -1
- data/lib/api_hammer/content_type_attrs.rb +2 -0
- data/lib/api_hammer/version.rb +1 -1
- metadata +11 -137
- data/.simplecov +0 -1
- data/.travis.yml +0 -13
- data/Gemfile +0 -10
- data/Rakefile.rb +0 -12
- data/gemfiles/Gemfile_rack_1 +0 -13
- data/gemfiles/Gemfile_rack_2 +0 -12
- data/test/check_required_params_test.rb +0 -80
- data/test/faraday_request_logger_test.rb +0 -228
- data/test/halt_test.rb +0 -66
- data/test/helper.rb +0 -15
- data/test/public_instance_exec_test.rb +0 -43
- data/test/request_logger_test.rb +0 -136
- data/test/show_text_exceptions_test.rb +0 -29
- data/test/trailing_newline_test.rb +0 -24
- data/test/weblink_test.rb +0 -83
- data/test/ycomb_test.rb +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 822c3220d1b6c07c850f3b0c66a5f18c6026bfd6415b059ff3c18569af48939b
|
4
|
+
data.tar.gz: 3ef1009398f37e4322809a381ccaa23072e3dbb2a32396012ba4f6754ec81d8d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87b589dc7d2228051c011483ac37738f32b82d2761d6a43b72a86cad0711ce214126657fee707ff3a2ef3d1f872f58e8b664be0786cfa1df4f4791cbb0b5940b
|
7
|
+
data.tar.gz: 61f839239d5997277a7ea88e47b20109b6fd2bb0ee81e54520da2f784088a592f8c3d35d91108455efd1b93a331849ccda861077ce884f9c1e94ea7682b1c73c
|
data/README.md
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# ApiHammer
|
2
2
|
|
3
|
-
[![Build Status](https://travis-ci.org/notEthan/api_hammer.svg?branch=master)](https://travis-ci.org/notEthan/api_hammer)
|
4
|
-
|
5
3
|
a collection of little tools I have used when creating APIs. these are generally too small to have their own
|
6
4
|
library, so have been collected here.
|
7
5
|
|
data/api_hammer.gemspec
CHANGED
@@ -13,27 +13,27 @@ Gem::Specification.new do |spec|
|
|
13
13
|
'is one large tool.'
|
14
14
|
spec.homepage = 'https://github.com/notEthan/api_hammer'
|
15
15
|
spec.license = 'MIT'
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
16
|
+
spec.files = [
|
17
|
+
*%w(
|
18
|
+
.yardopts
|
19
|
+
CHANGELOG.md
|
20
|
+
LICENSE.txt
|
21
|
+
README.md
|
22
|
+
api_hammer.gemspec
|
23
|
+
bin/hc
|
24
|
+
),
|
25
|
+
*Dir['lib/**/*'],
|
26
|
+
].reject { |f| File.lstat(f).ftype == 'directory' }
|
27
|
+
spec.bindir = 'bin'
|
28
|
+
spec.executables = ['hc']
|
22
29
|
spec.require_paths = ['lib']
|
23
30
|
|
24
31
|
spec.add_dependency 'rack'
|
25
|
-
spec.add_dependency 'faraday'
|
32
|
+
spec.add_dependency 'faraday', '~> 1.0'
|
26
33
|
spec.add_dependency 'term-ansicolor'
|
27
34
|
spec.add_dependency 'json'
|
28
35
|
spec.add_dependency 'json_pure'
|
29
36
|
spec.add_dependency 'addressable'
|
30
37
|
spec.add_dependency 'coderay'
|
31
38
|
spec.add_dependency 'i18n'
|
32
|
-
spec.add_development_dependency 'rake'
|
33
|
-
spec.add_development_dependency 'rack-test'
|
34
|
-
spec.add_development_dependency 'minitest'
|
35
|
-
spec.add_development_dependency 'minitest-reporters'
|
36
|
-
spec.add_development_dependency 'yard'
|
37
|
-
spec.add_development_dependency 'simplecov'
|
38
|
-
spec.add_development_dependency 'actionpack'
|
39
39
|
end
|
data/lib/api_hammer/body.rb
CHANGED
@@ -82,7 +82,7 @@ module ApiHammer
|
|
82
82
|
end
|
83
83
|
begin
|
84
84
|
JSON.generate([body])
|
85
|
-
rescue Encoding::UndefinedConversionError
|
85
|
+
rescue Encoding::UndefinedConversionError, JSON::GeneratorError
|
86
86
|
# if updating by content-type didn't do it, try UTF8 since JSON wants that - but only
|
87
87
|
# if it seems to be valid utf8.
|
88
88
|
# don't try utf8 if the response content-type indicated something else.
|
data/lib/api_hammer/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_hammer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.19.
|
4
|
+
version: 0.19.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ethan
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-11-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: faraday
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
33
|
+
version: '1.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: term-ansicolor
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -122,104 +122,6 @@ dependencies:
|
|
122
122
|
- - ">="
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: rake
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: rack-test
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: minitest
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - ">="
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '0'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - ">="
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '0'
|
167
|
-
- !ruby/object:Gem::Dependency
|
168
|
-
name: minitest-reporters
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - ">="
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
174
|
-
type: :development
|
175
|
-
prerelease: false
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
177
|
-
requirements:
|
178
|
-
- - ">="
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
181
|
-
- !ruby/object:Gem::Dependency
|
182
|
-
name: yard
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
184
|
-
requirements:
|
185
|
-
- - ">="
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
188
|
-
type: :development
|
189
|
-
prerelease: false
|
190
|
-
version_requirements: !ruby/object:Gem::Requirement
|
191
|
-
requirements:
|
192
|
-
- - ">="
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: '0'
|
195
|
-
- !ruby/object:Gem::Dependency
|
196
|
-
name: simplecov
|
197
|
-
requirement: !ruby/object:Gem::Requirement
|
198
|
-
requirements:
|
199
|
-
- - ">="
|
200
|
-
- !ruby/object:Gem::Version
|
201
|
-
version: '0'
|
202
|
-
type: :development
|
203
|
-
prerelease: false
|
204
|
-
version_requirements: !ruby/object:Gem::Requirement
|
205
|
-
requirements:
|
206
|
-
- - ">="
|
207
|
-
- !ruby/object:Gem::Version
|
208
|
-
version: '0'
|
209
|
-
- !ruby/object:Gem::Dependency
|
210
|
-
name: actionpack
|
211
|
-
requirement: !ruby/object:Gem::Requirement
|
212
|
-
requirements:
|
213
|
-
- - ">="
|
214
|
-
- !ruby/object:Gem::Version
|
215
|
-
version: '0'
|
216
|
-
type: :development
|
217
|
-
prerelease: false
|
218
|
-
version_requirements: !ruby/object:Gem::Requirement
|
219
|
-
requirements:
|
220
|
-
- - ">="
|
221
|
-
- !ruby/object:Gem::Version
|
222
|
-
version: '0'
|
223
125
|
description: actually a set of small API-related tools. very much unlike a hammer
|
224
126
|
at all, which is one large tool.
|
225
127
|
email:
|
@@ -229,18 +131,12 @@ executables:
|
|
229
131
|
extensions: []
|
230
132
|
extra_rdoc_files: []
|
231
133
|
files:
|
232
|
-
- ".simplecov"
|
233
|
-
- ".travis.yml"
|
234
134
|
- ".yardopts"
|
235
135
|
- CHANGELOG.md
|
236
|
-
- Gemfile
|
237
136
|
- LICENSE.txt
|
238
137
|
- README.md
|
239
|
-
- Rakefile.rb
|
240
138
|
- api_hammer.gemspec
|
241
139
|
- bin/hc
|
242
|
-
- gemfiles/Gemfile_rack_1
|
243
|
-
- gemfiles/Gemfile_rack_2
|
244
140
|
- lib/api_hammer.rb
|
245
141
|
- lib/api_hammer/body.rb
|
246
142
|
- lib/api_hammer/content_type_attrs.rb
|
@@ -275,21 +171,11 @@ files:
|
|
275
171
|
- lib/logstash/filters/request_bodies_parsed.rb
|
276
172
|
- lib/logstash/filters/ruby_logger.rb
|
277
173
|
- lib/logstash/filters/sidekiq.rb
|
278
|
-
- test/check_required_params_test.rb
|
279
|
-
- test/faraday_request_logger_test.rb
|
280
|
-
- test/halt_test.rb
|
281
|
-
- test/helper.rb
|
282
|
-
- test/public_instance_exec_test.rb
|
283
|
-
- test/request_logger_test.rb
|
284
|
-
- test/show_text_exceptions_test.rb
|
285
|
-
- test/trailing_newline_test.rb
|
286
|
-
- test/weblink_test.rb
|
287
|
-
- test/ycomb_test.rb
|
288
174
|
homepage: https://github.com/notEthan/api_hammer
|
289
175
|
licenses:
|
290
176
|
- MIT
|
291
177
|
metadata: {}
|
292
|
-
post_install_message:
|
178
|
+
post_install_message:
|
293
179
|
rdoc_options: []
|
294
180
|
require_paths:
|
295
181
|
- lib
|
@@ -304,20 +190,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
304
190
|
- !ruby/object:Gem::Version
|
305
191
|
version: '0'
|
306
192
|
requirements: []
|
307
|
-
|
308
|
-
|
309
|
-
signing_key:
|
193
|
+
rubygems_version: 3.5.0.dev
|
194
|
+
signing_key:
|
310
195
|
specification_version: 4
|
311
196
|
summary: an API tool
|
312
|
-
test_files:
|
313
|
-
- test/check_required_params_test.rb
|
314
|
-
- test/faraday_request_logger_test.rb
|
315
|
-
- test/halt_test.rb
|
316
|
-
- test/helper.rb
|
317
|
-
- test/public_instance_exec_test.rb
|
318
|
-
- test/request_logger_test.rb
|
319
|
-
- test/show_text_exceptions_test.rb
|
320
|
-
- test/trailing_newline_test.rb
|
321
|
-
- test/weblink_test.rb
|
322
|
-
- test/ycomb_test.rb
|
323
|
-
- ".simplecov"
|
197
|
+
test_files: []
|
data/.simplecov
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
SimpleCov.start
|
data/.travis.yml
DELETED
data/Gemfile
DELETED
data/Rakefile.rb
DELETED
data/gemfiles/Gemfile_rack_1
DELETED
data/gemfiles/Gemfile_rack_2
DELETED
@@ -1,80 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
class FakeController
|
5
|
-
def self.rescue_from(*args)
|
6
|
-
end
|
7
|
-
|
8
|
-
include(ApiHammer::Rails)
|
9
|
-
attr_accessor :params
|
10
|
-
end
|
11
|
-
|
12
|
-
# strong parameters doesn't require its dependencies so good
|
13
|
-
require 'rack/test'
|
14
|
-
require 'active_support/core_ext/module'
|
15
|
-
require 'action_controller/metal/strong_parameters'
|
16
|
-
|
17
|
-
[Hash, ActionController::Parameters].each do |params_class|
|
18
|
-
describe "ApiHammer::Rails#check_required_params with #{params_class}" do
|
19
|
-
define_method(:controller_with_params) do |params|
|
20
|
-
FakeController.new.tap { |c| c.params = params_class.new.merge(params) }
|
21
|
-
end
|
22
|
-
|
23
|
-
describe 'a moderately complex set of checks' do
|
24
|
-
let(:checks) { [:id, :person => [:name, :height], :lucky_numbers => Array] }
|
25
|
-
|
26
|
-
it 'passes with a moderately complex example' do
|
27
|
-
c = controller_with_params(:id => '99', :person => {:name => 'hammer', :height => '3'}, :lucky_numbers => ['2'])
|
28
|
-
c.check_required_params(checks)
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'is missing id' do
|
32
|
-
c = controller_with_params(:person => {:name => 'hammer', :height => '3'}, :lucky_numbers => ['2'])
|
33
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(checks) }
|
34
|
-
assert_equal({'error_message' => 'id is required but was not provided', 'errors' => {'id' => ['id is required but was not provided']}}, err.body)
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'is missing person' do
|
38
|
-
c = controller_with_params(:id => '99', :lucky_numbers => ['2'])
|
39
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(checks) }
|
40
|
-
assert_equal({'error_message' => 'person is required but was not provided', 'errors' => {'person' => ['person is required but was not provided']}}, err.body)
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'is has the wrong type for person' do
|
44
|
-
c = controller_with_params(:id => '99', :person => ['hammer', '3'], :lucky_numbers => ['2'])
|
45
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(checks) }
|
46
|
-
assert_equal({'error_message' => 'person must be a Hash', 'errors' => {'person' => ['person must be a Hash']}}, err.body)
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'is has the wrong type for person with hash check' do
|
50
|
-
c = controller_with_params(:person => [])
|
51
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(:person => {:id => Fixnum}) }
|
52
|
-
assert_equal({'error_message' => 'person must be a Hash', 'errors' => {'person' => ['person must be a Hash']}}, err.body)
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'is missing person#name' do
|
56
|
-
c = controller_with_params(:id => '99', :person => {:height => '3'}, :lucky_numbers => ['2'])
|
57
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(checks) }
|
58
|
-
assert_equal({'error_message' => 'person#name is required but was not provided', 'errors' => {'person#name' => ['person#name is required but was not provided']}}, err.body)
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'is missing lucky_numbers' do
|
62
|
-
c = controller_with_params(:id => '99', :person => {:name => 'hammer', :height => '3'})
|
63
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(checks) }
|
64
|
-
assert_equal({'error_message' => 'lucky_numbers is required but was not provided', 'errors' => {'lucky_numbers' => ['lucky_numbers is required but was not provided']}}, err.body)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'has the wrong type for lucky_numbers' do
|
68
|
-
c = controller_with_params(:id => '99', :person => {:name => 'hammer', :height => '3'}, :lucky_numbers => '2')
|
69
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(checks) }
|
70
|
-
assert_equal({'error_message' => 'lucky_numbers must be a Array', 'errors' => {'lucky_numbers' => ['lucky_numbers must be a Array']}}, err.body)
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'has multiple problems' do
|
74
|
-
c = controller_with_params({})
|
75
|
-
err = assert_raises(ApiHammer::Rails::Halt) { c.check_required_params(checks) }
|
76
|
-
assert_equal({'error_message' => 'id is required but was not provided. person is required but was not provided. lucky_numbers is required but was not provided.', 'errors' => {'id' => ['id is required but was not provided'], 'person' => ['person is required but was not provided'], 'lucky_numbers' => ['lucky_numbers is required but was not provided']}}, err.body)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
@@ -1,228 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
4
|
-
require 'helper'
|
5
|
-
require 'logger'
|
6
|
-
require 'stringio'
|
7
|
-
|
8
|
-
describe ApiHammer::RequestLogger do
|
9
|
-
let(:logio) { StringIO.new }
|
10
|
-
let(:logger) { Logger.new(logio) }
|
11
|
-
|
12
|
-
it 'logs' do
|
13
|
-
conn = Faraday.new do |f|
|
14
|
-
f.use ApiHammer::Faraday::RequestLogger, logger
|
15
|
-
f.use Faraday::Adapter::Rack, proc { |env| [200, {}, []] }
|
16
|
-
end
|
17
|
-
conn.get '/'
|
18
|
-
assert_match(/200/, logio.string)
|
19
|
-
lines = logio.string.split("\n")
|
20
|
-
assert_equal(2, lines.size)
|
21
|
-
assert lines.last =~ /INFO -- : /
|
22
|
-
json_bit = $'
|
23
|
-
JSON.parse json_bit # should not raise
|
24
|
-
end
|
25
|
-
|
26
|
-
{200 => :intense_green, 400 => :intense_yellow, 500 => :intense_red, 300 => :white}.each do |status, color|
|
27
|
-
it "colors by #{status} status" do
|
28
|
-
conn = Faraday.new do |f|
|
29
|
-
f.use ApiHammer::Faraday::RequestLogger, logger
|
30
|
-
f.use Faraday::Adapter::Rack, proc { |env| [status, {}, []] }
|
31
|
-
end
|
32
|
-
conn.get '/'
|
33
|
-
assert(logio.string.include?(Term::ANSIColor.send(color, status.to_s)))
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'registers by name' do
|
38
|
-
conn = Faraday.new do |f|
|
39
|
-
f.request :api_hammer_request_logger, logger
|
40
|
-
f.use Faraday::Adapter::Rack, proc { |env| [200, {}, []] }
|
41
|
-
end
|
42
|
-
conn.get '/'
|
43
|
-
assert_match(/200/, logio.string)
|
44
|
-
end
|
45
|
-
|
46
|
-
describe 'response body encoding' do
|
47
|
-
it 'deals with encoding specified properly by the content type' do
|
48
|
-
app = proc do |env|
|
49
|
-
[200, {'Content-Type' => 'text/plain; charset=utf-8'}, ["Jalapeños".force_encoding("ASCII-8BIT")]]
|
50
|
-
end
|
51
|
-
conn = Faraday.new do |f|
|
52
|
-
f.request :api_hammer_request_logger, logger
|
53
|
-
f.use Faraday::Adapter::Rack, app
|
54
|
-
end
|
55
|
-
conn.get '/'
|
56
|
-
assert_match(/Jalapeños/, logio.string)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'deals content type specifying no encoding' do
|
60
|
-
app = proc do |env|
|
61
|
-
[200, {'Content-Type' => 'text/plain; x=y'}, ["Jalapeños".force_encoding("ASCII-8BIT")]]
|
62
|
-
end
|
63
|
-
conn = Faraday.new do |f|
|
64
|
-
f.request :api_hammer_request_logger, logger
|
65
|
-
f.use Faraday::Adapter::Rack, app
|
66
|
-
end
|
67
|
-
conn.get '/'
|
68
|
-
assert_match(/Jalapeños/, logio.string)
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'deals with no content type' do
|
72
|
-
app = proc do |env|
|
73
|
-
[200, {}, ["Jalapeños".force_encoding("ASCII-8BIT")]]
|
74
|
-
end
|
75
|
-
conn = Faraday.new do |f|
|
76
|
-
f.request :api_hammer_request_logger, logger
|
77
|
-
f.use Faraday::Adapter::Rack, app
|
78
|
-
end
|
79
|
-
conn.get '/'
|
80
|
-
assert_match(/Jalapeños/, logio.string)
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'falls back to array of codepoints when encoding is improperly specified by the content type' do
|
84
|
-
app = proc do |env|
|
85
|
-
[200, {'Content-Type' => 'text/plain; charset=utf-8'}, ["xx" + [195].pack("C*")]]
|
86
|
-
end
|
87
|
-
conn = Faraday.new do |f|
|
88
|
-
f.request :api_hammer_request_logger, logger
|
89
|
-
f.use Faraday::Adapter::Rack, app
|
90
|
-
end
|
91
|
-
conn.get '/'
|
92
|
-
assert_match('[120,120,195]', logio.string)
|
93
|
-
end
|
94
|
-
|
95
|
-
it 'falls back to array of codepoints when encoding is not specified and not valid utf8' do
|
96
|
-
app = proc do |env|
|
97
|
-
[200, {}, ["xx" + [195].pack("C*")]]
|
98
|
-
end
|
99
|
-
conn = Faraday.new do |f|
|
100
|
-
f.request :api_hammer_request_logger, logger
|
101
|
-
f.use Faraday::Adapter::Rack, app
|
102
|
-
end
|
103
|
-
conn.get '/'
|
104
|
-
assert_match('[120,120,195]', logio.string)
|
105
|
-
end
|
106
|
-
end
|
107
|
-
describe 'logging body by content-type' do
|
108
|
-
{
|
109
|
-
'application/octet-stream' => false,
|
110
|
-
'image/png' => false,
|
111
|
-
'image/png; charset=what' => false,
|
112
|
-
'text/plain' => true,
|
113
|
-
'text/plain; charset=utf-8' => true,
|
114
|
-
}.each do |content_type, istext|
|
115
|
-
it "does #{istext ? '' : 'not'} log body for #{content_type}" do
|
116
|
-
app = proc do |env|
|
117
|
-
[200, {'Content-Type' => content_type}, ['data go here']]
|
118
|
-
end
|
119
|
-
conn = Faraday.new do |f|
|
120
|
-
f.request :api_hammer_request_logger, logger
|
121
|
-
f.use Faraday::Adapter::Rack, app
|
122
|
-
end
|
123
|
-
conn.get '/'
|
124
|
-
assert(logio.string.include?('data go here') == istext)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
end
|
128
|
-
|
129
|
-
describe 'log_bodies' do
|
130
|
-
it 'does not log bodies when log_bodies is false' do
|
131
|
-
app = proc do |env|
|
132
|
-
[200, {'Content-Type' => 'text/plain'}, ['data go here']]
|
133
|
-
end
|
134
|
-
conn = Faraday.new do |f|
|
135
|
-
f.request :api_hammer_request_logger, logger, :log_bodies => false
|
136
|
-
f.use Faraday::Adapter::Rack, app
|
137
|
-
end
|
138
|
-
conn.get '/'
|
139
|
-
assert(!logio.string.include?('data go here'))
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
describe 'filtering' do
|
144
|
-
describe 'json response' do
|
145
|
-
it 'filters' do
|
146
|
-
app = proc { |env| [200, {'Content-Type' => 'application/json'}, ['{"pin": "foobar", "bar": "baz"}']] }
|
147
|
-
conn = Faraday.new do |f|
|
148
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
149
|
-
f.use Faraday::Adapter::Rack, app
|
150
|
-
end
|
151
|
-
conn.get '/'
|
152
|
-
assert_includes(logio.string, %q("body":"{\"pin\": \"[FILTERED]\", \"bar\": \"baz\"}"))
|
153
|
-
end
|
154
|
-
it 'filters nested' do
|
155
|
-
app = proc { |env| [200, {'Content-Type' => 'application/json'}, ['{"object": {"pin": "foobar"}, "bar": "baz"}']] }
|
156
|
-
conn = Faraday.new do |f|
|
157
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
158
|
-
f.use Faraday::Adapter::Rack, app
|
159
|
-
end
|
160
|
-
conn.get '/'
|
161
|
-
assert_includes(logio.string, %q("body":"{\"object\": {\"pin\": \"[FILTERED]\"}, \"bar\": \"baz\"}"))
|
162
|
-
end
|
163
|
-
it 'filters in array' do
|
164
|
-
app = proc { |env| [200, {'Content-Type' => 'application/json'}, ['[{"object": [{"pin": ["foobar"]}], "bar": "baz"}]']] }
|
165
|
-
conn = Faraday.new do |f|
|
166
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
167
|
-
f.use Faraday::Adapter::Rack, app
|
168
|
-
end
|
169
|
-
conn.get '/'
|
170
|
-
assert_includes(logio.string, %q("body":"[{\"object\": [{\"pin\": \"[FILTERED]\"}], \"bar\": \"baz\"}]"))
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
describe 'json request' do
|
175
|
-
it 'filters a json request' do
|
176
|
-
app = proc { |env| [200, {}, []] }
|
177
|
-
conn = Faraday.new do |f|
|
178
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
179
|
-
f.use Faraday::Adapter::Rack, app
|
180
|
-
end
|
181
|
-
conn.post '/', '[{"object": [{"pin": ["foobar"]}], "bar": "baz"}]', {'Content-Type' => 'application/json'}
|
182
|
-
assert_includes(logio.string, %q("body":"[{\"object\": [{\"pin\": \"[FILTERED]\"}], \"bar\": \"baz\"}]"))
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
describe 'form encoded response' do
|
187
|
-
it 'filters' do
|
188
|
-
app = proc { |env| [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, ['pin=foobar&bar=baz']] }
|
189
|
-
conn = Faraday.new do |f|
|
190
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
191
|
-
f.use Faraday::Adapter::Rack, app
|
192
|
-
end
|
193
|
-
conn.get '/'
|
194
|
-
assert_includes(logio.string, %q("body":"pin=[FILTERED]&bar=baz"))
|
195
|
-
end
|
196
|
-
it 'filters nested' do
|
197
|
-
app = proc { |env| [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, ['object[pin]=foobar&bar=baz']] }
|
198
|
-
conn = Faraday.new do |f|
|
199
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
200
|
-
f.use Faraday::Adapter::Rack, app
|
201
|
-
end
|
202
|
-
conn.get '/'
|
203
|
-
assert_includes(logio.string, %q("body":"object[pin]=[FILTERED]&bar=baz"))
|
204
|
-
end
|
205
|
-
it 'filters in array' do
|
206
|
-
app = proc { |env| [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, ['object[][pin][]=foobar&bar=baz']] }
|
207
|
-
conn = Faraday.new do |f|
|
208
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
209
|
-
f.use Faraday::Adapter::Rack, app
|
210
|
-
end
|
211
|
-
conn.get '/'
|
212
|
-
assert_includes(logio.string, %q("body":"object[][pin][]=[FILTERED]&bar=baz"))
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
describe 'form encoded request' do
|
217
|
-
it 'filters a json request' do
|
218
|
-
app = proc { |env| [200, {}, []] }
|
219
|
-
conn = Faraday.new do |f|
|
220
|
-
f.request :api_hammer_request_logger, logger, :filter_keys => 'pin'
|
221
|
-
f.use Faraday::Adapter::Rack, app
|
222
|
-
end
|
223
|
-
conn.post '/', 'object[pin]=foobar&bar=baz', {'Content-Type' => 'application/x-www-form-urlencoded'}
|
224
|
-
assert_includes(logio.string, %q(object[pin]=[FILTERED]&bar=baz))
|
225
|
-
end
|
226
|
-
end
|
227
|
-
end
|
228
|
-
end
|
data/test/halt_test.rb
DELETED
@@ -1,66 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
class FakeController
|
5
|
-
def self.rescue_from(*args)
|
6
|
-
end
|
7
|
-
|
8
|
-
include(ApiHammer::Rails)
|
9
|
-
|
10
|
-
attr_reader :rendered
|
11
|
-
def render(opts)
|
12
|
-
@rendered = opts
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
describe 'ApiHammer::Rails#halt' do
|
17
|
-
it 'raises ApiHammer::Rails::Halt' do
|
18
|
-
haltex = assert_raises(ApiHammer::Rails::Halt) { FakeController.new.halt(200, {}) }
|
19
|
-
assert_equal({}, haltex.body)
|
20
|
-
assert_equal(200, haltex.render_options[:status])
|
21
|
-
end
|
22
|
-
describe 'status-specific halts' do
|
23
|
-
it 'halts ok' do
|
24
|
-
haltex = assert_raises(ApiHammer::Rails::Halt) { FakeController.new.halt_ok({}) }
|
25
|
-
assert_equal({}, haltex.body)
|
26
|
-
assert_equal(200, haltex.render_options[:status])
|
27
|
-
end
|
28
|
-
it 'halts unprocessable entity' do
|
29
|
-
haltex = assert_raises(ApiHammer::Rails::Halt) { FakeController.new.halt_unprocessable_entity({}) }
|
30
|
-
assert_equal({'errors' => {}}, haltex.body)
|
31
|
-
assert_equal(422, haltex.render_options[:status])
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
describe 'find_or_halt' do
|
36
|
-
it 'returns a record if it exists' do
|
37
|
-
record = Object.new
|
38
|
-
model = Class.new do
|
39
|
-
define_singleton_method(:where) { |attrs| [record] }
|
40
|
-
define_singleton_method(:table_name) { 'records' }
|
41
|
-
end
|
42
|
-
assert_equal record, FakeController.new.find_or_halt(model, {:id => 'anid'})
|
43
|
-
end
|
44
|
-
it 'it halts with 404 if not' do
|
45
|
-
model = Class.new do
|
46
|
-
(class << self; self; end).class_eval do
|
47
|
-
define_method(:where) { |attrs| [] }
|
48
|
-
define_method(:table_name) { 'record' }
|
49
|
-
end
|
50
|
-
end
|
51
|
-
haltex = assert_raises(ApiHammer::Rails::Halt) { FakeController.new.find_or_halt(model, {:id => 'anid'}) }
|
52
|
-
assert_equal({'error_message' => 'Unknown record! id: anid', 'errors' => {'record' => ['Unknown record! id: anid']}}, haltex.body)
|
53
|
-
assert_equal(404, haltex.render_options[:status])
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
describe 'ApiHammer::Rails#handle_halt' do
|
59
|
-
it 'renders the things from the error' do
|
60
|
-
controller = FakeController.new
|
61
|
-
haltex = (FakeController.new.halt_unprocessable_entity({}) rescue $!)
|
62
|
-
controller.handle_halt(haltex)
|
63
|
-
assert_equal(422, controller.rendered[:status])
|
64
|
-
assert_equal({'errors' => {}}, controller.rendered[:json])
|
65
|
-
end
|
66
|
-
end
|
data/test/helper.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('../lib', File.dirname(__FILE__)))
|
2
|
-
|
3
|
-
require 'bundler'
|
4
|
-
Bundler.setup
|
5
|
-
|
6
|
-
require 'simplecov'
|
7
|
-
|
8
|
-
# NO EXPECTATIONS
|
9
|
-
ENV["MT_NO_EXPECTATIONS"] = ''
|
10
|
-
|
11
|
-
require 'minitest/autorun'
|
12
|
-
require 'minitest/reporters'
|
13
|
-
Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
|
14
|
-
|
15
|
-
require 'api_hammer'
|
@@ -1,43 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
require 'api_hammer/public_instance_exec'
|
5
|
-
|
6
|
-
class Foo
|
7
|
-
def public_method(arg = :public)
|
8
|
-
arg
|
9
|
-
end
|
10
|
-
protected
|
11
|
-
def protected_method(arg = :protected)
|
12
|
-
arg
|
13
|
-
end
|
14
|
-
private
|
15
|
-
def private_method(arg = :private)
|
16
|
-
arg
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe '#public_instance_exec' do
|
21
|
-
it 'does things' do
|
22
|
-
foo = Foo.new
|
23
|
-
assert_equal(:public_exec, foo.public_instance_exec(:public_exec) { |arg| public_method(arg) })
|
24
|
-
regularex = (foo.protected_method rescue $!)
|
25
|
-
ex = assert_raises(regularex.class) { foo.public_instance_exec(:protected_exec) { |arg| protected_method(arg) } }
|
26
|
-
assert_includes(regularex.message, ex.message)
|
27
|
-
regularex = (foo.private_method rescue $!)
|
28
|
-
ex = assert_raises(regularex.class) { foo.public_instance_exec(:private_exec) { |arg| private_method(arg) } }
|
29
|
-
assert_includes(regularex.message, ex.message)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
describe '#public_instance_eval' do
|
33
|
-
it 'does things' do
|
34
|
-
foo = Foo.new
|
35
|
-
assert_equal(:public, foo.public_instance_eval { public_method })
|
36
|
-
regularex = (foo.protected_method rescue $!)
|
37
|
-
ex = assert_raises(regularex.class) { foo.public_instance_eval { protected_method } }
|
38
|
-
assert_includes(regularex.message, ex.message)
|
39
|
-
regularex = (foo.private_method rescue $!)
|
40
|
-
ex = assert_raises(regularex.class) { foo.public_instance_eval { private_method } }
|
41
|
-
assert_includes(regularex.message, ex.message)
|
42
|
-
end
|
43
|
-
end
|
data/test/request_logger_test.rb
DELETED
@@ -1,136 +0,0 @@
|
|
1
|
-
# -*- coding: utf-8 -*-
|
2
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
3
|
-
require 'helper'
|
4
|
-
require 'logger'
|
5
|
-
require 'stringio'
|
6
|
-
|
7
|
-
describe ApiHammer::RequestLogger do
|
8
|
-
let(:logio) { StringIO.new }
|
9
|
-
let(:logger) { Logger.new(logio) }
|
10
|
-
|
11
|
-
it 'logs' do
|
12
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [200, {}, []] }, logger)
|
13
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
14
|
-
assert_match(/200/, logio.string)
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'colors by status' do
|
18
|
-
{200 => :intense_green, 400 => :intense_yellow, 500 => :intense_red, 300 => :white}.each do |status, color|
|
19
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [status, {}, []] }, logger)
|
20
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
21
|
-
assert(logio.string.include?(Term::ANSIColor.send(color, status.to_s)))
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'logs id and uuid (json)' do
|
26
|
-
body = %Q({"uuid": "theuuid", "foo_uuid": "thefoouuid", "id": "theid", "id_for_x": "theidforx", "bar.id": "thebarid", "baz-guid": "bazzz", "bigthing": "#{' ' * 4096}"})
|
27
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [200, {"Content-Type" => 'application/json; charset=UTF8'}, [body]] }, logger)
|
28
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
29
|
-
assert_match(%q("body_ids":{"uuid":"theuuid","foo_uuid":"thefoouuid","id":"theid","id_for_x":"theidforx","bar.id":"thebarid","baz-guid":"bazzz"}), logio.string)
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'logs id and uuid (json array)' do
|
33
|
-
body = %Q([{"uuid": "theuuid", "foo_uuid": "thefoouuid"}, {"id": "theid", "id_for_x": "theidforx"}, {"bar.id": "thebarid", "baz-guid": "bazzz", "bigthing": "#{' ' * 4096}"}])
|
34
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [200, {"Content-Type" => 'application/json; charset=UTF8'}, [body]] }, logger)
|
35
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
36
|
-
assert_match(%q("body_ids":[{"uuid":"theuuid","foo_uuid":"thefoouuid"},{"id":"theid","id_for_x":"theidforx"},{"bar.id":"thebarid","baz-guid":"bazzz"}]), logio.string)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'logs id and uuid (form encoded)' do
|
40
|
-
body = %Q(uuid=theuuid&foo_uuid=thefoouuid&id=theid&id_for_x=theidforx&bar.id=thebarid&baz-guid=bazzz&bigthing=#{' ' * 4096})
|
41
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [200, {"Content-Type" => 'application/x-www-form-urlencoded; charset=UTF8'}, [body]] }, logger)
|
42
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
43
|
-
assert_match(%q("body_ids":{"uuid":"theuuid","foo_uuid":"thefoouuid","id":"theid","id_for_x":"theidforx","bar.id":"thebarid","baz-guid":"bazzz"}), logio.string)
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'logs not-too-big request response bodies' do
|
47
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [200, {}, ['the_response_body']] }, logger)
|
48
|
-
app.call(Rack::MockRequest.env_for('/', :input => 'the_request_body')).last.close
|
49
|
-
assert_match(/"request":\{.*"body":"the_request_body/, logio.string)
|
50
|
-
assert_match(/"response":\{.*"body":"the_response_body/, logio.string)
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'logs request and response body on error (even if big)' do
|
54
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [400, {}, ["the_response_body #{' ' * 4096}"]] }, logger)
|
55
|
-
app.call(Rack::MockRequest.env_for('/', :input => "the_request_body #{' ' * 4096}")).last.close
|
56
|
-
assert_match(/"request":\{.*"body":"the_request_body/, logio.string)
|
57
|
-
assert_match(/"response":\{.*"body":"the_response_body/, logio.string)
|
58
|
-
end
|
59
|
-
|
60
|
-
describe 'filtering' do
|
61
|
-
describe 'json response' do
|
62
|
-
it 'filters' do
|
63
|
-
body = %Q({"pin": "foobar"})
|
64
|
-
app = proc { |env| [200, {"Content-Type" => 'application/json; charset=UTF8'}, [body]] }
|
65
|
-
app = ApiHammer::RequestLogger.new(app, logger, :filter_keys => 'pin')
|
66
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
67
|
-
|
68
|
-
assert_includes(logio.string, %q("body":"{\"pin\": \"[FILTERED]\"}"))
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'filters unicode' do
|
72
|
-
body = %Q({"key": "Björn"})
|
73
|
-
app = proc { |env| [200, {"Content-Type" => 'application/json; charset=utf-8'}, [body]] }
|
74
|
-
app = ApiHammer::RequestLogger.new(app, logger)
|
75
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
76
|
-
|
77
|
-
assert_includes(logio.string, %q("body":"{\"key\": \"Björn\"}"))
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'filters nested' do
|
81
|
-
body = %Q({"object": {"pin": "foobar"}})
|
82
|
-
app = proc { |env| [200, {"Content-Type" => 'application/json; charset=UTF8'}, [body]] }
|
83
|
-
app = ApiHammer::RequestLogger.new(app, logger, :filter_keys => 'pin')
|
84
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
85
|
-
|
86
|
-
assert_includes(logio.string, %q("body":"{\"object\": {\"pin\": \"[FILTERED]\"}}"))
|
87
|
-
end
|
88
|
-
it 'filters in array' do
|
89
|
-
body = %Q([{"object": [{"pin": ["foobar"]}]}])
|
90
|
-
app = proc { |env| [200, {"Content-Type" => 'application/json; charset=UTF8'}, [body]] }
|
91
|
-
app = ApiHammer::RequestLogger.new(app, logger, :filter_keys => 'pin')
|
92
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
93
|
-
|
94
|
-
assert_includes(logio.string, %q("body":"[{\"object\": [{\"pin\": \"[FILTERED]\"}]}]"))
|
95
|
-
end
|
96
|
-
end
|
97
|
-
|
98
|
-
describe 'json request' do
|
99
|
-
it 'filters a json request' do
|
100
|
-
app = ApiHammer::RequestLogger.new(proc { |env| [200, {}, []] }, logger, :filter_keys => 'pin')
|
101
|
-
app.call(Rack::MockRequest.env_for('/', :input => '[{"object": [{"pin": ["foobar"]}]}]', 'CONTENT_TYPE' => 'application/json')).last.close
|
102
|
-
assert_includes(logio.string, %q("body":"[{\"object\": [{\"pin\": \"[FILTERED]\"}]}]"))
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
describe('form encoded response') do
|
107
|
-
it 'filters' do
|
108
|
-
app = proc { |env| [200, {"Content-Type" => 'application/x-www-form-urlencoded'}, ['pin=foobar']] }
|
109
|
-
app = ApiHammer::RequestLogger.new(app, logger, :filter_keys => 'pin')
|
110
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
111
|
-
assert_includes(logio.string, %q("body":"pin=[FILTERED]"))
|
112
|
-
end
|
113
|
-
it 'filters nested' do
|
114
|
-
app = proc { |env| [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, ['object[pin]=foobar']] }
|
115
|
-
app = ApiHammer::RequestLogger.new(app, logger, :filter_keys => 'pin')
|
116
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
117
|
-
assert_includes(logio.string, %q("body":"object[pin]=[FILTERED]"))
|
118
|
-
end
|
119
|
-
it 'filters in array' do
|
120
|
-
app = proc { |env| [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, ['object[][pin][]=foobar']] }
|
121
|
-
app = ApiHammer::RequestLogger.new(app, logger, :filter_keys => 'pin')
|
122
|
-
app.call(Rack::MockRequest.env_for('/')).last.close
|
123
|
-
assert_includes(logio.string, %q("body":"object[][pin][]=[FILTERED]"))
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
describe 'form encoded request' do
|
128
|
-
it 'filters a json request' do
|
129
|
-
app = proc { |env| [200, {}, []] }
|
130
|
-
app = ApiHammer::RequestLogger.new(app, logger, :filter_keys => 'pin')
|
131
|
-
app.call(Rack::MockRequest.env_for('/', :input => 'object[pin]=foobar', 'CONTENT_TYPE' => 'application/x-www-form-urlencoded')).last.close
|
132
|
-
assert_includes(logio.string, %q(object[pin]=[FILTERED]))
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
@@ -1,29 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
describe ApiHammer::ShowTextExceptions do
|
5
|
-
it 'lets normal responses through untouched' do
|
6
|
-
orig_response = [200, {}, []]
|
7
|
-
app = ApiHammer::ShowTextExceptions.new(proc { |env| orig_response }, {})
|
8
|
-
app_response = app.call(Rack::MockRequest.env_for('/'))
|
9
|
-
assert_equal(orig_response, app_response)
|
10
|
-
end
|
11
|
-
it '500s' do
|
12
|
-
app = ApiHammer::ShowTextExceptions.new(proc { |env| raise }, :full_error => true)
|
13
|
-
assert_equal(500, app.call(Rack::MockRequest.env_for('/')).first)
|
14
|
-
end
|
15
|
-
it 'includes the full error' do
|
16
|
-
app = ApiHammer::ShowTextExceptions.new(proc { |env| raise 'foo' }, :full_error => true)
|
17
|
-
assert_match(/RuntimeError: foo/, app.call(Rack::MockRequest.env_for('/')).last.to_enum.to_a.join)
|
18
|
-
end
|
19
|
-
it 'does not include the full error' do
|
20
|
-
app = ApiHammer::ShowTextExceptions.new(proc { |env| raise }, :full_error => false)
|
21
|
-
assert_equal("Internal Server Error\n", app.call(Rack::MockRequest.env_for('/')).last.to_enum.to_a.join)
|
22
|
-
end
|
23
|
-
it 'logs' do
|
24
|
-
logio=StringIO.new
|
25
|
-
app = ApiHammer::ShowTextExceptions.new(proc { |env| raise 'foo' }, :logger => Logger.new(logio))
|
26
|
-
app.call(Rack::MockRequest.env_for('/'))
|
27
|
-
assert_match(/RuntimeError: foo/, logio.string)
|
28
|
-
end
|
29
|
-
end
|
@@ -1,24 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
describe ApiHammer::TrailingNewline do
|
5
|
-
it 'adds a trailing newline when one is missing' do
|
6
|
-
app = ApiHammer::TrailingNewline.new(proc { |env| [200, {}, ["foo"]] })
|
7
|
-
assert_equal("foo\n", app.call(Rack::MockRequest.env_for('/')).last.to_enum.to_a.join)
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'does not add a trailing newline when one is present' do
|
11
|
-
app = ApiHammer::TrailingNewline.new(proc { |env| [200, {}, ["foo\n"]] })
|
12
|
-
assert_equal("foo\n", app.call(Rack::MockRequest.env_for('/')).last.to_enum.to_a.join)
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'does not add a trailing newline when the response is blank' do
|
16
|
-
app = ApiHammer::TrailingNewline.new(proc { |env| [200, {}, []] })
|
17
|
-
assert_equal([], app.call(Rack::MockRequest.env_for('/')).last.to_enum.to_a)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'updates Content-Length if present' do
|
21
|
-
app = ApiHammer::TrailingNewline.new(proc { |env| [200, {'Content-Length' => '3'}, ['foo']] })
|
22
|
-
assert_equal('4', app.call(Rack::MockRequest.env_for('/'))[1]['Content-Length'])
|
23
|
-
end
|
24
|
-
end
|
data/test/weblink_test.rb
DELETED
@@ -1,83 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
describe ApiHammer::Weblink do
|
5
|
-
describe '#parse_link_value' do
|
6
|
-
it 'parses link headers' do
|
7
|
-
examples = [
|
8
|
-
# one link with some attributes
|
9
|
-
[ %q(<http://example.com>; rel=foo; title=example; title*="an example"),
|
10
|
-
'http://example.com',
|
11
|
-
{'rel' => 'foo', 'title' => 'example', 'title*' => 'an example'},
|
12
|
-
],
|
13
|
-
# two links
|
14
|
-
[ %q(<http://example.com>; rel=foo; title=example; title*="an example", <http://example2.com>; rel=bar),
|
15
|
-
'http://example.com',
|
16
|
-
{'rel' => 'foo', 'title' => 'example', 'title*' => 'an example'},
|
17
|
-
'http://example2.com',
|
18
|
-
{'rel' => 'bar'},
|
19
|
-
],
|
20
|
-
# spaces
|
21
|
-
[ %q( <http://example.com> ;rel = foo ;title=example; title*="an example" ),
|
22
|
-
'http://example.com',
|
23
|
-
{'rel' => 'foo', 'title' => 'example', 'title*' => 'an example'},
|
24
|
-
],
|
25
|
-
# empty returns no links
|
26
|
-
[''],
|
27
|
-
]
|
28
|
-
examples.each do |example|
|
29
|
-
link_value = example.shift
|
30
|
-
links = ApiHammer::Weblink.parse_link_value(link_value)
|
31
|
-
assert_equal(example.size, links.size * 2)
|
32
|
-
example.each_slice(2).zip(links).each do |((target_uri, attributes), link)|
|
33
|
-
assert_equal(Addressable::URI.parse(target_uri), link.target_uri)
|
34
|
-
assert_equal(attributes, link.attributes)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'gives an absolute uri based on context' do
|
40
|
-
link = ApiHammer::Weblink.parse_link_value('</bar>; rel=foo', 'http://example.com/foo').first
|
41
|
-
assert_equal(Addressable::URI.parse('http://example.com/bar'), link.absolute_target_uri)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'errors without context, trying to generate an absolute uri' do
|
45
|
-
link = ApiHammer::Weblink.parse_link_value('</bar>; rel=foo').first
|
46
|
-
assert_raises(ApiHammer::Weblink::NoContextError) { link.absolute_target_uri }
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'returns an empty array for nil link header' do
|
50
|
-
assert_equal([], ApiHammer::Weblink.parse_link_value(nil))
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'parse errors' do
|
54
|
-
examples = [
|
55
|
-
# missing >
|
56
|
-
%q(<http://example.com),
|
57
|
-
# missing <
|
58
|
-
%q(http://example.com>; rel=foo),
|
59
|
-
# , instead of ;
|
60
|
-
%q(<http://example.com>, rel=foo),
|
61
|
-
# non-ptoken characters (\,) unquoted
|
62
|
-
%q(<http://example.com>; rel=b\\ar; title=example),
|
63
|
-
%q(<http://example.com>; rel=b,ar; title=example),
|
64
|
-
]
|
65
|
-
examples.each do |example|
|
66
|
-
assert_raises(ApiHammer::Weblink::ParseError) { ApiHammer::Weblink.parse_link_value(example) }
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe '#to_s' do
|
71
|
-
it 'makes a string' do
|
72
|
-
link = ApiHammer::Weblink.new('http://example.com', :rel => 'foo', :title => 'example', 'title*' => 'an example')
|
73
|
-
assert_equal(%q(<http://example.com>; rel="foo"; title="example"; title*="an example"), link.to_s)
|
74
|
-
end
|
75
|
-
it 'parses the string to the same values' do
|
76
|
-
link = ApiHammer::Weblink.new('http://example.com', 'rel' => 'foo', 'title' => 'example', 'title*' => 'an example')
|
77
|
-
parsed_link = ApiHammer::Weblink.parse_link_value(link.to_s).first
|
78
|
-
assert_equal(link.target_uri, parsed_link.target_uri)
|
79
|
-
assert_equal(link.attributes, parsed_link.attributes)
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
data/test/ycomb_test.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
proc { |p| $:.unshift(p) unless $:.any? { |lp| File.expand_path(lp) == p } }.call(File.expand_path('.', File.dirname(__FILE__)))
|
2
|
-
require 'helper'
|
3
|
-
|
4
|
-
require 'api_hammer/ycomb'
|
5
|
-
describe 'ycomb' do
|
6
|
-
it 'does the needful' do
|
7
|
-
length = ycomb do |len|
|
8
|
-
proc{|list| list == [] ? 0 : 1 + len.call(list[1..-1]) }
|
9
|
-
end
|
10
|
-
assert_equal(0, length.call([]))
|
11
|
-
assert_equal(3, length.call([:a, :b, :c]))
|
12
|
-
end
|
13
|
-
end
|