arkenstone-open 3.0.1
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 +7 -0
- data/.github/workflows/codacy-analysis.yml +46 -0
- data/.gitignore +19 -0
- data/.rubocop.yml +5 -0
- data/.ruby-version +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +21 -0
- data/Gemfile.lock +101 -0
- data/LICENSE.txt +11 -0
- data/README.md +87 -0
- data/Rakefile +36 -0
- data/arkenstone.gemspec +27 -0
- data/lib/arkenstone/associations/resources.rb +76 -0
- data/lib/arkenstone/associations.rb +389 -0
- data/lib/arkenstone/document.rb +289 -0
- data/lib/arkenstone/enumerable/query_list.rb +20 -0
- data/lib/arkenstone/errors/no_url_error.rb +14 -0
- data/lib/arkenstone/helpers.rb +18 -0
- data/lib/arkenstone/network/env.rb +19 -0
- data/lib/arkenstone/network/hook.rb +74 -0
- data/lib/arkenstone/network/network.rb +72 -0
- data/lib/arkenstone/query_builder.rb +84 -0
- data/lib/arkenstone/queryable.rb +38 -0
- data/lib/arkenstone/timestamps.rb +25 -0
- data/lib/arkenstone/validation/validation_error.rb +34 -0
- data/lib/arkenstone/validation/validations.rb +192 -0
- data/lib/arkenstone/version.rb +5 -0
- data/lib/arkenstone.rb +22 -0
- data/test/associations/test_document_overrides.rb +50 -0
- data/test/associations/test_has_and_belongs_to_many.rb +80 -0
- data/test/dummy/app/models/association.rb +35 -0
- data/test/dummy/app/models/superuser.rb +8 -0
- data/test/dummy/app/models/user.rb +10 -0
- data/test/spec_helper.rb +16 -0
- data/test/test_arkenstone.rb +354 -0
- data/test/test_arkenstone_hook_inheritance.rb +39 -0
- data/test/test_associations.rb +327 -0
- data/test/test_enumerables.rb +36 -0
- data/test/test_environment.rb +14 -0
- data/test/test_helpers.rb +18 -0
- data/test/test_hooks.rb +104 -0
- data/test/test_query_builder.rb +163 -0
- data/test/test_queryable.rb +59 -0
- data/test/test_validations.rb +197 -0
- metadata +133 -0
@@ -0,0 +1,327 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
class AssociationsTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@model = AssociatedUser.new
|
8
|
+
@model.id = 100
|
9
|
+
@dummy_things = [{ 'id' => 100, 'name' => 'test' }, { 'id' => 200, 'name' => 'dummy data' }]
|
10
|
+
|
11
|
+
stub_request(:get, "#{AssociatedUser.arkenstone_url}100/things").to_return do |_req|
|
12
|
+
{ body: @dummy_things.to_json }
|
13
|
+
end
|
14
|
+
|
15
|
+
stub_request(:get, "#{AssociatedUser.arkenstone_url}100/roles").to_return(body: '')
|
16
|
+
|
17
|
+
@dummy_resource = { 'id' => 50, 'name' => 'Resource 1' }
|
18
|
+
stub_request(:get, "#{AssociatedUser.arkenstone_url}100/resource").to_return do |_req|
|
19
|
+
if @dummy_resource.nil?
|
20
|
+
{ status: 200 }
|
21
|
+
else
|
22
|
+
{ body: @dummy_resource.to_json }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_associations_dont_clobber_existing_methods
|
28
|
+
AssociatedUser.add_association_method 'test_method' do
|
29
|
+
'replaced'
|
30
|
+
end
|
31
|
+
model = AssociatedUser.new
|
32
|
+
assert(model.test_method == 'on AssociatedUser')
|
33
|
+
# model = UserWithMethods.new
|
34
|
+
# assert(model.things == 'on UserWithMethods')
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_has_many_creates_child_array
|
38
|
+
assert(AssociatedUser.method_defined?(:things))
|
39
|
+
assert(@model.things.nil? == false)
|
40
|
+
assert(@model.things != [])
|
41
|
+
assert(@model.things.count == 2)
|
42
|
+
|
43
|
+
assert(@model.roles == [])
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_has_many_creates_cached_method
|
47
|
+
assert(AssociatedUser.method_defined?(:cached_things))
|
48
|
+
assert(@model.cached_things.count == 2)
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_has_many_creates_add_child
|
52
|
+
stub_request(:post, "#{AssociatedUser.arkenstone_url}100/things").to_return do |_req|
|
53
|
+
@dummy_things << { 'id' => 500, 'name' => 'new thing' }
|
54
|
+
{ status: 200 }
|
55
|
+
end
|
56
|
+
assert(AssociatedUser.method_defined?(:add_thing))
|
57
|
+
new_thing = Thing.new
|
58
|
+
new_thing.name = 'new thing'
|
59
|
+
new_thing.id = 500
|
60
|
+
@model.add_thing new_thing
|
61
|
+
assert(@model.cached_things.count == 3)
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_has_many_creates_remove_child
|
65
|
+
stub_request(:delete, "#{AssociatedUser.arkenstone_url}100/things/100").to_return do |_req|
|
66
|
+
@dummy_things = [{ 'id' => 200, 'name' => 'dummy data' }]
|
67
|
+
{ status: 200 }
|
68
|
+
end
|
69
|
+
|
70
|
+
assert(AssociatedUser.method_defined?(:remove_thing))
|
71
|
+
bad_thing = Thing.new
|
72
|
+
bad_thing.id = 100
|
73
|
+
@model.remove_thing bad_thing
|
74
|
+
assert(@model.cached_things.count == 1)
|
75
|
+
assert(@model.cached_things[0].id == 200)
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_has_one_creates_a_cached_object
|
79
|
+
assert(AssociatedUser.method_defined?('cached_resource'))
|
80
|
+
assert(!@model.cached_resource.nil?)
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_has_one_creates_a_uncached_object
|
84
|
+
assert(AssociatedUser.method_defined?('resource'))
|
85
|
+
assert(@model.resource.id == 50)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_has_one_creates_a_setter
|
89
|
+
new_values = { id: 75, name: 'new resource' }
|
90
|
+
stub_request(:post, "#{AssociatedUser.arkenstone_url}100/resource").to_return(body: '')
|
91
|
+
|
92
|
+
assert(AssociatedUser.method_defined?('resource='))
|
93
|
+
new_resource = Resource.build new_values
|
94
|
+
@model.resource = new_resource
|
95
|
+
@dummy_resource = new_resource
|
96
|
+
assert(@model.resource.id == 75)
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_has_one_can_delete_an_association
|
100
|
+
stub_request(:delete, "#{AssociatedUser.arkenstone_url}100/resource/50").to_return(status: 200)
|
101
|
+
@model.resource = nil
|
102
|
+
@dummy_resource = nil
|
103
|
+
assert(@model.resource.nil?)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_associations_uses_the_same_namespace
|
107
|
+
eval %(
|
108
|
+
module Foo
|
109
|
+
class Bar
|
110
|
+
include Arkenstone::Document
|
111
|
+
end
|
112
|
+
|
113
|
+
class MyClass
|
114
|
+
include Arkenstone::Document
|
115
|
+
url "http://example.com/myclasses/"
|
116
|
+
|
117
|
+
attributes :id, :name
|
118
|
+
|
119
|
+
has_many :bars
|
120
|
+
end
|
121
|
+
end
|
122
|
+
)
|
123
|
+
stub_request(:get, "#{Foo::MyClass.arkenstone_url}100/bars").to_return(body: '')
|
124
|
+
model = Foo::MyClass.new
|
125
|
+
model.id = 100
|
126
|
+
result = model.bars
|
127
|
+
assert(!result.nil?)
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_assoications_handles_405
|
131
|
+
eval %(
|
132
|
+
module Foo
|
133
|
+
class Bar
|
134
|
+
include Arkenstone::Document
|
135
|
+
end
|
136
|
+
|
137
|
+
class MyClass
|
138
|
+
include Arkenstone::Document
|
139
|
+
url "http://example.com/myclasses/"
|
140
|
+
|
141
|
+
attributes :id, :name
|
142
|
+
|
143
|
+
has_one :bar
|
144
|
+
end
|
145
|
+
end
|
146
|
+
)
|
147
|
+
stub_request(:get, "#{Foo::MyClass.arkenstone_url}100/bar").to_return(status: '405', body: 'ERROR')
|
148
|
+
model = Foo::MyClass.new
|
149
|
+
model.id = 100
|
150
|
+
result = model.bar
|
151
|
+
assert(result == [])
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_belongs_to_association
|
155
|
+
eval %(
|
156
|
+
module Foo
|
157
|
+
class Bar
|
158
|
+
include Arkenstone::Document
|
159
|
+
url 'http://example.com/bar'
|
160
|
+
|
161
|
+
attributes :id
|
162
|
+
belongs_to :freezer
|
163
|
+
end
|
164
|
+
|
165
|
+
class Freezer
|
166
|
+
include Arkenstone::Document
|
167
|
+
url 'http://example.com/freezer'
|
168
|
+
|
169
|
+
attributes :id, :age
|
170
|
+
has_many :bars
|
171
|
+
end
|
172
|
+
end
|
173
|
+
)
|
174
|
+
|
175
|
+
stub_request(:post, "#{Foo::Freezer.arkenstone_url}/").to_return(status: '200', body: { id: 1 }.to_json)
|
176
|
+
stub_request(:post, "#{Foo::Bar.arkenstone_url}/").to_return(status: '200', body: { id: 1, freezer_id: 1 }.to_json)
|
177
|
+
|
178
|
+
freezer = Foo::Freezer.create({ age: 30 })
|
179
|
+
bar = Foo::Bar.create({ freezer: })
|
180
|
+
|
181
|
+
stub_request(:get, "#{Foo::Freezer.arkenstone_url}/1").to_return(status: 200, body: freezer.to_json)
|
182
|
+
|
183
|
+
assert_equal(freezer.id, bar.freezer_id)
|
184
|
+
assert_equal(freezer.to_json, bar.freezer.to_json)
|
185
|
+
assert_equal(bar.cached_freezer.id, freezer.id)
|
186
|
+
end
|
187
|
+
|
188
|
+
def test_has_and_belongs_to_many
|
189
|
+
# Pending Test
|
190
|
+
|
191
|
+
return true
|
192
|
+
eval %(
|
193
|
+
module Foo
|
194
|
+
class Bar
|
195
|
+
include Arkenstone::Document
|
196
|
+
url 'http://example.com/bar'
|
197
|
+
|
198
|
+
attributes :id
|
199
|
+
has_and_belongs_to_many :freezers
|
200
|
+
end
|
201
|
+
|
202
|
+
class Freezer
|
203
|
+
include Arkenstone::Document
|
204
|
+
url 'http://example.com/freezer'
|
205
|
+
|
206
|
+
attributes :id, :age
|
207
|
+
has_and_belongs_to_many :bars
|
208
|
+
end
|
209
|
+
end
|
210
|
+
)
|
211
|
+
|
212
|
+
stub_request(:post, "#{Foo::Freezer.arkenstone_url}/").to_return(status: '200',
|
213
|
+
body: {
|
214
|
+
id: 1, bar_ids: []
|
215
|
+
}.to_json)
|
216
|
+
stub_request(:post, "#{Foo::Bar.arkenstone_url}/").to_return(status: '200',
|
217
|
+
body: {
|
218
|
+
id: 1, freezer_ids: [1]
|
219
|
+
}.to_json)
|
220
|
+
|
221
|
+
freezer = Foo::Freezer.create({ age: 30 })
|
222
|
+
bar = Foo::Bar.create({ freezers: [freezer] })
|
223
|
+
|
224
|
+
stub_request(:get, "#{Foo::Freezer.arkenstone_url}/1").to_return(status: 200,
|
225
|
+
body: freezer.merge({ bar_ids: [bar.id] }).to_json)
|
226
|
+
stub_request(:get, "#{Foo::Bar.arkenstone_url}/1").to_return(status: 200,
|
227
|
+
body: bar.merge({ freezer_ids: [freezer.id] }).to_json)
|
228
|
+
|
229
|
+
assert(bar.freezer_ids.include?(freezer.id))
|
230
|
+
assert(freezer.bar_ids.include?(bar.id))
|
231
|
+
|
232
|
+
freezer = Foo::Freezer.find(1)
|
233
|
+
bar = Foo::Bar.find(1)
|
234
|
+
|
235
|
+
assert_equal(1, freezer.bars.length)
|
236
|
+
assert_equal(1, bar.freezers.length)
|
237
|
+
|
238
|
+
found_freezer = bar.freezers.first
|
239
|
+
found_bar = freezer.bars.first
|
240
|
+
|
241
|
+
assert_equal(freezer.to_json, found_freezer.to_json)
|
242
|
+
assert_equal(bar.to_json, found_bar.to_json)
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_handles_nested_json
|
246
|
+
eval %(
|
247
|
+
module Foo
|
248
|
+
class Bar
|
249
|
+
include Arkenstone::Document
|
250
|
+
url 'http://example.com/bar'
|
251
|
+
|
252
|
+
attributes :id
|
253
|
+
belongs_to :freezer
|
254
|
+
end
|
255
|
+
|
256
|
+
class Freezer
|
257
|
+
include Arkenstone::Document
|
258
|
+
url 'http://example.com/freezer'
|
259
|
+
|
260
|
+
attributes :id, :age
|
261
|
+
has_many :bars
|
262
|
+
end
|
263
|
+
end
|
264
|
+
)
|
265
|
+
|
266
|
+
stub_request(:post, "#{Foo::Freezer.arkenstone_url}/").to_return(status: '200', body: { id: 1 }.to_json)
|
267
|
+
stub_request(:post, "#{Foo::Bar.arkenstone_url}/").to_return(status: '200', body: { id: 1, freezer_id: 1 }.to_json)
|
268
|
+
|
269
|
+
freezer = Foo::Freezer.create({ age: 30 })
|
270
|
+
bar = Foo::Bar.create({ freezer: })
|
271
|
+
|
272
|
+
stub_request(:get, "#{Foo::Freezer.arkenstone_url}/1").to_return(status: 200,
|
273
|
+
body: {
|
274
|
+
id: 1, age: 30, bars: [{ id: 1 }]
|
275
|
+
}.to_json)
|
276
|
+
stub_request(:get, "#{Foo::Freezer.arkenstone_url}/1/bars").to_return(status: 200, body: [{ id: 1 }].to_json)
|
277
|
+
|
278
|
+
freezer = Foo::Freezer.find(freezer.id)
|
279
|
+
|
280
|
+
assert(freezer.bars)
|
281
|
+
assert(freezer.bar_ids)
|
282
|
+
assert(freezer.bar_ids.include?(bar.id))
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_allows_custom_url
|
286
|
+
eval %(
|
287
|
+
class Tool
|
288
|
+
include Arkenstone::Document
|
289
|
+
attributes :name
|
290
|
+
url 'http://example.com/tools'
|
291
|
+
end
|
292
|
+
|
293
|
+
class Garage
|
294
|
+
include Arkenstone::Document
|
295
|
+
attributes :address
|
296
|
+
url 'http://example.com/garages'
|
297
|
+
|
298
|
+
has_many :tools, model_name: 'derps'
|
299
|
+
end
|
300
|
+
)
|
301
|
+
stub_request(:get,
|
302
|
+
"#{Garage.arkenstone_url}/10/derps").to_return(body: [{ name: 'test' }, { name: 'other' }].to_json)
|
303
|
+
g = Garage.new
|
304
|
+
g.id = 10
|
305
|
+
tools = g.tools
|
306
|
+
assert_equal(2, tools.count)
|
307
|
+
end
|
308
|
+
|
309
|
+
def test_has_many_custom_class
|
310
|
+
eval %(
|
311
|
+
class Organization
|
312
|
+
include Arkenstone::Document
|
313
|
+
attributes :name
|
314
|
+
url 'http://example.com/organizations'
|
315
|
+
|
316
|
+
has_many :child_organizations, class_name: :organization, model_name: 'descendents'
|
317
|
+
end
|
318
|
+
)
|
319
|
+
url = "#{Organization.arkenstone_url}/10/descendents"
|
320
|
+
children = [{ name: 'child 1' }, { name: 'child 2' }]
|
321
|
+
stub_request(:get, url).to_return(body: children.to_json)
|
322
|
+
parent = Organization.new
|
323
|
+
parent.id = 10
|
324
|
+
child_orgs = parent.child_organizations
|
325
|
+
assert_equal(2, child_orgs.count)
|
326
|
+
end
|
327
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
class EnumerableTests < Test::Unit::TestCase
|
6
|
+
def test_json_returns_attributes_of_elements
|
7
|
+
eval %(
|
8
|
+
class EnumerableElement
|
9
|
+
include Arkenstone::Document
|
10
|
+
|
11
|
+
attributes :name, :id
|
12
|
+
end
|
13
|
+
)
|
14
|
+
dummy = EnumerableElement.new
|
15
|
+
dummy.name = 'test'
|
16
|
+
dummy.id = 100
|
17
|
+
|
18
|
+
dummy2 = EnumerableElement.new
|
19
|
+
dummy2.name = 'test2'
|
20
|
+
dummy2.id = 101
|
21
|
+
|
22
|
+
list = Arkenstone::QueryList.new [dummy, dummy2]
|
23
|
+
result = list.to_json
|
24
|
+
assert_equal(result, '[{"name":"test","id":100},{"name":"test2","id":101}]')
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_initialize_takes_array
|
28
|
+
list = Arkenstone::QueryList.new [10, 20]
|
29
|
+
assert_equal([10, 20], list)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_initialize_takes_element
|
33
|
+
list = Arkenstone::QueryList.new 'test'
|
34
|
+
assert_equal ['test'], list
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
class ArkenstoneEnvTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@env = Arkenstone::Environment.new url: 'http://example.com', verb: :get
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_env_takes_hash_to_init
|
11
|
+
assert(@env.url == 'http://example.com')
|
12
|
+
assert(@env.verb == :get)
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
class HelpersTest < Test::Unit::TestCase
|
6
|
+
def test_full_url
|
7
|
+
eval %(
|
8
|
+
class FooTest
|
9
|
+
include Arkenstone::Document
|
10
|
+
include Arkenstone::Helpers
|
11
|
+
|
12
|
+
url 'http://example.com'
|
13
|
+
end
|
14
|
+
)
|
15
|
+
|
16
|
+
assert_equal('http://example.com/', FooTest.full_url(FooTest.arkenstone_url))
|
17
|
+
end
|
18
|
+
end
|
data/test/test_hooks.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
class RequestHook < Arkenstone::Hook
|
6
|
+
attr_accessor :called
|
7
|
+
|
8
|
+
def before_request(_req)
|
9
|
+
@called = true
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class ResponseHook < Arkenstone::Hook
|
14
|
+
attr_accessor :called
|
15
|
+
|
16
|
+
def after_complete(_resp)
|
17
|
+
@called = true
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class ArkenstoneHookTest < Test::Unit::TestCase
|
22
|
+
def test_hook_called_before_request
|
23
|
+
request_hook = RequestHook.new
|
24
|
+
User.add_hook request_hook
|
25
|
+
assert(User.arkenstone_hooks.count == 1)
|
26
|
+
stub_request(:get, "#{User.arkenstone_url}1").to_return(body: '{}')
|
27
|
+
User.find(1)
|
28
|
+
assert(request_hook.called, 'hook was not called')
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_hook_called_after_complete
|
32
|
+
resp_hook = ResponseHook.new
|
33
|
+
User.add_hook resp_hook
|
34
|
+
stub_request(:get, "#{User.arkenstone_url}1").to_return(body: '{}')
|
35
|
+
User.find(1)
|
36
|
+
assert(resp_hook.called, 'response hook was not called')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_has_hooks
|
40
|
+
eval %(
|
41
|
+
class BaseThing
|
42
|
+
include Arkenstone::Document
|
43
|
+
add_hook RequestHook.new
|
44
|
+
end
|
45
|
+
)
|
46
|
+
assert_equal(true, Arkenstone::Hook.has_hooks?(BaseThing))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_has_hooks_via_inheritance
|
50
|
+
eval %(
|
51
|
+
class BaseThing
|
52
|
+
include Arkenstone::Document
|
53
|
+
add_hook RequestHook.new
|
54
|
+
end
|
55
|
+
|
56
|
+
class ChildThing < BaseThing
|
57
|
+
inherit_hooks
|
58
|
+
end
|
59
|
+
|
60
|
+
)
|
61
|
+
assert_equal(true, Arkenstone::Hook.has_hooks?(ChildThing))
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_has_hooks_negative
|
65
|
+
eval %(
|
66
|
+
class NoHooks
|
67
|
+
end
|
68
|
+
)
|
69
|
+
assert_equal(false, Arkenstone::Hook.has_hooks?(NoHooks))
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_all_hooks_for_class_verifies_inherit_hooks
|
73
|
+
eval %(
|
74
|
+
class BaseThing
|
75
|
+
include Arkenstone::Document
|
76
|
+
add_hook ResponseHook.new
|
77
|
+
end
|
78
|
+
|
79
|
+
class ChildThing < BaseThing
|
80
|
+
add_hook RequestHook.new
|
81
|
+
end
|
82
|
+
)
|
83
|
+
assert_equal(1, Arkenstone::Hook.all_hooks_for_class(ChildThing).count)
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_all_hooks_for_class_walks_the_inheritance_chain
|
87
|
+
eval %(
|
88
|
+
class BaseBaseThing
|
89
|
+
include Arkenstone::Document
|
90
|
+
add_hook ResponseHook.new
|
91
|
+
end
|
92
|
+
|
93
|
+
class DerpChildThing < BaseBaseThing
|
94
|
+
add_hook RequestHook.new
|
95
|
+
inherit_hooks
|
96
|
+
end
|
97
|
+
)
|
98
|
+
assert_equal(2, Arkenstone::Hook.all_hooks_for_class(DerpChildThing).count)
|
99
|
+
end
|
100
|
+
|
101
|
+
def teardown
|
102
|
+
User.arkenstone_hooks = []
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
class QueryBuilderTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@builder = Arkenstone::QueryBuilder.new
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_build_find_with_one_param
|
11
|
+
json = @builder.build do
|
12
|
+
{
|
13
|
+
foo: 'foo'
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
assert_equal '{"foo":"foo"}', json
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_build_find_in
|
21
|
+
json = @builder.build do
|
22
|
+
{
|
23
|
+
foo: _in(%w[foo bar])
|
24
|
+
}
|
25
|
+
end
|
26
|
+
assert_equal '{"foo":{"$in":["foo","bar"]}}', json
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_query_find_comparison
|
30
|
+
json = @builder.build do
|
31
|
+
{
|
32
|
+
foo: _gt(500)
|
33
|
+
}
|
34
|
+
end
|
35
|
+
assert_equal '{"foo":{"$gt":500}}', json
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_query_complex_find
|
39
|
+
json = @builder.build do
|
40
|
+
{
|
41
|
+
foo: 'foo',
|
42
|
+
bar: _in(%w[foo bar]),
|
43
|
+
baz: _gt(400)
|
44
|
+
}
|
45
|
+
end
|
46
|
+
assert_equal '{"foo":"foo","bar":{"$in":["foo","bar"]},"baz":{"$gt":400}}', json
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_query_and
|
50
|
+
json = @builder.build do
|
51
|
+
_and(
|
52
|
+
{ foo: 'foo' },
|
53
|
+
{ bar: 'bar' }
|
54
|
+
)
|
55
|
+
end
|
56
|
+
assert_equal '{"$and":[{"foo":"foo"},{"bar":"bar"}]}', json
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_query_and_with_gt
|
60
|
+
json = @builder.build do
|
61
|
+
_and(
|
62
|
+
{ foo: _gt(200) },
|
63
|
+
{ foo: _lt(300) }
|
64
|
+
)
|
65
|
+
end
|
66
|
+
assert_equal '{"$and":[{"foo":{"$gt":200}},{"foo":{"$lt":300}}]}', json
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_include
|
70
|
+
json = @builder.build do
|
71
|
+
_include %w[Foo Bar]
|
72
|
+
{
|
73
|
+
foo: 'foo'
|
74
|
+
}
|
75
|
+
end
|
76
|
+
assert_equal '{"$include":["Foo","Bar"],"foo":"foo"}', json
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_limit
|
80
|
+
json = @builder.build do
|
81
|
+
_limit 5
|
82
|
+
{
|
83
|
+
foo: 'foo'
|
84
|
+
}
|
85
|
+
end
|
86
|
+
assert_equal '{"$limit":5,"foo":"foo"}', json
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_complex_include_with_booleans
|
90
|
+
json = @builder.build do
|
91
|
+
_include %w[DocDataElement Document]
|
92
|
+
_or(
|
93
|
+
_and(
|
94
|
+
{ 'DocDataElement.Name' => 'AccountNumber' },
|
95
|
+
{ 'Value' => '123456' }
|
96
|
+
),
|
97
|
+
_and(
|
98
|
+
{ 'DocDataElement.Name' => 'Zip' },
|
99
|
+
{ 'Value' => '55555' }
|
100
|
+
)
|
101
|
+
)
|
102
|
+
end
|
103
|
+
assert_equal '{"$include":["DocDataElement","Document"],"$or":[{"$and":[{"DocDataElement.Name":"AccountNumber"},{"Value":"123456"}]},{"$and":[{"DocDataElement.Name":"Zip"},{"Value":"55555"}]}]}',
|
104
|
+
json
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_query_not
|
108
|
+
json = @builder.build do
|
109
|
+
_or(
|
110
|
+
_and(
|
111
|
+
{ foo: _gt(200) },
|
112
|
+
{ bar: 'bar' }
|
113
|
+
),
|
114
|
+
_not(
|
115
|
+
{ baz: 'derp' }
|
116
|
+
)
|
117
|
+
)
|
118
|
+
end
|
119
|
+
assert_equal '{"$or":[{"$and":[{"foo":{"$gt":200}},{"bar":"bar"}]},{"$not":[{"baz":"derp"}]}]}', json
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_query_or
|
123
|
+
json = @builder.build do
|
124
|
+
_or(
|
125
|
+
{ foo: _gt(200) },
|
126
|
+
{ bar: 'bar' }
|
127
|
+
)
|
128
|
+
end
|
129
|
+
assert_equal '{"$or":[{"foo":{"$gt":200}},{"bar":"bar"}]}', json
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_query_complex_and
|
133
|
+
json = @builder.build do
|
134
|
+
_or(
|
135
|
+
_and(
|
136
|
+
{ foo: _gt(200) },
|
137
|
+
{ bar: 'bar' }
|
138
|
+
),
|
139
|
+
_and(
|
140
|
+
{ derp: 'derp' }
|
141
|
+
)
|
142
|
+
)
|
143
|
+
end
|
144
|
+
assert_equal '{"$or":[{"$and":[{"foo":{"$gt":200}},{"bar":"bar"}]},{"$and":[{"derp":"derp"}]}]}', json
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_query_is_idempotent
|
148
|
+
json = @builder.build do
|
149
|
+
_and(
|
150
|
+
{ foo: _gt(200) },
|
151
|
+
{ bar: 'bar' }
|
152
|
+
)
|
153
|
+
end
|
154
|
+
assert_equal '{"$and":[{"foo":{"$gt":200}},{"bar":"bar"}]}', json
|
155
|
+
json = @builder.build do
|
156
|
+
_and(
|
157
|
+
{ foo: _gt(200) },
|
158
|
+
{ derp: 'derp derp' }
|
159
|
+
)
|
160
|
+
end
|
161
|
+
assert_equal '{"$and":[{"foo":{"$gt":200}},{"derp":"derp derp"}]}', json
|
162
|
+
end
|
163
|
+
end
|