crud-service 0.0.9 → 0.1.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 +6 -14
- data/lib/crud-service.rb +6 -3
- data/lib/crud-service/api.rb +152 -0
- data/lib/{dal.rb → crud-service/dal.rb} +25 -5
- data/lib/{service.rb → crud-service/service.rb} +7 -1
- data/lib/crud-service/version.rb +5 -0
- data/spec/api_spec.rb +609 -0
- data/spec/dal_spec.rb +1363 -0
- data/spec/{unit/service_spec.rb → service_spec.rb} +23 -23
- data/spec/spec_helper.rb +58 -0
- metadata +70 -106
- data/lib/api.rb +0 -129
- data/spec/helper.rb +0 -12
- data/spec/helpers_spec.rb +0 -30
- data/spec/unit/dal_spec.rb +0 -1174
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
YTI3MDU2ZmU4MTc1ZDU2MWM3NmM1MGFiYTIwMDYzYWEzNWY3MGQ1MzY3YjBh
|
10
|
-
Y2Q5NWEyYjczZmIzZmMzZGY0Mjg5MGEzMTViOWE4NGRiODc1NThjZjA5NGE0
|
11
|
-
MzcyZmQxMmIxZDE2ZmZhMGY3OGY1NzU4ZjE0ZDczMTE4NGQ4ZWQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
YTQzOGZlMjM2MDkxODAzZDU0ZmMyZDM1MzQ2Njc0ZTM2MTg1MmQ4ZmI4MTAw
|
14
|
-
NzVmZTkzNDJmMTRlNjBlNDQ2YmQ1MTY1YzE0MmI1MzljZTZhZjE4ZWJkODky
|
15
|
-
N2I0MjIwMWE0M2IwZjA2YjMxMmU2NzRhODhjNWM3MWY3ZDZiNjI=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7790c1877ec4d0783a3813a172928fb84e8611c0
|
4
|
+
data.tar.gz: 53ec5d4ae333d795cf0aaa1a47b7211ce79256e2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 2900ea911d11cb0f7c2ab0c00280a656c135216309eee42397350ee06e0f072db7d2a71554d54d98b7ea071165b23a10b2073c798c463115d133d8f450478b32
|
7
|
+
data.tar.gz: 22124825d383be131bc3f58ac0f0eef5a9cadcf4f886e5548cf053c1c3bcc7e9b35e24a7174ba9b6529ab5dd5317bd984ae1c798b03b3e66c8787c7028bea1ba
|
data/lib/crud-service.rb
CHANGED
@@ -0,0 +1,152 @@
|
|
1
|
+
module CrudService
|
2
|
+
# This mixin provides a static methods to configure a sinatra class with the
|
3
|
+
# provided resource name, service and api_options
|
4
|
+
module Api
|
5
|
+
# Set up full CRUD API functionality on the given resource
|
6
|
+
def crud_api(resource_name, service_name, primary_key_name, api_options = {})
|
7
|
+
api_options = get_defaults(api_options)
|
8
|
+
|
9
|
+
crud_options(resource_name, api_options) if api_options[:enable_options]
|
10
|
+
|
11
|
+
if api_options[:enable_write]
|
12
|
+
crud_post(resource_name, service_name, primary_key_name, api_options) if api_options[:enable_post]
|
13
|
+
crud_put(resource_name, service_name, primary_key_name, api_options) if api_options[:enable_put]
|
14
|
+
crud_delete(resource_name, service_name, primary_key_name, api_options) if api_options[:enable_delete]
|
15
|
+
end
|
16
|
+
|
17
|
+
if api_options[:enable_read]
|
18
|
+
crud_get(resource_name, service_name, primary_key_name, api_options) if api_options[:enable_get]
|
19
|
+
crud_get_all(resource_name, service_name, api_options) if api_options[:enable_get_all]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
# Set up OPTIONS functionality on the given resource
|
24
|
+
def crud_options(resource_name, api_options = {})
|
25
|
+
api_options = get_defaults(api_options)
|
26
|
+
options '/'+resource_name do
|
27
|
+
204
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# Set up UPDATE/put functionality on the given resource
|
32
|
+
def crud_put(resource_name, service_name, primary_key_name, api_options = {})
|
33
|
+
api_options = get_defaults(api_options)
|
34
|
+
put '/'+resource_name+'/:'+primary_key_name do
|
35
|
+
service = settings.send(service_name)
|
36
|
+
|
37
|
+
# Must Exist
|
38
|
+
return 404 unless service.exists_by_primary_key?(params[primary_key_name.to_sym])
|
39
|
+
|
40
|
+
# Get The Data
|
41
|
+
begin
|
42
|
+
data = JSON.parse(request.body.read)
|
43
|
+
rescue Exception => e
|
44
|
+
return 422
|
45
|
+
end
|
46
|
+
|
47
|
+
# Valid Update?
|
48
|
+
return 422 unless service.valid_update?(data)
|
49
|
+
|
50
|
+
# Do Update
|
51
|
+
record = service.update_by_primary_key(params[primary_key_name.to_sym],data)
|
52
|
+
|
53
|
+
# Other Error
|
54
|
+
return 500 if record.nil?
|
55
|
+
|
56
|
+
# Return new Region
|
57
|
+
JSON.fast_generate record
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Set up GET/get_one functionality on the given resource
|
62
|
+
def crud_get(resource_name, service_name, primary_key_name, api_options = {})
|
63
|
+
api_options = get_defaults(api_options)
|
64
|
+
get '/'+resource_name+'/:'+primary_key_name do
|
65
|
+
service = settings.send(service_name)
|
66
|
+
|
67
|
+
sanitize_params(params)
|
68
|
+
return 400 unless service.valid_query?(params)
|
69
|
+
|
70
|
+
record = service.get_one_by_query(params)
|
71
|
+
return 404 if record.nil?
|
72
|
+
JSON.fast_generate record
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# Set up GET/get_all functionality on the given resource
|
77
|
+
def crud_get_all(resource_name, service_name, api_options = {})
|
78
|
+
api_options = get_defaults(api_options)
|
79
|
+
get '/'+resource_name do
|
80
|
+
service = settings.send(service_name)
|
81
|
+
|
82
|
+
sanitize_params(params)
|
83
|
+
# Check query validity
|
84
|
+
return 400 unless service.valid_query?(params)
|
85
|
+
|
86
|
+
# Return Regions on Query
|
87
|
+
JSON.fast_generate service.get_all_by_query(params)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Set up DELETE functionality on the given resource
|
92
|
+
def crud_delete(resource_name, service_name, primary_key_name, api_options = {})
|
93
|
+
api_options = get_defaults(api_options)
|
94
|
+
delete '/'+resource_name+'/:'+primary_key_name do
|
95
|
+
service = settings.send(service_name)
|
96
|
+
|
97
|
+
# Must Exist
|
98
|
+
return 404 unless service.exists_by_primary_key?(params[primary_key_name.to_sym])
|
99
|
+
|
100
|
+
# Do Delete
|
101
|
+
return 500 unless service.delete_by_primary_key(params[primary_key_name.to_sym])
|
102
|
+
|
103
|
+
204
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Set up POST/insert functionality on the given resource
|
108
|
+
def crud_post(resource_name, service_name, primary_key_name, api_options = {})
|
109
|
+
api_options = get_defaults(api_options)
|
110
|
+
post '/'+resource_name do
|
111
|
+
service = settings.send(service_name)
|
112
|
+
|
113
|
+
# Get The data
|
114
|
+
begin
|
115
|
+
data = JSON.parse(request.body.read)
|
116
|
+
rescue Exception => e
|
117
|
+
return 422
|
118
|
+
end
|
119
|
+
|
120
|
+
# Valid POST?
|
121
|
+
return 422 unless service.valid_insert?(data)
|
122
|
+
|
123
|
+
# Already Exists?
|
124
|
+
return 409 if service.exists_by_primary_key?(data[primary_key_name])
|
125
|
+
|
126
|
+
# Do Insert
|
127
|
+
record = service.insert(data)
|
128
|
+
|
129
|
+
# Other Error
|
130
|
+
return 500 if record.nil?
|
131
|
+
|
132
|
+
# Output new record
|
133
|
+
JSON.fast_generate record
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
# Return the given options with defaults set
|
138
|
+
def get_defaults(api_options)
|
139
|
+
defaults = {
|
140
|
+
:enable_read => true,
|
141
|
+
:enable_write => true,
|
142
|
+
:enable_options => true,
|
143
|
+
:enable_get_all => true,
|
144
|
+
:enable_get => true,
|
145
|
+
:enable_post => true,
|
146
|
+
:enable_put => true,
|
147
|
+
:enable_delete => true,
|
148
|
+
}
|
149
|
+
api_options.merge!(defaults) { |key, v1, v2| v1 }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'json'
|
2
1
|
require 'mysql2'
|
3
2
|
|
4
3
|
module CrudService
|
@@ -7,7 +6,24 @@ module CrudService
|
|
7
6
|
# Your should extend this class to provide configuration for your dal, please see
|
8
7
|
# the README file at http://github.com/tomcully/crud-service
|
9
8
|
class Dal
|
10
|
-
|
9
|
+
# The DB layer to use, e.g. an instance of Mysql2::Client
|
10
|
+
attr_accessor :mysql
|
11
|
+
# The Memcache layer to use, e.g. an instance of Dalli::Client
|
12
|
+
attr_accessor :memcache
|
13
|
+
# The logger to use, e.g. an instance of Console::Logger
|
14
|
+
attr_accessor :log
|
15
|
+
# The DB table name
|
16
|
+
attr_accessor :table_name
|
17
|
+
# A Hash of table fields (See README)
|
18
|
+
attr_accessor :fields
|
19
|
+
# A Hash of table relations (See README)
|
20
|
+
attr_accessor :relations
|
21
|
+
# The primary key name
|
22
|
+
attr_accessor :primary_key
|
23
|
+
# If true, the primary key values are assigned by the DB layer
|
24
|
+
attr_accessor :auto_primary_key
|
25
|
+
# The memcache key prefix for this DAL
|
26
|
+
attr_accessor :cache_prefix
|
11
27
|
|
12
28
|
# Create an instance.
|
13
29
|
def initialize(mysql, memcache = nil, log)
|
@@ -105,6 +121,7 @@ module CrudService
|
|
105
121
|
where.chomp(' AND ')
|
106
122
|
end
|
107
123
|
|
124
|
+
# Build a simple where clause from the given query with the given table/db namespace
|
108
125
|
def build_where_ns(query,ns)
|
109
126
|
where = ""
|
110
127
|
query.each_pair do |k, v|
|
@@ -214,6 +231,7 @@ module CrudService
|
|
214
231
|
map_to_hash_by_primary_key(get_all_by_query(query))
|
215
232
|
end
|
216
233
|
|
234
|
+
# Map in the included relations to each of the supplied result rows
|
217
235
|
def map_in_included_relations!(result, query)
|
218
236
|
dat = get_relation_data_as_hash(query)
|
219
237
|
result.each do |res|
|
@@ -230,7 +248,7 @@ module CrudService
|
|
230
248
|
|
231
249
|
# Get data for included relations for a query
|
232
250
|
def get_relation_data_as_hash(query)
|
233
|
-
return {} if @relations.nil?
|
251
|
+
return {} if @relations.nil? or @relations.empty?
|
234
252
|
|
235
253
|
includes = get_includes(query)
|
236
254
|
|
@@ -248,6 +266,7 @@ module CrudService
|
|
248
266
|
reldata
|
249
267
|
end
|
250
268
|
|
269
|
+
# Remove the given key from each record in the supplied hash
|
251
270
|
def remove_key_from_hash_of_arrays!(hash,key)
|
252
271
|
hash.each do |name,arr|
|
253
272
|
arr.each do |record|
|
@@ -311,6 +330,7 @@ module CrudService
|
|
311
330
|
return get_has_many_through_relation_query_sql(relation, query)
|
312
331
|
else
|
313
332
|
@log.error("Relation type #{relation[:type]} undefined!")
|
333
|
+
nil
|
314
334
|
end
|
315
335
|
end
|
316
336
|
|
@@ -354,7 +374,7 @@ module CrudService
|
|
354
374
|
when :has_many_through
|
355
375
|
return [@table_name, relation[:table], relation[:link_table]].sort
|
356
376
|
else
|
357
|
-
|
377
|
+
raise "Unknown Relation type #{relation[:type]}"
|
358
378
|
end
|
359
379
|
end
|
360
380
|
|
@@ -427,7 +447,7 @@ module CrudService
|
|
427
447
|
queryresult = @mysql.query(query)
|
428
448
|
rescue Exception => e
|
429
449
|
@log.error("#{e}")
|
430
|
-
return
|
450
|
+
return nil
|
431
451
|
end
|
432
452
|
|
433
453
|
expire_table_cache(get_all_related_tables)
|
@@ -1,6 +1,12 @@
|
|
1
1
|
module CrudService
|
2
|
+
# Service provides a generic mapping layer between the API and the DAL.
|
3
|
+
# You should extend this class, or provide a class with the same interface,
|
4
|
+
# to implement service level functionality, or support REST-like RPC.
|
2
5
|
class Service
|
3
|
-
|
6
|
+
# The DAL layer to use, e.g. an instance of CrudService::DAL
|
7
|
+
attr_accessor :dal
|
8
|
+
# The logger to use, e.g. an instance of Console::Logger
|
9
|
+
attr_accessor :log
|
4
10
|
|
5
11
|
# Instantiate a service with the specified DAL and logger.
|
6
12
|
def initialize(dal, log)
|
data/spec/api_spec.rb
ADDED
@@ -0,0 +1,609 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
class TestAPI
|
4
|
+
include CrudService::Api
|
5
|
+
end
|
6
|
+
|
7
|
+
describe CrudService::Api do
|
8
|
+
|
9
|
+
describe '#get_defaults' do
|
10
|
+
|
11
|
+
it 'should produce correct fields' do
|
12
|
+
inst = TestAPI.new
|
13
|
+
|
14
|
+
mock_opts = {
|
15
|
+
:enable_read=>true,
|
16
|
+
:enable_write=>true,
|
17
|
+
:enable_options=>true,
|
18
|
+
:enable_get_all=>true,
|
19
|
+
:enable_get=>true,
|
20
|
+
:enable_post=>true,
|
21
|
+
:enable_put=>true,
|
22
|
+
:enable_delete=>true
|
23
|
+
}
|
24
|
+
|
25
|
+
expect(inst.get_defaults({})).to eq(mock_opts)
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should not overwrite existing fields' do
|
29
|
+
inst = TestAPI.new
|
30
|
+
|
31
|
+
mock_opts = {
|
32
|
+
:enable_read=>true,
|
33
|
+
:enable_write=>true,
|
34
|
+
:enable_options=>false,
|
35
|
+
:enable_get_all=>true,
|
36
|
+
:enable_get=>true,
|
37
|
+
:enable_post=>true,
|
38
|
+
:enable_put=>true,
|
39
|
+
:enable_delete=>true
|
40
|
+
}
|
41
|
+
|
42
|
+
expect(inst.get_defaults({:enable_options=>false})).to eq(mock_opts)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
describe '#crud_api' do
|
47
|
+
it 'should call correct methods in correct order for defaults' do
|
48
|
+
mock_opts = {
|
49
|
+
:enable_read=>true,
|
50
|
+
:enable_write=>true,
|
51
|
+
:enable_options=>true,
|
52
|
+
:enable_get_all=>true,
|
53
|
+
:enable_get=>true,
|
54
|
+
:enable_post=>true,
|
55
|
+
:enable_put=>true,
|
56
|
+
:enable_delete=>true
|
57
|
+
}
|
58
|
+
|
59
|
+
inst = TestAPI.new
|
60
|
+
|
61
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
62
|
+
expect(inst).to receive(:crud_post).with(1,2,3,mock_opts)
|
63
|
+
expect(inst).to receive(:crud_put).with(1,2,3,mock_opts)
|
64
|
+
expect(inst).to receive(:crud_delete).with(1,2,3,mock_opts)
|
65
|
+
expect(inst).to receive(:crud_get).with(1,2,3,mock_opts)
|
66
|
+
expect(inst).to receive(:crud_get_all).with(1,2,mock_opts)
|
67
|
+
|
68
|
+
inst.crud_api(1,2,3,{})
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'should not call write methods if enable_write is false' do
|
72
|
+
mock_opts = { :enable_write=>false, :enable_post=>true, :enable_put=>true, :enable_delete=>true }
|
73
|
+
|
74
|
+
inst = TestAPI.new
|
75
|
+
|
76
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
77
|
+
expect(inst).not_to receive(:crud_post).with(1,2,3,mock_opts)
|
78
|
+
expect(inst).not_to receive(:crud_put).with(1,2,3,mock_opts)
|
79
|
+
expect(inst).not_to receive(:crud_delete).with(1,2,3,mock_opts)
|
80
|
+
expect(inst).to receive(:crud_get).with(1,2,3,mock_opts)
|
81
|
+
expect(inst).to receive(:crud_get_all).with(1,2,mock_opts)
|
82
|
+
|
83
|
+
inst.crud_api(1,2,3,mock_opts)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should not call read methods if enable_read is false' do
|
87
|
+
mock_opts = { :enable_read=>false, :enable_get=>true, :enable_get_all=>true }
|
88
|
+
|
89
|
+
inst = TestAPI.new
|
90
|
+
|
91
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
92
|
+
expect(inst).to receive(:crud_post).with(1,2,3,mock_opts)
|
93
|
+
expect(inst).to receive(:crud_put).with(1,2,3,mock_opts)
|
94
|
+
expect(inst).to receive(:crud_delete).with(1,2,3,mock_opts)
|
95
|
+
expect(inst).not_to receive(:crud_get).with(1,2,3,mock_opts)
|
96
|
+
expect(inst).not_to receive(:crud_get_all).with(1,2,mock_opts)
|
97
|
+
|
98
|
+
inst.crud_api(1,2,3,mock_opts)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should not call crud_post method if enable_post is false' do
|
102
|
+
mock_opts = { :enable_read=>true, :enable_write=>true, :enable_post=>false }
|
103
|
+
|
104
|
+
inst = TestAPI.new
|
105
|
+
|
106
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
107
|
+
expect(inst).not_to receive(:crud_post).with(1,2,3,mock_opts)
|
108
|
+
expect(inst).to receive(:crud_put).with(1,2,3,mock_opts)
|
109
|
+
expect(inst).to receive(:crud_delete).with(1,2,3,mock_opts)
|
110
|
+
expect(inst).to receive(:crud_get).with(1,2,3,mock_opts)
|
111
|
+
expect(inst).to receive(:crud_get_all).with(1,2,mock_opts)
|
112
|
+
|
113
|
+
inst.crud_api(1,2,3,mock_opts)
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should not call crud_put method if enable_put is false' do
|
117
|
+
mock_opts = { :enable_read=>true, :enable_write=>true, :enable_put=>false }
|
118
|
+
|
119
|
+
inst = TestAPI.new
|
120
|
+
|
121
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
122
|
+
expect(inst).to receive(:crud_post).with(1,2,3,mock_opts)
|
123
|
+
expect(inst).not_to receive(:crud_put).with(1,2,3,mock_opts)
|
124
|
+
expect(inst).to receive(:crud_delete).with(1,2,3,mock_opts)
|
125
|
+
expect(inst).to receive(:crud_get).with(1,2,3,mock_opts)
|
126
|
+
expect(inst).to receive(:crud_get_all).with(1,2,mock_opts)
|
127
|
+
|
128
|
+
inst.crud_api(1,2,3,mock_opts)
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'should not call crud_delete method if enable_delete is false' do
|
132
|
+
mock_opts = { :enable_read=>true, :enable_write=>true, :enable_delete=>false }
|
133
|
+
|
134
|
+
inst = TestAPI.new
|
135
|
+
|
136
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
137
|
+
expect(inst).to receive(:crud_post).with(1,2,3,mock_opts)
|
138
|
+
expect(inst).to receive(:crud_put).with(1,2,3,mock_opts)
|
139
|
+
expect(inst).not_to receive(:crud_delete).with(1,2,3,mock_opts)
|
140
|
+
expect(inst).to receive(:crud_get).with(1,2,3,mock_opts)
|
141
|
+
expect(inst).to receive(:crud_get_all).with(1,2,mock_opts)
|
142
|
+
|
143
|
+
inst.crud_api(1,2,3,mock_opts)
|
144
|
+
end
|
145
|
+
|
146
|
+
it 'should not call crud_get method if enable_get is false' do
|
147
|
+
mock_opts = { :enable_read=>true, :enable_write=>true, :enable_get=>false }
|
148
|
+
|
149
|
+
inst = TestAPI.new
|
150
|
+
|
151
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
152
|
+
expect(inst).to receive(:crud_post).with(1,2,3,mock_opts)
|
153
|
+
expect(inst).to receive(:crud_put).with(1,2,3,mock_opts)
|
154
|
+
expect(inst).to receive(:crud_delete).with(1,2,3,mock_opts)
|
155
|
+
expect(inst).not_to receive(:crud_get).with(1,2,3,mock_opts)
|
156
|
+
expect(inst).to receive(:crud_get_all).with(1,2,mock_opts)
|
157
|
+
|
158
|
+
inst.crud_api(1,2,3,mock_opts)
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'should not call crud_get_all method if enable_get_all is false' do
|
162
|
+
mock_opts = { :enable_read=>true, :enable_write=>true, :enable_get_all=>false }
|
163
|
+
|
164
|
+
inst = TestAPI.new
|
165
|
+
|
166
|
+
expect(inst).to receive(:crud_options).with(1,mock_opts)
|
167
|
+
expect(inst).to receive(:crud_post).with(1,2,3,mock_opts)
|
168
|
+
expect(inst).to receive(:crud_put).with(1,2,3,mock_opts)
|
169
|
+
expect(inst).to receive(:crud_delete).with(1,2,3,mock_opts)
|
170
|
+
expect(inst).to receive(:crud_get).with(1,2,3,mock_opts)
|
171
|
+
expect(inst).not_to receive(:crud_get_all).with(1,2,mock_opts)
|
172
|
+
|
173
|
+
inst.crud_api(1,2,3,mock_opts)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe '#crud_options' do
|
178
|
+
it 'should call get_defaults and options' do
|
179
|
+
mock_opts = { :enable_get_all=>false }
|
180
|
+
|
181
|
+
inst = TestAPI.new
|
182
|
+
|
183
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
184
|
+
expect(inst).to receive(:options) do |resname, &block|
|
185
|
+
expect(resname).to eq('/resource')
|
186
|
+
expect(block.call).to eq(204)
|
187
|
+
end
|
188
|
+
|
189
|
+
inst.crud_options('resource', mock_opts)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe '#crud_put' do
|
194
|
+
it 'should call get_defaults and options, return 404 if record doesnt exist' do
|
195
|
+
mock_opts = { :enable_get_all=>false }
|
196
|
+
|
197
|
+
inst = TestAPI.new
|
198
|
+
|
199
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
200
|
+
expect(inst).to receive(:put) do |resname, &block|
|
201
|
+
expect(resname).to eq('/resource/:primary')
|
202
|
+
|
203
|
+
settings = OpenStruct.new
|
204
|
+
service = OpenStruct.new
|
205
|
+
expect(inst).to receive(:settings).and_return(settings)
|
206
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
207
|
+
|
208
|
+
expect(inst).to receive(:params).and_return({:primary=>34567})
|
209
|
+
expect(service).to receive(:exists_by_primary_key?).with(34567).and_return(false)
|
210
|
+
block.call
|
211
|
+
|
212
|
+
end
|
213
|
+
|
214
|
+
expect(inst.crud_put('resource','service','primary',mock_opts)).to eq(404)
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'should call get_defaults and options, return 422 if JSON parse fails' do
|
218
|
+
mock_opts = { :enable_get_all=>false }
|
219
|
+
|
220
|
+
inst = TestAPI.new
|
221
|
+
|
222
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
223
|
+
expect(inst).to receive(:put) do |resname, &block|
|
224
|
+
expect(resname).to eq('/resource/:primary')
|
225
|
+
|
226
|
+
settings = OpenStruct.new
|
227
|
+
service = OpenStruct.new
|
228
|
+
expect(inst).to receive(:settings).and_return(settings)
|
229
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
230
|
+
|
231
|
+
expect(inst).to receive(:params).and_return({:primary=>34567})
|
232
|
+
expect(service).to receive(:exists_by_primary_key?).with(34567).and_return(true)
|
233
|
+
|
234
|
+
request = OpenStruct.new({:body=>OpenStruct.new({:read => '{"one":1'})})
|
235
|
+
expect(inst).to receive(:request).and_return(request)
|
236
|
+
|
237
|
+
block.call
|
238
|
+
end
|
239
|
+
|
240
|
+
expect(inst.crud_put('resource','service','primary',mock_opts)).to eq(422)
|
241
|
+
end
|
242
|
+
|
243
|
+
it 'should call get_defaults and options, return 500 if update fails' do
|
244
|
+
mock_opts = { :enable_get_all=>false }
|
245
|
+
|
246
|
+
inst = TestAPI.new
|
247
|
+
|
248
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
249
|
+
expect(inst).to receive(:put) do |resname, &block|
|
250
|
+
expect(resname).to eq('/resource/:primary')
|
251
|
+
|
252
|
+
settings = OpenStruct.new
|
253
|
+
service = OpenStruct.new
|
254
|
+
expect(inst).to receive(:settings).and_return(settings)
|
255
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
256
|
+
|
257
|
+
expect(inst).to receive(:params).twice.and_return({:primary=>34567})
|
258
|
+
expect(service).to receive(:exists_by_primary_key?).with(34567).and_return(true)
|
259
|
+
|
260
|
+
request = OpenStruct.new({:body=>OpenStruct.new({:read => '{"one":1}'})})
|
261
|
+
expect(inst).to receive(:request).and_return(request)
|
262
|
+
|
263
|
+
expect(service).to receive(:valid_update?).with({"one"=>1}).and_return(true)
|
264
|
+
|
265
|
+
expect(service).to receive(:update_by_primary_key).with(34567, {"one"=>1}).and_return(nil)
|
266
|
+
|
267
|
+
block.call
|
268
|
+
end
|
269
|
+
|
270
|
+
expect(inst.crud_put('resource','service','primary',mock_opts)).to eq(500)
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should call get_defaults and options, return JSON string of record' do
|
274
|
+
mock_opts = { :enable_get_all=>false }
|
275
|
+
|
276
|
+
inst = TestAPI.new
|
277
|
+
|
278
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
279
|
+
expect(inst).to receive(:put) do |resname, &block|
|
280
|
+
expect(resname).to eq('/resource/:primary')
|
281
|
+
|
282
|
+
settings = OpenStruct.new
|
283
|
+
service = OpenStruct.new
|
284
|
+
expect(inst).to receive(:settings).and_return(settings)
|
285
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
286
|
+
|
287
|
+
expect(inst).to receive(:params).twice.and_return({:primary=>34567})
|
288
|
+
expect(service).to receive(:exists_by_primary_key?).with(34567).and_return(true)
|
289
|
+
|
290
|
+
request = OpenStruct.new({:body=>OpenStruct.new({:read => '{"one":1}'})})
|
291
|
+
expect(inst).to receive(:request).and_return(request)
|
292
|
+
|
293
|
+
expect(service).to receive(:valid_update?).with({"one"=>1}).and_return(true)
|
294
|
+
|
295
|
+
expect(service).to receive(:update_by_primary_key).with(34567, {"one"=>1}).and_return({"two"=>2})
|
296
|
+
|
297
|
+
block.call
|
298
|
+
end
|
299
|
+
|
300
|
+
expect(inst.crud_put('resource','service','primary',mock_opts)).to eq('{"two":2}')
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
describe '#crud_get' do
|
305
|
+
it 'should call get_defaults and options, return 400 if bad query' do
|
306
|
+
mock_opts = { :enable_get_all=>false }
|
307
|
+
|
308
|
+
inst = TestAPI.new
|
309
|
+
|
310
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
311
|
+
expect(inst).to receive(:get) do |resname, &block|
|
312
|
+
expect(resname).to eq('/resource/:primary')
|
313
|
+
|
314
|
+
service = OpenStruct.new
|
315
|
+
settings = OpenStruct.new("service_name" => service)
|
316
|
+
params = OpenStruct.new
|
317
|
+
expect(inst).to receive(:settings).and_return(settings)
|
318
|
+
expect(inst).to receive(:params).twice.and_return(params)
|
319
|
+
|
320
|
+
expect(inst).to receive(:sanitize_params).with(params)
|
321
|
+
expect(service).to receive(:valid_query?).with(params).and_return(false)
|
322
|
+
|
323
|
+
block.call
|
324
|
+
end
|
325
|
+
|
326
|
+
expect(inst.crud_get('resource','service_name','primary',mock_opts)).to eq(400)
|
327
|
+
end
|
328
|
+
|
329
|
+
it 'should call get_defaults and options, return 404 if not found' do
|
330
|
+
mock_opts = { :enable_get_all=>false }
|
331
|
+
|
332
|
+
inst = TestAPI.new
|
333
|
+
|
334
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
335
|
+
expect(inst).to receive(:get) do |resname, &block|
|
336
|
+
expect(resname).to eq('/resource/:primary')
|
337
|
+
|
338
|
+
service = OpenStruct.new
|
339
|
+
settings = OpenStruct.new("service_name" => service)
|
340
|
+
params = OpenStruct.new
|
341
|
+
expect(inst).to receive(:settings).and_return(settings)
|
342
|
+
expect(inst).to receive(:params).thrice.and_return(params)
|
343
|
+
|
344
|
+
expect(inst).to receive(:sanitize_params).with(params)
|
345
|
+
expect(service).to receive(:valid_query?).with(params).and_return(true)
|
346
|
+
|
347
|
+
expect(service).to receive(:get_one_by_query).with(params).and_return(nil)
|
348
|
+
|
349
|
+
block.call
|
350
|
+
end
|
351
|
+
|
352
|
+
expect(inst.crud_get('resource','service_name','primary',mock_opts)).to eq(404)
|
353
|
+
end
|
354
|
+
|
355
|
+
it 'should call get_defaults and options, return 404 if not found' do
|
356
|
+
mock_opts = { :enable_get_all=>false }
|
357
|
+
|
358
|
+
inst = TestAPI.new
|
359
|
+
|
360
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
361
|
+
expect(inst).to receive(:get) do |resname, &block|
|
362
|
+
expect(resname).to eq('/resource/:primary')
|
363
|
+
|
364
|
+
service = OpenStruct.new
|
365
|
+
settings = OpenStruct.new("service_name" => service)
|
366
|
+
params = OpenStruct.new
|
367
|
+
expect(inst).to receive(:settings).and_return(settings)
|
368
|
+
expect(inst).to receive(:params).thrice.and_return(params)
|
369
|
+
|
370
|
+
expect(inst).to receive(:sanitize_params).with(params)
|
371
|
+
expect(service).to receive(:valid_query?).with(params).and_return(true)
|
372
|
+
|
373
|
+
expect(service).to receive(:get_one_by_query).with(params).and_return({"three"=>3})
|
374
|
+
|
375
|
+
block.call
|
376
|
+
end
|
377
|
+
|
378
|
+
expect(inst.crud_get('resource','service_name','primary',mock_opts)).to eq('{"three":3}')
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
describe '#crud_get_all' do
|
383
|
+
it 'should call get_defaults and options, return 400 if bad query' do
|
384
|
+
mock_opts = { :enable_get_all=>false }
|
385
|
+
|
386
|
+
inst = TestAPI.new
|
387
|
+
|
388
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
389
|
+
expect(inst).to receive(:get) do |resname, &block|
|
390
|
+
expect(resname).to eq('/resource')
|
391
|
+
|
392
|
+
service = OpenStruct.new
|
393
|
+
settings = OpenStruct.new("service_name" => service)
|
394
|
+
params = OpenStruct.new
|
395
|
+
expect(inst).to receive(:settings).and_return(settings)
|
396
|
+
expect(inst).to receive(:params).twice.and_return(params)
|
397
|
+
|
398
|
+
expect(inst).to receive(:sanitize_params).with(params)
|
399
|
+
expect(service).to receive(:valid_query?).with(params).and_return(false)
|
400
|
+
|
401
|
+
block.call
|
402
|
+
end
|
403
|
+
|
404
|
+
expect(inst.crud_get_all('resource','service_name',mock_opts)).to eq(400)
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'should call get_defaults and options, return JSON string from records' do
|
408
|
+
mock_opts = { :enable_get_all=>false }
|
409
|
+
|
410
|
+
inst = TestAPI.new
|
411
|
+
|
412
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
413
|
+
expect(inst).to receive(:get) do |resname, &block|
|
414
|
+
expect(resname).to eq('/resource')
|
415
|
+
|
416
|
+
service = OpenStruct.new
|
417
|
+
settings = OpenStruct.new("service_name" => service)
|
418
|
+
params = OpenStruct.new
|
419
|
+
expect(inst).to receive(:settings).and_return(settings)
|
420
|
+
expect(inst).to receive(:params).thrice.and_return(params)
|
421
|
+
|
422
|
+
expect(inst).to receive(:sanitize_params).with(params)
|
423
|
+
expect(service).to receive(:valid_query?).with(params).and_return(true)
|
424
|
+
|
425
|
+
expect(service).to receive(:get_all_by_query).with(params).and_return([{"three"=>3}])
|
426
|
+
|
427
|
+
block.call
|
428
|
+
end
|
429
|
+
|
430
|
+
expect(inst.crud_get_all('resource','service_name',mock_opts)).to eq('[{"three":3}]')
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
describe '#crud_delete' do
|
435
|
+
it 'should call get_defaults and options, return 404 if not found' do
|
436
|
+
mock_opts = { :enable_get_all=>false }
|
437
|
+
|
438
|
+
inst = TestAPI.new
|
439
|
+
|
440
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
441
|
+
expect(inst).to receive(:delete) do |resname, &block|
|
442
|
+
expect(resname).to eq('/resource/:primary')
|
443
|
+
|
444
|
+
service = OpenStruct.new
|
445
|
+
settings = OpenStruct.new("service_name" => service)
|
446
|
+
params = OpenStruct.new({"primary"=>6})
|
447
|
+
expect(inst).to receive(:settings).and_return(settings)
|
448
|
+
expect(inst).to receive(:params).and_return(params)
|
449
|
+
|
450
|
+
expect(service).to receive(:exists_by_primary_key?).with(6).and_return(false)
|
451
|
+
|
452
|
+
block.call
|
453
|
+
end
|
454
|
+
|
455
|
+
expect(inst.crud_delete('resource','service_name','primary',mock_opts)).to eq(404)
|
456
|
+
end
|
457
|
+
|
458
|
+
it 'should call get_defaults and options, return 500 if record failed to delete' do
|
459
|
+
mock_opts = { :enable_get_all=>false }
|
460
|
+
|
461
|
+
inst = TestAPI.new
|
462
|
+
|
463
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
464
|
+
expect(inst).to receive(:delete) do |resname, &block|
|
465
|
+
expect(resname).to eq('/resource/:primary')
|
466
|
+
|
467
|
+
service = OpenStruct.new
|
468
|
+
settings = OpenStruct.new("service_name" => service)
|
469
|
+
params = OpenStruct.new({"primary"=>6})
|
470
|
+
expect(inst).to receive(:settings).and_return(settings)
|
471
|
+
expect(inst).to receive(:params).twice.and_return(params)
|
472
|
+
|
473
|
+
expect(service).to receive(:exists_by_primary_key?).with(6).and_return(true)
|
474
|
+
expect(service).to receive(:delete_by_primary_key).with(6).and_return(false)
|
475
|
+
|
476
|
+
block.call
|
477
|
+
end
|
478
|
+
|
479
|
+
expect(inst.crud_delete('resource','service_name','primary',mock_opts)).to eq(500)
|
480
|
+
end
|
481
|
+
|
482
|
+
it 'should call get_defaults and options, return 204 if record deletes ok' do
|
483
|
+
mock_opts = { :enable_get_all=>false }
|
484
|
+
|
485
|
+
inst = TestAPI.new
|
486
|
+
|
487
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
488
|
+
expect(inst).to receive(:delete) do |resname, &block|
|
489
|
+
expect(resname).to eq('/resource/:primary')
|
490
|
+
|
491
|
+
service = OpenStruct.new
|
492
|
+
settings = OpenStruct.new("service_name" => service)
|
493
|
+
params = OpenStruct.new({"primary"=>6})
|
494
|
+
expect(inst).to receive(:settings).and_return(settings)
|
495
|
+
expect(inst).to receive(:params).twice.and_return(params)
|
496
|
+
|
497
|
+
expect(service).to receive(:exists_by_primary_key?).with(6).and_return(true)
|
498
|
+
expect(service).to receive(:delete_by_primary_key).with(6).and_return(true)
|
499
|
+
|
500
|
+
block.call
|
501
|
+
end
|
502
|
+
|
503
|
+
expect(inst.crud_delete('resource','service_name','primary',mock_opts)).to eq(204)
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
describe '#crud_put' do
|
508
|
+
it 'should call get_defaults and options, return 422 if body parse fails' do
|
509
|
+
mock_opts = { :enable_get_all=>false }
|
510
|
+
|
511
|
+
inst = TestAPI.new
|
512
|
+
|
513
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
514
|
+
expect(inst).to receive(:post) do |resname, &block|
|
515
|
+
expect(resname).to eq('/resource')
|
516
|
+
|
517
|
+
settings = OpenStruct.new
|
518
|
+
service = OpenStruct.new
|
519
|
+
expect(inst).to receive(:settings).and_return(settings)
|
520
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
521
|
+
|
522
|
+
request = OpenStruct.new({:body=>OpenStruct.new({:read => '{"one":1'})})
|
523
|
+
expect(inst).to receive(:request).and_return(request)
|
524
|
+
block.call
|
525
|
+
end
|
526
|
+
|
527
|
+
expect(inst.crud_post('resource','service','primary',mock_opts)).to eq(422)
|
528
|
+
end
|
529
|
+
|
530
|
+
it 'should call get_defaults and options, return 422 if non valid insert' do
|
531
|
+
mock_opts = { :enable_get_all=>false }
|
532
|
+
|
533
|
+
inst = TestAPI.new
|
534
|
+
|
535
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
536
|
+
expect(inst).to receive(:post) do |resname, &block|
|
537
|
+
expect(resname).to eq('/resource')
|
538
|
+
|
539
|
+
settings = OpenStruct.new
|
540
|
+
service = OpenStruct.new
|
541
|
+
expect(inst).to receive(:settings).and_return(settings)
|
542
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
543
|
+
|
544
|
+
request = OpenStruct.new({:body=>OpenStruct.new({:read => '{"one":1}'})})
|
545
|
+
expect(inst).to receive(:request).and_return(request)
|
546
|
+
|
547
|
+
expect(service).to receive(:valid_insert?).with({"one"=>1}).and_return(false)
|
548
|
+
|
549
|
+
block.call
|
550
|
+
end
|
551
|
+
|
552
|
+
expect(inst.crud_post('resource','service','one',mock_opts)).to eq(422)
|
553
|
+
end
|
554
|
+
|
555
|
+
it 'should call get_defaults and options, return 409 if pk already exists' do
|
556
|
+
mock_opts = { :enable_get_all=>false }
|
557
|
+
|
558
|
+
inst = TestAPI.new
|
559
|
+
|
560
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
561
|
+
expect(inst).to receive(:post) do |resname, &block|
|
562
|
+
expect(resname).to eq('/resource')
|
563
|
+
|
564
|
+
settings = OpenStruct.new
|
565
|
+
service = OpenStruct.new
|
566
|
+
expect(inst).to receive(:settings).and_return(settings)
|
567
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
568
|
+
|
569
|
+
request = OpenStruct.new({:body=>OpenStruct.new({:read => '{"one":1}'})})
|
570
|
+
expect(inst).to receive(:request).and_return(request)
|
571
|
+
|
572
|
+
expect(service).to receive(:valid_insert?).with({"one"=>1}).and_return(true)
|
573
|
+
expect(service).to receive(:exists_by_primary_key?).with(1).and_return(true)
|
574
|
+
|
575
|
+
block.call
|
576
|
+
end
|
577
|
+
|
578
|
+
expect(inst.crud_post('resource','service','one',mock_opts)).to eq(409)
|
579
|
+
end
|
580
|
+
|
581
|
+
it 'should call get_defaults and options, return 500 if record fails to insert' do
|
582
|
+
mock_opts = { :enable_get_all=>false }
|
583
|
+
|
584
|
+
inst = TestAPI.new
|
585
|
+
|
586
|
+
expect(inst).to receive(:get_defaults).with(mock_opts)
|
587
|
+
expect(inst).to receive(:post) do |resname, &block|
|
588
|
+
expect(resname).to eq('/resource')
|
589
|
+
|
590
|
+
settings = OpenStruct.new
|
591
|
+
service = OpenStruct.new
|
592
|
+
expect(inst).to receive(:settings).and_return(settings)
|
593
|
+
expect(settings).to receive(:send).with('service').and_return(service)
|
594
|
+
|
595
|
+
request = OpenStruct.new({:body=>OpenStruct.new({:read => '{"one":1}'})})
|
596
|
+
expect(inst).to receive(:request).and_return(request)
|
597
|
+
|
598
|
+
expect(service).to receive(:valid_insert?).with({"one"=>1}).and_return(true)
|
599
|
+
expect(service).to receive(:exists_by_primary_key?).with(1).and_return(false)
|
600
|
+
expect(service).to receive(:insert).with({"one"=>1}).and_return({"five"=>5})
|
601
|
+
|
602
|
+
block.call
|
603
|
+
end
|
604
|
+
|
605
|
+
expect(inst.crud_post('resource','service','one',mock_opts)).to eq("{\"five\":5}")
|
606
|
+
end
|
607
|
+
|
608
|
+
end
|
609
|
+
end
|