lhs 2.0.5 → 2.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 +4 -4
- data/docs/items.md +7 -1
- data/docs/services.md +6 -0
- data/lib/lhs/concerns/item/destroy.rb +2 -2
- data/lib/lhs/concerns/item/save.rb +2 -2
- data/lib/lhs/concerns/item/update.rb +1 -1
- data/lib/lhs/concerns/item/validation.rb +1 -1
- data/lib/lhs/concerns/service/all.rb +2 -2
- data/lib/lhs/concerns/service/batch.rb +3 -3
- data/lib/lhs/concerns/service/build.rb +2 -0
- data/lib/lhs/concerns/service/create.rb +3 -3
- data/lib/lhs/concerns/service/endpoints.rb +54 -52
- data/lib/lhs/concerns/service/find.rb +2 -2
- data/lib/lhs/concerns/service/find_by.rb +1 -1
- data/lib/lhs/concerns/service/includes.rb +11 -5
- data/lib/lhs/concerns/service/mapping.rb +9 -8
- data/lib/lhs/concerns/service/request.rb +112 -108
- data/lib/lhs/concerns/service/where.rb +1 -1
- data/lib/lhs/data.rb +5 -5
- data/lib/lhs/proxy.rb +1 -1
- data/lib/lhs/service.rb +1 -3
- data/lib/lhs/version.rb +1 -1
- data/spec/service/build_spec.rb +1 -1
- data/spec/service/endpoint_options_spec.rb +1 -1
- data/spec/service/endpoints_spec.rb +7 -7
- data/spec/service/new_spec.rb +25 -0
- data/spec/support/cleanup_services.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df827d2008392c40865a0c82e9a515b4bc541ee2
|
4
|
+
data.tar.gz: 5b589ba038ded4cb9407c24091ed7c0b08f96a63
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3648b5f1e76c703a6f56cfc78b9b8d4bc2a983947f42dfd819e087aca2d5100b8846ca3a8c4059a86b54cf033a18e648f9881d8cf5a40fbfe337268d3d53472f
|
7
|
+
data.tar.gz: 8f797d35de13f0e3f1e8171c15730137834029a95aae831a2d174e78e377779b5fd3d0227e578bb00469bbfc17528388279147c2f2944ef0758d0e1d14960fd4
|
data/docs/items.md
CHANGED
@@ -16,7 +16,7 @@ An item proxy contains setter methods, in order to set/change values.
|
|
16
16
|
rcord.recommended = false
|
17
17
|
```
|
18
18
|
|
19
|
-
## Build
|
19
|
+
## Build (new)
|
20
20
|
|
21
21
|
Build and persist new items from scratch.
|
22
22
|
|
@@ -25,6 +25,12 @@ feedback = Feedback.build(recommended: true)
|
|
25
25
|
feedback.save
|
26
26
|
```
|
27
27
|
|
28
|
+
`new` is an alias for `build`:
|
29
|
+
|
30
|
+
```ruby
|
31
|
+
Feedback.new(recommended: true)
|
32
|
+
```
|
33
|
+
|
28
34
|
## Save
|
29
35
|
|
30
36
|
You can persist changes like you would usually do with `save`.
|
data/docs/services.md
CHANGED
@@ -7,8 +7,8 @@ class LHS::Item < LHS::Proxy
|
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
9
|
def destroy
|
10
|
-
|
11
|
-
_data._request =
|
10
|
+
service = _data._root._service
|
11
|
+
_data._request = service.request(method: :delete, url: href)._request
|
12
12
|
_data
|
13
13
|
end
|
14
14
|
end
|
@@ -19,9 +19,9 @@ class LHS::Item < LHS::Proxy
|
|
19
19
|
url = if href.present?
|
20
20
|
href
|
21
21
|
else
|
22
|
-
service.
|
22
|
+
service.find_endpoint(data).compile(data)
|
23
23
|
end
|
24
|
-
data = service.
|
24
|
+
data = service.request(method: :post, url: url, body: data.to_json, headers: {'Content-Type' => 'application/json'})
|
25
25
|
self._data.merge_raw!(data)
|
26
26
|
true
|
27
27
|
end
|
@@ -16,7 +16,7 @@ class LHS::Item < LHS::Proxy
|
|
16
16
|
def update!(params)
|
17
17
|
service = _data._root._service
|
18
18
|
_data.merge_raw!(LHS::Data.new(params))
|
19
|
-
response_data = service.
|
19
|
+
response_data = service.request(
|
20
20
|
method: :post,
|
21
21
|
url: href,
|
22
22
|
body: _data.to_json,
|
@@ -29,7 +29,7 @@ class LHS::Item < LHS::Proxy
|
|
29
29
|
private
|
30
30
|
|
31
31
|
def validation_endpoint
|
32
|
-
endpoint = _data._service.
|
32
|
+
endpoint = _data._service.find_endpoint(_data._raw)
|
33
33
|
endpoint ||= LHS::Endpoint.for_url(_data.href) if _data.href
|
34
34
|
validates = endpoint.options && endpoint.options.fetch(:validates, false)
|
35
35
|
fail 'Endpoint does not support validations!' unless validates
|
@@ -15,7 +15,7 @@ class LHS::Service
|
|
15
15
|
def all(params = {})
|
16
16
|
all = []
|
17
17
|
default_max_limit = 100
|
18
|
-
data =
|
18
|
+
data = request(params: params.merge(limit: default_max_limit))
|
19
19
|
all.concat(data._raw[:items])
|
20
20
|
total_left = data._raw[:total] - data.count
|
21
21
|
limit = data._raw[:limit] || data.count
|
@@ -23,7 +23,7 @@ class LHS::Service
|
|
23
23
|
requests = total_left / limit
|
24
24
|
requests.times do |i|
|
25
25
|
offset = limit * (i+1) + 1
|
26
|
-
all.concat
|
26
|
+
all.concat request(params: params.merge(limit: limit, offset: offset))._raw[:items]
|
27
27
|
end
|
28
28
|
end
|
29
29
|
LHS::Data.new(all, nil, self)
|
@@ -11,8 +11,8 @@ class LHS::Service
|
|
11
11
|
def find_each(options = {})
|
12
12
|
find_in_batches(options) do |data|
|
13
13
|
data.each do |record|
|
14
|
-
item = LHS::Item.new(LHS::Data.new(record, data, self
|
15
|
-
yield LHS::Data.new(item, data, self
|
14
|
+
item = LHS::Item.new(LHS::Data.new(record, data, self))
|
15
|
+
yield LHS::Data.new(item, data, self)
|
16
16
|
end
|
17
17
|
end
|
18
18
|
end
|
@@ -24,7 +24,7 @@ class LHS::Service
|
|
24
24
|
batch_size = options[:batch_size] || 100
|
25
25
|
params = options[:params] || {}
|
26
26
|
loop do # as suggested by Matz
|
27
|
-
data =
|
27
|
+
data = request(params: params.merge(limit: batch_size, offset: start))
|
28
28
|
batch_size = data._raw[:limit]
|
29
29
|
left = data._raw[:total].to_i - data._raw[:offset].to_i - data._raw[:limit].to_i
|
30
30
|
yield data
|
@@ -11,15 +11,15 @@ class LHS::Service
|
|
11
11
|
create!(data)
|
12
12
|
rescue LHC::Error => e
|
13
13
|
json = JSON.parse(data.to_json)
|
14
|
-
data = LHS::Data.new(json, nil, self
|
14
|
+
data = LHS::Data.new(json, nil, self, e.response.request)
|
15
15
|
item = LHS::Item.new(data)
|
16
16
|
item.errors = LHS::Errors.new(e.response)
|
17
17
|
LHS::Data.new(item, data)
|
18
18
|
end
|
19
19
|
|
20
20
|
def create!(data = {})
|
21
|
-
url =
|
22
|
-
|
21
|
+
url = compute_url!(data)
|
22
|
+
request(url: url, method: :post, body: data.to_json, headers: {'Content-Type' => 'application/json'})
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -9,18 +9,25 @@ class LHS::Service
|
|
9
9
|
module Endpoints
|
10
10
|
extend ActiveSupport::Concern
|
11
11
|
|
12
|
-
attr_accessor :endpoints
|
13
12
|
mattr_accessor :all
|
14
13
|
|
15
14
|
module ClassMethods
|
16
15
|
|
16
|
+
def endpoints
|
17
|
+
@endpoints ||= []
|
18
|
+
end
|
19
|
+
|
20
|
+
def endpoints=(endpoints)
|
21
|
+
@endpoints = endpoints
|
22
|
+
end
|
23
|
+
|
17
24
|
# Adds the endpoint to the list of endpoints.
|
18
25
|
def endpoint(url, options = nil)
|
19
26
|
endpoint = LHC::Endpoint.new(url, options)
|
20
|
-
|
21
|
-
|
27
|
+
sanity_check(endpoint)
|
28
|
+
endpoints.push(endpoint)
|
22
29
|
LHS::Service::Endpoints.all ||= {}
|
23
|
-
LHS::Service::Endpoints.all[url] =
|
30
|
+
LHS::Service::Endpoints.all[url] = self
|
24
31
|
end
|
25
32
|
|
26
33
|
def for_url(url)
|
@@ -30,63 +37,58 @@ class LHS::Service
|
|
30
37
|
end
|
31
38
|
service
|
32
39
|
end
|
33
|
-
end
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
def find_endpoint(params = {})
|
44
|
-
endpoint = find_best_endpoint(params) if params && params.keys.count > 0
|
45
|
-
endpoint ||= find_base_endpoint
|
46
|
-
endpoint
|
47
|
-
end
|
41
|
+
# Find an endpoint based on the provided parameters.
|
42
|
+
# If no parameters are provided it finds the base endpoint
|
43
|
+
# otherwise it finds the endpoint that matches the parameters best.
|
44
|
+
def find_endpoint(params = {})
|
45
|
+
endpoint = find_best_endpoint(params) if params && params.keys.count > 0
|
46
|
+
endpoint ||= find_base_endpoint
|
47
|
+
endpoint
|
48
|
+
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
# Prevent clashing endpoints.
|
51
|
+
def sanity_check(endpoint)
|
52
|
+
placeholders = endpoint.placeholders
|
53
|
+
fail 'Clashing endpoints.' if endpoints.any? { |e| e.placeholders.sort == placeholders.sort }
|
54
|
+
end
|
54
55
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
56
|
+
# Computes the url from params
|
57
|
+
# by identifiying endpoint and compiles it if necessary.
|
58
|
+
# Id in params is threaded in a special way.
|
59
|
+
def compute_url!(params)
|
60
|
+
endpoint = find_endpoint(params)
|
61
|
+
url = endpoint.compile(params)
|
62
|
+
endpoint.remove_interpolated_params!(params)
|
63
|
+
url
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
+
private
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
# Finds the best endpoint.
|
69
|
+
# The best endpoint is the one where all placeholders are interpolated.
|
70
|
+
def find_best_endpoint(params)
|
71
|
+
sorted_endpoints.find do |endpoint|
|
72
|
+
endpoint.placeholders.all? { |match| endpoint.find_value(match, params) }
|
73
|
+
end
|
72
74
|
end
|
73
|
-
end
|
74
75
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
76
|
+
# Sort endpoints by number of placeholders, heighest first
|
77
|
+
def sorted_endpoints
|
78
|
+
endpoints.sort{|a, b| b.placeholders.count <=> a.placeholders.count }
|
79
|
+
end
|
79
80
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
# Finds the base endpoint.
|
82
|
+
# A base endpoint is the one thats has the least amont of placeholers.
|
83
|
+
# There cannot be multiple base endpoints.
|
84
|
+
def find_base_endpoint
|
85
|
+
endpoints = self.endpoints.group_by do |endpoint|
|
86
|
+
endpoint.placeholders.length
|
87
|
+
end
|
88
|
+
bases = endpoints[endpoints.keys.min]
|
89
|
+
fail 'Multiple base endpoints found' if bases.count > 1
|
90
|
+
bases.first
|
86
91
|
end
|
87
|
-
bases = endpoints[endpoints.keys.min]
|
88
|
-
fail 'Multiple base endpoints found' if bases.count > 1
|
89
|
-
bases.first
|
90
92
|
end
|
91
93
|
end
|
92
94
|
end
|
@@ -19,7 +19,7 @@ class LHS::Service
|
|
19
19
|
private
|
20
20
|
|
21
21
|
def find_with_parameters(params)
|
22
|
-
data =
|
22
|
+
data = request(params: params)
|
23
23
|
if data._proxy.is_a?(LHS::Collection)
|
24
24
|
fail LHC::NotFound.new('Requested unique item. Multiple were found.', data._request.response) if data.count > 1
|
25
25
|
data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
|
@@ -29,7 +29,7 @@ class LHS::Service
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def find_by_id(id)
|
32
|
-
|
32
|
+
request(params: { id: id })
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
@@ -23,7 +23,7 @@ class LHS::Service
|
|
23
23
|
|
24
24
|
def _find_by(params)
|
25
25
|
params = params.dup.merge(limit: 1)
|
26
|
-
data =
|
26
|
+
data = request(params: params)
|
27
27
|
if data._proxy.is_a?(LHS::Collection)
|
28
28
|
data.first || fail(LHC::NotFound.new('No item was found.', data._request.response))
|
29
29
|
else
|
@@ -5,15 +5,21 @@ class LHS::Service
|
|
5
5
|
module Includes
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
-
attr_accessor :includes
|
9
|
-
|
10
8
|
module ClassMethods
|
11
9
|
|
10
|
+
def including
|
11
|
+
@including
|
12
|
+
end
|
13
|
+
|
14
|
+
def including=(including)
|
15
|
+
@including = including
|
16
|
+
end
|
17
|
+
|
12
18
|
def includes(*args)
|
13
19
|
class_clone = clone
|
14
|
-
class_clone.
|
15
|
-
class_clone.
|
16
|
-
class_clone.
|
20
|
+
class_clone.endpoints = endpoints
|
21
|
+
class_clone.mapping = mapping
|
22
|
+
class_clone.including = args.size == 1 ? args[0] : args
|
17
23
|
class_clone
|
18
24
|
end
|
19
25
|
end
|
@@ -6,18 +6,19 @@ class LHS::Service
|
|
6
6
|
module Mapping
|
7
7
|
extend ActiveSupport::Concern
|
8
8
|
|
9
|
-
attr_accessor :mapping
|
10
|
-
|
11
9
|
module ClassMethods
|
10
|
+
|
11
|
+
def mapping
|
12
|
+
@mapping ||= {}
|
13
|
+
end
|
12
14
|
|
13
|
-
def
|
14
|
-
|
15
|
+
def mapping=(mapping)
|
16
|
+
@mapping = mapping
|
15
17
|
end
|
16
|
-
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
def map(name, block)
|
20
|
+
mapping[name] = block
|
21
|
+
end
|
21
22
|
end
|
22
23
|
end
|
23
24
|
end
|
@@ -5,138 +5,142 @@ class LHS::Service
|
|
5
5
|
module Request
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def request(options)
|
11
|
+
if options.is_a? Array
|
12
|
+
multiple_requests(options)
|
13
|
+
else
|
14
|
+
single_request(options)
|
15
|
+
end
|
13
16
|
end
|
14
|
-
end
|
15
17
|
|
16
|
-
|
18
|
+
private
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
# Convert URLs in options to endpoint templates
|
21
|
+
def convert_options_to_endpoints(options)
|
22
|
+
if options.is_a?(Array)
|
23
|
+
options.map { |option| convert_option_to_endpoints(option) }
|
24
|
+
else
|
25
|
+
convert_option_to_endpoints(options)
|
26
|
+
end
|
24
27
|
end
|
25
|
-
end
|
26
28
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
29
|
+
def convert_option_to_endpoints(option)
|
30
|
+
new_options = option.dup
|
31
|
+
url = option[:url]
|
32
|
+
return unless endpoint = LHS::Endpoint.for_url(url)
|
33
|
+
template = endpoint.url
|
34
|
+
new_options = new_options.merge(params: LHC::Endpoint.values_as_params(template, url))
|
35
|
+
new_options[:url] = template
|
36
|
+
new_options
|
37
|
+
end
|
36
38
|
|
37
|
-
|
38
|
-
|
39
|
-
data.
|
40
|
-
|
41
|
-
|
39
|
+
# Extends existing raw data with additionaly fetched data
|
40
|
+
def extend_raw_data(data, addition, key)
|
41
|
+
if data._proxy.is_a? LHS::Collection
|
42
|
+
data.each_with_index do |item, i|
|
43
|
+
item = item[i] if item.is_a? LHS::Collection
|
44
|
+
item._raw[key.to_sym].merge!(addition[i]._raw)
|
45
|
+
end
|
46
|
+
elsif data._proxy.is_a? LHS::Item
|
47
|
+
data._raw[key.to_sym].merge!(addition._raw)
|
42
48
|
end
|
43
|
-
elsif data._proxy.is_a? LHS::Item
|
44
|
-
data._raw[key.to_sym].merge!(addition._raw)
|
45
49
|
end
|
46
|
-
end
|
47
50
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
def handle_includes(includes, data)
|
52
|
+
if includes.is_a? Hash
|
53
|
+
includes.each { |_include, sub_includes| handle_include(_include, data, sub_includes) }
|
54
|
+
elsif includes.is_a? Array
|
55
|
+
includes.each { |_include| handle_includes(_include, data) }
|
56
|
+
else
|
57
|
+
handle_include(includes, data)
|
58
|
+
end
|
55
59
|
end
|
56
|
-
end
|
57
60
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
def handle_include(_include, data, sub_includes = nil)
|
62
|
+
return unless data.present?
|
63
|
+
options = if data._proxy.is_a? LHS::Collection
|
64
|
+
options_for_multiple(data, _include)
|
65
|
+
else
|
66
|
+
url_option_for(data, _include)
|
67
|
+
end
|
68
|
+
addition = load_include(options, data, sub_includes)
|
69
|
+
extend_raw_data(data, addition, _include)
|
64
70
|
end
|
65
|
-
addition = load_include(options, data, sub_includes)
|
66
|
-
extend(data, addition, _include)
|
67
|
-
end
|
68
71
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
72
|
+
# Load additional resources that are requested with include
|
73
|
+
def load_include(options, data, sub_includes)
|
74
|
+
service = service_for_options(options) || self
|
75
|
+
options = convert_options_to_endpoints(options) if service_for_options(options)
|
76
|
+
begin
|
77
|
+
service.includes(sub_includes).request(options)
|
78
|
+
rescue LHC::NotFound
|
79
|
+
LHS::Data.new({}, data, service)
|
80
|
+
end
|
77
81
|
end
|
78
|
-
end
|
79
82
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
83
|
+
# Merge explicit params nested in 'params' namespace with original hash.
|
84
|
+
def merge_explicit_params!(params)
|
85
|
+
return true unless params
|
86
|
+
explicit_params = params[:params]
|
87
|
+
params.delete(:params)
|
88
|
+
params.merge!(explicit_params) if explicit_params
|
89
|
+
end
|
87
90
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
91
|
+
def multiple_requests(options)
|
92
|
+
options = options.map { |options| process_options(options) }
|
93
|
+
responses = LHC.request(options)
|
94
|
+
data = responses.map{ |response| LHS::Data.new(response.body, nil, self, response.request) }
|
95
|
+
data = LHS::Data.new(data, nil, self)
|
96
|
+
handle_includes(including, data) if including
|
97
|
+
data
|
98
|
+
end
|
96
99
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
+
def options_for_multiple(data, key)
|
101
|
+
data.map do |item|
|
102
|
+
url_option_for(item, key)
|
103
|
+
end
|
100
104
|
end
|
101
|
-
end
|
102
105
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
106
|
+
# Merge explicit params and take configured endpoints options as base
|
107
|
+
def process_options(options)
|
108
|
+
options ||= {}
|
109
|
+
options = options.dup
|
110
|
+
options[:params].deep_symbolize_keys! if options[:params]
|
111
|
+
endpoint = find_endpoint(options[:params])
|
112
|
+
options = (endpoint.options || {}).merge(options)
|
113
|
+
options[:url] = compute_url!(options[:params]) unless options.key?(:url)
|
114
|
+
merge_explicit_params!(options[:params])
|
115
|
+
options.delete(:params) if options[:params] && options[:params].empty?
|
116
|
+
options
|
117
|
+
end
|
115
118
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
119
|
+
def service_for_options(options)
|
120
|
+
services = []
|
121
|
+
if options.is_a?(Array)
|
122
|
+
options.each do |option|
|
123
|
+
next unless service = LHS::Service.for_url(option[:url])
|
124
|
+
services.push(service)
|
125
|
+
end
|
126
|
+
fail 'Found more than one service that could be used to do the request' if services.uniq.count > 1
|
127
|
+
services.uniq.first
|
128
|
+
else # Hash
|
129
|
+
LHS::Service.for_url(options[:url])
|
122
130
|
end
|
123
|
-
fail 'Found more than one service that could be used to do the request' if services.uniq.count > 1
|
124
|
-
services.uniq.first
|
125
|
-
else # Hash
|
126
|
-
LHS::Service.for_url(options[:url])
|
127
131
|
end
|
128
|
-
end
|
129
132
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
133
|
+
def single_request(options)
|
134
|
+
response = LHC.request(process_options(options))
|
135
|
+
data = LHS::Data.new(response.body, nil, self, response.request)
|
136
|
+
handle_includes(including, data) if including
|
137
|
+
data
|
138
|
+
end
|
136
139
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
+
def url_option_for(item, key)
|
141
|
+
link = item[key]
|
142
|
+
{ url: link.href }
|
143
|
+
end
|
140
144
|
end
|
141
145
|
end
|
142
146
|
end
|
data/lib/lhs/data.rb
CHANGED
@@ -52,7 +52,7 @@ class LHS::Data
|
|
52
52
|
end
|
53
53
|
|
54
54
|
def respond_to_missing?(name, include_all = false)
|
55
|
-
(root_item? && _root._service.
|
55
|
+
(root_item? && _root._service.mapping.keys.map(&:to_s).include?(name.to_s)) ||
|
56
56
|
_proxy.respond_to?(name, include_all)
|
57
57
|
end
|
58
58
|
|
@@ -63,10 +63,10 @@ class LHS::Data
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def mapping_for(name)
|
66
|
-
|
67
|
-
|
68
|
-
return unless
|
69
|
-
|
66
|
+
service = LHS::Service.for_url(_raw[:href]) if _raw.is_a?(Hash)
|
67
|
+
service ||= _root._service if root_item? && _root._service
|
68
|
+
return unless service
|
69
|
+
service.mapping[name]
|
70
70
|
end
|
71
71
|
|
72
72
|
def root_item
|
data/lib/lhs/proxy.rb
CHANGED
@@ -18,7 +18,7 @@ class LHS::Proxy
|
|
18
18
|
def reload!
|
19
19
|
fail 'No href found' unless _data.href
|
20
20
|
service = _data._root._service
|
21
|
-
data = service.
|
21
|
+
data = service.request(url: _data.href, method: :get)
|
22
22
|
_data.merge_raw!(data)
|
23
23
|
self._loaded = true
|
24
24
|
self
|
data/lib/lhs/service.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
require 'singleton'
|
2
1
|
Dir[File.dirname(__FILE__) + '/concerns/service/*.rb'].each {|file| require file }
|
3
2
|
|
4
|
-
# A Service makes data available using
|
3
|
+
# A Service makes data available by using backend endpoints.
|
5
4
|
class LHS::Service
|
6
5
|
include All
|
7
6
|
include Batch
|
@@ -15,6 +14,5 @@ class LHS::Service
|
|
15
14
|
include Model
|
16
15
|
include Includes
|
17
16
|
include Request
|
18
|
-
include Singleton
|
19
17
|
include Where
|
20
18
|
end
|
data/lib/lhs/version.rb
CHANGED
data/spec/service/build_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe LHS::Service do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'stores endpoints with options' do
|
14
|
-
expect(SomeService.
|
14
|
+
expect(SomeService.endpoints[0].options).to eq(cache_expires_in: 86400, retry: 2, cache: true)
|
15
15
|
end
|
16
16
|
|
17
17
|
it 'uses the options that are configured for an endpoint' do
|
@@ -22,24 +22,24 @@ describe LHS::Service do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
it 'stores the endpoints of the service' do
|
25
|
-
expect(SomeService.
|
26
|
-
expect(SomeService.
|
27
|
-
expect(SomeService.
|
28
|
-
expect(SomeService.
|
25
|
+
expect(SomeService.endpoints.count).to eq 3
|
26
|
+
expect(SomeService.endpoints[0].url).to eq ':datastore/entries/:entry_id/content-ads/:campaign_id/feedbacks'
|
27
|
+
expect(SomeService.endpoints[1].url).to eq ':datastore/:campaign_id/feedbacks'
|
28
|
+
expect(SomeService.endpoints[2].url).to eq ':datastore/feedbacks'
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'finds the endpoint by the one with the most route param hits' do
|
32
32
|
expect(
|
33
|
-
SomeService.
|
33
|
+
SomeService.find_endpoint(campaign_id: '12345').url
|
34
34
|
).to eq ':datastore/:campaign_id/feedbacks'
|
35
35
|
expect(
|
36
|
-
SomeService.
|
36
|
+
SomeService.find_endpoint(campaign_id: '12345', entry_id: '123').url
|
37
37
|
).to eq ':datastore/entries/:entry_id/content-ads/:campaign_id/feedbacks'
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'finds the base endpoint (endpoint with least amount of route params)' do
|
41
41
|
expect(
|
42
|
-
SomeService.
|
42
|
+
SomeService.find_endpoint.url
|
43
43
|
).to eq ':datastore/feedbacks'
|
44
44
|
end
|
45
45
|
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Service do
|
4
|
+
|
5
|
+
context 'new' do
|
6
|
+
|
7
|
+
let(:datastore) { 'http://local.ch/v2' }
|
8
|
+
|
9
|
+
before(:each) do
|
10
|
+
LHC.config.placeholder('datastore', datastore)
|
11
|
+
class Feedback < LHS::Service
|
12
|
+
endpoint ':datastore/content-ads/:campaign_id/feedbacks'
|
13
|
+
endpoint ':datastore/feedbacks'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'builds a new item from scratch (like build)' do
|
18
|
+
feedback = Feedback.new recommended: true
|
19
|
+
expect(feedback.recommended).to eq true
|
20
|
+
stub_request(:post, "http://local.ch/v2/feedbacks")
|
21
|
+
.with(body: "{\"recommended\":true}")
|
22
|
+
feedback.save
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lhs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- local.ch
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-12-
|
11
|
+
date: 2015-12-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: lhc
|
@@ -240,6 +240,7 @@ files:
|
|
240
240
|
- spec/service/includes_spec.rb
|
241
241
|
- spec/service/mapping_spec.rb
|
242
242
|
- spec/service/model_name_spec.rb
|
243
|
+
- spec/service/new_spec.rb
|
243
244
|
- spec/service/request_spec.rb
|
244
245
|
- spec/service/where_spec.rb
|
245
246
|
- spec/spec_helper.rb
|
@@ -355,6 +356,7 @@ test_files:
|
|
355
356
|
- spec/service/includes_spec.rb
|
356
357
|
- spec/service/mapping_spec.rb
|
357
358
|
- spec/service/model_name_spec.rb
|
359
|
+
- spec/service/new_spec.rb
|
358
360
|
- spec/service/request_spec.rb
|
359
361
|
- spec/service/where_spec.rb
|
360
362
|
- spec/spec_helper.rb
|