json-crud-api 0.0.1 → 0.0.2
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/json-crud-api.rb +1 -0
- data/lib/json-crud-api/crud.rb +6 -6
- data/lib/json-crud-api/presenter.rb +38 -0
- data/lib/json-crud-api/service.rb +16 -16
- data/spec/unit/presenter_spec.rb +154 -0
- data/spec/unit/service_spec.rb +28 -18
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4018cb35450e8da438cc7ff5bc87ec1b97deba51
|
4
|
+
data.tar.gz: 2c8b73bc85c0732e240e9e465fe76c814b3b9cbc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8d94888ebcfe5da8fe37d14b642ce09e3e34dc1eba72325cda431f7134a244fa9821a2153217a6c810ed4dce0033fff8f3b1398e6c5eacce8a84c42cb1fc126c
|
7
|
+
data.tar.gz: 529751ff66be5745f916ebea5d75eeb63388ad210e32635ebfc24f2d272fc8f120a8b9a1d495dfa1060fadb1efb29db7001621c506a8f047b09c77230744e619
|
data/lib/json-crud-api.rb
CHANGED
data/lib/json-crud-api/crud.rb
CHANGED
@@ -13,7 +13,7 @@ module JsonCrudApi
|
|
13
13
|
entities = service.get_all
|
14
14
|
fail_not_found if entities.nil?
|
15
15
|
|
16
|
-
JSON.fast_generate settings.presenters[key].render(entities)
|
16
|
+
JSON.fast_generate settings.presenters[key].render(entities, :get_all)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -25,7 +25,7 @@ module JsonCrudApi
|
|
25
25
|
entity = service.get(params["id"])
|
26
26
|
fail_not_found if entity.nil?
|
27
27
|
|
28
|
-
JSON.fast_generate settings.presenters[key].render(entity)
|
28
|
+
JSON.fast_generate settings.presenters[key].render(entity, :get)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
@@ -38,9 +38,9 @@ module JsonCrudApi
|
|
38
38
|
service = settings.services[key]
|
39
39
|
presenter = settings.presenters[key]
|
40
40
|
fail_unauthorized 'create' unless service.user_authorized_for? :create
|
41
|
-
entity = service.create(presenter.parse(@payload))
|
41
|
+
entity = service.create(presenter.parse(@payload, :post))
|
42
42
|
|
43
|
-
JSON.fast_generate settings.presenters[key].render(entity)
|
43
|
+
JSON.fast_generate settings.presenters[key].render(entity, :post)
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -49,9 +49,9 @@ module JsonCrudApi
|
|
49
49
|
service = settings.services[key]
|
50
50
|
presenter = settings.presenters[key]
|
51
51
|
fail_unauthorized 'update' unless service.user_authorized_for? :update
|
52
|
-
fail_not_found unless service.update(params["id"], presenter.parse(@payload))
|
52
|
+
fail_not_found unless service.update(params["id"], presenter.parse(@payload, :put))
|
53
53
|
entity = service.get(params["id"])
|
54
|
-
JSON.fast_generate settings.presenters[key].render(entity)
|
54
|
+
JSON.fast_generate settings.presenters[key].render(entity, :put)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module JsonCrudApi
|
2
|
+
class Presenter
|
3
|
+
|
4
|
+
attr_accessor :model, :exclude
|
5
|
+
|
6
|
+
def initialize(options)
|
7
|
+
@model = options[:model]
|
8
|
+
@exclude = options[:exclude]
|
9
|
+
|
10
|
+
throw "Model must be defined" if @model.nil?
|
11
|
+
end
|
12
|
+
|
13
|
+
def render(data, operation = nil)
|
14
|
+
return data.map {|d| render(d, operation) } if data.is_a?(Array)
|
15
|
+
|
16
|
+
properties = @model.properties.map { |p| p.name.to_sym }
|
17
|
+
unless @exclude.nil? or @exclude[:render].nil?
|
18
|
+
properties -= @exclude[:render][:all] unless @exclude[:render][:all].nil?
|
19
|
+
properties -= @exclude[:render][operation] unless @exclude[:render][operation].nil?
|
20
|
+
end
|
21
|
+
|
22
|
+
Hash[properties.map { |p| [p, data.send(p)] }]
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse(data, operation = nil)
|
26
|
+
return data.map {|d| parse(d, operation) } if data.is_a?(Array)
|
27
|
+
|
28
|
+
properties = @model.properties.map { |p| p.name.to_sym }
|
29
|
+
unless @exclude.nil? or @exclude[:parse].nil?
|
30
|
+
properties -= @exclude[:parse][:all] unless @exclude[:parse][:all].nil?
|
31
|
+
properties -= @exclude[:parse][operation] unless @exclude[:parse][operation].nil?
|
32
|
+
end
|
33
|
+
|
34
|
+
Hash[properties.map { |p| [p,data[p]] }]
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -3,11 +3,11 @@ require 'rubygems'
|
|
3
3
|
module JsonCrudApi
|
4
4
|
class Service
|
5
5
|
|
6
|
-
attr_accessor :log_service, :
|
6
|
+
attr_accessor :log_service, :model, :user, :scope_map, :user_scopes
|
7
7
|
|
8
8
|
def initialize(options)
|
9
9
|
@log_service = options[:log_service]
|
10
|
-
@
|
10
|
+
@model = options[:model]
|
11
11
|
@scope_map = options[:scope_map]
|
12
12
|
@user = nil
|
13
13
|
@user_scopes = nil
|
@@ -15,37 +15,37 @@ module JsonCrudApi
|
|
15
15
|
|
16
16
|
# Create a record with the given attributes
|
17
17
|
def create(params)
|
18
|
-
@
|
18
|
+
@model.create(params)
|
19
19
|
end
|
20
20
|
|
21
|
-
# Determine if a record with the given
|
22
|
-
def exists?(
|
23
|
-
@
|
21
|
+
# Determine if a record with the given key exists
|
22
|
+
def exists?(key)
|
23
|
+
@model.all(@model.key.first.name => key).count > 0
|
24
24
|
end
|
25
25
|
|
26
26
|
# Get all records
|
27
27
|
def get_all
|
28
|
-
@
|
28
|
+
@model.all
|
29
29
|
end
|
30
30
|
|
31
|
-
# Get the first record with the given
|
32
|
-
def get(
|
33
|
-
@
|
31
|
+
# Get the first record with the given key
|
32
|
+
def get(key)
|
33
|
+
@model.first(@model.key.first.name => key)
|
34
34
|
end
|
35
35
|
|
36
|
-
# Update a record with the given
|
36
|
+
# Update a record with the given key with the given attributes
|
37
37
|
# Returns false if the record does not exist.
|
38
|
-
def update(
|
39
|
-
record = get(
|
38
|
+
def update(key, params)
|
39
|
+
record = get(key)
|
40
40
|
return false if record.nil?
|
41
41
|
|
42
42
|
record.update(params)
|
43
43
|
end
|
44
44
|
|
45
|
-
# Delete a record with the given
|
45
|
+
# Delete a record with the given key
|
46
46
|
# Returns false if the record does not exist.
|
47
|
-
def delete(
|
48
|
-
record = get(
|
47
|
+
def delete(key)
|
48
|
+
record = get(key)
|
49
49
|
return false if record.nil?
|
50
50
|
|
51
51
|
record.destroy
|
@@ -0,0 +1,154 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
describe JsonCrudApi::Presenter do
|
4
|
+
before(:each) do
|
5
|
+
@mock_model = double('model')
|
6
|
+
|
7
|
+
@presenter = JsonCrudApi::Presenter.new({
|
8
|
+
:model => @mock_model,
|
9
|
+
})
|
10
|
+
end
|
11
|
+
|
12
|
+
describe '#initialize' do
|
13
|
+
it 'should inject dependencies correctly' do
|
14
|
+
@presenter.model.should be @mock_model
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should throw an exception if model is not set' do
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#render' do
|
22
|
+
it 'should output a single property in data based on model properties' do
|
23
|
+
@mock_model.should_receive(:properties)
|
24
|
+
.and_return([OpenStruct.new(:name => :one)])
|
25
|
+
data = OpenStruct.new(:one => "Test")
|
26
|
+
|
27
|
+
@presenter.render(data).should eq({ :one => "Test" })
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'should not return data properties that do not have model properties' do
|
31
|
+
@mock_model.should_receive(:properties)
|
32
|
+
.and_return([OpenStruct.new(:name => :one)])
|
33
|
+
data = OpenStruct.new(:one => "YES", :two => "OK")
|
34
|
+
|
35
|
+
@presenter.render(data).should eq({ :one => "YES" })
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'should return nil for model properties that do not have data' do
|
39
|
+
@mock_model.should_receive(:properties)
|
40
|
+
.and_return([
|
41
|
+
OpenStruct.new(:name => :one),
|
42
|
+
OpenStruct.new(:name => :two),
|
43
|
+
])
|
44
|
+
data = OpenStruct.new(:two => "OK")
|
45
|
+
|
46
|
+
@presenter.render(data).should eq({ :one => nil, :two => 'OK' })
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should call itself when supplied with an array and return an array of the results' do
|
50
|
+
@mock_model.stub :properties do
|
51
|
+
[OpenStruct.new(:name => :one)]
|
52
|
+
end
|
53
|
+
data = [OpenStruct.new(:one => "Test"), OpenStruct.new(:one => "TEST2")]
|
54
|
+
|
55
|
+
@presenter.render(data).should eq([{ :one => "Test" }, { :one => "TEST2" }])
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should exclude render:all properties' do
|
59
|
+
@presenter.exclude = { :render => { :all => [:one] } }
|
60
|
+
@mock_model.stub :properties do
|
61
|
+
[OpenStruct.new(:name => :one), OpenStruct.new(:name => :two)]
|
62
|
+
end
|
63
|
+
data = OpenStruct.new(:one => "Test",:two => "Two")
|
64
|
+
|
65
|
+
@presenter.render(data).should eq({ :two => "Two" })
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should exclude render:operation properties' do
|
69
|
+
@presenter.exclude = { :render => { :test => [:one] } }
|
70
|
+
@mock_model.stub :properties do
|
71
|
+
[OpenStruct.new(:name => :one), OpenStruct.new(:name => :two)]
|
72
|
+
end
|
73
|
+
data = OpenStruct.new(:one => "Test",:two => "Two")
|
74
|
+
|
75
|
+
@presenter.render(data, :test).should eq({ :two => "Two" })
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should exclude combinations of render:all and render:operation properties' do
|
79
|
+
@presenter.exclude = { :render => { :all => [:two] , :test => [:one] } }
|
80
|
+
@mock_model.stub :properties do
|
81
|
+
[OpenStruct.new(:name => :one), OpenStruct.new(:name => :two), OpenStruct.new(:name => :three)]
|
82
|
+
end
|
83
|
+
data = OpenStruct.new(:one => "Test",:two => "Two",:three => "Three")
|
84
|
+
|
85
|
+
@presenter.render(data, :test).should eq({ :three => "Three" })
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
describe '#parse' do
|
90
|
+
it 'should output a single property in data based on model properties' do
|
91
|
+
@mock_model.stub :properties do
|
92
|
+
[OpenStruct.new(:name => :one)]
|
93
|
+
end
|
94
|
+
data = { :one => 1 }
|
95
|
+
@presenter.parse(data).should eq({:one => 1})
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should not output properties of data that are not in model properties' do
|
99
|
+
@mock_model.stub :properties do
|
100
|
+
[OpenStruct.new(:name => :one)]
|
101
|
+
end
|
102
|
+
data = { :one => 1, :two => 2 }
|
103
|
+
@presenter.parse(data).should eq({:one => 1})
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'should not output model properties with no data property' do
|
107
|
+
@mock_model.stub :properties do
|
108
|
+
[OpenStruct.new(:name => :one)]
|
109
|
+
[OpenStruct.new(:name => :two)]
|
110
|
+
end
|
111
|
+
data = { :two => 2 }
|
112
|
+
@presenter.parse(data).should eq({:two => 2})
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should call itself when supplied with an array and return an array of the results' do
|
116
|
+
@mock_model.stub :properties do
|
117
|
+
[OpenStruct.new(:name => :one)]
|
118
|
+
end
|
119
|
+
data = [{ :one => 1 }]
|
120
|
+
|
121
|
+
@presenter.parse(data).should eq([{ :one => 1 }])
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'should exclude parse:all properties' do
|
125
|
+
@presenter.exclude = { :parse => { :all => [:one] } }
|
126
|
+
@mock_model.stub :properties do
|
127
|
+
[OpenStruct.new(:name => :one), OpenStruct.new(:name => :two)]
|
128
|
+
end
|
129
|
+
data = OpenStruct.new(:one => "Test",:two => "Two")
|
130
|
+
|
131
|
+
@presenter.parse(data).should eq({ :two => "Two" })
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'should exclude parse:operation properties' do
|
135
|
+
@presenter.exclude = { :parse => { :test => [:one] } }
|
136
|
+
@mock_model.stub :properties do
|
137
|
+
[OpenStruct.new(:name => :one), OpenStruct.new(:name => :two)]
|
138
|
+
end
|
139
|
+
data = OpenStruct.new(:one => "Test",:two => "Two")
|
140
|
+
|
141
|
+
@presenter.parse(data, :test).should eq({ :two => "Two" })
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should exclude combinations of parse:all and parse:operation properties' do
|
145
|
+
@presenter.exclude = { :parse => { :all => [:two] , :test => [:one] } }
|
146
|
+
@mock_model.stub :properties do
|
147
|
+
[OpenStruct.new(:name => :one), OpenStruct.new(:name => :two), OpenStruct.new(:name => :three)]
|
148
|
+
end
|
149
|
+
data = OpenStruct.new(:one => "Test",:two => "Two",:three => "Three")
|
150
|
+
|
151
|
+
@presenter.parse(data, :test).should eq({ :three => "Three" })
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
data/spec/unit/service_spec.rb
CHANGED
@@ -2,13 +2,13 @@ require "helper"
|
|
2
2
|
|
3
3
|
describe JsonCrudApi::Service do
|
4
4
|
before(:each) do
|
5
|
-
@
|
5
|
+
@mock_model = double('model')
|
6
6
|
@mock_log = double('Log')
|
7
7
|
@mock_map = double('Map')
|
8
8
|
|
9
9
|
@service = JsonCrudApi::Service.new({
|
10
10
|
:log_service => @mock_log,
|
11
|
-
:
|
11
|
+
:model => @mock_model,
|
12
12
|
:scope_map => @mock_map
|
13
13
|
})
|
14
14
|
end
|
@@ -16,7 +16,7 @@ describe JsonCrudApi::Service do
|
|
16
16
|
describe '#initialize' do
|
17
17
|
it 'should inject dependencies correctly' do
|
18
18
|
@service.log_service.should be @mock_log
|
19
|
-
@service.
|
19
|
+
@service.model.should be @mock_model
|
20
20
|
@service.scope_map.should be @mock_map
|
21
21
|
end
|
22
22
|
|
@@ -27,53 +27,63 @@ describe JsonCrudApi::Service do
|
|
27
27
|
end
|
28
28
|
|
29
29
|
describe '#create' do
|
30
|
-
it 'should call create on
|
30
|
+
it 'should call create on model with params' do
|
31
31
|
params = { :one => 'one', :two => 'two' }
|
32
|
-
@
|
32
|
+
@mock_model.should_receive(:create).with(params).and_return(2)
|
33
33
|
@service.create(params).should eq 2
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
37
|
describe '#exists?' do
|
38
|
-
it 'should call all on
|
38
|
+
it 'should call all on model with correct id' do
|
39
39
|
query_object = OpenStruct.new :count => 1
|
40
|
-
@
|
40
|
+
@mock_model.should_receive(:key)
|
41
|
+
.and_return(OpenStruct.new(:first => OpenStruct.new(:name => :id)))
|
42
|
+
@mock_model.should_receive(:all).with(:id => 3)
|
41
43
|
.and_return(query_object)
|
42
44
|
@service.exists?(3).should eq true
|
43
45
|
end
|
44
46
|
|
45
47
|
it 'should return false when count is zero' do
|
46
48
|
query_object = OpenStruct.new :count => 0
|
47
|
-
@
|
49
|
+
@mock_model.should_receive(:key)
|
50
|
+
.and_return(OpenStruct.new(:first => OpenStruct.new(:name => :id)))
|
51
|
+
@mock_model.should_receive(:all).with(:id => 3)
|
48
52
|
.and_return(query_object)
|
49
53
|
@service.exists?(3).should eq false
|
50
54
|
end
|
51
55
|
|
52
56
|
it 'should return true when count is one' do
|
53
57
|
query_object = OpenStruct.new :count => 1
|
54
|
-
@
|
58
|
+
@mock_model.should_receive(:key)
|
59
|
+
.and_return(OpenStruct.new(:first => OpenStruct.new(:name => :id)))
|
60
|
+
@mock_model.should_receive(:all).with(:id => 3)
|
55
61
|
.and_return(query_object)
|
56
62
|
@service.exists?(3).should eq true
|
57
63
|
end
|
58
64
|
|
59
65
|
it 'should return true when count is more than one' do
|
60
66
|
query_object = OpenStruct.new :count => 2
|
61
|
-
@
|
62
|
-
.and_return(
|
67
|
+
@mock_model.should_receive(:key)
|
68
|
+
.and_return(OpenStruct.new(:first => OpenStruct.new(:name => :id)))
|
69
|
+
@mock_model.should_receive(:all).with(:id => 3)
|
70
|
+
.and_return(query_object)
|
63
71
|
@service.exists?(3).should eq true
|
64
72
|
end
|
65
73
|
end
|
66
74
|
|
67
75
|
describe '#get_all' do
|
68
|
-
it 'should call all on
|
69
|
-
@
|
76
|
+
it 'should call all on model and return output' do
|
77
|
+
@mock_model.should_receive(:all).with().and_return(67)
|
70
78
|
@service.get_all.should eq 67
|
71
79
|
end
|
72
80
|
end
|
73
81
|
|
74
82
|
describe '#get' do
|
75
|
-
it 'should call first on
|
76
|
-
|
83
|
+
it 'should call first on model with correct id and return result' do
|
84
|
+
@mock_model.should_receive(:key)
|
85
|
+
.and_return(OpenStruct.new(:first => OpenStruct.new(:name => :id)))
|
86
|
+
@mock_model.should_receive(:first).with({:id=>8}).and_return(123)
|
77
87
|
@service.get(8).should eq 123
|
78
88
|
end
|
79
89
|
end
|
@@ -93,9 +103,9 @@ describe JsonCrudApi::Service do
|
|
93
103
|
params = { :one => 'one', :two => 'two' }
|
94
104
|
record = double('entity')
|
95
105
|
@service.should_receive(:get).with(5)
|
96
|
-
|
106
|
+
.and_return(record)
|
97
107
|
record.should_receive(:update).with(params)
|
98
|
-
|
108
|
+
.and_return(789)
|
99
109
|
@service.update(5,params).should eq 789
|
100
110
|
end
|
101
111
|
end
|
@@ -114,7 +124,7 @@ describe JsonCrudApi::Service do
|
|
114
124
|
it 'should call delete on record' do
|
115
125
|
record = double('entity')
|
116
126
|
@service.should_receive(:get).with(5)
|
117
|
-
|
127
|
+
.and_return(record)
|
118
128
|
record.should_receive(:destroy).and_return(109)
|
119
129
|
@service.delete(5).should eq 109
|
120
130
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json-crud-api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Cully
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: coveralls
|
@@ -203,11 +203,13 @@ files:
|
|
203
203
|
- lib/json-crud-api/api.rb
|
204
204
|
- lib/json-crud-api/auth_client.rb
|
205
205
|
- lib/json-crud-api/crud.rb
|
206
|
+
- lib/json-crud-api/presenter.rb
|
206
207
|
- lib/json-crud-api/service.rb
|
207
208
|
- lib/json-crud-api.rb
|
208
209
|
- spec/helper.rb
|
209
210
|
- spec/helpers_spec.rb
|
210
211
|
- spec/unit/auth_client_spec.rb
|
212
|
+
- spec/unit/presenter_spec.rb
|
211
213
|
- spec/unit/service_spec.rb
|
212
214
|
homepage: http://rubygems.org/gems/json-crud-api
|
213
215
|
licenses:
|
@@ -237,4 +239,5 @@ test_files:
|
|
237
239
|
- spec/helper.rb
|
238
240
|
- spec/helpers_spec.rb
|
239
241
|
- spec/unit/auth_client_spec.rb
|
242
|
+
- spec/unit/presenter_spec.rb
|
240
243
|
- spec/unit/service_spec.rb
|