rory 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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