hoodoo 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
!binary "U0hBMQ==":
|
|
3
3
|
metadata.gz: !binary |-
|
|
4
|
-
|
|
4
|
+
OGQ2ZGRmYWM3NTIwOWEwOGIyNjFiOTkyN2I4ZDdhNzY1YWUzZWIyNw==
|
|
5
5
|
data.tar.gz: !binary |-
|
|
6
|
-
|
|
6
|
+
OWUxNzBkMjc2NzM5N2ViZDM5ZWY2ZjNjMDFhZjJiNDVmNzA5NDYxMA==
|
|
7
7
|
SHA512:
|
|
8
8
|
metadata.gz: !binary |-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
MjE2MTQ5YTU0OWFkZWEyN2Y0YTU5ZDJhOWU5MjkwODI3MmViYWFmODg4ZDll
|
|
10
|
+
MWI5MjUyNjIzNGFjMWZiYmViYzhhYTcyZGQyZmRhMjk5M2ZjMjQzOWJiNWFl
|
|
11
|
+
Mzg4NWZlMDFhZjQ3MjA4ZmQxZWM1YzM5YTY4YTJiNTE4MjFjOGQ=
|
|
12
12
|
data.tar.gz: !binary |-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
NWFlNzg2Y2E4ODg4ODY3MjYwMTRmMzQzZmYzMWQ0OGJkYzljZDdhZjY0ZmYw
|
|
14
|
+
YjUwNjljZjkwMWM5Y2ZjOTgwNmJiNTZkNzg4MGE3OTk4M2ZlOWQxZDEzMWQy
|
|
15
|
+
ZDJiYzBjNTAzMDkwOGIzYzI3MjU1OGQxMjk0MDg2OTcwMTdjMWY=
|
|
@@ -88,6 +88,27 @@ module Hoodoo
|
|
|
88
88
|
#
|
|
89
89
|
module ClassMethods
|
|
90
90
|
|
|
91
|
+
# Returns an ActiveRecord::Relation instance representing a primitive
|
|
92
|
+
# base scope that includes various context-related aspects according
|
|
93
|
+
# to the prevailing mixins included by "this" class, if any - e.g.
|
|
94
|
+
# security, dating and/or translation.
|
|
95
|
+
#
|
|
96
|
+
# See Hoodoo::ActiveRecord::Support#full_scope_for to see the list
|
|
97
|
+
# of things that get included. If there are no "interesting" mixins,
|
|
98
|
+
# the returned scope will just return the same thing that the +all+
|
|
99
|
+
# method in ActiveRecord would have returned. Consequently, a default
|
|
100
|
+
# scope _will_ be honoured if one has been declared, though default
|
|
101
|
+
# scopes are generally considered an anti-pattern to be avoided.
|
|
102
|
+
#
|
|
103
|
+
# +context+:: Hoodoo::Services::Context instance describing a call
|
|
104
|
+
# context. This is typically a value passed to one of
|
|
105
|
+
# the Hoodoo::Services::Implementation instance methods
|
|
106
|
+
# that a resource subclass implements.
|
|
107
|
+
#
|
|
108
|
+
def scoped_in( context )
|
|
109
|
+
Hoodoo::ActiveRecord::Support.full_scope_for( self, context )
|
|
110
|
+
end
|
|
111
|
+
|
|
91
112
|
# "Polymorphic" find - support for finding a model by fields other
|
|
92
113
|
# than just +:id+, based on a single unique identifier. Use #acquire
|
|
93
114
|
# just like you'd use +find_by_id+ and only bother with it if you
|
|
@@ -159,10 +180,11 @@ module Hoodoo
|
|
|
159
180
|
end
|
|
160
181
|
|
|
161
182
|
# Implicily secure, translated, dated etc. etc. version of #acquire,
|
|
162
|
-
# according to which modules are mixed into your model class.
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
# that
|
|
183
|
+
# according to which modules are mixed into your model class. Uses
|
|
184
|
+
# #scoped_in to obtain a base scope in which to operate, so it is
|
|
185
|
+
# "mixin aware" and incorporates other Hoodoo extensions within the
|
|
186
|
+
# wider scope chain. See that method's documentation for more
|
|
187
|
+
# information.
|
|
166
188
|
#
|
|
167
189
|
# For example, if you are using or at some point intend to mix in and
|
|
168
190
|
# use the mechanism described by the likes of
|
|
@@ -213,8 +235,7 @@ module Hoodoo
|
|
|
213
235
|
# SomeModel.acquire_in( context )
|
|
214
236
|
#
|
|
215
237
|
# The same applies to forgetting dated scopes, translated scopes, or
|
|
216
|
-
# anything else that
|
|
217
|
-
# might include for you.
|
|
238
|
+
# anything else that #scoped_in might include for you.
|
|
218
239
|
#
|
|
219
240
|
# Parameters:
|
|
220
241
|
#
|
|
@@ -226,8 +247,7 @@ module Hoodoo
|
|
|
226
247
|
# Returns a found model instance or +nil+ for no match.
|
|
227
248
|
#
|
|
228
249
|
def acquire_in( context )
|
|
229
|
-
|
|
230
|
-
return scope.acquire( context.request.ident )
|
|
250
|
+
return scoped_in( context ).acquire( context.request.ident )
|
|
231
251
|
end
|
|
232
252
|
|
|
233
253
|
# Describe the list of model fields _in_ _addition_ _to_ +id+ which
|
|
@@ -294,11 +314,13 @@ module Hoodoo
|
|
|
294
314
|
#
|
|
295
315
|
# Normally such a scope could only ever return a single record based
|
|
296
316
|
# on an assuption of uniqueness constraints around columns which one
|
|
297
|
-
# might use in an equivalent of a +find+ call.
|
|
298
|
-
#
|
|
299
|
-
#
|
|
300
|
-
#
|
|
301
|
-
#
|
|
317
|
+
# might use in an equivalent of a +find+ call. This scope is often
|
|
318
|
+
# chained on top of a wider listing scope provided by #scoped_in to
|
|
319
|
+
# create a fully context-aware, secure, dated, translated etc. query.
|
|
320
|
+
# It is possible however that the chosen +ident+ value might not
|
|
321
|
+
# resolve to a single unique record depending on how your data works
|
|
322
|
+
# and you may need to manually apply additional constraints to the
|
|
323
|
+
# returned ActiveRecord::Relation instance.
|
|
302
324
|
#
|
|
303
325
|
def acquisition_scope( ident )
|
|
304
326
|
extra_fields = self.acquired_with()
|
|
@@ -432,9 +454,8 @@ module Hoodoo
|
|
|
432
454
|
|
|
433
455
|
# Implicily secure, translated, dated etc. etc. version of #list,
|
|
434
456
|
# according to which modules are mixed into your model class. See
|
|
435
|
-
#
|
|
436
|
-
#
|
|
437
|
-
# that are in use.
|
|
457
|
+
# #scoped_in to see the list of things that get included in the
|
|
458
|
+
# scope according to the mixins that are in use.
|
|
438
459
|
#
|
|
439
460
|
# For example, if you have included Hoodoo::ActiveRecord::Secure,
|
|
440
461
|
# this method provides you with an implicitly secure query. Read the
|
|
@@ -450,8 +471,7 @@ module Hoodoo
|
|
|
450
471
|
# SomeModel.list_in( context )
|
|
451
472
|
#
|
|
452
473
|
# The same applies to forgetting dated scopes, translated scopes, or
|
|
453
|
-
# anything else that
|
|
454
|
-
# might include for you.
|
|
474
|
+
# anything else that #scoped_in might include for you.
|
|
455
475
|
#
|
|
456
476
|
# +context+:: Hoodoo::Services::Context instance describing a call
|
|
457
477
|
# context. This is typically a value passed to one of
|
|
@@ -462,8 +482,7 @@ module Hoodoo
|
|
|
462
482
|
# query methods like +where+ or fetching from the database with +all+.
|
|
463
483
|
#
|
|
464
484
|
def list_in( context )
|
|
465
|
-
|
|
466
|
-
return scope.list( context.request.list )
|
|
485
|
+
return scoped_in( context ).list( context.request.list )
|
|
467
486
|
end
|
|
468
487
|
|
|
469
488
|
# Given some scope - typically that obtained from a prior call to
|
data/lib/hoodoo/version.rb
CHANGED
|
@@ -129,7 +129,90 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
|
129
129
|
|
|
130
130
|
# ==========================================================================
|
|
131
131
|
|
|
132
|
-
context '
|
|
132
|
+
context '#scoped_in' do
|
|
133
|
+
before :each do
|
|
134
|
+
|
|
135
|
+
# Get a good-enough-for-test interaction which has a context
|
|
136
|
+
# that contains a Session we can modify.
|
|
137
|
+
|
|
138
|
+
@interaction = Hoodoo::Services::Middleware::Interaction.new( {}, nil )
|
|
139
|
+
@interaction.context = Hoodoo::Services::Context.new(
|
|
140
|
+
Hoodoo::Services::Session.new,
|
|
141
|
+
@interaction.context.request,
|
|
142
|
+
@interaction.context.response,
|
|
143
|
+
@interaction
|
|
144
|
+
)
|
|
145
|
+
|
|
146
|
+
@context = @interaction.context
|
|
147
|
+
@session = @interaction.context.session
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# If security scoping works _and_ we know that it called #full_scope_for
|
|
151
|
+
# in the "internal"-ish support API, then we consider that good enough
|
|
152
|
+
# to prove that it's calling the scope engine and that engine has its
|
|
153
|
+
# own comprehensive test coverage in suport_spec.rb.
|
|
154
|
+
#
|
|
155
|
+
it 'generates appropriate scope' do
|
|
156
|
+
@session.scoping = { :authorised_uuids => [ 'uuid 1', 'uuid 2' ], :authorised_code => 'code 1' }
|
|
157
|
+
|
|
158
|
+
expect( Hoodoo::ActiveRecord::Support ).to(
|
|
159
|
+
receive( :full_scope_for ).once().with(
|
|
160
|
+
RSpecModelFinderTest, @context
|
|
161
|
+
).and_call_original()
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
sql = RSpecModelFinderTest.scoped_in( @context ).to_sql
|
|
165
|
+
|
|
166
|
+
expect( sql ).to eq( "SELECT \"r_spec_model_finder_tests\".* "<<
|
|
167
|
+
"FROM \"r_spec_model_finder_tests\" " <<
|
|
168
|
+
"WHERE " <<
|
|
169
|
+
"\"r_spec_model_finder_tests\".\"uuid\" IN ('uuid 1', 'uuid 2') AND " <<
|
|
170
|
+
"\"r_spec_model_finder_tests\".\"code\" = 'code 1'" )
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# ==========================================================================
|
|
175
|
+
|
|
176
|
+
context 'acquisition scope and overrides' do
|
|
177
|
+
def expect_sql( sql, id_attr_name )
|
|
178
|
+
expect( sql ).to eq( "SELECT \"r_spec_model_finder_tests\".* "<<
|
|
179
|
+
"FROM \"r_spec_model_finder_tests\" " <<
|
|
180
|
+
"WHERE (" <<
|
|
181
|
+
"(" <<
|
|
182
|
+
"\"r_spec_model_finder_tests\".\"#{ id_attr_name }\" = '#{ @id }' OR " <<
|
|
183
|
+
"\"r_spec_model_finder_tests\".\"uuid\" = '#{ @id }'" <<
|
|
184
|
+
") OR " <<
|
|
185
|
+
"\"r_spec_model_finder_tests\".\"code\" = '#{ @id }'" <<
|
|
186
|
+
")" )
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
context '#acquisition_scope' do
|
|
190
|
+
it 'SQL generation is as expected' do
|
|
191
|
+
sql = RSpecModelFinderTest.acquisition_scope( @id ).to_sql()
|
|
192
|
+
expect_sql( sql, 'id' )
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
context '#acquire_with_id_substitute' do
|
|
197
|
+
before :each do
|
|
198
|
+
@alt_attr_name = 'foo'
|
|
199
|
+
RSpecModelFinderTest.acquire_with_id_substitute( @alt_attr_name )
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
after :each do
|
|
203
|
+
RSpecModelFinderTest.acquire_with_id_substitute( 'id' )
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it 'SQL generation is as expected' do
|
|
207
|
+
sql = RSpecModelFinderTest.acquisition_scope( @id ).to_sql()
|
|
208
|
+
expect_sql( sql, @alt_attr_name )
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# ==========================================================================
|
|
214
|
+
|
|
215
|
+
context '#acquire' do
|
|
133
216
|
it 'finds from the class' do
|
|
134
217
|
found = RSpecModelFinderTest.acquire( @id )
|
|
135
218
|
expect( found ).to eq(@a)
|
|
@@ -203,7 +286,7 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
|
203
286
|
|
|
204
287
|
# ==========================================================================
|
|
205
288
|
|
|
206
|
-
context 'acquire_in' do
|
|
289
|
+
context '#acquire_in' do
|
|
207
290
|
before :each do
|
|
208
291
|
@scoped_1 = RSpecModelFinderTest.new
|
|
209
292
|
@scoped_1.id = 'id 1'
|
|
@@ -350,46 +433,7 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
|
350
433
|
|
|
351
434
|
# ==========================================================================
|
|
352
435
|
|
|
353
|
-
context '
|
|
354
|
-
def expect_sql( sql, id_attr_name )
|
|
355
|
-
expect( sql ).to eq( "SELECT \"r_spec_model_finder_tests\".* "<<
|
|
356
|
-
"FROM \"r_spec_model_finder_tests\" " <<
|
|
357
|
-
"WHERE (" <<
|
|
358
|
-
"(" <<
|
|
359
|
-
"\"r_spec_model_finder_tests\".\"#{ id_attr_name }\" = '#{ @id }' OR " <<
|
|
360
|
-
"\"r_spec_model_finder_tests\".\"uuid\" = '#{ @id }'" <<
|
|
361
|
-
") OR " <<
|
|
362
|
-
"\"r_spec_model_finder_tests\".\"code\" = '#{ @id }'" <<
|
|
363
|
-
")" )
|
|
364
|
-
end
|
|
365
|
-
|
|
366
|
-
context 'acquisition_scope' do
|
|
367
|
-
it 'SQL generation is as expected' do
|
|
368
|
-
sql = RSpecModelFinderTest.acquisition_scope( @id ).to_sql()
|
|
369
|
-
expect_sql( sql, 'id' )
|
|
370
|
-
end
|
|
371
|
-
end
|
|
372
|
-
|
|
373
|
-
context 'acquire_with_id_substitute' do
|
|
374
|
-
before :each do
|
|
375
|
-
@alt_attr_name = 'foo'
|
|
376
|
-
RSpecModelFinderTest.acquire_with_id_substitute( @alt_attr_name )
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
after :each do
|
|
380
|
-
RSpecModelFinderTest.acquire_with_id_substitute( 'id' )
|
|
381
|
-
end
|
|
382
|
-
|
|
383
|
-
it 'SQL generation is as expected' do
|
|
384
|
-
sql = RSpecModelFinderTest.acquisition_scope( @id ).to_sql()
|
|
385
|
-
expect_sql( sql, @alt_attr_name )
|
|
386
|
-
end
|
|
387
|
-
end
|
|
388
|
-
end
|
|
389
|
-
|
|
390
|
-
# ==========================================================================
|
|
391
|
-
|
|
392
|
-
context 'lists' do
|
|
436
|
+
context '#list' do
|
|
393
437
|
it 'lists with pages, offsets and counts' do
|
|
394
438
|
@list_params.offset = 1 # 0 is first record
|
|
395
439
|
@list_params.limit = 1
|
|
@@ -695,7 +739,7 @@ describe Hoodoo::ActiveRecord::Finder do
|
|
|
695
739
|
|
|
696
740
|
# ==========================================================================
|
|
697
741
|
|
|
698
|
-
context 'list_in' do
|
|
742
|
+
context '#list_in' do
|
|
699
743
|
before :each do
|
|
700
744
|
@scoped_1 = RSpecModelFinderTest.new
|
|
701
745
|
@scoped_1.id = 'id 1'
|
|
@@ -74,6 +74,14 @@ describe Hoodoo::ActiveRecord::Support do
|
|
|
74
74
|
t.string :bar
|
|
75
75
|
t.timestamps :null => true
|
|
76
76
|
end
|
|
77
|
+
|
|
78
|
+
ActiveRecord::Migration.create_table( :r_spec_full_scope_for_manually_dateds ) do | t |
|
|
79
|
+
t.string :baz
|
|
80
|
+
t.string :uuid, :length => 32
|
|
81
|
+
t.datetime :effective_start
|
|
82
|
+
t.datetime :effective_end
|
|
83
|
+
t.timestamps :null => true
|
|
84
|
+
end
|
|
77
85
|
end
|
|
78
86
|
|
|
79
87
|
# Note inheritance from plain ActiveRecord::Base, important for
|
|
@@ -107,6 +115,16 @@ describe Hoodoo::ActiveRecord::Support do
|
|
|
107
115
|
class RSpecFullScopeForTestBaseSubclassWithoutOverrides < RSpecFullScopeForTestBaseWithDirectives
|
|
108
116
|
# No overrides at all
|
|
109
117
|
end
|
|
118
|
+
|
|
119
|
+
# Manual and automatic effective dating can live in the same mixin
|
|
120
|
+
# collection but can't both be enabled at the same time, so do this
|
|
121
|
+
# in a special test class with a database table that meets the
|
|
122
|
+
# related requirements.
|
|
123
|
+
#
|
|
124
|
+
class RSpecFullScopeForManuallyDated < Hoodoo::ActiveRecord::Base
|
|
125
|
+
secure_with( :baz => :baz )
|
|
126
|
+
manual_dating_enabled()
|
|
127
|
+
end
|
|
110
128
|
end
|
|
111
129
|
|
|
112
130
|
before :each do
|
|
@@ -221,5 +239,37 @@ describe Hoodoo::ActiveRecord::Support do
|
|
|
221
239
|
expect( auto_scope ).to eq( manual_scope )
|
|
222
240
|
end
|
|
223
241
|
end
|
|
242
|
+
|
|
243
|
+
context '(with manual dating enabled)' do
|
|
244
|
+
before :each do
|
|
245
|
+
@session.scoping.baz = [ @test_scoping_value ]
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
context 'gets customised scope:' do
|
|
249
|
+
it 'manually dated' do
|
|
250
|
+
manual_scope = RSpecFullScopeForManuallyDated.manually_dated( @context ).to_sql()
|
|
251
|
+
|
|
252
|
+
expect( manual_scope ).to include( 'FROM "r_spec_full_scope_for_manually_dateds"' )
|
|
253
|
+
expect( manual_scope ).to include( "\"effective_end\" > #{ RSpecFullScopeForTestSubclass.sanitize( @test_time_value.to_time.round( Hoodoo::ActiveRecord::ManuallyDated::SECONDS_DECIMAL_PLACES ) ) }" )
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it 'secure' do
|
|
257
|
+
manual_scope = RSpecFullScopeForManuallyDated.secure( @context ).to_sql()
|
|
258
|
+
|
|
259
|
+
expect( manual_scope ).to include( "\"r_spec_full_scope_for_manually_dateds\".\"baz\" = '#{ @test_scoping_value }'" )
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
pending 'translated' do
|
|
263
|
+
raise "Scope verification for '\#translated'"
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it 'everything' do
|
|
267
|
+
auto_scope = described_class.full_scope_for( RSpecFullScopeForManuallyDated, @context ).to_sql()
|
|
268
|
+
manual_scope = RSpecFullScopeForManuallyDated.manually_dated( @context ).secure( @context ).translated( @context ).to_sql()
|
|
269
|
+
|
|
270
|
+
expect( auto_scope ).to eq( manual_scope )
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
end
|
|
224
274
|
end
|
|
225
275
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hoodoo
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Loyalty New Zealand
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-02-
|
|
11
|
+
date: 2016-02-23 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: kgio
|