hoodoo 1.19.0 → 2.0.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 +4 -4
- data/lib/hoodoo/active/active_model/uuid_validator.rb +0 -1
- data/lib/hoodoo/active/active_record/dated.rb +2 -2
- data/lib/hoodoo/active/active_record/support.rb +2 -1
- data/lib/hoodoo/active/active_record/uuid.rb +2 -2
- data/lib/hoodoo/active/active_record/writer.rb +1 -1
- data/lib/hoodoo/generator.rb +52 -12
- data/lib/hoodoo/monkey/patch/datadog_traced_amqp.rb +11 -6
- data/lib/hoodoo/monkey/patch/newrelic_middleware_analytics.rb +17 -10
- data/lib/hoodoo/monkey/patch/newrelic_traced_amqp.rb +71 -33
- data/lib/hoodoo/services/discovery/discoverers/by_drb/by_drb.rb +13 -8
- data/lib/hoodoo/services/middleware/exception_reporting/reporters/airbrake_reporter.rb +8 -3
- data/lib/hoodoo/services/middleware/interaction.rb +1 -1
- data/lib/hoodoo/services/middleware/middleware.rb +52 -41
- data/lib/hoodoo/version.rb +2 -2
- data/spec/active/active_record/creator_spec.rb +1 -1
- data/spec/active/active_record/dated_spec.rb +7 -7
- data/spec/active/active_record/finder_spec.rb +953 -839
- data/spec/active/active_record/manually_dated_spec.rb +1 -1
- data/spec/active/active_record/search_helper_spec.rb +1 -1
- data/spec/active/active_record/secure_spec.rb +2 -2
- data/spec/active/active_record/support_spec.rb +3 -3
- data/spec/monkey/patch/datadog_traced_amqp_spec.rb +10 -2
- data/spec/monkey/patch/newrelic_traced_amqp_spec.rb +54 -21
- data/spec/new_relic/agent/logger.rb +24 -0
- data/spec/new_relic/agent/transaction.rb +32 -0
- data/spec/services/discovery/discoverers/by_drb/by_drb_spec.rb +48 -2
- data/spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb +4 -4
- data/spec/services/middleware/middleware_multi_local_spec.rb +41 -13
- data/spec/services/middleware/middleware_multi_remote_spec.rb +93 -67
- data/spec/services/middleware/middleware_spec.rb +80 -7
- data/spec/services/services/interface_spec.rb +2 -2
- data/spec/transient_store/transient_store/mocks/redis_spec.rb +8 -6
- metadata +30 -26
@@ -63,7 +63,7 @@ module Hoodoo
|
|
63
63
|
# +version+:: Passed to #discover_remote.
|
64
64
|
# +options+:: Options hash as described below.
|
65
65
|
#
|
66
|
-
# Options keys are
|
66
|
+
# Options keys are:
|
67
67
|
#
|
68
68
|
# +host+:: Host name as a string for location of service endpoint,
|
69
69
|
# over HTTP (usually, local development is assumed).
|
@@ -72,20 +72,25 @@ module Hoodoo
|
|
72
72
|
#
|
73
73
|
# +path+:: Path on the above host and port of service endpoint.
|
74
74
|
#
|
75
|
+
# If any are missing or +nil+, remote announcement is aborted and
|
76
|
+
# the return value is correspondingly +nil+.
|
77
|
+
#
|
75
78
|
def announce_remote( resource, version, options = {} )
|
76
79
|
|
77
80
|
host = options[ :host ]
|
78
81
|
port = options[ :port ]
|
79
82
|
path = options[ :path ]
|
80
83
|
|
81
|
-
endpoint_uri_string =
|
84
|
+
endpoint_uri_string = unless host.nil? || port.nil? || path.nil?
|
85
|
+
"http://#{ host }:#{ port }#{ path }"
|
86
|
+
end
|
82
87
|
|
83
|
-
# Announce our local services if we
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
88
|
+
# Announce our local services only if we have an endpoint URI. In a
|
89
|
+
# 'guard' based environment, first-run determines host and port but
|
90
|
+
# subsequent runs do not - yet it stays the same, so it works out
|
91
|
+
# OK there.
|
87
92
|
#
|
88
|
-
unless
|
93
|
+
unless endpoint_uri_string.nil? || discover_remote( resource, version )
|
89
94
|
drb_service().add( resource, version, endpoint_uri_string )
|
90
95
|
end
|
91
96
|
|
@@ -157,7 +162,7 @@ module Hoodoo
|
|
157
162
|
rescue DRb::DRbConnError
|
158
163
|
if start_on_localhost_if_not_already_running
|
159
164
|
script_path = File.join( File.dirname( __FILE__ ), 'drb_server_start.rb' )
|
160
|
-
command = "bundle exec ruby '#{ script_path }'"
|
165
|
+
command = "#{ defined?( Bundler ) ? 'bundle exec ' : '' }ruby '#{ script_path }'"
|
161
166
|
command << " --port #{ @drb_port }" unless @drb_port.nil? || @drb_port.empty?
|
162
167
|
|
163
168
|
Process.detach( spawn( command ) )
|
@@ -27,7 +27,8 @@ module Hoodoo; module Services
|
|
27
27
|
# require 'airbrake'
|
28
28
|
#
|
29
29
|
# Airbrake.configure do | config |
|
30
|
-
# config.
|
30
|
+
# config.project_key = 'YOUR_AIRBRAKE_PROJECT_KEY'
|
31
|
+
# config.project_id = 'YOUR_AIRBRAKE_PROJECT_ID'
|
31
32
|
# end
|
32
33
|
#
|
33
34
|
# Hoodoo::Services::Middleware::ExceptionReporting.add(
|
@@ -57,7 +58,11 @@ module Hoodoo; module Services
|
|
57
58
|
opts = { :backtrace => Kernel.caller() }
|
58
59
|
opts[ :rack_env ] = env unless env.nil?
|
59
60
|
|
60
|
-
|
61
|
+
# Since an ExceptionReporter is already a "slow communicatory",
|
62
|
+
# Hoodoo is using threads for behaviour; we don't need the async
|
63
|
+
# Airbrake mechanism to waste resources doing the same.
|
64
|
+
#
|
65
|
+
Airbrake.notify_sync( e, opts )
|
61
66
|
end
|
62
67
|
|
63
68
|
# Report an exception for errors that occur within a fully handled Rack
|
@@ -77,7 +82,7 @@ module Hoodoo; module Services
|
|
77
82
|
:session => user_data_for( context ) || 'unknown'
|
78
83
|
}
|
79
84
|
|
80
|
-
Airbrake.
|
85
|
+
Airbrake.notify_sync( e, opts )
|
81
86
|
end
|
82
87
|
end
|
83
88
|
|
@@ -12,6 +12,7 @@
|
|
12
12
|
########################################################################
|
13
13
|
|
14
14
|
require 'set'
|
15
|
+
require 'cgi'
|
15
16
|
require 'uri'
|
16
17
|
require 'json'
|
17
18
|
require 'benchmark'
|
@@ -186,6 +187,15 @@ module Hoodoo; module Services
|
|
186
187
|
nil
|
187
188
|
}
|
188
189
|
|
190
|
+
# A validation Proc for FRAMEWORK_QUERY_DATA - see that for details. This
|
191
|
+
# one ensures that the value is a valid UUID and evaluates to that UUID
|
192
|
+
# string if so.
|
193
|
+
#
|
194
|
+
FRAMEWORK_QUERY_VALUE_UUID_PROC = -> ( value ) {
|
195
|
+
value = Hoodoo::UUID.valid?( value ) && value
|
196
|
+
value || nil # => 'value' if 'value' is truthy, 'nil' if 'value' falsy
|
197
|
+
}
|
198
|
+
|
189
199
|
# Out-of-box search and filter query keys. Interfaces can override the
|
190
200
|
# support for these inside the Hoodoo::Services::Interface.to_list block
|
191
201
|
# using Hoodoo::Services::Interface::ToListDSL.do_not_search and
|
@@ -216,6 +226,7 @@ module Hoodoo; module Services
|
|
216
226
|
FRAMEWORK_QUERY_DATA = {
|
217
227
|
'created_after' => FRAMEWORK_QUERY_VALUE_DATE_PROC,
|
218
228
|
'created_before' => FRAMEWORK_QUERY_VALUE_DATE_PROC,
|
229
|
+
'created_by' => FRAMEWORK_QUERY_VALUE_UUID_PROC
|
219
230
|
}
|
220
231
|
|
221
232
|
# Utility - returns the execution environment as a Rails-like environment
|
@@ -478,7 +489,6 @@ module Hoodoo; module Services
|
|
478
489
|
# implementation Hoodoo::Services::Implementation subclass *instance* to
|
479
490
|
# use on match
|
480
491
|
#
|
481
|
-
#
|
482
492
|
@@services = service_container.component_interfaces.map do | interface |
|
483
493
|
|
484
494
|
if interface.nil? || interface.endpoint.nil? || interface.implementation.nil?
|
@@ -620,10 +630,10 @@ module Hoodoo; module Services
|
|
620
630
|
#
|
621
631
|
# +version+:: Required implemented version for the endpoint. Integer.
|
622
632
|
#
|
623
|
-
# +interaction+:: The Hoodoo::Services::Interaction instance
|
624
|
-
# the inbound call, the processing of which is
|
625
|
-
# a request for an inter-resource call by an
|
626
|
-
# implementation.
|
633
|
+
# +interaction+:: The Hoodoo::Services::Middleware::Interaction instance
|
634
|
+
# describing the inbound call, the processing of which is
|
635
|
+
# leading to a request for an inter-resource call by an
|
636
|
+
# endpoint implementation.
|
627
637
|
#
|
628
638
|
def inter_resource_endpoint_for( resource, version, interaction )
|
629
639
|
resource = resource.to_sym
|
@@ -720,11 +730,12 @@ module Hoodoo; module Services
|
|
720
730
|
#
|
721
731
|
# Named parameters are as follows:
|
722
732
|
#
|
723
|
-
# +source_interaction+:: A Hoodoo::Services::Interaction
|
724
|
-
# inbound call which is being
|
725
|
-
# by some resource endpoint
|
726
|
-
# implementation
|
727
|
-
# call as part of its
|
733
|
+
# +source_interaction+:: A Hoodoo::Services::Middleware::Interaction
|
734
|
+
# instance for the inbound call which is being
|
735
|
+
# processed right now by some resource endpoint
|
736
|
+
# implementation and this implementation is now
|
737
|
+
# making an inter-resource call as part of its
|
738
|
+
# processing;
|
728
739
|
#
|
729
740
|
# +discovery_result+:: A Hoodoo::Services::Discovery::ForLocal instance
|
730
741
|
# describing the target of the inter-resource call;
|
@@ -991,13 +1002,13 @@ module Hoodoo; module Services
|
|
991
1002
|
|
992
1003
|
# Make an "inbound" call log based on the given interaction.
|
993
1004
|
#
|
994
|
-
# +interaction+:: Hoodoo::Services::Interaction describing the
|
995
|
-
# request. The +interaction_id+, +rack_request+ and
|
996
|
-
# +session+ data is used (the latter being optional).
|
997
|
-
#
|
998
|
-
#
|
999
|
-
#
|
1000
|
-
#
|
1005
|
+
# +interaction+:: Hoodoo::Services::Middleware::Interaction describing the
|
1006
|
+
# inbound request. The +interaction_id+, +rack_request+ and
|
1007
|
+
# +session+ data is used (the latter being optional). If
|
1008
|
+
# +target_interface+ and +requested_action+ are available,
|
1009
|
+
# body data _might_ be logged according to secure log
|
1010
|
+
# settings in the interface; if these values are unset,
|
1011
|
+
# body data is _not_ logged.
|
1001
1012
|
#
|
1002
1013
|
def monkey_log_inbound_request( interaction )
|
1003
1014
|
|
@@ -1181,12 +1192,12 @@ module Hoodoo; module Services
|
|
1181
1192
|
# Build common log information for the 'data' part of a payload based
|
1182
1193
|
# on the given interaction. Returned as a Hash with Symbol keys.
|
1183
1194
|
#
|
1184
|
-
# +interaction+:: Hoodoo::Services::Interaction describing a
|
1185
|
-
# A +context+ and +interaction_id+ are expected.
|
1186
|
-
# +target_interface+ and +requested_action+ are
|
1187
|
-
# and if present result in a <tt>:target</tt>
|
1188
|
-
# the returned Hash. The +context.session+ value
|
1189
|
-
# present will be included in a <tt>:session</tt> entry;
|
1195
|
+
# +interaction+:: Hoodoo::Services::Middleware::Interaction describing a
|
1196
|
+
# request. A +context+ and +interaction_id+ are expected.
|
1197
|
+
# The +target_interface+ and +requested_action+ are
|
1198
|
+
# optional and if present result in a <tt>:target</tt>
|
1199
|
+
# entry in the returned Hash. The +context.session+ value
|
1200
|
+
# if present will be included in a <tt>:session</tt> entry;
|
1190
1201
|
# if verbose logging is enabled this will be quoted in
|
1191
1202
|
# full, else only identity-related parts are recorded.
|
1192
1203
|
#
|
@@ -1577,8 +1588,8 @@ module Hoodoo; module Services
|
|
1577
1588
|
end
|
1578
1589
|
end
|
1579
1590
|
|
1580
|
-
host
|
1581
|
-
port
|
1591
|
+
host ||= @@recorded_host if defined?( @@recorded_host )
|
1592
|
+
port ||= @@recorded_port if defined?( @@recorded_port )
|
1582
1593
|
|
1583
1594
|
# Under test, ensure a simulation of an available host and port is
|
1584
1595
|
# always available for discovery-related tests.
|
@@ -1588,23 +1599,23 @@ module Hoodoo; module Services
|
|
1588
1599
|
port ||= '9292'
|
1589
1600
|
end
|
1590
1601
|
|
1591
|
-
# Announce the resource endpoints
|
1592
|
-
#
|
1602
|
+
# Announce the resource endpoints. We might not be able to annouce
|
1603
|
+
# the remote availability of this endpoint if the host/port are not
|
1604
|
+
# determined; but that might just be because we are running under
|
1605
|
+
# "racksh" and we wouldn't want to announce remotely anyway.
|
1593
1606
|
|
1594
|
-
|
1595
|
-
|
1596
|
-
interface = service.interface_class
|
1607
|
+
services.each do | service |
|
1608
|
+
interface = service.interface_class
|
1597
1609
|
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1605
|
-
|
1606
|
-
|
1607
|
-
end
|
1610
|
+
@discoverer.announce(
|
1611
|
+
interface.resource,
|
1612
|
+
interface.version,
|
1613
|
+
{
|
1614
|
+
:host => host,
|
1615
|
+
:port => port,
|
1616
|
+
:path => service.base_path
|
1617
|
+
}
|
1618
|
+
)
|
1608
1619
|
end
|
1609
1620
|
end
|
1610
1621
|
end
|
@@ -1752,7 +1763,7 @@ module Hoodoo; module Services
|
|
1752
1763
|
# We try the custom routing path first, then the de facto path, then
|
1753
1764
|
# give up if neither match.
|
1754
1765
|
|
1755
|
-
uri_path = CGI.unescape( interaction.rack_request.path() )
|
1766
|
+
uri_path = ::CGI.unescape( interaction.rack_request.path() )
|
1756
1767
|
|
1757
1768
|
selected_path_data = nil
|
1758
1769
|
selected_services = @@services.select do | service_data |
|
data/lib/hoodoo/version.rb
CHANGED
@@ -12,11 +12,11 @@ module Hoodoo
|
|
12
12
|
# The Hoodoo gem version. If this changes, be sure to re-run
|
13
13
|
# <tt>bundle install</tt> or <tt>bundle update</tt>.
|
14
14
|
#
|
15
|
-
VERSION = '
|
15
|
+
VERSION = '2.0.0'
|
16
16
|
|
17
17
|
# The Hoodoo gem date. If this changes, be sure to re-run
|
18
18
|
# <tt>bundle install</tt> or <tt>bundle update</tt>.
|
19
19
|
#
|
20
|
-
DATE = '2017-
|
20
|
+
DATE = '2017-10-13'
|
21
21
|
|
22
22
|
end
|
@@ -9,7 +9,7 @@ describe Hoodoo::ActiveRecord::Dated do
|
|
9
9
|
ActiveRecord::Migration.create_table( :r_spec_model_effective_date_tests, :id => false ) do | t |
|
10
10
|
t.text :id, :null => false
|
11
11
|
t.text :data
|
12
|
-
t.timestamps
|
12
|
+
t.timestamps :null => true
|
13
13
|
end
|
14
14
|
|
15
15
|
ActiveRecord::Migration.create_table( :r_spec_model_effective_date_tests_history_entries, :id => false ) do | t |
|
@@ -18,7 +18,7 @@ describe Hoodoo::ActiveRecord::Dated do
|
|
18
18
|
t.text :data
|
19
19
|
t.datetime :effective_start, :null => false
|
20
20
|
t.datetime :effective_end, :null => false
|
21
|
-
t.timestamps
|
21
|
+
t.timestamps :null => true
|
22
22
|
end
|
23
23
|
|
24
24
|
class RSpecModelEffectiveDateTest < ActiveRecord::Base
|
@@ -29,7 +29,7 @@ describe Hoodoo::ActiveRecord::Dated do
|
|
29
29
|
ActiveRecord::Migration.create_table( :r_spec_model_effective_date_test_overrides, :id => false ) do | t |
|
30
30
|
t.text :id, :null => false
|
31
31
|
t.text :data
|
32
|
-
t.timestamps
|
32
|
+
t.timestamps :null => true
|
33
33
|
end
|
34
34
|
|
35
35
|
ActiveRecord::Migration.create_table( :r_spec_model_effective_date_history_entries, :id => false ) do | t |
|
@@ -38,7 +38,7 @@ describe Hoodoo::ActiveRecord::Dated do
|
|
38
38
|
t.text :data
|
39
39
|
t.datetime :effective_start, :null => false
|
40
40
|
t.datetime :effective_end, :null => false
|
41
|
-
t.timestamps
|
41
|
+
t.timestamps :null => true
|
42
42
|
end
|
43
43
|
|
44
44
|
class RSpecModelEffectiveDateTestOverride < ActiveRecord::Base
|
@@ -299,7 +299,7 @@ describe Hoodoo::ActiveRecord::Dated do
|
|
299
299
|
context "SQL and column selections" do
|
300
300
|
before :each do
|
301
301
|
@now = Time.now.utc
|
302
|
-
@safe_now = RSpecModelEffectiveDateTestOverride.
|
302
|
+
@safe_now = RSpecModelEffectiveDateTestOverride.connection.quoted_date( @now )
|
303
303
|
|
304
304
|
request = Hoodoo::Services::Request.new
|
305
305
|
@context = Hoodoo::Services::Context.new( nil, request, nil, nil )
|
@@ -309,8 +309,8 @@ describe Hoodoo::ActiveRecord::Dated do
|
|
309
309
|
|
310
310
|
def run_other_expectations( sql )
|
311
311
|
expect( sql ).to include( "from r_spec_model_effective_date_history_entries" )
|
312
|
-
expect( sql ).to include( "\"effective_start\" <= #{ @safe_now }" )
|
313
|
-
expect( sql ).to include( "\"effective_end\" > #{ @safe_now }" )
|
312
|
+
expect( sql ).to include( "\"effective_start\" <= '#{ @safe_now }'" )
|
313
|
+
expect( sql ).to include( "\"effective_end\" > '#{ @safe_now }'" )
|
314
314
|
expect( sql ).to include( "\"effective_end\" is null" )
|
315
315
|
end
|
316
316
|
|
@@ -1,7 +1,14 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'active_record'
|
3
3
|
|
4
|
-
|
4
|
+
# The "counting" tests must run first and in-order internally, else e.g. an
|
5
|
+
# ANALYZE might happen before the pre-ANALYZE test, breaking the results.
|
6
|
+
# Other tests that create objects in the table can cause the estimated count
|
7
|
+
# to shift away from initial expectations too, so this test is run early.
|
8
|
+
# All other tests are wrapped in a giant context that allows for random
|
9
|
+
# ordering to be preserved there.
|
10
|
+
#
|
11
|
+
describe Hoodoo::ActiveRecord::Finder, :order => :defined do
|
5
12
|
before :all do
|
6
13
|
spec_helper_silence_stdout() do
|
7
14
|
ActiveRecord::Migration.create_table( :r_spec_model_finder_tests, :id => false ) do | t |
|
@@ -12,7 +19,8 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
12
19
|
t.text :field_two
|
13
20
|
t.text :field_three
|
14
21
|
|
15
|
-
t.timestamps
|
22
|
+
t.timestamps :null => true
|
23
|
+
t.text :created_by
|
16
24
|
end
|
17
25
|
end
|
18
26
|
|
@@ -79,7 +87,8 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
79
87
|
:wild_field_one => sh.ciaw_match_generic( 'field_one '),
|
80
88
|
:field_two => sh.cs_match_csv(),
|
81
89
|
'field_three' => sh.cs_match_array(),
|
82
|
-
'created_after' => sh.cs_gte( 'updated_at' )
|
90
|
+
'created_after' => sh.cs_gte( 'updated_at' ), # Deliberate framework override
|
91
|
+
'created_by' => sh.ci_match_generic( 'code' ) # Deliberate framework override
|
83
92
|
}
|
84
93
|
|
85
94
|
search_with( search_and_filter_map )
|
@@ -118,7 +127,9 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
118
127
|
end
|
119
128
|
|
120
129
|
before :each do
|
121
|
-
@tn
|
130
|
+
@tn = Time.now.round()
|
131
|
+
@cb1 = Hoodoo::UUID.generate()
|
132
|
+
@cb2 = Hoodoo::UUID.generate()
|
122
133
|
|
123
134
|
@a = RSpecModelFinderTest.new
|
124
135
|
@a.id = "one"
|
@@ -128,6 +139,7 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
128
139
|
@a.field_three = 'three a'
|
129
140
|
@a.created_at = @tn - 1.year
|
130
141
|
@a.updated_at = @tn - 1.month
|
142
|
+
@a.created_by = @cb1
|
131
143
|
@a.save!
|
132
144
|
@id = @a.id
|
133
145
|
|
@@ -140,6 +152,7 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
140
152
|
@b.field_three = 'three b'
|
141
153
|
@b.created_at = @tn - 1.month
|
142
154
|
@b.updated_at = @tn - 1.week
|
155
|
+
@b.created_by = @cb1
|
143
156
|
@b.save!
|
144
157
|
@uuid = @b.uuid
|
145
158
|
|
@@ -151,6 +164,7 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
151
164
|
@c.field_three = 'three c'
|
152
165
|
@c.created_at = @tn
|
153
166
|
@c.updated_at = @tn + 1.day
|
167
|
+
@c.created_by = @cb2
|
154
168
|
@c.save!
|
155
169
|
@code = @c.code
|
156
170
|
|
@@ -191,700 +205,692 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
191
205
|
|
192
206
|
# ==========================================================================
|
193
207
|
|
194
|
-
context
|
195
|
-
|
208
|
+
context "(ordered)" do
|
209
|
+
context 'counting' do
|
210
|
+
it 'lists with a normal count' do
|
211
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
196
212
|
|
197
|
-
|
198
|
-
|
213
|
+
expect( finder ).to receive( :dataset_size ).at_least( :once ).and_call_original
|
214
|
+
expect( finder ).to receive( :count ).at_least( :once ).and_call_original
|
199
215
|
|
200
|
-
|
201
|
-
|
202
|
-
Hoodoo::Services::Session.new,
|
203
|
-
@interaction.context.request,
|
204
|
-
@interaction.context.response,
|
205
|
-
@interaction
|
206
|
-
)
|
216
|
+
expect( finder ).to_not receive( :estimated_dataset_size )
|
217
|
+
expect( finder ).to_not receive( :estimated_count )
|
207
218
|
|
208
|
-
|
209
|
-
@session = @interaction.context.session
|
210
|
-
end
|
219
|
+
result = finder.dataset_size()
|
211
220
|
|
212
|
-
|
213
|
-
|
214
|
-
# to prove that it's calling the scope engine and that engine has its
|
215
|
-
# own comprehensive test coverage in suport_spec.rb.
|
216
|
-
#
|
217
|
-
it 'generates appropriate scope' do
|
218
|
-
@session.scoping = { :authorised_uuids => [ 'uuid 1', 'uuid 2' ], :authorised_code => 'code 1' }
|
221
|
+
expect( result ).to_not be_nil
|
222
|
+
end
|
219
223
|
|
220
|
-
|
221
|
-
|
222
|
-
RSpecModelFinderTest, @context
|
223
|
-
).and_call_original()
|
224
|
-
)
|
224
|
+
it 'lists with an estimated count' do
|
225
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
225
226
|
|
226
|
-
|
227
|
+
expect( finder ).to_not receive( :dataset_size )
|
227
228
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
"\"r_spec_model_finder_tests\".\"uuid\" IN ('uuid 1', 'uuid 2') AND " \
|
232
|
-
"\"r_spec_model_finder_tests\".\"code\" = 'code 1'" )
|
233
|
-
end
|
234
|
-
end
|
229
|
+
expect( finder ).to receive( :estimated_dataset_size ).at_least( :once ).and_call_original
|
230
|
+
expect( finder ).to receive( :estimated_count ).at_least( :once ).and_call_original
|
231
|
+
expect( finder ).to receive( :count ).at_least( :once ).and_call_original
|
235
232
|
|
236
|
-
|
237
|
-
|
238
|
-
context 'acquisition scope and overrides' do
|
239
|
-
def expect_sql( sql, id_attr_name )
|
240
|
-
expect( sql ).to eq( "SELECT \"r_spec_model_finder_tests\".* " \
|
241
|
-
"FROM \"r_spec_model_finder_tests\" " \
|
242
|
-
"WHERE (" \
|
243
|
-
"(" \
|
244
|
-
"\"r_spec_model_finder_tests\".\"#{ id_attr_name }\" = '#{ @id }' OR " \
|
245
|
-
"\"r_spec_model_finder_tests\".\"uuid\" = '#{ @id }'" \
|
246
|
-
") OR " \
|
247
|
-
"\"r_spec_model_finder_tests\".\"code\" = '#{ @id }'" \
|
248
|
-
")" )
|
249
|
-
end
|
233
|
+
result = finder.estimated_dataset_size
|
250
234
|
|
251
|
-
|
252
|
-
it 'SQL generation is as expected' do
|
253
|
-
sql = RSpecModelFinderTest.acquisition_scope( @id ).to_sql()
|
254
|
-
expect_sql( sql, 'id' )
|
235
|
+
expect( result ).to_not be_nil
|
255
236
|
end
|
256
|
-
end
|
257
237
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
238
|
+
context 'RDoc-recommended PostgreSQL migration example' do
|
239
|
+
before :each do
|
240
|
+
ActiveRecord::Base.connection.execute <<-SQL
|
241
|
+
CREATE FUNCTION estimated_count(query text) RETURNS integer AS
|
242
|
+
$func$
|
243
|
+
DECLARE
|
244
|
+
rec record;
|
245
|
+
rows integer;
|
246
|
+
BEGIN
|
247
|
+
FOR rec IN EXECUTE 'EXPLAIN ' || query LOOP
|
248
|
+
rows := substring(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)');
|
249
|
+
EXIT WHEN rows IS NOT NULL;
|
250
|
+
END LOOP;
|
251
|
+
|
252
|
+
RETURN rows;
|
253
|
+
END
|
254
|
+
$func$ LANGUAGE plpgsql;
|
255
|
+
SQL
|
256
|
+
|
257
|
+
counter = Proc.new do | sql |
|
258
|
+
begin
|
259
|
+
ActiveRecord::Base.connection.execute(
|
260
|
+
"SELECT estimated_count('#{ sql}')"
|
261
|
+
).first[ 'estimated_count' ].to_i
|
262
|
+
rescue
|
263
|
+
nil
|
264
|
+
end
|
265
|
+
end
|
263
266
|
|
264
|
-
|
265
|
-
RSpecModelFinderTest.acquire_with_id_substitute( 'id' )
|
266
|
-
end
|
267
|
+
RSpecModelFinderTest.estimate_counts_with( counter )
|
267
268
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
end
|
269
|
+
# Tests start by ensuring the database knows about the current
|
270
|
+
# object count.
|
271
|
+
#
|
272
|
+
ActiveRecord::Base.connection.execute( 'ANALYZE' )
|
273
|
+
end
|
274
274
|
|
275
|
-
|
275
|
+
after :each do
|
276
|
+
ActiveRecord::Base.connection.execute "DROP FUNCTION estimated_count(query text);"
|
277
|
+
RSpecModelFinderTest.estimate_counts_with( nil )
|
278
|
+
end
|
276
279
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
expect( found ).to eq(@a)
|
280
|
+
context 'estimate' do
|
281
|
+
before :each do
|
282
|
+
@initial_count = RSpecModelFinderTest.count
|
281
283
|
|
282
|
-
|
283
|
-
|
284
|
+
# The outer 'before' code ensures an accurate initial count of 3,
|
285
|
+
# but we're going add in a few more unestimated items.
|
286
|
+
#
|
287
|
+
@uncounted1 = RSpecModelFinderTest.new.save!
|
288
|
+
@uncounted2 = RSpecModelFinderTest.new.save!
|
289
|
+
@uncounted3 = RSpecModelFinderTest.new.save!
|
284
290
|
|
285
|
-
|
286
|
-
|
287
|
-
end
|
291
|
+
@subsequent_accurate_count = RSpecModelFinderTest.count
|
292
|
+
end
|
288
293
|
|
289
|
-
|
290
|
-
|
294
|
+
it 'may be initially inaccurate' do
|
295
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
296
|
+
result = finder.estimated_dataset_size
|
297
|
+
expect( result ).to eq( @initial_count ).or( eq( @subsequent_accurate_count ) )
|
298
|
+
end
|
291
299
|
|
292
|
-
|
293
|
-
|
300
|
+
# The outer 'before' code kind of already tests this anyway since if
|
301
|
+
# the analyze call therein didn't work, prerequisites in the tests
|
302
|
+
# would be wrong and other tests would fail. It's useful to
|
303
|
+
# double-check something this important though.
|
304
|
+
#
|
305
|
+
it 'is accurate after ANALYZE' do
|
306
|
+
ActiveRecord::Base.connection.execute( 'ANALYZE' )
|
294
307
|
|
295
|
-
|
296
|
-
|
308
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
309
|
+
result = finder.estimated_dataset_size
|
310
|
+
expect( result ).to eq( @subsequent_accurate_count )
|
311
|
+
end
|
297
312
|
|
298
|
-
|
299
|
-
|
313
|
+
it 'is "nil" if the Proc evaluates thus' do
|
314
|
+
RSpecModelFinderTest.estimate_counts_with( Proc.new() { | sql | nil } )
|
315
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
316
|
+
result = finder.estimated_dataset_size
|
317
|
+
expect( result ).to be_nil
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
300
321
|
end
|
322
|
+
end
|
301
323
|
|
302
|
-
|
303
|
-
# performed two database calls, via a count then a true find. This was
|
304
|
-
# refactored to only make one call per attribute, but that in turn can
|
305
|
-
# be much improved via the AREL table to compose a single query that
|
306
|
-
# uses "OR" to get the database to check each attribute in order. Thus
|
307
|
-
# every test below expects exactly one database call only.
|
308
|
-
#
|
309
|
-
context 'only makes one database call when' do
|
324
|
+
# ==========================================================================
|
310
325
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
expect( found ).to eq(@a)
|
315
|
-
end
|
326
|
+
context "(randomised)", :order => :random do
|
327
|
+
context '#scoped_in' do
|
328
|
+
before :each do
|
316
329
|
|
317
|
-
|
318
|
-
|
330
|
+
# Get a good-enough-for-test interaction which has a context
|
331
|
+
# that contains a Session we can modify.
|
319
332
|
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
333
|
+
@interaction = Hoodoo::Services::Middleware::Interaction.new( {}, nil )
|
334
|
+
@interaction.context = Hoodoo::Services::Context.new(
|
335
|
+
Hoodoo::Services::Session.new,
|
336
|
+
@interaction.context.request,
|
337
|
+
@interaction.context.response,
|
338
|
+
@interaction
|
339
|
+
)
|
325
340
|
|
326
|
-
|
341
|
+
@context = @interaction.context
|
342
|
+
@session = @interaction.context.session
|
327
343
|
end
|
328
344
|
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
345
|
+
# If security scoping works _and_ we know that it called #full_scope_for
|
346
|
+
# in the "internal"-ish support API, then we consider that good enough
|
347
|
+
# to prove that it's calling the scope engine and that engine has its
|
348
|
+
# own comprehensive test coverage in suport_spec.rb.
|
349
|
+
#
|
350
|
+
it 'generates appropriate scope' do
|
351
|
+
@session.scoping = { :authorised_uuids => [ 'uuid 1', 'uuid 2' ], :authorised_code => 'code 1' }
|
352
|
+
|
353
|
+
expect( Hoodoo::ActiveRecord::Support ).to(
|
354
|
+
receive( :full_scope_for ).once().with(
|
355
|
+
RSpecModelFinderTest, @context
|
356
|
+
).and_call_original()
|
357
|
+
)
|
358
|
+
|
359
|
+
sql = RSpecModelFinderTest.scoped_in( @context ).to_sql
|
360
|
+
|
361
|
+
expect( sql ).to eq( "SELECT \"r_spec_model_finder_tests\".* " \
|
362
|
+
"FROM \"r_spec_model_finder_tests\" " \
|
363
|
+
"WHERE " \
|
364
|
+
"\"r_spec_model_finder_tests\".\"uuid\" IN ('uuid 1', 'uuid 2') AND " \
|
365
|
+
"\"r_spec_model_finder_tests\".\"code\" = 'code 1'" )
|
366
|
+
end
|
367
|
+
end
|
334
368
|
|
335
|
-
|
369
|
+
# ========================================================================
|
370
|
+
|
371
|
+
context 'acquisition scope and overrides' do
|
372
|
+
def expect_sql( sql, id_attr_name )
|
373
|
+
expect( sql ).to eq( "SELECT \"r_spec_model_finder_tests\".* " \
|
374
|
+
"FROM \"r_spec_model_finder_tests\" " \
|
375
|
+
"WHERE (" \
|
376
|
+
"(" \
|
377
|
+
"\"r_spec_model_finder_tests\".\"#{ id_attr_name }\" = '#{ @id }' OR " \
|
378
|
+
"\"r_spec_model_finder_tests\".\"uuid\" = '#{ @id }'" \
|
379
|
+
") OR " \
|
380
|
+
"\"r_spec_model_finder_tests\".\"code\" = '#{ @id }'" \
|
381
|
+
")" )
|
336
382
|
end
|
337
383
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
384
|
+
context '#acquisition_scope' do
|
385
|
+
it 'SQL generation is as expected' do
|
386
|
+
sql = RSpecModelFinderTest.acquisition_scope( @id ).to_sql()
|
387
|
+
expect_sql( sql, 'id' )
|
342
388
|
end
|
343
|
-
|
344
|
-
expect( count ).to eq( 1 )
|
345
389
|
end
|
346
|
-
end
|
347
|
-
end
|
348
390
|
|
349
|
-
|
391
|
+
context '#acquire_with_id_substitute' do
|
392
|
+
before :each do
|
393
|
+
@alt_attr_name = 'foo'
|
394
|
+
RSpecModelFinderTest.acquire_with_id_substitute( @alt_attr_name )
|
395
|
+
end
|
350
396
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
@scoped_1.id = 'id 1'
|
355
|
-
@scoped_1.uuid = 'uuid 1'
|
356
|
-
@scoped_1.code = 'code 1'
|
357
|
-
@scoped_1.field_one = 'scoped 1'
|
358
|
-
@scoped_1.save!
|
359
|
-
|
360
|
-
@scoped_2 = RSpecModelFinderTest.new
|
361
|
-
@scoped_2.id = 'id 2'
|
362
|
-
@scoped_2.uuid = 'uuid 1'
|
363
|
-
@scoped_2.code = 'code 2'
|
364
|
-
@scoped_2.field_one = 'scoped 2'
|
365
|
-
@scoped_2.save!
|
366
|
-
|
367
|
-
@scoped_3 = RSpecModelFinderTest.new
|
368
|
-
@scoped_3.id = 'id 3'
|
369
|
-
@scoped_3.uuid = 'uuid 2'
|
370
|
-
@scoped_3.code = 'code 2'
|
371
|
-
@scoped_3.field_one = 'scoped 3'
|
372
|
-
@scoped_3.save!
|
373
|
-
|
374
|
-
# Get a good-enough-for-test interaction which has a context
|
375
|
-
# that contains a Session we can modify.
|
376
|
-
|
377
|
-
@interaction = Hoodoo::Services::Middleware::Interaction.new( {}, nil )
|
378
|
-
@interaction.context = Hoodoo::Services::Context.new(
|
379
|
-
Hoodoo::Services::Session.new,
|
380
|
-
@interaction.context.request,
|
381
|
-
@interaction.context.response,
|
382
|
-
@interaction
|
383
|
-
)
|
397
|
+
after :each do
|
398
|
+
RSpecModelFinderTest.acquire_with_id_substitute( 'id' )
|
399
|
+
end
|
384
400
|
|
385
|
-
|
386
|
-
|
401
|
+
it 'SQL generation is as expected' do
|
402
|
+
sql = RSpecModelFinderTest.acquisition_scope( @id ).to_sql()
|
403
|
+
expect_sql( sql, @alt_attr_name )
|
404
|
+
end
|
405
|
+
end
|
387
406
|
end
|
388
407
|
|
389
|
-
|
390
|
-
|
391
|
-
# Note the corresponding 'acquire_with' used Symbols and had a
|
392
|
-
# duplicated entry - we expect Strings and no duplicates here.
|
393
|
-
#
|
394
|
-
expect( RSpecModelFinderTest.acquired_with() ).to eq( [ 'uuid', 'code' ] )
|
395
|
-
|
396
|
-
end
|
408
|
+
# ========================================================================
|
397
409
|
|
398
|
-
|
399
|
-
|
410
|
+
context '#acquire' do
|
411
|
+
it 'finds from the class' do
|
412
|
+
found = RSpecModelFinderTest.acquire( @id )
|
413
|
+
expect( found ).to eq(@a)
|
400
414
|
|
401
|
-
|
402
|
-
|
403
|
-
expect( found ).to eq( @scoped_1 )
|
415
|
+
found = RSpecModelFinderTest.acquire( @uuid )
|
416
|
+
expect( found ).to eq(@b)
|
404
417
|
|
405
|
-
|
406
|
-
|
407
|
-
|
418
|
+
found = RSpecModelFinderTest.acquire( @code )
|
419
|
+
expect( found ).to eq(@c)
|
420
|
+
end
|
408
421
|
|
409
|
-
|
410
|
-
|
411
|
-
expect( found ).to be_nil
|
422
|
+
it 'finds with a chain' do
|
423
|
+
finder = RSpecModelFinderTest.where( :field_one => 'group 1' )
|
412
424
|
|
413
|
-
|
425
|
+
found = finder.acquire( @id )
|
426
|
+
expect( found ).to eq(@a)
|
414
427
|
|
415
|
-
|
416
|
-
|
417
|
-
expect( found ).to be_nil
|
428
|
+
found = finder.acquire( @uuid )
|
429
|
+
expect( found ).to eq(@b)
|
418
430
|
|
419
|
-
|
420
|
-
|
421
|
-
|
431
|
+
found = finder.acquire( @code )
|
432
|
+
expect( found ).to eq(nil) # Not in 'group 1'
|
433
|
+
end
|
422
434
|
|
423
|
-
|
424
|
-
|
425
|
-
|
435
|
+
# Early versions of the 'acquire'-backed methods always inadvertently
|
436
|
+
# performed two database calls, via a count then a true find. This was
|
437
|
+
# refactored to only make one call per attribute, but that in turn can
|
438
|
+
# be much improved via the AREL table to compose a single query that
|
439
|
+
# uses "OR" to get the database to check each attribute in order. Thus
|
440
|
+
# every test below expects exactly one database call only.
|
441
|
+
#
|
442
|
+
context 'only makes one database call when' do
|
426
443
|
|
427
|
-
|
444
|
+
it 'finding on the first attribute' do
|
445
|
+
count = spec_helper_count_database_calls_in do
|
446
|
+
found = RSpecModelFinderTest.acquire( @id )
|
447
|
+
expect( found ).to eq(@a)
|
448
|
+
end
|
428
449
|
|
429
|
-
|
430
|
-
|
431
|
-
expect( found ).to be_nil
|
450
|
+
expect( count ).to eq( 1 )
|
451
|
+
end
|
432
452
|
|
433
|
-
|
434
|
-
|
435
|
-
|
453
|
+
it 'finding on the second attribute' do
|
454
|
+
count = spec_helper_count_database_calls_in do
|
455
|
+
found = RSpecModelFinderTest.acquire( @uuid )
|
456
|
+
expect( found ).to eq(@b)
|
457
|
+
end
|
436
458
|
|
437
|
-
|
438
|
-
|
439
|
-
expect( found ).to eq( @scoped_3 )
|
459
|
+
expect( count ).to eq( 1 )
|
460
|
+
end
|
440
461
|
|
441
|
-
|
462
|
+
it 'finding on the third attribute' do
|
463
|
+
count = spec_helper_count_database_calls_in do
|
464
|
+
found = RSpecModelFinderTest.acquire( @code )
|
465
|
+
expect( found ).to eq(@c)
|
466
|
+
end
|
442
467
|
|
443
|
-
|
444
|
-
|
445
|
-
expect( found ).to be_nil
|
468
|
+
expect( count ).to eq( 1 )
|
469
|
+
end
|
446
470
|
|
447
|
-
|
448
|
-
|
449
|
-
|
471
|
+
it 'checking all three attributes but finding nothing' do
|
472
|
+
count = spec_helper_count_database_calls_in do
|
473
|
+
found = RSpecModelFinderTest.acquire( Hoodoo::UUID.generate )
|
474
|
+
expect( found ).to be_nil
|
475
|
+
end
|
450
476
|
|
451
|
-
|
452
|
-
|
453
|
-
|
477
|
+
expect( count ).to eq( 1 )
|
478
|
+
end
|
479
|
+
end
|
454
480
|
end
|
455
481
|
|
456
|
-
|
457
|
-
@session.scoping = { :authorised_uuids => [ 'uuid 1' ], :authorised_code => 'code 1' }
|
482
|
+
# ========================================================================
|
458
483
|
|
459
|
-
|
460
|
-
|
461
|
-
|
484
|
+
context '#acquire_in' do
|
485
|
+
before :each do
|
486
|
+
@scoped_1 = RSpecModelFinderTest.new
|
487
|
+
@scoped_1.id = 'id 1'
|
488
|
+
@scoped_1.uuid = 'uuid 1'
|
489
|
+
@scoped_1.code = 'code 1'
|
490
|
+
@scoped_1.field_one = 'scoped 1'
|
491
|
+
@scoped_1.save!
|
492
|
+
|
493
|
+
@scoped_2 = RSpecModelFinderTest.new
|
494
|
+
@scoped_2.id = 'id 2'
|
495
|
+
@scoped_2.uuid = 'uuid 1'
|
496
|
+
@scoped_2.code = 'code 2'
|
497
|
+
@scoped_2.field_one = 'scoped 2'
|
498
|
+
@scoped_2.save!
|
499
|
+
|
500
|
+
@scoped_3 = RSpecModelFinderTest.new
|
501
|
+
@scoped_3.id = 'id 3'
|
502
|
+
@scoped_3.uuid = 'uuid 2'
|
503
|
+
@scoped_3.code = 'code 2'
|
504
|
+
@scoped_3.field_one = 'scoped 3'
|
505
|
+
@scoped_3.save!
|
506
|
+
|
507
|
+
# Get a good-enough-for-test interaction which has a context
|
508
|
+
# that contains a Session we can modify.
|
509
|
+
|
510
|
+
@interaction = Hoodoo::Services::Middleware::Interaction.new( {}, nil )
|
511
|
+
@interaction.context = Hoodoo::Services::Context.new(
|
512
|
+
Hoodoo::Services::Session.new,
|
513
|
+
@interaction.context.request,
|
514
|
+
@interaction.context.response,
|
515
|
+
@interaction
|
516
|
+
)
|
517
|
+
|
518
|
+
@context = @interaction.context
|
519
|
+
@session = @interaction.context.session
|
520
|
+
end
|
462
521
|
|
463
|
-
|
464
|
-
found = RSpecModelFinderTest.where( :field_one => @scoped_1.field_one + '!' ).acquire_in( @context )
|
465
|
-
expect( found ).to be_nil
|
522
|
+
it 'knowns how to acquire' do
|
466
523
|
|
467
|
-
|
468
|
-
|
469
|
-
|
524
|
+
# Note the corresponding 'acquire_with' used Symbols and had a
|
525
|
+
# duplicated entry - we expect Strings and no duplicates here.
|
526
|
+
#
|
527
|
+
expect( RSpecModelFinderTest.acquired_with() ).to eq( [ 'uuid', 'code' ] )
|
470
528
|
|
471
|
-
|
472
|
-
found = RSpecModelFinderTest.where( :field_one => @scoped_3.field_one ).acquire_in( @context )
|
473
|
-
expect( found ).to be_nil
|
529
|
+
end
|
474
530
|
|
475
|
-
|
476
|
-
|
531
|
+
it 'finds with secure scopes from the class' do
|
532
|
+
@session.scoping = { :authorised_uuids => [ 'uuid 1' ], :authorised_code => 'code 1' }
|
477
533
|
|
478
|
-
|
479
|
-
|
480
|
-
|
534
|
+
@context.request.uri_path_components = [ @scoped_1.id ]
|
535
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
536
|
+
expect( found ).to eq( @scoped_1 )
|
481
537
|
|
482
|
-
|
483
|
-
|
484
|
-
|
538
|
+
@context.request.uri_path_components = [ @scoped_2.id ]
|
539
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
540
|
+
expect( found ).to be_nil
|
485
541
|
|
486
|
-
|
487
|
-
|
488
|
-
|
542
|
+
@context.request.uri_path_components = [ @scoped_3.id ]
|
543
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
544
|
+
expect( found ).to be_nil
|
489
545
|
|
490
|
-
|
491
|
-
found = RSpecModelFinderTest.where( :field_one => @scoped_3.field_one + '!' ).acquire_in( @context )
|
492
|
-
expect( found ).to be_nil
|
493
|
-
end
|
494
|
-
end
|
546
|
+
@session.scoping.authorised_code = 'code 2'
|
495
547
|
|
496
|
-
|
548
|
+
@context.request.uri_path_components = [ @scoped_1.id ]
|
549
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
550
|
+
expect( found ).to be_nil
|
497
551
|
|
498
|
-
|
499
|
-
|
500
|
-
|
552
|
+
@context.request.uri_path_components = [ @scoped_2.id ]
|
553
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
554
|
+
expect( found ).to eq( @scoped_2 )
|
501
555
|
|
502
|
-
|
503
|
-
|
556
|
+
@context.request.uri_path_components = [ @scoped_3.id ]
|
557
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
558
|
+
expect( found ).to be_nil
|
504
559
|
|
505
|
-
|
506
|
-
expect( finder ).to eq([@b])
|
507
|
-
expect( finder.dataset_size).to eq(3)
|
560
|
+
@session.scoping.authorised_uuids = [ 'uuid 2' ]
|
508
561
|
|
509
|
-
|
510
|
-
|
562
|
+
@context.request.uri_path_components = [ @scoped_1.id ]
|
563
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
564
|
+
expect( found ).to be_nil
|
511
565
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
end
|
516
|
-
end
|
566
|
+
@context.request.uri_path_components = [ @scoped_2.id ]
|
567
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
568
|
+
expect( found ).to be_nil
|
517
569
|
|
518
|
-
|
570
|
+
@context.request.uri_path_components = [ @scoped_3.id ]
|
571
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
572
|
+
expect( found ).to eq( @scoped_3 )
|
519
573
|
|
520
|
-
|
521
|
-
it 'lists with a normal count' do
|
522
|
-
finder = RSpecModelFinderTest.list( @list_params )
|
574
|
+
@session.scoping.authorised_uuids = [ 'uuid 1', 'uuid 2' ]
|
523
575
|
|
524
|
-
|
525
|
-
|
576
|
+
@context.request.uri_path_components = [ @scoped_1.id ]
|
577
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
578
|
+
expect( found ).to be_nil
|
526
579
|
|
527
|
-
|
528
|
-
|
580
|
+
@context.request.uri_path_components = [ @scoped_2.id ]
|
581
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
582
|
+
expect( found ).to eq( @scoped_2 )
|
529
583
|
|
530
|
-
|
584
|
+
@context.request.uri_path_components = [ @scoped_3.id ]
|
585
|
+
found = RSpecModelFinderTest.acquire_in( @context )
|
586
|
+
expect( found ).to eq( @scoped_3 )
|
587
|
+
end
|
531
588
|
|
532
|
-
|
533
|
-
|
589
|
+
it 'finds with secure scopes with a chain' do
|
590
|
+
@session.scoping = { :authorised_uuids => [ 'uuid 1' ], :authorised_code => 'code 1' }
|
534
591
|
|
535
|
-
|
536
|
-
|
592
|
+
@context.request.uri_path_components = [ @scoped_1.id ]
|
593
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_1.field_one ).acquire_in( @context )
|
594
|
+
expect( found ).to eq( @scoped_1 )
|
537
595
|
|
538
|
-
|
596
|
+
@context.request.uri_path_components = [ @scoped_1.id ]
|
597
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_1.field_one + '!' ).acquire_in( @context )
|
598
|
+
expect( found ).to be_nil
|
539
599
|
|
540
|
-
|
541
|
-
|
542
|
-
|
600
|
+
@context.request.uri_path_components = [ @scoped_2.id ]
|
601
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_2.field_one ).acquire_in( @context )
|
602
|
+
expect( found ).to be_nil
|
543
603
|
|
544
|
-
|
604
|
+
@context.request.uri_path_components = [ @scoped_3.id ]
|
605
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_3.field_one ).acquire_in( @context )
|
606
|
+
expect( found ).to be_nil
|
545
607
|
|
546
|
-
|
547
|
-
|
608
|
+
@session.scoping.authorised_uuids = [ 'uuid 1', 'uuid 2' ]
|
609
|
+
@session.scoping.authorised_code = 'code 2'
|
548
610
|
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
CREATE FUNCTION estimated_count(query text) RETURNS integer AS
|
553
|
-
$func$
|
554
|
-
DECLARE
|
555
|
-
rec record;
|
556
|
-
rows integer;
|
557
|
-
BEGIN
|
558
|
-
FOR rec IN EXECUTE 'EXPLAIN ' || query LOOP
|
559
|
-
rows := substring(rec."QUERY PLAN" FROM ' rows=([[:digit:]]+)');
|
560
|
-
EXIT WHEN rows IS NOT NULL;
|
561
|
-
END LOOP;
|
562
|
-
|
563
|
-
RETURN rows;
|
564
|
-
END
|
565
|
-
$func$ LANGUAGE plpgsql;
|
566
|
-
SQL
|
567
|
-
|
568
|
-
counter = Proc.new do | sql |
|
569
|
-
begin
|
570
|
-
ActiveRecord::Base.connection.execute(
|
571
|
-
"SELECT estimated_count('#{ sql}')"
|
572
|
-
).first[ 'estimated_count' ].to_i
|
573
|
-
rescue
|
574
|
-
nil
|
575
|
-
end
|
576
|
-
end
|
611
|
+
@context.request.uri_path_components = [ @scoped_1.id ]
|
612
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_1.field_one ).acquire_in( @context )
|
613
|
+
expect( found ).to be_nil
|
577
614
|
|
578
|
-
|
615
|
+
@context.request.uri_path_components = [ @scoped_2.id ]
|
616
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_2.field_one ).acquire_in( @context )
|
617
|
+
expect( found ).to eq( @scoped_2 )
|
579
618
|
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
end
|
619
|
+
@context.request.uri_path_components = [ @scoped_3.id ]
|
620
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_3.field_one ).acquire_in( @context )
|
621
|
+
expect( found ).to eq( @scoped_3 )
|
584
622
|
|
585
|
-
|
586
|
-
|
587
|
-
|
623
|
+
@context.request.uri_path_components = [ @scoped_3.id ]
|
624
|
+
found = RSpecModelFinderTest.where( :field_one => @scoped_3.field_one + '!' ).acquire_in( @context )
|
625
|
+
expect( found ).to be_nil
|
588
626
|
end
|
627
|
+
end
|
589
628
|
|
590
|
-
|
591
|
-
# pre-ANALYZE test, breaking the results.
|
592
|
-
#
|
593
|
-
context 'estimate', :order => :defined do
|
594
|
-
before :each do
|
595
|
-
@initial_count = RSpecModelFinderTest.count
|
596
|
-
|
597
|
-
# The outer 'before' code ensures an accurate initial count of 3,
|
598
|
-
# but we're going add in a few more unestimated items.
|
599
|
-
#
|
600
|
-
@uncounted1 = RSpecModelFinderTest.new.save!
|
601
|
-
@uncounted2 = RSpecModelFinderTest.new.save!
|
602
|
-
@uncounted3 = RSpecModelFinderTest.new.save!
|
629
|
+
# ========================================================================
|
603
630
|
|
604
|
-
|
605
|
-
|
631
|
+
context '#list' do
|
632
|
+
it 'lists with pages, offsets and counts' do
|
633
|
+
expect_any_instance_of( RSpecModelFinderTest ).to_not receive( :estimated_dataset_size )
|
606
634
|
|
607
|
-
|
608
|
-
|
609
|
-
result = finder.estimated_dataset_size
|
610
|
-
expect( result ).to eq( @initial_count ).or( eq( @subsequent_accurate_count ) )
|
611
|
-
end
|
635
|
+
@list_params.offset = 1 # 0 is first record
|
636
|
+
@list_params.limit = 1
|
612
637
|
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
# double-check something this important though.
|
617
|
-
#
|
618
|
-
it 'is accurate after ANALYZE' do
|
619
|
-
ActiveRecord::Base.connection.execute( 'ANALYZE' )
|
638
|
+
finder = RSpecModelFinderTest.order( :field_three => :asc ).list( @list_params )
|
639
|
+
expect( finder ).to eq([@b])
|
640
|
+
expect( finder.dataset_size).to eq(3)
|
620
641
|
|
621
|
-
|
622
|
-
|
623
|
-
expect( result ).to eq( @subsequent_accurate_count )
|
624
|
-
end
|
642
|
+
@list_params.offset = 1
|
643
|
+
@list_params.limit = 2
|
625
644
|
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
result = finder.estimated_dataset_size
|
630
|
-
expect( result ).to be_nil
|
631
|
-
end
|
645
|
+
finder = RSpecModelFinderTest.order( :field_three => :asc ).list( @list_params )
|
646
|
+
expect( finder ).to eq([@b, @c])
|
647
|
+
expect( finder.dataset_size).to eq(3)
|
632
648
|
end
|
633
649
|
end
|
634
|
-
end
|
635
650
|
|
636
|
-
|
651
|
+
# ========================================================================
|
637
652
|
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
653
|
+
context 'search' do
|
654
|
+
it 'searches without chain' do
|
655
|
+
@list_params.search_data = {
|
656
|
+
'field_one' => 'group 1'
|
657
|
+
}
|
643
658
|
|
644
|
-
|
645
|
-
|
659
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
660
|
+
expect( finder ).to eq([@b, @a])
|
646
661
|
|
647
|
-
|
648
|
-
|
649
|
-
|
662
|
+
@list_params.search_data = {
|
663
|
+
'field_one' => 'group 2'
|
664
|
+
}
|
650
665
|
|
651
|
-
|
652
|
-
|
666
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
667
|
+
expect( finder ).to eq([@c])
|
653
668
|
|
654
|
-
|
655
|
-
|
656
|
-
|
669
|
+
@list_params.search_data = {
|
670
|
+
'field_two' => 'TWO_A'
|
671
|
+
}
|
657
672
|
|
658
|
-
|
659
|
-
|
673
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
674
|
+
expect( finder ).to eq([@a])
|
660
675
|
|
661
|
-
|
662
|
-
|
663
|
-
|
676
|
+
@list_params.search_data = {
|
677
|
+
'field_three' => [ 'three a', 'three c' ]
|
678
|
+
}
|
664
679
|
|
665
|
-
|
666
|
-
|
680
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
681
|
+
expect( finder ).to eq([@c, @a])
|
667
682
|
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
683
|
+
@list_params.search_data = {
|
684
|
+
'field_two' => 'two c',
|
685
|
+
'field_three' => [ 'three a', 'three c' ]
|
686
|
+
}
|
672
687
|
|
673
|
-
|
674
|
-
|
688
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
689
|
+
expect( finder ).to eq([@c])
|
675
690
|
|
676
|
-
|
677
|
-
|
678
|
-
|
691
|
+
@list_params.search_data = {
|
692
|
+
'created_after' => @tn - 1.month
|
693
|
+
}
|
679
694
|
|
680
|
-
|
681
|
-
|
695
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
696
|
+
expect( finder ).to eq([@c])
|
682
697
|
|
683
|
-
|
684
|
-
|
685
|
-
|
698
|
+
@list_params.search_data = {
|
699
|
+
'created_before' => @tn - 1.month
|
700
|
+
}
|
686
701
|
|
687
|
-
|
688
|
-
|
702
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
703
|
+
expect( finder ).to eq([@a])
|
689
704
|
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
finder = RSpecModelFinderTest.list( @list_params )
|
695
|
-
expect( finder ).to eq([@b, @a])
|
696
|
-
end
|
705
|
+
@list_params.search_data = {
|
706
|
+
'created_before' => @tn - 1.month + 1.day
|
707
|
+
}
|
697
708
|
|
698
|
-
|
699
|
-
|
709
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
710
|
+
expect( finder ).to eq([@b, @a])
|
700
711
|
|
701
|
-
|
702
|
-
|
703
|
-
|
712
|
+
@list_params.search_data = {
|
713
|
+
'created_by' => @cb1
|
714
|
+
}
|
704
715
|
|
705
|
-
|
706
|
-
|
716
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
717
|
+
expect( finder ).to eq([@b, @a])
|
707
718
|
|
708
|
-
|
709
|
-
|
710
|
-
|
719
|
+
@list_params.search_data = {
|
720
|
+
'created_by' => @cb2
|
721
|
+
}
|
711
722
|
|
712
|
-
|
713
|
-
|
723
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
724
|
+
expect( finder ).to eq([@c])
|
725
|
+
end
|
714
726
|
|
715
|
-
|
716
|
-
|
717
|
-
}
|
727
|
+
it 'searches with chain' do
|
728
|
+
constraint = RSpecModelFinderTest.where( :field_one => 'group 1' )
|
718
729
|
|
719
|
-
|
720
|
-
|
730
|
+
@list_params.search_data = {
|
731
|
+
'field_one' => 'group 1'
|
732
|
+
}
|
721
733
|
|
722
|
-
|
723
|
-
|
724
|
-
}
|
734
|
+
finder = constraint.list( @list_params )
|
735
|
+
expect( finder ).to eq([@b, @a])
|
725
736
|
|
726
|
-
|
727
|
-
|
737
|
+
@list_params.search_data = {
|
738
|
+
'field_one' => 'group 2'
|
739
|
+
}
|
728
740
|
|
729
|
-
|
730
|
-
|
731
|
-
'field_three' => [ 'three a', 'three c' ]
|
732
|
-
}
|
741
|
+
finder = constraint.list( @list_params )
|
742
|
+
expect( finder ).to eq([])
|
733
743
|
|
734
|
-
|
735
|
-
|
744
|
+
@list_params.search_data = {
|
745
|
+
'field_two' => 'TWO_A'
|
746
|
+
}
|
736
747
|
|
737
|
-
|
738
|
-
|
739
|
-
}
|
748
|
+
finder = constraint.list( @list_params )
|
749
|
+
expect( finder ).to eq([@a])
|
740
750
|
|
741
|
-
|
742
|
-
|
751
|
+
@list_params.search_data = {
|
752
|
+
'field_three' => [ 'three a', 'three c' ]
|
753
|
+
}
|
743
754
|
|
744
|
-
|
745
|
-
|
746
|
-
}
|
755
|
+
finder = constraint.list( @list_params )
|
756
|
+
expect( finder ).to eq([@a])
|
747
757
|
|
748
|
-
|
749
|
-
|
758
|
+
@list_params.search_data = {
|
759
|
+
'field_two' => 'two c',
|
760
|
+
'field_three' => [ 'three a', 'three c' ]
|
761
|
+
}
|
750
762
|
|
751
|
-
|
752
|
-
|
753
|
-
}
|
763
|
+
finder = constraint.list( @list_params )
|
764
|
+
expect( finder ).to eq([])
|
754
765
|
|
755
|
-
|
756
|
-
|
757
|
-
|
758
|
-
end
|
766
|
+
@list_params.search_data = {
|
767
|
+
'created_after' => @tn - 1.month
|
768
|
+
}
|
759
769
|
|
760
|
-
|
770
|
+
finder = constraint.list( @list_params )
|
771
|
+
expect( finder ).to eq([])
|
761
772
|
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
'mapped_code' => @code
|
766
|
-
}
|
773
|
+
@list_params.search_data = {
|
774
|
+
'created_before' => @tn - 1.month
|
775
|
+
}
|
767
776
|
|
768
|
-
|
769
|
-
|
770
|
-
end
|
777
|
+
finder = constraint.list( @list_params )
|
778
|
+
expect( finder ).to eq([@a])
|
771
779
|
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
}
|
780
|
+
@list_params.search_data = {
|
781
|
+
'created_before' => @tn - 1.month + 1.day
|
782
|
+
}
|
776
783
|
|
777
|
-
|
778
|
-
|
779
|
-
end
|
784
|
+
finder = constraint.list( @list_params )
|
785
|
+
expect( finder ).to eq([@b, @a])
|
780
786
|
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
}
|
787
|
+
@list_params.search_data = {
|
788
|
+
'created_by' => @cb1
|
789
|
+
}
|
785
790
|
|
786
|
-
|
787
|
-
|
791
|
+
finder = constraint.list( @list_params )
|
792
|
+
expect( finder ).to eq([@b, @a])
|
788
793
|
|
789
|
-
|
790
|
-
|
791
|
-
|
794
|
+
@list_params.search_data = {
|
795
|
+
'created_by' => @cb2
|
796
|
+
}
|
792
797
|
|
793
|
-
|
794
|
-
|
798
|
+
finder = constraint.list( @list_params )
|
799
|
+
expect( finder ).to eq([])
|
800
|
+
end
|
795
801
|
end
|
796
802
|
|
797
|
-
|
798
|
-
@list_params.search_data = {
|
799
|
-
'field_two' => 'two a,something else,two c,more'
|
800
|
-
}
|
803
|
+
# ========================================================================
|
801
804
|
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
+
context 'helper-based search' do
|
806
|
+
it 'finds by mapped code' do
|
807
|
+
@list_params.search_data = {
|
808
|
+
'mapped_code' => @code
|
809
|
+
}
|
805
810
|
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
}
|
811
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
812
|
+
expect( finder ).to eq( [ @c_wh ] )
|
813
|
+
end
|
810
814
|
|
811
|
-
|
812
|
-
|
813
|
-
|
815
|
+
it 'finds by mapped field-one' do
|
816
|
+
@list_params.search_data = {
|
817
|
+
'mapped_field_one' => :'grOUp 1'
|
818
|
+
}
|
814
819
|
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
}
|
820
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
821
|
+
expect( finder ).to eq( [ @b_wh, @a_wh ] )
|
822
|
+
end
|
819
823
|
|
820
|
-
|
821
|
-
|
824
|
+
it 'finds by mapped, wildcard field-one' do
|
825
|
+
@list_params.search_data = {
|
826
|
+
'wild_field_one' => :'oUP '
|
827
|
+
}
|
822
828
|
|
823
|
-
|
824
|
-
|
825
|
-
}
|
829
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
830
|
+
expect( finder ).to eq( [ @c_wh, @b_wh, @a_wh ] )
|
826
831
|
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
end
|
832
|
+
@list_params.search_data = {
|
833
|
+
'wild_field_one' => :'o!p '
|
834
|
+
}
|
831
835
|
|
832
|
-
|
836
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
837
|
+
expect( finder ).to eq( [] )
|
838
|
+
end
|
833
839
|
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
}
|
840
|
+
it 'finds by comma-separated list' do
|
841
|
+
@list_params.search_data = {
|
842
|
+
'field_two' => 'two a,something else,two c,more'
|
843
|
+
}
|
839
844
|
|
840
|
-
|
841
|
-
|
842
|
-
|
845
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
846
|
+
expect( finder ).to eq( [ @c_wh, @a_wh ] )
|
847
|
+
end
|
843
848
|
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
849
|
+
it 'finds by Array' do
|
850
|
+
@list_params.search_data = {
|
851
|
+
'field_three' => [ 'hello', :'three b', 'three c', :there ]
|
852
|
+
}
|
848
853
|
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
end
|
854
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
855
|
+
expect( finder ).to eq( [ @c_wh, @b_wh ] )
|
856
|
+
end
|
853
857
|
|
854
|
-
|
858
|
+
it 'finds with framework override (to same column)' do
|
859
|
+
@list_params.search_data = {
|
860
|
+
'created_after' => @tn - 1.week
|
861
|
+
}
|
862
|
+
|
863
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
864
|
+
expect( finder ).to eq( [ @c_wh, @b_wh ] )
|
855
865
|
|
856
|
-
context 'as a Hoodoo::ActiveRecord::Base subclass and sub-subclass' do # (instead of explicitly including the Finder module)
|
857
|
-
context 'custom search' do
|
858
|
-
it 'on mapped_code' do
|
859
866
|
@list_params.search_data = {
|
860
|
-
'
|
867
|
+
'created_after' => @tn + 1.day
|
861
868
|
}
|
862
869
|
|
863
|
-
finder =
|
864
|
-
expect( finder ).to eq( [ @
|
870
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
871
|
+
expect( finder ).to eq( [ @c_wh ] )
|
872
|
+
end
|
865
873
|
|
866
|
-
|
867
|
-
|
874
|
+
it 'finds by framework override (to different column)' do
|
875
|
+
@list_params.search_data = {
|
876
|
+
'created_by' => 'b' # Maps to 'code' field, case insensitive
|
877
|
+
}
|
868
878
|
|
869
|
-
finder =
|
870
|
-
expect( finder ).to eq( [ @
|
879
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
880
|
+
expect( finder ).to eq( [ @b_wh ] )
|
871
881
|
end
|
872
882
|
end
|
873
883
|
|
884
|
+
# ========================================================================
|
885
|
+
|
874
886
|
context 'pure framework search' do
|
875
887
|
it 'on created_after' do
|
876
888
|
@list_params.search_data = {
|
877
889
|
'created_after' => @tn - 1.month
|
878
890
|
}
|
879
891
|
|
880
|
-
finder =
|
881
|
-
expect( finder ).to eq( [ @
|
882
|
-
|
883
|
-
finder = RSpecModelFinderSubclassWithoutSearchOrFilterATest.list( @list_params )
|
884
|
-
expect( finder ).to eq( [ @c_sc_wosf_a ] )
|
885
|
-
|
886
|
-
finder = RSpecModelFinderSubclassWithoutSearchOrFilterBTest.list( @list_params )
|
887
|
-
expect( finder ).to eq( [ @c_sc_wosf_b ] )
|
892
|
+
finder = RSpecModelFinderWithoutSearchOrFilterTest.list( @list_params )
|
893
|
+
expect( finder ).to eq( [ @c_wosf ] )
|
888
894
|
end
|
889
895
|
|
890
896
|
it 'on created_before' do
|
@@ -892,279 +898,316 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
892
898
|
'created_before' => @tn - 1.month
|
893
899
|
}
|
894
900
|
|
895
|
-
finder =
|
896
|
-
expect( finder ).to eq( [ @
|
901
|
+
finder = RSpecModelFinderWithoutSearchOrFilterTest.list( @list_params )
|
902
|
+
expect( finder ).to eq( [ @a_wosf ] )
|
903
|
+
end
|
897
904
|
|
898
|
-
|
899
|
-
|
905
|
+
it 'on created_by' do
|
906
|
+
@list_params.search_data = {
|
907
|
+
'created_by' => @cb1
|
908
|
+
}
|
900
909
|
|
901
|
-
finder =
|
902
|
-
expect( finder ).to eq( [ @
|
910
|
+
finder = RSpecModelFinderWithoutSearchOrFilterTest.list( @list_params )
|
911
|
+
expect( finder ).to eq( [ @b_wosf, @a_wosf ] )
|
903
912
|
end
|
904
913
|
end
|
905
|
-
end
|
906
914
|
|
907
|
-
|
915
|
+
# ========================================================================
|
908
916
|
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
917
|
+
context 'as a Hoodoo::ActiveRecord::Base subclass and sub-subclass' do # (instead of explicitly including the Finder module)
|
918
|
+
context 'custom search' do
|
919
|
+
it 'on mapped_code' do
|
920
|
+
@list_params.search_data = {
|
921
|
+
'mapped_code' => @code
|
922
|
+
}
|
914
923
|
|
915
|
-
|
916
|
-
|
924
|
+
finder = RSpecModelFinderSubclassTest.list( @list_params )
|
925
|
+
expect( finder ).to eq( [ @c_sc ] )
|
917
926
|
|
918
|
-
|
919
|
-
|
920
|
-
}
|
927
|
+
finder = RSpecModelFinderSubclassATest.list( @list_params )
|
928
|
+
expect( finder ).to eq( [ @c_sc_a ] )
|
921
929
|
|
922
|
-
|
923
|
-
|
930
|
+
finder = RSpecModelFinderSubclassBTest.list( @list_params )
|
931
|
+
expect( finder ).to eq( [ @c_sc_b ] )
|
932
|
+
end
|
933
|
+
end
|
924
934
|
|
925
|
-
|
926
|
-
|
927
|
-
|
935
|
+
context 'pure framework search' do
|
936
|
+
it 'on created_after' do
|
937
|
+
@list_params.search_data = {
|
938
|
+
'created_after' => @tn - 1.month
|
939
|
+
}
|
928
940
|
|
929
|
-
|
930
|
-
|
941
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterTest.list( @list_params )
|
942
|
+
expect( finder ).to eq( [ @c_sc_wosf ] )
|
931
943
|
|
932
|
-
|
933
|
-
|
934
|
-
}
|
944
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterATest.list( @list_params )
|
945
|
+
expect( finder ).to eq( [ @c_sc_wosf_a ] )
|
935
946
|
|
936
|
-
|
937
|
-
|
947
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterBTest.list( @list_params )
|
948
|
+
expect( finder ).to eq( [ @c_sc_wosf_b ] )
|
949
|
+
end
|
938
950
|
|
939
|
-
|
940
|
-
|
941
|
-
|
942
|
-
|
951
|
+
it 'on created_before' do
|
952
|
+
@list_params.search_data = {
|
953
|
+
'created_before' => @tn - 1.month
|
954
|
+
}
|
943
955
|
|
944
|
-
|
945
|
-
|
956
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterTest.list( @list_params )
|
957
|
+
expect( finder ).to eq( [ @a_sc_wosf ] )
|
946
958
|
|
947
|
-
|
948
|
-
|
949
|
-
}
|
959
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterATest.list( @list_params )
|
960
|
+
expect( finder ).to eq( [ @a_sc_wosf_a ] )
|
950
961
|
|
951
|
-
|
952
|
-
|
962
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterBTest.list( @list_params )
|
963
|
+
expect( finder ).to eq( [ @a_sc_wosf_b ] )
|
964
|
+
end
|
965
|
+
end
|
966
|
+
end
|
953
967
|
|
954
|
-
|
955
|
-
'created_before' => @tn - 1.month
|
956
|
-
}
|
968
|
+
# ========================================================================
|
957
969
|
|
958
|
-
|
959
|
-
|
970
|
+
context 'filter' do
|
971
|
+
it 'filters without chain' do
|
972
|
+
@list_params.filter_data = {
|
973
|
+
'field_two' => 'two a'
|
974
|
+
}
|
960
975
|
|
961
|
-
|
962
|
-
|
963
|
-
}
|
976
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
977
|
+
expect( finder ).to eq([@c, @b])
|
964
978
|
|
965
|
-
|
966
|
-
|
967
|
-
|
979
|
+
@list_params.filter_data = {
|
980
|
+
'field_three' => 'three c'
|
981
|
+
}
|
968
982
|
|
969
|
-
|
983
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
984
|
+
expect( finder ).to eq([@b, @a])
|
970
985
|
|
971
|
-
|
972
|
-
|
986
|
+
@list_params.filter_data = {
|
987
|
+
'field_one' => [ 'group 1', 'group 2' ]
|
988
|
+
}
|
973
989
|
|
974
|
-
|
990
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
991
|
+
expect( finder ).to eq([])
|
975
992
|
|
976
|
-
|
977
|
-
|
978
|
-
|
993
|
+
@list_params.filter_data = {
|
994
|
+
'field_one' => [ 'group 2' ]
|
995
|
+
}
|
979
996
|
|
980
|
-
|
981
|
-
|
997
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
998
|
+
expect( finder ).to eq([@b, @a])
|
982
999
|
|
983
|
-
|
984
|
-
|
985
|
-
|
1000
|
+
@list_params.filter_data = {
|
1001
|
+
'field_one' => [ 'group 2' ],
|
1002
|
+
'field_three' => 'three a'
|
1003
|
+
}
|
986
1004
|
|
987
|
-
|
988
|
-
|
1005
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
1006
|
+
expect( finder ).to eq([@b])
|
989
1007
|
|
990
|
-
|
991
|
-
|
992
|
-
|
1008
|
+
@list_params.filter_data = {
|
1009
|
+
'created_after' => @tn - 1.month
|
1010
|
+
}
|
993
1011
|
|
994
|
-
|
995
|
-
|
1012
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
1013
|
+
expect( finder ).to eq([@b, @a])
|
996
1014
|
|
997
|
-
|
998
|
-
|
999
|
-
|
1015
|
+
@list_params.filter_data = {
|
1016
|
+
'created_before' => @tn - 1.month
|
1017
|
+
}
|
1000
1018
|
|
1001
|
-
|
1002
|
-
|
1019
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
1020
|
+
expect( finder ).to eq([@c, @b])
|
1003
1021
|
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
}
|
1022
|
+
@list_params.filter_data = {
|
1023
|
+
'created_before' => @tn - 1.month + 1.day
|
1024
|
+
}
|
1008
1025
|
|
1009
|
-
|
1010
|
-
|
1026
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
1027
|
+
expect( finder ).to eq([@c])
|
1011
1028
|
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1029
|
+
@list_params.filter_data = {
|
1030
|
+
'created_by' => @cb1
|
1031
|
+
}
|
1015
1032
|
|
1016
|
-
|
1017
|
-
|
1033
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
1034
|
+
expect( finder ).to eq([@c])
|
1018
1035
|
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1036
|
+
@list_params.filter_data = {
|
1037
|
+
'created_by' => @cb2
|
1038
|
+
}
|
1022
1039
|
|
1023
|
-
|
1024
|
-
|
1040
|
+
finder = RSpecModelFinderTest.list( @list_params )
|
1041
|
+
expect( finder ).to eq([@b, @a])
|
1042
|
+
end
|
1025
1043
|
|
1026
|
-
|
1027
|
-
'created_before' => @tn - 1.month + 1.day
|
1028
|
-
}
|
1044
|
+
it 'filters with chain' do
|
1029
1045
|
|
1030
|
-
|
1031
|
-
|
1032
|
-
end
|
1033
|
-
end
|
1046
|
+
# Remember, the constraint is *inclusive* unlike all the
|
1047
|
+
# subsequent filters which *exclude*.
|
1034
1048
|
|
1035
|
-
|
1049
|
+
constraint = RSpecModelFinderTest.where( :field_one => 'group 2' )
|
1036
1050
|
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
# a finder-level, the tests here have a chance of catching that.
|
1051
|
+
@list_params.filter_data = {
|
1052
|
+
'field_two' => 'two a'
|
1053
|
+
}
|
1041
1054
|
|
1042
|
-
|
1043
|
-
|
1044
|
-
@list_params.filter_data = {
|
1045
|
-
'mapped_code' => @code
|
1046
|
-
}
|
1055
|
+
finder = constraint.list( @list_params )
|
1056
|
+
expect( finder ).to eq([@c])
|
1047
1057
|
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1058
|
+
@list_params.filter_data = {
|
1059
|
+
'field_three' => 'three c'
|
1060
|
+
}
|
1051
1061
|
|
1052
|
-
|
1053
|
-
|
1054
|
-
'mapped_field_one' => :'grOUp 1'
|
1055
|
-
}
|
1062
|
+
finder = constraint.list( @list_params )
|
1063
|
+
expect( finder ).to eq([])
|
1056
1064
|
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1065
|
+
@list_params.filter_data = {
|
1066
|
+
'field_one' => [ 'group 1', 'group 2' ]
|
1067
|
+
}
|
1060
1068
|
|
1061
|
-
|
1062
|
-
|
1063
|
-
'wild_field_one' => :'oUP '
|
1064
|
-
}
|
1069
|
+
finder = constraint.list( @list_params )
|
1070
|
+
expect( finder ).to eq([])
|
1065
1071
|
|
1066
|
-
|
1067
|
-
|
1072
|
+
@list_params.filter_data = {
|
1073
|
+
'field_one' => [ 'group 2' ]
|
1074
|
+
}
|
1068
1075
|
|
1069
|
-
|
1070
|
-
|
1071
|
-
}
|
1076
|
+
finder = constraint.list( @list_params )
|
1077
|
+
expect( finder ).to eq([])
|
1072
1078
|
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1079
|
+
@list_params.filter_data = {
|
1080
|
+
'field_one' => [ 'group 2' ],
|
1081
|
+
'field_three' => 'three a'
|
1082
|
+
}
|
1076
1083
|
|
1077
|
-
|
1078
|
-
|
1079
|
-
'field_two' => 'two a,something else,two c,more'
|
1080
|
-
}
|
1084
|
+
finder = constraint.list( @list_params )
|
1085
|
+
expect( finder ).to eq([])
|
1081
1086
|
|
1082
|
-
|
1083
|
-
|
1084
|
-
|
1087
|
+
@list_params.filter_data = {
|
1088
|
+
'created_after' => @tn - 1.month
|
1089
|
+
}
|
1085
1090
|
|
1086
|
-
|
1087
|
-
|
1088
|
-
'field_three' => [ 'hello', :'three b', 'three c', :there ]
|
1089
|
-
}
|
1091
|
+
finder = constraint.list( @list_params )
|
1092
|
+
expect( finder ).to eq([])
|
1090
1093
|
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
+
@list_params.filter_data = {
|
1095
|
+
'created_before' => @tn - 1.month
|
1096
|
+
}
|
1094
1097
|
|
1095
|
-
|
1096
|
-
|
1097
|
-
'created_after' => @tn - 1.week
|
1098
|
-
}
|
1098
|
+
finder = constraint.list( @list_params )
|
1099
|
+
expect( finder ).to eq([@c])
|
1099
1100
|
|
1100
|
-
|
1101
|
-
|
1101
|
+
@list_params.filter_data = {
|
1102
|
+
'created_before' => @tn - 1.month + 1.day
|
1103
|
+
}
|
1102
1104
|
|
1103
|
-
|
1104
|
-
|
1105
|
-
}
|
1105
|
+
finder = constraint.list( @list_params )
|
1106
|
+
expect( finder ).to eq([@c])
|
1106
1107
|
|
1107
|
-
|
1108
|
-
|
1109
|
-
|
1110
|
-
end
|
1108
|
+
@list_params.filter_data = {
|
1109
|
+
'created_by' => @cb1
|
1110
|
+
}
|
1111
1111
|
|
1112
|
-
|
1112
|
+
finder = constraint.list( @list_params )
|
1113
|
+
expect( finder ).to eq([@c])
|
1113
1114
|
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
'created_after' => @tn - 1.month
|
1118
|
-
}
|
1115
|
+
@list_params.filter_data = {
|
1116
|
+
'created_by' => @cb2
|
1117
|
+
}
|
1119
1118
|
|
1120
|
-
|
1121
|
-
|
1119
|
+
finder = constraint.list( @list_params )
|
1120
|
+
expect( finder ).to eq([])
|
1121
|
+
end
|
1122
1122
|
end
|
1123
1123
|
|
1124
|
-
|
1125
|
-
@list_params.filter_data = {
|
1126
|
-
'created_before' => @tn - 1.month
|
1127
|
-
}
|
1124
|
+
# ========================================================================
|
1128
1125
|
|
1129
|
-
|
1130
|
-
|
1131
|
-
end
|
1132
|
-
|
1126
|
+
# This set of copy-and-modify tests based on the helper-based search tests
|
1127
|
+
# earlier seems somewhat redundant but should anyone accidentally decouple
|
1128
|
+
# the search/filter back-end processing and introduce some sort of error
|
1129
|
+
# at a finder-level, the tests here have a chance of catching that.
|
1130
|
+
#
|
1131
|
+
context 'helper-based filtering' do
|
1132
|
+
it 'filters by mapped code' do
|
1133
|
+
@list_params.filter_data = {
|
1134
|
+
'mapped_code' => @code
|
1135
|
+
}
|
1133
1136
|
|
1134
|
-
|
1137
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1138
|
+
expect( finder ).to eq( [ @b_wh, @a_wh ] )
|
1139
|
+
end
|
1135
1140
|
|
1136
|
-
|
1137
|
-
context 'custom filter' do
|
1138
|
-
it 'on mapped_code' do
|
1141
|
+
it 'filters by mapped field-one' do
|
1139
1142
|
@list_params.filter_data = {
|
1140
|
-
'
|
1143
|
+
'mapped_field_one' => :'grOUp 1'
|
1144
|
+
}
|
1145
|
+
|
1146
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1147
|
+
expect( finder ).to eq( [ @c_wh ] )
|
1148
|
+
end
|
1149
|
+
|
1150
|
+
it 'filters by mapped, wildcard field-one' do
|
1151
|
+
@list_params.filter_data = {
|
1152
|
+
'wild_field_one' => :'oUP '
|
1153
|
+
}
|
1154
|
+
|
1155
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1156
|
+
expect( finder ).to eq( [] )
|
1157
|
+
|
1158
|
+
@list_params.filter_data = {
|
1159
|
+
'wild_field_one' => :'o!p '
|
1160
|
+
}
|
1161
|
+
|
1162
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1163
|
+
expect( finder ).to eq( [ @c_wh, @b_wh, @a_wh ] )
|
1164
|
+
end
|
1165
|
+
|
1166
|
+
it 'filters by comma-separated list' do
|
1167
|
+
@list_params.filter_data = {
|
1168
|
+
'field_two' => 'two a,something else,two c,more'
|
1169
|
+
}
|
1170
|
+
|
1171
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1172
|
+
expect( finder ).to eq( [ @b_wh ] )
|
1173
|
+
end
|
1174
|
+
|
1175
|
+
it 'filters by Array' do
|
1176
|
+
@list_params.filter_data = {
|
1177
|
+
'field_three' => [ 'hello', :'three b', 'three c', :there ]
|
1178
|
+
}
|
1179
|
+
|
1180
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1181
|
+
expect( finder ).to eq( [ @a_wh ] )
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
it 'filters with framework override' do
|
1185
|
+
@list_params.filter_data = {
|
1186
|
+
'created_after' => @tn - 1.week
|
1141
1187
|
}
|
1142
1188
|
|
1143
|
-
finder =
|
1144
|
-
expect( finder ).to eq( [ @
|
1189
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1190
|
+
expect( finder ).to eq( [ @a_wh ] )
|
1145
1191
|
|
1146
|
-
|
1147
|
-
|
1192
|
+
@list_params.filter_data = {
|
1193
|
+
'created_after' => @tn + 1.day
|
1194
|
+
}
|
1148
1195
|
|
1149
|
-
finder =
|
1150
|
-
expect( finder ).to eq( [ @
|
1196
|
+
finder = RSpecModelFinderTestWithHelpers.list( @list_params )
|
1197
|
+
expect( finder ).to eq( [ @b_wh, @a_wh ] )
|
1151
1198
|
end
|
1152
1199
|
end
|
1153
1200
|
|
1201
|
+
# ========================================================================
|
1202
|
+
|
1154
1203
|
context 'pure framework filter' do
|
1155
1204
|
it 'on created_after' do
|
1156
1205
|
@list_params.filter_data = {
|
1157
1206
|
'created_after' => @tn - 1.month
|
1158
1207
|
}
|
1159
1208
|
|
1160
|
-
finder =
|
1161
|
-
expect( finder ).to eq( [ @
|
1162
|
-
|
1163
|
-
finder = RSpecModelFinderSubclassWithoutSearchOrFilterATest.list( @list_params )
|
1164
|
-
expect( finder ).to eq( [ @b_sc_wosf_a, @a_sc_wosf_a ] )
|
1165
|
-
|
1166
|
-
finder = RSpecModelFinderSubclassWithoutSearchOrFilterBTest.list( @list_params )
|
1167
|
-
expect( finder ).to eq( [ @b_sc_wosf_b, @a_sc_wosf_b ] )
|
1209
|
+
finder = RSpecModelFinderWithoutSearchOrFilterTest.list( @list_params )
|
1210
|
+
expect( finder ).to eq( [ @b_wosf, @a_wosf ] )
|
1168
1211
|
end
|
1169
1212
|
|
1170
1213
|
it 'on created_before' do
|
@@ -1172,159 +1215,230 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
1172
1215
|
'created_before' => @tn - 1.month
|
1173
1216
|
}
|
1174
1217
|
|
1175
|
-
finder =
|
1176
|
-
expect( finder ).to eq( [ @
|
1218
|
+
finder = RSpecModelFinderWithoutSearchOrFilterTest.list( @list_params )
|
1219
|
+
expect( finder ).to eq( [ @c_wosf, @b_wosf ] )
|
1220
|
+
end
|
1177
1221
|
|
1178
|
-
|
1179
|
-
|
1222
|
+
it 'on created_by' do
|
1223
|
+
@list_params.filter_data = {
|
1224
|
+
'created_by' => @cb1
|
1225
|
+
}
|
1180
1226
|
|
1181
|
-
finder =
|
1182
|
-
expect( finder ).to eq( [ @
|
1227
|
+
finder = RSpecModelFinderWithoutSearchOrFilterTest.list( @list_params )
|
1228
|
+
expect( finder ).to eq( [ @c_wosf ] )
|
1183
1229
|
end
|
1184
1230
|
end
|
1185
|
-
end
|
1186
1231
|
|
1187
|
-
|
1232
|
+
# ========================================================================
|
1188
1233
|
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
@scoped_1.field_one = 'scoped 1'
|
1196
|
-
@scoped_1.created_at = @tn - 1.year
|
1197
|
-
@scoped_1.save!
|
1198
|
-
|
1199
|
-
@scoped_2 = RSpecModelFinderTest.new
|
1200
|
-
@scoped_2.id = 'id 2'
|
1201
|
-
@scoped_2.uuid = 'uuid 1'
|
1202
|
-
@scoped_2.code = 'code 2'
|
1203
|
-
@scoped_2.field_one = 'scoped 2'
|
1204
|
-
@scoped_2.save!
|
1205
|
-
|
1206
|
-
@scoped_3 = RSpecModelFinderTest.new
|
1207
|
-
@scoped_3.id = 'id 3'
|
1208
|
-
@scoped_3.uuid = 'uuid 2'
|
1209
|
-
@scoped_3.code = 'code 2'
|
1210
|
-
@scoped_3.field_one = 'scoped 3'
|
1211
|
-
@scoped_3.save!
|
1212
|
-
|
1213
|
-
# Get a good-enough-for-test interaction which has a context
|
1214
|
-
# that contains a Session we can modify.
|
1215
|
-
|
1216
|
-
@interaction = Hoodoo::Services::Middleware::Interaction.new( {}, nil )
|
1217
|
-
@interaction.context = Hoodoo::Services::Context.new(
|
1218
|
-
Hoodoo::Services::Session.new,
|
1219
|
-
@interaction.context.request,
|
1220
|
-
@interaction.context.response,
|
1221
|
-
@interaction
|
1222
|
-
)
|
1234
|
+
context 'as a Hoodoo::ActiveRecord::Base subclass and sub-subclass' do # (instead of explicitly including the Finder module)
|
1235
|
+
context 'custom filter' do
|
1236
|
+
it 'on mapped_code' do
|
1237
|
+
@list_params.filter_data = {
|
1238
|
+
'mapped_code' => @code
|
1239
|
+
}
|
1223
1240
|
|
1224
|
-
|
1225
|
-
|
1226
|
-
end
|
1241
|
+
finder = RSpecModelFinderSubclassTest.list( @list_params )
|
1242
|
+
expect( finder ).to eq( [ @b_sc, @a_sc ] )
|
1227
1243
|
|
1228
|
-
|
1229
|
-
|
1244
|
+
finder = RSpecModelFinderSubclassATest.list( @list_params )
|
1245
|
+
expect( finder ).to eq( [ @b_sc_a, @a_sc_a ] )
|
1230
1246
|
|
1231
|
-
|
1232
|
-
|
1247
|
+
finder = RSpecModelFinderSubclassBTest.list( @list_params )
|
1248
|
+
expect( finder ).to eq( [ @b_sc_b, @a_sc_b ] )
|
1249
|
+
end
|
1250
|
+
end
|
1251
|
+
|
1252
|
+
context 'pure framework filter' do
|
1253
|
+
it 'on created_after' do
|
1254
|
+
@list_params.filter_data = {
|
1255
|
+
'created_after' => @tn - 1.month
|
1256
|
+
}
|
1257
|
+
|
1258
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterTest.list( @list_params )
|
1259
|
+
expect( finder ).to eq( [ @b_sc_wosf, @a_sc_wosf ] )
|
1233
1260
|
|
1234
|
-
|
1261
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterATest.list( @list_params )
|
1262
|
+
expect( finder ).to eq( [ @b_sc_wosf_a, @a_sc_wosf_a ] )
|
1235
1263
|
|
1236
|
-
|
1237
|
-
|
1264
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterBTest.list( @list_params )
|
1265
|
+
expect( finder ).to eq( [ @b_sc_wosf_b, @a_sc_wosf_b ] )
|
1266
|
+
end
|
1238
1267
|
|
1239
|
-
|
1268
|
+
it 'on created_before' do
|
1269
|
+
@list_params.filter_data = {
|
1270
|
+
'created_before' => @tn - 1.month
|
1271
|
+
}
|
1240
1272
|
|
1241
|
-
|
1242
|
-
|
1273
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterTest.list( @list_params )
|
1274
|
+
expect( finder ).to eq( [ @c_sc_wosf, @b_sc_wosf ] )
|
1243
1275
|
|
1244
|
-
|
1276
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterATest.list( @list_params )
|
1277
|
+
expect( finder ).to eq( [ @c_sc_wosf_a, @b_sc_wosf_a ] )
|
1245
1278
|
|
1246
|
-
|
1247
|
-
|
1279
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterBTest.list( @list_params )
|
1280
|
+
expect( finder ).to eq( [ @c_sc_wosf_b, @b_sc_wosf_b ] )
|
1281
|
+
end
|
1248
1282
|
|
1249
|
-
|
1250
|
-
|
1283
|
+
it 'on created_by' do
|
1284
|
+
@list_params.filter_data = {
|
1285
|
+
'created_by' => @cb2
|
1286
|
+
}
|
1251
1287
|
|
1252
|
-
|
1253
|
-
|
1288
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterTest.list( @list_params )
|
1289
|
+
expect( finder ).to eq( [ @b_sc_wosf, @a_sc_wosf ] )
|
1254
1290
|
|
1255
|
-
|
1256
|
-
|
1291
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterATest.list( @list_params )
|
1292
|
+
expect( finder ).to eq( [ @b_sc_wosf_a, @a_sc_wosf_a ] )
|
1257
1293
|
|
1258
|
-
|
1259
|
-
|
1294
|
+
finder = RSpecModelFinderSubclassWithoutSearchOrFilterBTest.list( @list_params )
|
1295
|
+
expect( finder ).to eq( [ @b_sc_wosf_b, @a_sc_wosf_b ] )
|
1296
|
+
end
|
1297
|
+
end
|
1260
1298
|
end
|
1261
1299
|
|
1262
|
-
|
1263
|
-
@session.scoping = { :authorised_uuids => [ 'uuid 1' ], :authorised_code => 'code 1' }
|
1300
|
+
# ========================================================================
|
1264
1301
|
|
1265
|
-
|
1266
|
-
|
1302
|
+
context '#list_in' do
|
1303
|
+
before :each do
|
1304
|
+
@scoped_1 = RSpecModelFinderTest.new
|
1305
|
+
@scoped_1.id = 'id 1'
|
1306
|
+
@scoped_1.uuid = 'uuid 1'
|
1307
|
+
@scoped_1.code = 'code 1'
|
1308
|
+
@scoped_1.field_one = 'scoped 1'
|
1309
|
+
@scoped_1.created_at = @tn - 1.year
|
1310
|
+
@scoped_1.save!
|
1311
|
+
|
1312
|
+
@scoped_2 = RSpecModelFinderTest.new
|
1313
|
+
@scoped_2.id = 'id 2'
|
1314
|
+
@scoped_2.uuid = 'uuid 1'
|
1315
|
+
@scoped_2.code = 'code 2'
|
1316
|
+
@scoped_2.field_one = 'scoped 2'
|
1317
|
+
@scoped_2.save!
|
1318
|
+
|
1319
|
+
@scoped_3 = RSpecModelFinderTest.new
|
1320
|
+
@scoped_3.id = 'id 3'
|
1321
|
+
@scoped_3.uuid = 'uuid 2'
|
1322
|
+
@scoped_3.code = 'code 2'
|
1323
|
+
@scoped_3.field_one = 'scoped 3'
|
1324
|
+
@scoped_3.save!
|
1325
|
+
|
1326
|
+
# Get a good-enough-for-test interaction which has a context
|
1327
|
+
# that contains a Session we can modify.
|
1328
|
+
|
1329
|
+
@interaction = Hoodoo::Services::Middleware::Interaction.new( {}, nil )
|
1330
|
+
@interaction.context = Hoodoo::Services::Context.new(
|
1331
|
+
Hoodoo::Services::Session.new,
|
1332
|
+
@interaction.context.request,
|
1333
|
+
@interaction.context.response,
|
1334
|
+
@interaction
|
1335
|
+
)
|
1336
|
+
|
1337
|
+
@context = @interaction.context
|
1338
|
+
@session = @interaction.context.session
|
1339
|
+
end
|
1267
1340
|
|
1268
|
-
|
1269
|
-
|
1341
|
+
it 'lists with secure scopes from the class' do
|
1342
|
+
@session.scoping = { :authorised_uuids => [ 'uuid 1' ], :authorised_code => 'code 1' }
|
1270
1343
|
|
1271
|
-
|
1272
|
-
|
1344
|
+
list = RSpecModelFinderTest.list_in( @context )
|
1345
|
+
expect( list ).to eq( [ @scoped_1 ] )
|
1273
1346
|
|
1274
|
-
|
1275
|
-
expect( list ).to eq( [] )
|
1347
|
+
@session.scoping.authorised_code = 'code 2'
|
1276
1348
|
|
1277
|
-
|
1278
|
-
|
1349
|
+
list = RSpecModelFinderTest.list_in( @context )
|
1350
|
+
expect( list ).to eq( [ @scoped_2 ] )
|
1279
1351
|
|
1280
|
-
|
1281
|
-
expect( list ).to eq( [ @scoped_2 ] )
|
1352
|
+
@session.scoping.authorised_uuids = [ 'uuid 2' ]
|
1282
1353
|
|
1283
|
-
|
1284
|
-
|
1354
|
+
list = RSpecModelFinderTest.list_in( @context )
|
1355
|
+
expect( list ).to eq( [ @scoped_3 ] )
|
1285
1356
|
|
1286
|
-
|
1287
|
-
expect( list ).to eq( [ @scoped_2, @scoped_3 ] )
|
1357
|
+
@session.scoping.authorised_uuids = [ 'uuid 1', 'uuid 2' ]
|
1288
1358
|
|
1289
|
-
|
1290
|
-
|
1291
|
-
end
|
1292
|
-
end
|
1359
|
+
# OK, so these test 'with a chain' too... It's just convenient to (re-)cover
|
1360
|
+
# that aspect here.
|
1293
1361
|
|
1294
|
-
|
1362
|
+
list = RSpecModelFinderTest.list_in( @context ).reorder( 'field_one' => 'asc' )
|
1363
|
+
expect( list ).to eq( [ @scoped_2, @scoped_3 ] )
|
1295
1364
|
|
1296
|
-
|
1297
|
-
|
1298
|
-
expect( $stderr ).to receive( :puts ).once
|
1299
|
-
expect( RSpecModelFinderTest ).to receive( :acquire ).once.with( 21 )
|
1300
|
-
RSpecModelFinderTest.polymorphic_find( RSpecModelFinderTest, 21 )
|
1301
|
-
end
|
1365
|
+
list = RSpecModelFinderTest.list_in( @context ).reorder( 'field_one' => 'desc' )
|
1366
|
+
expect( list ).to eq( [ @scoped_3, @scoped_2 ] )
|
1302
1367
|
|
1303
|
-
|
1304
|
-
|
1305
|
-
expect( RSpecModelFinderTest ).to receive( :acquire_with ).once.with( :uuid, :code )
|
1306
|
-
RSpecModelFinderTest.polymorphic_id_fields( :uuid, :code )
|
1307
|
-
end
|
1368
|
+
list = RSpecModelFinderTest.reorder( 'field_one' => 'asc' ).list_in( @context )
|
1369
|
+
expect( list ).to eq( [ @scoped_2, @scoped_3 ] )
|
1308
1370
|
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1371
|
+
list = RSpecModelFinderTest.reorder( 'field_one' => 'desc' ).list_in( @context )
|
1372
|
+
expect( list ).to eq( [ @scoped_3, @scoped_2 ] )
|
1373
|
+
end
|
1374
|
+
|
1375
|
+
it 'finds with secure scopes with a chain' do
|
1376
|
+
@session.scoping = { :authorised_uuids => [ 'uuid 1' ], :authorised_code => 'code 1' }
|
1377
|
+
|
1378
|
+
list = RSpecModelFinderTest.where( :field_one => @scoped_1.field_one ).list_in( @context )
|
1379
|
+
expect( list ).to eq( [ @scoped_1 ] )
|
1380
|
+
|
1381
|
+
list = RSpecModelFinderTest.where( :field_one => @scoped_1.field_one + '!' ).list_in( @context )
|
1382
|
+
expect( list ).to eq( [] )
|
1383
|
+
|
1384
|
+
list = RSpecModelFinderTest.list_in( @context ).where( :field_one => @scoped_1.field_one )
|
1385
|
+
expect( list ).to eq( [ @scoped_1 ] )
|
1386
|
+
|
1387
|
+
list = RSpecModelFinderTest.list_in( @context ).where( :field_one => @scoped_1.field_one + '!' )
|
1388
|
+
expect( list ).to eq( [] )
|
1389
|
+
|
1390
|
+
@session.scoping.authorised_uuids = [ 'uuid 1', 'uuid 2' ]
|
1391
|
+
@session.scoping.authorised_code = 'code 2'
|
1392
|
+
|
1393
|
+
list = RSpecModelFinderTest.where( :field_one => [ @scoped_1.field_one, @scoped_2.field_one ] ).list_in( @context )
|
1394
|
+
expect( list ).to eq( [ @scoped_2 ] )
|
1395
|
+
|
1396
|
+
list = RSpecModelFinderTest.list_in( @context ).where( :field_one => [ @scoped_1.field_one, @scoped_2.field_one ] )
|
1397
|
+
expect( list ).to eq( [ @scoped_2 ] )
|
1315
1398
|
|
1316
|
-
|
1317
|
-
|
1318
|
-
|
1319
|
-
|
1320
|
-
|
1399
|
+
list = RSpecModelFinderTest.where( :field_one => [ @scoped_2.field_one, @scoped_3.field_one ] ).list_in( @context ).reorder( 'field_one' => 'asc' )
|
1400
|
+
expect( list ).to eq( [ @scoped_2, @scoped_3 ] )
|
1401
|
+
|
1402
|
+
list = RSpecModelFinderTest.list_in( @context ).reorder( 'field_one' => 'asc' ).where( :field_one => [ @scoped_2.field_one, @scoped_3.field_one ] )
|
1403
|
+
expect( list ).to eq( [ @scoped_2, @scoped_3 ] )
|
1404
|
+
end
|
1321
1405
|
end
|
1322
1406
|
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
|
1327
|
-
|
1407
|
+
# ========================================================================
|
1408
|
+
|
1409
|
+
context 'deprecated' do
|
1410
|
+
it '#polymorphic_find calls #acquire' do
|
1411
|
+
expect( $stderr ).to receive( :puts ).once
|
1412
|
+
expect( RSpecModelFinderTest ).to receive( :acquire ).once.with( 21 )
|
1413
|
+
RSpecModelFinderTest.polymorphic_find( RSpecModelFinderTest, 21 )
|
1414
|
+
end
|
1415
|
+
|
1416
|
+
it '#polymorphic_id_fields calls #acquire_with' do
|
1417
|
+
expect( $stderr ).to receive( :puts ).once
|
1418
|
+
expect( RSpecModelFinderTest ).to receive( :acquire_with ).once.with( :uuid, :code )
|
1419
|
+
RSpecModelFinderTest.polymorphic_id_fields( :uuid, :code )
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
it '#list_finder calls #list' do
|
1423
|
+
params = { :search => { :field_one => 'one' } }
|
1424
|
+
expect( $stderr ).to receive( :puts ).once
|
1425
|
+
expect( RSpecModelFinderTest ).to receive( :list ).once.with( params )
|
1426
|
+
RSpecModelFinderTest.list_finder( params )
|
1427
|
+
end
|
1428
|
+
|
1429
|
+
it '#list_search_map calls #search_with' do
|
1430
|
+
params = { :foo => nil, :bar => nil }
|
1431
|
+
expect( $stderr ).to receive( :puts ).once
|
1432
|
+
expect( RSpecModelFinderTest ).to receive( :search_with ).once.with( params )
|
1433
|
+
RSpecModelFinderTest.list_search_map( params )
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
it '#list_filter_map calls #filter_with' do
|
1437
|
+
params = { :foo => nil, :bar => nil }
|
1438
|
+
expect( $stderr ).to receive( :puts ).once
|
1439
|
+
expect( RSpecModelFinderTest ).to receive( :filter_with ).once.with( params )
|
1440
|
+
RSpecModelFinderTest.list_filter_map( params )
|
1441
|
+
end
|
1328
1442
|
end
|
1329
1443
|
end
|
1330
1444
|
end
|