lhs 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +38 -0
- data/Gemfile +11 -0
- data/README.md +67 -0
- data/Rakefile +26 -0
- data/docs/collections.md +28 -0
- data/docs/data.md +39 -0
- data/docs/examples/claim_no_include.json +16 -0
- data/docs/examples/claim_with_include.json +47 -0
- data/docs/items.md +55 -0
- data/docs/service.jpg +0 -0
- data/docs/service.pdf +649 -3
- data/docs/services.md +191 -0
- data/lhs.gemspec +31 -0
- data/lib/lhs.rb +6 -0
- data/lib/lhs/collection.rb +78 -0
- data/lib/lhs/concerns/data/json.rb +12 -0
- data/lib/lhs/concerns/item/destroy.rb +15 -0
- data/lib/lhs/concerns/item/save.rb +29 -0
- data/lib/lhs/concerns/item/update.rb +24 -0
- data/lib/lhs/concerns/service/all.rb +24 -0
- data/lib/lhs/concerns/service/batch.rb +37 -0
- data/lib/lhs/concerns/service/build.rb +17 -0
- data/lib/lhs/concerns/service/create.rb +26 -0
- data/lib/lhs/concerns/service/endpoints.rb +82 -0
- data/lib/lhs/concerns/service/find.rb +36 -0
- data/lib/lhs/concerns/service/find_by.rb +35 -0
- data/lib/lhs/concerns/service/first.rb +19 -0
- data/lib/lhs/concerns/service/includes.rb +21 -0
- data/lib/lhs/concerns/service/mapping.rb +23 -0
- data/lib/lhs/concerns/service/model.rb +16 -0
- data/lib/lhs/concerns/service/request.rb +96 -0
- data/lib/lhs/concerns/service/where.rb +16 -0
- data/lib/lhs/data.rb +103 -0
- data/lib/lhs/errors.rb +86 -0
- data/lib/lhs/item.rb +83 -0
- data/lib/lhs/proxy.rb +26 -0
- data/lib/lhs/service.rb +20 -0
- data/lib/lhs/version.rb +3 -0
- data/script/ci/build.sh +19 -0
- data/spec/collection/meta_data_spec.rb +54 -0
- data/spec/collection/respond_to_spec.rb +19 -0
- data/spec/collection/without_object_items_spec.rb +26 -0
- data/spec/data/collection_spec.rb +36 -0
- data/spec/data/item_spec.rb +44 -0
- data/spec/data/merge_spec.rb +32 -0
- data/spec/data/raw_spec.rb +39 -0
- data/spec/data/respond_to_spec.rb +26 -0
- data/spec/data/root_spec.rb +25 -0
- data/spec/data/to_json_spec.rb +39 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +14 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +34 -0
- data/spec/dummy/config/environments/production.rb +75 -0
- data/spec/dummy/config/environments/test.rb +39 -0
- data/spec/dummy/config/initializers/assets.rb +8 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +9 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/item/destroy_spec.rb +39 -0
- data/spec/item/getter_spec.rb +24 -0
- data/spec/item/respond_to_spec.rb +29 -0
- data/spec/item/save_errors_spec.rb +48 -0
- data/spec/item/save_spec.rb +58 -0
- data/spec/item/setter_spec.rb +38 -0
- data/spec/item/update_spec.rb +56 -0
- data/spec/proxy/load_spec.rb +47 -0
- data/spec/rails_helper.rb +9 -0
- data/spec/service/all_spec.rb +31 -0
- data/spec/service/build_spec.rb +25 -0
- data/spec/service/create_spec.rb +81 -0
- data/spec/service/creation_failed_spec.rb +54 -0
- data/spec/service/endpoint_misconfiguration_spec.rb +26 -0
- data/spec/service/endpoint_options_spec.rb +23 -0
- data/spec/service/endpoints_spec.rb +57 -0
- data/spec/service/find_by_spec.rb +49 -0
- data/spec/service/find_each_spec.rb +47 -0
- data/spec/service/find_in_batches_spec.rb +68 -0
- data/spec/service/find_spec.rb +71 -0
- data/spec/service/first_spec.rb +39 -0
- data/spec/service/includes_spec.rb +61 -0
- data/spec/service/mapping_spec.rb +72 -0
- data/spec/service/model_name_spec.rb +17 -0
- data/spec/service/request_spec.rb +22 -0
- data/spec/service/where_spec.rb +33 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/support/cleanup_configuration.rb +17 -0
- data/spec/support/cleanup_services.rb +20 -0
- data/spec/support/fixtures/json/feedback.json +11 -0
- data/spec/support/fixtures/json/feedbacks.json +174 -0
- data/spec/support/fixtures/json/localina_content_ad.json +23 -0
- data/spec/support/load_json.rb +3 -0
- metadata +346 -0
data/lib/lhs/errors.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Like ActiveModel::Errors
|
2
|
+
class LHS::Errors
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_reader :messages, :message
|
6
|
+
|
7
|
+
def initialize(response)
|
8
|
+
@messages = messages_from_response(response)
|
9
|
+
@message = message_from_response(response)
|
10
|
+
rescue JSON::ParserError
|
11
|
+
end
|
12
|
+
|
13
|
+
def include?(attribute)
|
14
|
+
messages[attribute].present?
|
15
|
+
end
|
16
|
+
alias :has_key? :include?
|
17
|
+
alias :key? :include?
|
18
|
+
|
19
|
+
def get(key)
|
20
|
+
messages[key]
|
21
|
+
end
|
22
|
+
|
23
|
+
def set(key, value)
|
24
|
+
messages[key] = value
|
25
|
+
end
|
26
|
+
|
27
|
+
def delete(key)
|
28
|
+
messages.delete(key)
|
29
|
+
end
|
30
|
+
|
31
|
+
def [](attribute)
|
32
|
+
get(attribute.to_sym) || set(attribute.to_sym, [])
|
33
|
+
end
|
34
|
+
|
35
|
+
def []=(attribute, error)
|
36
|
+
self[attribute] << error
|
37
|
+
end
|
38
|
+
|
39
|
+
def each
|
40
|
+
messages.each_key do |attribute|
|
41
|
+
self[attribute].each { |error| yield attribute, error }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def size
|
46
|
+
values.flatten.size
|
47
|
+
end
|
48
|
+
|
49
|
+
def values
|
50
|
+
messages.values
|
51
|
+
end
|
52
|
+
|
53
|
+
def keys
|
54
|
+
messages.keys
|
55
|
+
end
|
56
|
+
|
57
|
+
def count
|
58
|
+
to_a.size
|
59
|
+
end
|
60
|
+
|
61
|
+
def empty?
|
62
|
+
all? { |k, v| v && v.empty? && !v.is_a?(String) }
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def messages_from_response(response)
|
68
|
+
messages = {}
|
69
|
+
return messages if !response.body.is_a?(String) || response.body.length.zero?
|
70
|
+
json = JSON.parse(response.body)
|
71
|
+
return messages unless json['fields']
|
72
|
+
json['fields'].each do |field|
|
73
|
+
name = field['name'].to_sym
|
74
|
+
messages[name] ||= []
|
75
|
+
field['details'].each do |detail|
|
76
|
+
messages[name].push(detail['code'])
|
77
|
+
end
|
78
|
+
end
|
79
|
+
messages
|
80
|
+
end
|
81
|
+
|
82
|
+
def message_from_response(response)
|
83
|
+
json = JSON.parse(response.body)
|
84
|
+
json['message']
|
85
|
+
end
|
86
|
+
end
|
data/lib/lhs/item.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require File.join(__dir__, 'proxy.rb')
|
2
|
+
Dir[File.dirname(__FILE__) + '/concerns/item/*.rb'].each {|file| require file }
|
3
|
+
|
4
|
+
# An item is a concrete record.
|
5
|
+
# It can be part of another proxy like collection.
|
6
|
+
class LHS::Item < LHS::Proxy
|
7
|
+
include Destroy
|
8
|
+
include Save
|
9
|
+
include Update
|
10
|
+
|
11
|
+
# prevent clashing with attributes of underlying data
|
12
|
+
attr_accessor :errors
|
13
|
+
|
14
|
+
def _raw
|
15
|
+
_data._raw
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def method_missing(name, *args, &block)
|
21
|
+
return set(name, args.try(&:first)) if name.to_s[/=$/]
|
22
|
+
name = args.first if name == :[]
|
23
|
+
value = _data._raw[name.to_s]
|
24
|
+
value = _data._raw[name.to_sym] if value.nil?
|
25
|
+
if value.is_a?(Hash)
|
26
|
+
handle_hash(value)
|
27
|
+
elsif value.is_a?(Array)
|
28
|
+
data = LHS::Data.new(value, _data)
|
29
|
+
collection = LHS::Collection.new(data)
|
30
|
+
LHS::Data.new(collection, _data)
|
31
|
+
else
|
32
|
+
convert(value)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def respond_to_missing?(name, include_all = false)
|
37
|
+
# We accept every message that does not belong to set of keywords
|
38
|
+
BLACKLISTED_KEYWORDS.exclude?(name.to_s)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# FIXME: Extend the set of keywords
|
44
|
+
BLACKLISTED_KEYWORDS = %w( new proxy_association )
|
45
|
+
|
46
|
+
def convert(value)
|
47
|
+
return value unless value.is_a?(String)
|
48
|
+
if date_time?(value)
|
49
|
+
DateTime.parse(value)
|
50
|
+
elsif date?(value)
|
51
|
+
Date.parse(value)
|
52
|
+
else
|
53
|
+
value
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def handle_hash(value)
|
58
|
+
LHS::Data.new(value, _data)
|
59
|
+
end
|
60
|
+
|
61
|
+
def set(name, value)
|
62
|
+
key = name.to_s.gsub(/=$/, '')
|
63
|
+
_data._raw[key] = value
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def date?(value)
|
69
|
+
value[date_time_regex, :date].presence
|
70
|
+
end
|
71
|
+
|
72
|
+
def time?(value)
|
73
|
+
value[date_time_regex, :time].presence
|
74
|
+
end
|
75
|
+
|
76
|
+
def date_time?(value)
|
77
|
+
date?(value) && time?(value)
|
78
|
+
end
|
79
|
+
|
80
|
+
def date_time_regex
|
81
|
+
/(?<date>\d{4}-\d{2}-\d{2})?(?<time>T\d{2}:\d{2}:\d{2}\.\d*.\d{2}:\d{2})?/
|
82
|
+
end
|
83
|
+
end
|
data/lib/lhs/proxy.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Proxy makes different kind of data accessible
|
2
|
+
# If href is present it also alows loading/reloading
|
3
|
+
class LHS::Proxy
|
4
|
+
|
5
|
+
# prevent clashing with attributes of underlying data
|
6
|
+
attr_accessor :_data, :_loaded
|
7
|
+
|
8
|
+
def initialize(data)
|
9
|
+
self._data = data
|
10
|
+
self._loaded = false
|
11
|
+
end
|
12
|
+
|
13
|
+
def load!
|
14
|
+
return self if _loaded
|
15
|
+
reload!
|
16
|
+
end
|
17
|
+
|
18
|
+
def reload!
|
19
|
+
fail 'No href found' unless _data.href
|
20
|
+
service = _data._root._service
|
21
|
+
data = service.instance.request(url: _data.href, method: :get)
|
22
|
+
merge!(data)
|
23
|
+
self._loaded = true
|
24
|
+
self
|
25
|
+
end
|
26
|
+
end
|
data/lib/lhs/service.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
Dir[File.dirname(__FILE__) + '/concerns/service/*.rb'].each {|file| require file }
|
3
|
+
|
4
|
+
# A Service makes data available using multiple endpoints.
|
5
|
+
class LHS::Service
|
6
|
+
include All
|
7
|
+
include Batch
|
8
|
+
include Build
|
9
|
+
include Create
|
10
|
+
include Endpoints
|
11
|
+
include Find
|
12
|
+
include FindBy
|
13
|
+
include First
|
14
|
+
include Mapping
|
15
|
+
include Model
|
16
|
+
include Includes
|
17
|
+
include Request
|
18
|
+
include Singleton
|
19
|
+
include Where
|
20
|
+
end
|
data/lib/lhs/version.rb
ADDED
data/script/ci/build.sh
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash -e
|
2
|
+
|
3
|
+
# custom vars
|
4
|
+
# RUBY = ruby-1.9.3-p125
|
5
|
+
# GEMSET = location-app-${GitHub pull request id|branch name}
|
6
|
+
# standard vars
|
7
|
+
# https://jenkins.intra.local.ch/env-vars.html/
|
8
|
+
|
9
|
+
if [ -z "$SKIP_RVM" ]; then
|
10
|
+
[[ -s "/usr/local/rvm/scripts/rvm" ]] && . "/usr/local/rvm/scripts/rvm"
|
11
|
+
RUBY=${RUBY:-ruby-2.1.2}
|
12
|
+
GEMSET=${GEMSET:-LHS}
|
13
|
+
rvm use ${RUBY}@${GEMSET} --create
|
14
|
+
gem install bundler --no-rdoc --no-ri
|
15
|
+
fi
|
16
|
+
|
17
|
+
bundle install --local || bundle install
|
18
|
+
RAILS_ENV=test bundle exec rspec
|
19
|
+
rvm --force gemset delete ${RUBY}@${GEMSET}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Collection do
|
4
|
+
|
5
|
+
let(:total) { 0 }
|
6
|
+
|
7
|
+
let(:limit) { 50 }
|
8
|
+
|
9
|
+
let(:offset) { 0 }
|
10
|
+
|
11
|
+
let(:collection) do
|
12
|
+
{
|
13
|
+
href: "#{datastore}/feedbacks",
|
14
|
+
items: [],
|
15
|
+
total: total,
|
16
|
+
limit: limit,
|
17
|
+
offset: offset
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:item) do
|
22
|
+
{
|
23
|
+
href: "#{datastore}/users/1",
|
24
|
+
feedbacks: collection
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
let(:datastore) { 'http://datastore-stg.lb-service.sunrise.intra.local.ch/v2' }
|
29
|
+
|
30
|
+
before(:each) do
|
31
|
+
LHC.config.placeholder('datastore', datastore)
|
32
|
+
class Feedback < LHS::Service
|
33
|
+
endpoint ':datastore/feedbacks'
|
34
|
+
end
|
35
|
+
class User < LHS::Service
|
36
|
+
endpoint ':datastore/users'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'provides meta data for collections' do
|
41
|
+
stub_request(:get, "#{datastore}/feedbacks").to_return(status: 200, body: collection.to_json)
|
42
|
+
feedbacks = Feedback.where
|
43
|
+
expect(feedbacks.total).to eq total
|
44
|
+
expect(feedbacks.limit).to eq limit
|
45
|
+
expect(feedbacks.offset).to eq offset
|
46
|
+
expect(feedbacks.href).to eq "#{datastore}/feedbacks"
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'provides meta data also when navigating' do
|
50
|
+
stub_request(:get, "#{datastore}/users/1").to_return(status: 200, body: item.to_json)
|
51
|
+
user = User.find(1)
|
52
|
+
expect(user.feedbacks.href).to eq "#{datastore}/feedbacks"
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Collection do
|
4
|
+
|
5
|
+
let(:data) {
|
6
|
+
['ROLE_USER', 'ROLE_LOCALCH_ACCOUNT']
|
7
|
+
}
|
8
|
+
|
9
|
+
let(:collection){
|
10
|
+
described_class.new(LHS::Data.new(data))
|
11
|
+
}
|
12
|
+
|
13
|
+
context '#respond_to?' do
|
14
|
+
# In this case raw collection is an Array implementing first
|
15
|
+
it 'forwards calls to raw collection' do
|
16
|
+
expect(collection.respond_to?(:first)).to be(true)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Collection do
|
4
|
+
|
5
|
+
let(:datastore) { 'http://datastore-stg.lb-service.sunrise.intra.local.ch/v2' }
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
LHC.config.placeholder('datastore', datastore)
|
9
|
+
class Account < LHS::Service
|
10
|
+
endpoint ':datastore/accounts'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:data) {
|
15
|
+
{
|
16
|
+
'authorities' => ['ROLE_USER', 'ROLE_LOCALCH_ACCOUNT']
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
it 'lets you access items of an array if they are not objects' do
|
21
|
+
stub_request(:get, "#{datastore}/accounts/1").to_return(status: 200, body: data.to_json)
|
22
|
+
feedback = Account.find(1)
|
23
|
+
expect(feedback.authorities.first).to eq 'ROLE_USER'
|
24
|
+
expect(feedback.authorities[1]).to eq 'ROLE_LOCALCH_ACCOUNT'
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Data do
|
4
|
+
|
5
|
+
let(:json) do
|
6
|
+
load_json(:feedbacks)
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:data) do
|
10
|
+
LHS::Data.new(json)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'collections' do
|
14
|
+
|
15
|
+
it 'forwards calls to the collection' do
|
16
|
+
expect(data.count).to be_kind_of Fixnum
|
17
|
+
expect(data[0]).to be_kind_of LHS::Data
|
18
|
+
expect(data.sample).to be_kind_of LHS::Data
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'provides a total method to get the number of total records' do
|
22
|
+
expect(data.total).to be_kind_of Fixnum
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'collections from arrays' do
|
27
|
+
|
28
|
+
let(:data) do
|
29
|
+
LHS::Data.new([1,2,3,4])
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'uses collection as proxy for arrays' do
|
33
|
+
expect(data._proxy).to be_kind_of LHS::Collection
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Data do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
class SomeService < LHS::Service
|
7
|
+
endpoint ':datastore/v2/:campaign_id/feedbacks'
|
8
|
+
endpoint ':datastore/v2/feedbacks'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:json) do
|
13
|
+
load_json(:feedbacks)
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:data) do
|
17
|
+
LHS::Data.new(json, nil, SomeService)
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:item) do
|
21
|
+
data[0]
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'item' do
|
25
|
+
|
26
|
+
it 'makes data accessible' do
|
27
|
+
expect(item.href).to be_kind_of String
|
28
|
+
expect(item.recommended).to be_kind_of TrueClass
|
29
|
+
expect(item.average_rating).to be_kind_of Float
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns nil if no data is present' do
|
33
|
+
expect(item.something).to eq nil
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'returns datetime if string can be parsed as date_time' do
|
37
|
+
expect(item.created_date).to be_kind_of DateTime
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'returns date if string can be parsed as date' do
|
41
|
+
expect(item.valid_from).to be_kind_of Date
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rails_helper'
|
2
|
+
|
3
|
+
describe LHS::Data do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
class SomeService < LHS::Service
|
7
|
+
endpoint ':datastore/v2/:campaign_id/feedbacks'
|
8
|
+
endpoint ':datastore/v2/feedbacks'
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:data) do
|
13
|
+
LHS::Data.new({
|
14
|
+
href: 'http://www.local.ch/v2/stuff'
|
15
|
+
}, nil, SomeService)
|
16
|
+
end
|
17
|
+
|
18
|
+
let(:loaded_data) do
|
19
|
+
LHS::Data.new({
|
20
|
+
href: 'http://www.local.ch/v2/stuff',
|
21
|
+
id: '123123123'
|
22
|
+
}, nil, SomeService)
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'merging' do
|
26
|
+
|
27
|
+
it 'merges data' do
|
28
|
+
data.merge!(loaded_data)
|
29
|
+
expect(data.id).to eq loaded_data.id
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|