rory 0.5.3 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 519e856afba46c0680d6d3af79ec301e16437bce
4
- data.tar.gz: b6f3aff18d16be85d47eae141dd8f11f7946fcf8
3
+ metadata.gz: 40ba6de912d0a2eff585bacee9ac6e17583bf70c
4
+ data.tar.gz: de1a192df73c293d81945d0f015173c3e338484e
5
5
  SHA512:
6
- metadata.gz: ea76b00f53570b120d821f2e4f356cca6531ae15f85b4fe61a41f856d3ac025773b3e326bf9eef49ff2151e7a6d91189d9c3f876f0f08b294fe6fe36ff45df98
7
- data.tar.gz: eed96368cd3a1e75d274f4c0f21d55a2b51b8340c10af48c92b7694b287837ccc9119fd9b54aee8850145f8a1d635f22b8f431432a8d9b72a655af32c847beca
6
+ metadata.gz: 864bb31119f46b7f067df7dcb60779844b53efd383f8a40de18376054abb36263694a19b9f40fc0414fcf7ce36577a83a59d55e7f03cedf23e170309a409a2c1
7
+ data.tar.gz: 23e76ae90efc1de98ecd4cd629ca64624eccc09576156d7cc7a647de7ab07a05326890b9fea1b54304e81138e997c86c51e347a7613a4b8f00e578ca017a08a0
@@ -1,11 +1,8 @@
1
1
  ENV['RORY_ENV'] ||= ENV['RACK_ENV'] || 'development'
2
2
 
3
- if ENV['RORY_STAGE']
4
- raise "Use of 'RORY_STAGE' no longer supported. Use 'RORY_ENV' instead."
5
- end
6
-
7
3
  require 'yaml'
8
4
  require 'sequel'
5
+ require 'rack/contrib'
9
6
  require 'rory/application'
10
7
  require 'rory/dispatcher'
11
8
  require 'rory/route'
@@ -1,6 +1,9 @@
1
1
  require 'pathname'
2
2
  require 'logger'
3
3
  require 'rory/route_mapper'
4
+ require 'rack/commonlogger'
5
+ require_relative 'request_parameter_logger'
6
+
4
7
 
5
8
  module Rory
6
9
  # Main application superclass. Applications should subclass this class,
@@ -17,9 +20,9 @@ module Rory
17
20
  private :new
18
21
  attr_reader :root
19
22
 
20
- def inherited(base)
23
+ def inherited(subclass)
21
24
  super
22
- Rory.application = base.instance
25
+ Rory.application = subclass.instance
23
26
  end
24
27
 
25
28
  def method_missing(*args, &block)
@@ -59,9 +62,11 @@ module Rory
59
62
  end
60
63
 
61
64
  def config_path
62
- @config_path ||= begin
63
- root_path.join('config')
64
- end
65
+ @config_path ||= root_path.join('config')
66
+ end
67
+
68
+ def log_path
69
+ @log_path ||= root_path.join('log')
65
70
  end
66
71
 
67
72
  def set_routes(&block)
@@ -96,6 +101,7 @@ module Rory
96
101
  end
97
102
 
98
103
  def use_middleware(*args, &block)
104
+ @stack = nil
99
105
  middleware << [args, block]
100
106
  end
101
107
 
@@ -107,25 +113,44 @@ module Rory
107
113
  Rory::Dispatcher.rack_app(self)
108
114
  end
109
115
 
110
- def stack
111
- builder = Rack::Builder.new
112
- middleware.each do |args, block|
113
- builder.use *args, &block
116
+ def request_logging_on?
117
+ @request_logging != false
118
+ end
119
+
120
+ def turn_off_request_logging!
121
+ @stack = nil
122
+ @request_logging = false
123
+ end
124
+
125
+ def use_default_middleware
126
+ if request_logging_on?
127
+ use_middleware Rack::PostBodyContentTypeParser
128
+ use_middleware Rack::CommonLogger, logger
129
+ use_middleware Rory::RequestParameterLogger, logger
114
130
  end
115
- builder.run dispatcher
116
- builder
131
+ end
132
+
133
+ def stack
134
+ @stack ||= Rack::Builder.new.tap { |builder|
135
+ use_default_middleware
136
+ middleware.each do |args, block|
137
+ builder.use *args, &block
138
+ end
139
+ builder.run dispatcher
140
+ }
117
141
  end
118
142
 
119
143
  def call(env)
120
144
  stack.call(env)
121
145
  end
122
146
 
147
+ def log_file
148
+ Dir.mkdir(log_path) unless File.exists?(log_path)
149
+ File.open(log_path.join("#{ENV['RORY_ENV']}.log"), 'a').tap { |file| file.sync = true }
150
+ end
151
+
123
152
  def logger
124
- @logger ||= begin
125
- Dir.mkdir('log') unless File.exists?('log')
126
- file = File.open(File.join('log', "#{ENV['RORY_ENV']}.log"), 'a')
127
- Logger.new(file)
128
- end
153
+ @logger ||= Logger.new(log_file)
129
154
  end
130
155
  end
131
156
  end
@@ -0,0 +1,64 @@
1
+ module Rory
2
+ class ParameterFilter
3
+ FILTERED = '[FILTERED]'.freeze
4
+
5
+ def initialize(filters = [])
6
+ @filters = filters
7
+ end
8
+
9
+ def filter(params)
10
+ compiled_filter.call(params)
11
+ end
12
+
13
+ private
14
+
15
+ def compiled_filter
16
+ @compiled_filter ||= CompiledFilter.compile(@filters)
17
+ end
18
+
19
+ class CompiledFilter
20
+ def self.compile(filters)
21
+ return lambda { |params| params.dup } if filters.empty?
22
+
23
+ strings, regexps, blocks = [], [], []
24
+
25
+ filters.each do |item|
26
+ case item
27
+ when Regexp
28
+ regexps << item
29
+ else
30
+ strings << item.to_s
31
+ end
32
+ end
33
+
34
+ regexps << Regexp.new(strings.join('|'), true) unless strings.empty?
35
+ new regexps, blocks
36
+ end
37
+
38
+ attr_reader :regexps, :blocks
39
+
40
+ def initialize(regexps, blocks)
41
+ @regexps = regexps
42
+ @blocks = blocks
43
+ end
44
+
45
+ def call(original_params)
46
+ filtered_params = {}
47
+
48
+ original_params.each do |key, value|
49
+ if regexps.any? { |r| key =~ r }
50
+ value = FILTERED
51
+ elsif value.is_a?(Hash)
52
+ value = call(value)
53
+ elsif value.is_a?(Array)
54
+ value = value.map { |v| v.is_a?(Hash) ? call(v) : v }
55
+ end
56
+
57
+ filtered_params[key] = value
58
+ end
59
+
60
+ filtered_params
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,58 @@
1
+ require_relative 'parameter_filter'
2
+
3
+ module Rory
4
+ class RequestParameterLogger
5
+
6
+ def initialize(app, logger=nil, filters=[:password])
7
+ @app = app
8
+ @logger = logger
9
+ @filters = filters
10
+ end
11
+
12
+ def call(env)
13
+ @env = env
14
+ @env['rack.input'].rewind
15
+ log_request
16
+ @app.call(@env)
17
+ end
18
+
19
+ private
20
+
21
+ def log_request
22
+ log_message(request_signature)
23
+ log_message("Parameters: #{filtered_params}")
24
+ end
25
+
26
+ def logger
27
+ @logger || @env['rack.errors']
28
+ end
29
+
30
+ def log_message(message)
31
+ if logger.respond_to?(:write)
32
+ logger.write(message + "\n")
33
+ else
34
+ logger.info(message)
35
+ end
36
+ end
37
+
38
+ def parameter_filter
39
+ Rory::ParameterFilter.new(@filters)
40
+ end
41
+
42
+ def filtered_params
43
+ parameter_filter.filter(unfiltered_params)
44
+ end
45
+
46
+ def request
47
+ Rack::Request.new(@env)
48
+ end
49
+
50
+ def unfiltered_params
51
+ request.params
52
+ end
53
+
54
+ def request_signature
55
+ %{Started #{@env['REQUEST_METHOD']} "#{@env['PATH_INFO']}" for #{@env['REMOTE_ADDR']} at #{Time.now}}
56
+ end
57
+ end
58
+ end
@@ -1,3 +1,3 @@
1
1
  module Rory
2
- VERSION = '0.5.3'
2
+ VERSION = '0.6.0'
3
3
  end
@@ -28,16 +28,18 @@ EOF
28
28
  s.licenses = ["MIT"]
29
29
  s.require_paths = ["lib"]
30
30
 
31
- s.add_runtime_dependency 'rack', '>= 1.0'
31
+ s.add_runtime_dependency 'rack', '~> 1.0'
32
+ s.add_runtime_dependency 'rack-contrib', '~> 1.2'
32
33
  s.add_runtime_dependency 'sequel', '~> 4.0'
33
34
  s.add_runtime_dependency 'thin', '~> 1.0'
34
35
 
35
- s.add_development_dependency 'rake'
36
+ s.add_development_dependency 'rake', '~> 10.4'
36
37
  s.add_development_dependency 'rspec', '~> 3'
37
- s.add_development_dependency 'capybara'
38
- s.add_development_dependency 'yard'
39
- s.add_development_dependency 'reek'
40
- s.add_development_dependency 'simplecov'
38
+ s.add_development_dependency 'capybara', '~> 2.4'
39
+ s.add_development_dependency 'yard', '~> 0.8'
40
+ s.add_development_dependency 'reek', '~> 2.2'
41
+ s.add_development_dependency 'simplecov', '~> 0.10'
41
42
  s.add_development_dependency 'bundler', '~> 1.0'
43
+ s.add_development_dependency 'pry', '~> 0.10'
42
44
  end
43
45
 
@@ -1,4 +1,5 @@
1
1
  module Fixture
2
2
  class Application < Rory::Application
3
+ turn_off_request_logging!
3
4
  end
4
5
  end
File without changes
@@ -1,16 +1,23 @@
1
1
  describe Rory::Application do
2
+ let(:subject) {
3
+ Class.new(Rory::Application).tap { |app|
4
+ app.root = "whatever"
5
+ app.turn_off_request_logging!
6
+ }
7
+ }
8
+
2
9
  describe ".configure" do
3
10
  it 'yields the given block to self' do
4
- Fixture::Application.configure do |c|
5
- expect(c).to eq(Fixture::Application.instance)
11
+ subject.configure do |c|
12
+ expect(c).to eq(subject.instance)
6
13
  end
7
14
  end
8
15
  end
9
16
 
10
17
  describe '.config_path' do
11
18
  it 'is set to {root}/config by default' do
12
- expect(Fixture::Application.config_path).to eq(
13
- Pathname.new(Fixture::Application.root).join('config')
19
+ expect(subject.config_path).to eq(
20
+ Pathname.new(subject.root).join('config')
14
21
  )
15
22
  end
16
23
 
@@ -20,64 +27,112 @@ describe Rory::Application do
20
27
  expect {
21
28
  RootlessApp.config_path
22
29
  }.to raise_error(RootlessApp::RootNotConfigured)
23
- Rory.application = Fixture::Application.instance
30
+ Rory.application = subject.instance
31
+ end
32
+ end
33
+
34
+ describe '.log_path' do
35
+ it 'is set to {root}/config by default' do
36
+ expect(subject.log_path).to eq(
37
+ Pathname.new(subject.root).join('log')
38
+ )
39
+ end
40
+
41
+ it 'raises exception if root not set' do
42
+ Rory.application = nil
43
+ class RootlessApp < Rory::Application; end
44
+ expect {
45
+ RootlessApp.config_path
46
+ }.to raise_error(RootlessApp::RootNotConfigured)
47
+ Rory.application = subject.instance
24
48
  end
25
49
  end
26
50
 
27
51
  describe ".respond_to?" do
28
52
  it 'returns true if the instance said so' do
29
- expect(Fixture::Application.instance).to receive(:respond_to?).with(:goat).and_return(true)
30
- expect(Fixture::Application.respond_to?(:goat)).to be_truthy
53
+ expect(subject.instance).to receive(:respond_to?).with(:goat).and_return(true)
54
+ expect(subject.respond_to?(:goat)).to be_truthy
31
55
  end
32
56
 
33
57
  it 'does the usual thing if instance says no' do
34
- expect(Fixture::Application.instance).to receive(:respond_to?).twice.and_return(false)
35
- expect(Fixture::Application.respond_to?(:to_s)).to be_truthy
36
- expect(Fixture::Application.respond_to?(:obviously_not_a_real_method)).to be_falsey
58
+ expect(subject.instance).to receive(:respond_to?).twice.and_return(false)
59
+ expect(subject.respond_to?(:to_s)).to be_truthy
60
+ expect(subject.respond_to?(:obviously_not_a_real_method)).to be_falsey
37
61
  end
38
62
  end
39
63
 
40
64
  describe ".call" do
41
65
  it "forwards arg to new dispatcher, and calls dispatch" do
42
66
  dispatcher = double(:dispatch => :expected)
43
- rack_request = double
44
- allow(Rack::Request).to receive(:new).with(:env).and_return(rack_request)
45
- expect(Rory::Dispatcher).to receive(:new).with(rack_request, Fixture::Application.instance).and_return(dispatcher)
46
- expect(Fixture::Application.call(:env)).to eq(:expected)
67
+ rack_request = double(:media_type => 'application/json')
68
+ env = { "rack.input" => double(:read => {}) }
69
+ allow(Rack::Request).to receive(:new).with(env).and_return(rack_request)
70
+ expect(Rory::Dispatcher).to receive(:new).with(rack_request, subject.instance).and_return(dispatcher)
71
+ expect(subject.call(env)).to eq(:expected)
72
+ end
73
+ end
74
+
75
+ describe ".log_file" do
76
+ it "creates the log file directory if it does not exist" do
77
+ file = double(:sync= => true)
78
+ allow(File).to receive(:exists?).and_return(false)
79
+ allow(Dir).to receive(:mkdir).and_return(true)
80
+ allow(File).to receive(:open).and_return(file)
81
+ expect(subject.log_file).to eq(file)
82
+ end
83
+
84
+ it "returns the file and does not create the log file directory if it does not exist" do
85
+ file = double(:sync= => true)
86
+ allow(File).to receive(:exists?).and_return(true)
87
+ allow(File).to receive(:open).and_return(file)
88
+ expect(subject.log_file).to eq(file)
89
+ end
90
+ end
91
+
92
+ describe ".logger" do
93
+ it "reutrns a logger" do
94
+ logger = double
95
+ allow_any_instance_of(subject).to receive(:log_file)
96
+ allow(Logger).to receive(:new).and_return(logger)
97
+ expect(subject.logger).to eq(logger)
98
+ end
99
+ end
100
+
101
+ describe ".use_default_middleware" do
102
+ it "adds middleware when request logging is on" do
103
+ allow(subject.instance).to receive(:request_logging_on?).and_return(true)
104
+ allow(subject.instance).to receive(:logger).and_return(:the_logger)
105
+ subject.use_default_middleware
106
+ expect(subject.middleware.count).to_not eq(0)
107
+ end
108
+
109
+ it "does not add middleware when request logging is off" do
110
+ allow(subject.instance).to receive(:request_logging_on?).and_return(false)
111
+ allow(subject.instance).to receive(:logger).and_return(:the_logger)
112
+ subject.use_default_middleware
113
+ expect(subject.middleware.count).to eq(0)
47
114
  end
48
115
  end
49
116
 
50
117
  describe ".load_config_data" do
51
118
  it "returns parsed yaml file with given name from directory at config_path" do
52
- allow_any_instance_of(Fixture::Application).to receive(:config_path).and_return('Africa the Great')
119
+ allow_any_instance_of(subject).to receive(:config_path).and_return('Africa the Great')
53
120
  allow(YAML).to receive(:load_file).with(
54
121
  File.expand_path(File.join('Africa the Great', 'foo_type.yml'))).
55
122
  and_return(:oscar_the_grouch_takes_a_nap)
56
- expect(Fixture::Application.load_config_data(:foo_type)).to eq(:oscar_the_grouch_takes_a_nap)
123
+ expect(subject.load_config_data(:foo_type)).to eq(:oscar_the_grouch_takes_a_nap)
57
124
  end
58
125
  end
59
126
 
60
127
  describe ".connect_db" do
61
128
  it "sets up sequel connection to DB from YAML file" do
62
129
  config = { 'development' => :expected }
63
- allow_any_instance_of(Fixture::Application).to receive(:load_config_data).with(:database).and_return(config)
64
- expect(Sequel).to receive(:connect).with(:expected).and_return(double(:loggers => []))
65
- Fixture::Application.connect_db('development')
66
- end
67
- end
68
-
69
- describe ".routes" do
70
- it "generates a collection of routing objects from route configuration" do
71
- expect(Fixture::Application.routes).to eq [
72
- Rory::Route.new('foo/:id/bar', :to => 'foo#bar', :methods => [:get, :post]),
73
- Rory::Route.new('this/:path/is/:very_awesome', :to => 'awesome#rad'),
74
- Rory::Route.new('lumpies/:lump', :to => 'lumpies#show', :methods => [:get], :module => 'goose'),
75
- Rory::Route.new('rabbits/:chew', :to => 'rabbits#chew', :methods => [:get], :module => 'goose/wombat'),
76
- Rory::Route.new('', :to => 'root#vegetable', :methods => [:get]),
77
- Rory::Route.new('', :to => 'root#no_vegetable', :methods => [:delete]),
78
- Rory::Route.new('for_reals/switching', :to => 'for_reals#switching', :methods => [:get]),
79
- Rory::Route.new('for_reals/:parbles', :to => 'for_reals#srsly', :methods => [:get])
80
- ]
130
+ logger_array = []
131
+ allow(subject.instance).to receive(:logger).and_return(:the_logger)
132
+ allow(subject.instance).to receive(:load_config_data).with(:database).and_return(config)
133
+ expect(Sequel).to receive(:connect).with(:expected).and_return(double(:loggers => logger_array))
134
+ subject.connect_db('development')
135
+ expect(logger_array).to match_array([:the_logger])
81
136
  end
82
137
  end
83
138
 
@@ -90,43 +145,61 @@ describe Rory::Application do
90
145
 
91
146
  describe '.auto_require_paths' do
92
147
  after(:each) do
93
- Fixture::Application.instance.instance_variable_set(:@auto_require_paths, nil)
148
+ subject.instance.instance_variable_set(:@auto_require_paths, nil)
94
149
  end
95
150
 
96
151
  it 'includes models, controllers, and helpers by default' do
97
- expect(Fixture::Application.auto_require_paths).to eq(['models', 'controllers', 'helpers'])
152
+ expect(subject.auto_require_paths).to eq(['models', 'controllers', 'helpers'])
98
153
  end
99
154
 
100
155
  it 'accepts new paths' do
101
- Fixture::Application.auto_require_paths << 'chocolates'
102
- expect(Fixture::Application.auto_require_paths).to eq(['models', 'controllers', 'helpers', 'chocolates'])
156
+ subject.auto_require_paths << 'chocolates'
157
+ expect(subject.auto_require_paths).to eq(['models', 'controllers', 'helpers', 'chocolates'])
103
158
  end
104
159
  end
105
160
 
106
161
  describe '.require_all_files' do
107
162
  it 'requires all files in auto_require_paths' do
108
- allow_any_instance_of(Fixture::Application).to receive(:auto_require_paths).and_return(['goats', 'rhubarbs'])
163
+ allow_any_instance_of(subject).to receive(:auto_require_paths).and_return(['goats', 'rhubarbs'])
109
164
  [:goats, :rhubarbs].each do |folder|
110
165
  expect(Rory::Support).to receive(:require_all_files_in_directory).
111
- with(Pathname.new(Fixture::Application.root).join("#{folder}"))
166
+ with(Pathname.new(subject.root).join("#{folder}"))
112
167
  end
113
- Fixture::Application.require_all_files
168
+ subject.require_all_files
114
169
  end
115
170
  end
116
171
 
117
172
  describe '.use_middleware' do
118
173
  it 'adds the given middleware to the stack, retaining args and block' do
119
- require Fixture::Application.root.join('lib', 'dummy_middleware')
120
- Fixture::Application.use_middleware DummyMiddleware, :puppy do |dm|
174
+ require_relative '../../fixture_app/lib/dummy_middleware'
175
+ subject.use_middleware DummyMiddleware, :puppy do |dm|
121
176
  dm.prefix = 'a salubrious'
122
177
  end
123
178
 
124
- expect(Fixture::Application.instance).to receive(:dispatcher).
179
+ expect(subject.instance).to receive(:dispatcher).
125
180
  and_return(dispatch_stack_mock = double)
126
181
  expect(dispatch_stack_mock).to receive(:call).
127
182
  with('a salubrious puppy')
128
- Fixture::Application.call({})
129
- Fixture::Application.middleware.clear
183
+ subject.call({})
184
+ subject.middleware.clear
185
+ end
186
+ end
187
+
188
+ context "with fixture application" do
189
+ subject { Fixture::Application }
190
+ describe ".routes" do
191
+ it "generates a collection of routing objects from route configuration" do
192
+ expect(subject.routes).to eq [
193
+ Rory::Route.new('foo/:id/bar', :to => 'foo#bar', :methods => [:get, :post]),
194
+ Rory::Route.new('this/:path/is/:very_awesome', :to => 'awesome#rad'),
195
+ Rory::Route.new('lumpies/:lump', :to => 'lumpies#show', :methods => [:get], :module => 'goose'),
196
+ Rory::Route.new('rabbits/:chew', :to => 'rabbits#chew', :methods => [:get], :module => 'goose/wombat'),
197
+ Rory::Route.new('', :to => 'root#vegetable', :methods => [:get]),
198
+ Rory::Route.new('', :to => 'root#no_vegetable', :methods => [:delete]),
199
+ Rory::Route.new('for_reals/switching', :to => 'for_reals#switching', :methods => [:get]),
200
+ Rory::Route.new('for_reals/:parbles', :to => 'for_reals#srsly', :methods => [:get])
201
+ ]
202
+ end
130
203
  end
131
204
  end
132
- end
205
+ end
@@ -215,7 +215,7 @@ describe Rory::Controller do
215
215
 
216
216
  describe "#generate_body_from_template" do
217
217
  it "returns rendered template with given name" do
218
- expect(subject.generate_body_from_template('test/letsgo')).to eq("Let's go content")
218
+ expect(subject.generate_body_from_template('test/letsgo', :app => Fixture::Application)).to eq("Let's go content")
219
219
  end
220
220
 
221
221
  it "returns renderer output" do
@@ -0,0 +1,50 @@
1
+ describe Rory::ParameterFilter do
2
+
3
+ describe '#initialize' do
4
+ it 'sets the filters' do
5
+ expect(subject.instance_variable_get(:@filters)).to eq []
6
+ end
7
+ end
8
+
9
+ describe '#filter' do
10
+ it 'returns params unchanged' do
11
+ unfiltered_params = {"address"=>"11802 MCDONALD ST, Los Angeles, CA 90230",
12
+ "owners"=>[{"first_name"=>"GOLD", "last_name"=>"PATH", "ssn"=>"000-02-9999"}],
13
+ "overrides"=>{"ofac_7403"=>"clear"}}
14
+
15
+ expect(subject.filter(unfiltered_params)).to eq unfiltered_params
16
+ end
17
+
18
+ it 'returns params filtered by' do
19
+ subject = described_class.new([:ssn])
20
+ unfiltered_params = {"address"=>"11802 MCDONALD ST, Los Angeles, CA 90230",
21
+ "owners"=>[{"first_name"=>"GOLD", "last_name"=>"PATH", "ssn"=>"000-02-9999"}],
22
+ "overrides"=>{"ofac_7403"=>"clear"}}
23
+
24
+ filtered_params = {"address"=>"11802 MCDONALD ST, Los Angeles, CA 90230",
25
+ "owners"=>[{"first_name"=>"GOLD", "last_name"=>"PATH", "ssn"=>"[FILTERED]"}],
26
+ "overrides"=>{"ofac_7403"=>"clear"}}
27
+
28
+
29
+ expect(subject.filter(unfiltered_params)).to eq filtered_params
30
+ end
31
+
32
+ it 'filters based upon regex' do
33
+
34
+ filter_words = []
35
+ filter_words << /ofac*/
36
+
37
+ subject = described_class.new(filter_words)
38
+
39
+ unfiltered_params = {:address=>"11802 MCDONALD ST, Los Angeles, CA 90230",
40
+ "owners"=>[{"first_name"=>"GOLD", "last_name"=>"PATH", "ssn"=>"000-02-9999"}],
41
+ "overrides"=>{"ofac_7403"=>"clear"}}
42
+
43
+ filtered_params = {:address=>"11802 MCDONALD ST, Los Angeles, CA 90230",
44
+ "owners"=>[{"first_name"=>"GOLD", "last_name"=>"PATH", "ssn"=>"000-02-9999"}],
45
+ "overrides"=>{"ofac_7403"=>"[FILTERED]"}}
46
+
47
+ expect(subject.filter(unfiltered_params)).to eq filtered_params
48
+ end
49
+ end
50
+ end
@@ -1,34 +1,36 @@
1
- describe Rory::Renderer do
1
+ describe Rory::Renderer do
2
2
  describe "#render" do
3
+ let(:app) { Fixture::Application }
4
+
3
5
  it "returns text of template" do
4
- renderer = Rory::Renderer.new('test/static')
6
+ renderer = Rory::Renderer.new('test/static', :app => app)
5
7
  expect(renderer.render).to eq('Static content')
6
8
  end
7
9
 
8
10
  it "returns text of template in given layout" do
9
- controller = Rory::Renderer.new('test/static', :layout => 'surround')
11
+ controller = Rory::Renderer.new('test/static', :layout => 'surround', :app => app)
10
12
  expect(controller.render).to eq('Surrounding Static content is fun')
11
13
  end
12
14
 
13
15
  it "handles symbolized layout name" do
14
- controller = Rory::Renderer.new('test/static', :layout => :surround)
16
+ controller = Rory::Renderer.new('test/static', :layout => :surround, :app => app)
15
17
  expect(controller.render).to eq('Surrounding Static content is fun')
16
18
  end
17
19
 
18
20
  it "exposes locals to template" do
19
- controller = Rory::Renderer.new('test/dynamic', :locals => { :word => 'hockey' })
21
+ controller = Rory::Renderer.new('test/dynamic', :locals => { :word => 'hockey' }, :app => app)
20
22
  expect(controller.render).to eq('Word: hockey')
21
23
  end
22
24
 
23
25
  it "can render nested templates" do
24
- controller = Rory::Renderer.new('test/double_nested', :locals => { :word => 'hockey' })
26
+ controller = Rory::Renderer.new('test/double_nested', :locals => { :word => 'hockey' }, :app => app)
25
27
  expect(controller.render).to eq(
26
28
  "Don't Say A Bad Word: Poop!"
27
29
  )
28
30
  end
29
31
 
30
32
  it "exposes base_path to template" do
31
- controller = Rory::Renderer.new('test/a_link', :base_path => 'spoo')
33
+ controller = Rory::Renderer.new('test/a_link', :base_path => 'spoo', :app => app)
32
34
  expect(controller.render).to eq('You came from spoo.')
33
35
  end
34
36
  end
@@ -41,8 +43,8 @@ describe Rory::Renderer do
41
43
  end
42
44
 
43
45
  it 'uses Rory.root if no app specified' do
44
- renderer = Rory::Renderer.new('goose')
45
- expect(renderer.view_path).to eq(File.join(Rory.root, 'views', 'goose.html.erb'))
46
+ renderer = Rory::Renderer.new('goose', :app => double(:root => "horse"))
47
+ expect(renderer.view_path).to eq(File.expand_path(File.join('views', 'goose.html.erb'), "horse"))
46
48
  end
47
49
  end
48
50
  end
@@ -0,0 +1,95 @@
1
+ describe Rory::RequestParameterLogger do
2
+
3
+ let(:logger) { double(:write) }
4
+ let(:app) { double(:call) }
5
+ subject { described_class.new(app, logger, :filters) }
6
+
7
+ describe '#initialize' do
8
+ it 'returns a new RequestParameterLogger' do
9
+ expect(subject).to be_an_instance_of(Rory::RequestParameterLogger)
10
+ end
11
+
12
+ it 'returns a new RequestParameterLogger with parameters' do
13
+ expect(subject.instance_variable_get(:@app)).to eq(app)
14
+ expect(subject.instance_variable_get(:@logger)).to eq(logger)
15
+ expect(subject.instance_variable_get(:@filters)).to eq(:filters)
16
+ end
17
+ end
18
+
19
+ describe '#log_request' do
20
+
21
+ context 'when logger responds to write' do
22
+ it 'writes the request to the logger' do
23
+ allow(subject).to receive(:request_signature).and_return('request_signature')
24
+ allow(subject).to receive(:filtered_params).and_return('filtered_params')
25
+ expect(logger).to receive(:write).exactly(2).times
26
+ subject.send(:log_request)
27
+ end
28
+ end
29
+
30
+ context 'when logger does not respond to write' do
31
+ let(:logger) { double(:info) }
32
+ it 'writes the request to the logger' do
33
+ allow(subject).to receive(:request_signature).and_return('request_signature')
34
+ allow(subject).to receive(:filtered_params).and_return('filtered_params')
35
+ expect(logger).to receive(:info).exactly(2).times
36
+ subject.send(:log_request)
37
+ end
38
+ end
39
+ end
40
+
41
+ describe '#logger' do
42
+ it 'returns @logger' do
43
+ expect(subject.send(:logger)).to eq(logger)
44
+ end
45
+
46
+ it 'returns rack.errors ' do
47
+ subject = described_class.new(:app)
48
+ subject.instance_variable_set(:@env, {'rack.errors' => 'cocoa'})
49
+ expect(subject.send(:logger)).to eq('cocoa')
50
+ end
51
+ end
52
+
53
+ describe '#filtered_params' do
54
+ it 'filters the params' do
55
+ expect(Rory::ParameterFilter).to receive(:new).and_return(double(:filter => nil))
56
+ expect(subject).to receive(:unfiltered_params)
57
+ subject.send(:filtered_params)
58
+ end
59
+ end
60
+
61
+ describe '#unfiltered_params' do
62
+ it 'returns unfiltered params' do
63
+ expect(Rack::Request).to receive(:new).and_return(double(:params => nil))
64
+ subject.send(:unfiltered_params)
65
+ end
66
+ end
67
+
68
+ describe '#request_signature' do
69
+ it 'returns a request signature formatted string' do
70
+ env = {
71
+ 'REQUEST_METHOD' => "POST",
72
+ 'PATH_INFO' => "/mushy_mushy",
73
+ 'REMOTE_ADDR' => "127.0.0.1"
74
+ }
75
+
76
+ allow(Time).to receive(:now).and_return("2015-06-08 15:16:42 -0700")
77
+ subject.instance_variable_set(:@env, env)
78
+ expect(subject.send(:request_signature)).to eq('Started POST "/mushy_mushy" for 127.0.0.1 at 2015-06-08 15:16:42 -0700')
79
+ end
80
+ end
81
+
82
+
83
+ describe '#call' do
84
+ it 'writes the request and parameters to the log file' do
85
+ env = {
86
+ 'rack.input' => double(:rewind => nil)
87
+ }
88
+ expect(app).to receive(:call).with(env)
89
+ expect(subject).to receive(:log_request)
90
+
91
+ subject.call(env)
92
+ expect(subject.instance_variable_get(:@env)).to eq(env)
93
+ end
94
+ end
95
+ end
@@ -1,13 +1,15 @@
1
1
  describe Rory do
2
+ let!(:new_app) { Class.new(Rory::Application) }
3
+
2
4
  describe '.application' do
3
5
  it 'is by default set to the Rory::Application instance' do
4
- expect(Rory.application).to eq(Fixture::Application.instance)
6
+ expect(Rory.application).to eq(new_app.instance)
5
7
  end
6
8
  end
7
9
 
8
10
  describe '.root' do
9
11
  it 'returns root of application' do
10
- expect(Rory.root).to eq(Rory.application.root)
12
+ expect(Rory.root).to eq(new_app.root)
11
13
  end
12
14
  end
13
15
  end
@@ -20,5 +20,5 @@ Fixture::Application.require_all_files
20
20
  Capybara.app = Fixture::Application
21
21
 
22
22
  RSpec.configure do |config|
23
-
23
+ config.order = "random"
24
24
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ravi Gadad
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-09 00:00:00.000000000 Z
11
+ date: 2015-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rack-contrib
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.2'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: sequel
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -56,16 +70,16 @@ dependencies:
56
70
  name: rake
57
71
  requirement: !ruby/object:Gem::Requirement
58
72
  requirements:
59
- - - ">="
73
+ - - "~>"
60
74
  - !ruby/object:Gem::Version
61
- version: '0'
75
+ version: '10.4'
62
76
  type: :development
63
77
  prerelease: false
64
78
  version_requirements: !ruby/object:Gem::Requirement
65
79
  requirements:
66
- - - ">="
80
+ - - "~>"
67
81
  - !ruby/object:Gem::Version
68
- version: '0'
82
+ version: '10.4'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -84,58 +98,58 @@ dependencies:
84
98
  name: capybara
85
99
  requirement: !ruby/object:Gem::Requirement
86
100
  requirements:
87
- - - ">="
101
+ - - "~>"
88
102
  - !ruby/object:Gem::Version
89
- version: '0'
103
+ version: '2.4'
90
104
  type: :development
91
105
  prerelease: false
92
106
  version_requirements: !ruby/object:Gem::Requirement
93
107
  requirements:
94
- - - ">="
108
+ - - "~>"
95
109
  - !ruby/object:Gem::Version
96
- version: '0'
110
+ version: '2.4'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: yard
99
113
  requirement: !ruby/object:Gem::Requirement
100
114
  requirements:
101
- - - ">="
115
+ - - "~>"
102
116
  - !ruby/object:Gem::Version
103
- version: '0'
117
+ version: '0.8'
104
118
  type: :development
105
119
  prerelease: false
106
120
  version_requirements: !ruby/object:Gem::Requirement
107
121
  requirements:
108
- - - ">="
122
+ - - "~>"
109
123
  - !ruby/object:Gem::Version
110
- version: '0'
124
+ version: '0.8'
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: reek
113
127
  requirement: !ruby/object:Gem::Requirement
114
128
  requirements:
115
- - - ">="
129
+ - - "~>"
116
130
  - !ruby/object:Gem::Version
117
- version: '0'
131
+ version: '2.2'
118
132
  type: :development
119
133
  prerelease: false
120
134
  version_requirements: !ruby/object:Gem::Requirement
121
135
  requirements:
122
- - - ">="
136
+ - - "~>"
123
137
  - !ruby/object:Gem::Version
124
- version: '0'
138
+ version: '2.2'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: simplecov
127
141
  requirement: !ruby/object:Gem::Requirement
128
142
  requirements:
129
- - - ">="
143
+ - - "~>"
130
144
  - !ruby/object:Gem::Version
131
- version: '0'
145
+ version: '0.10'
132
146
  type: :development
133
147
  prerelease: false
134
148
  version_requirements: !ruby/object:Gem::Requirement
135
149
  requirements:
136
- - - ">="
150
+ - - "~>"
137
151
  - !ruby/object:Gem::Version
138
- version: '0'
152
+ version: '0.10'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: bundler
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +164,20 @@ dependencies:
150
164
  - - "~>"
151
165
  - !ruby/object:Gem::Version
152
166
  version: '1.0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: pry
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '0.10'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '0.10'
153
181
  description: |
154
182
  An exercise: Untangle the collusion of Rails idioms
155
183
  from my Ruby knowledge, while trying to understand some
@@ -171,9 +199,11 @@ files:
171
199
  - lib/rory/application.rb
172
200
  - lib/rory/controller.rb
173
201
  - lib/rory/dispatcher.rb
202
+ - lib/rory/parameter_filter.rb
174
203
  - lib/rory/path_generation.rb
175
204
  - lib/rory/renderer.rb
176
205
  - lib/rory/renderer/context.rb
206
+ - lib/rory/request_parameter_logger.rb
177
207
  - lib/rory/route.rb
178
208
  - lib/rory/route_mapper.rb
179
209
  - lib/rory/support.rb
@@ -191,6 +221,7 @@ files:
191
221
  - spec/fixture_app/controllers/goose/wombat/rabbits_controller.rb
192
222
  - spec/fixture_app/controllers/stub_controller.rb
193
223
  - spec/fixture_app/lib/dummy_middleware.rb
224
+ - spec/fixture_app/log/test.log
194
225
  - spec/fixture_app/views/for_reals/but_wait.html.erb
195
226
  - spec/fixture_app/views/for_reals/custom.html.erb
196
227
  - spec/fixture_app/views/for_reals/srsly.html.erb
@@ -204,8 +235,10 @@ files:
204
235
  - spec/lib/rory/application_spec.rb
205
236
  - spec/lib/rory/controller_spec.rb
206
237
  - spec/lib/rory/dispatcher_spec.rb
238
+ - spec/lib/rory/parameter_filter_spec.rb
207
239
  - spec/lib/rory/renderer/context_spec.rb
208
240
  - spec/lib/rory/renderer_spec.rb
241
+ - spec/lib/rory/request_parameter_logger_spec.rb
209
242
  - spec/lib/rory/route_spec.rb
210
243
  - spec/lib/rory/support_spec.rb
211
244
  - spec/lib/rory_spec.rb