xing-backend 0.0.13 → 0.0.14
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/deprecated_classes.rb +2 -1
- data/lib/xing-backend.rb +1 -0
- data/lib/xing/builders.rb +7 -0
- data/lib/xing/builders/list_difference_builder.rb +60 -0
- data/lib/xing/builders/ordered_list_difference_builder.rb +25 -0
- data/lib/xing/mappers/base.rb +20 -3
- data/lib/xing/services.rb +1 -0
- data/lib/xing/services/locator.rb +22 -0
- data/spec/deprecated_classes/list_difference_builder_spec.rb +19 -0
- data/spec/xing/builders/list_difference_builder_spec.rb +193 -0
- data/spec/xing/builders/ordered_list_difference_builder_spec.rb +210 -0
- metadata +18 -13
- data/spec_help/dummy/db/test.sqlite3 +0 -0
- data/spec_help/dummy/log/test.log +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 74175fddf1215ed94724354b57fcc40ece2d292e
|
4
|
+
data.tar.gz: e05dd42fd8d0b1cac13b84a99da52d9f5c225413
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c927c8307144a1d5727d786f6ba4659cebb6a84197295682ba942eca3e063a612a4f5dd2b2619454a830c879f7e59508961ccfee22c13f1381d24d0a81737537
|
7
|
+
data.tar.gz: 634f88679c1c9430cfebef12caac13c829aeb0eb5680f5c3096f2c828f1949f606c54fbcef5e8e9333b7967d95e1e8edde5c634065f509f06da00f60b90da2c6
|
data/lib/deprecated_classes.rb
CHANGED
@@ -8,7 +8,8 @@ module Xing
|
|
8
8
|
:ResourcesSerializer => Xing::Serializers::RootResources,
|
9
9
|
:JsonTreeLister => Xing::Services::JsonTreeLister,
|
10
10
|
:ActiveModelErrorConverter => Xing::Services::ErrorConverter,
|
11
|
-
:RemoteSnapshotFetcher => Xing::Services::SnapshotFetcher
|
11
|
+
:RemoteSnapshotFetcher => Xing::Services::SnapshotFetcher,
|
12
|
+
:ListDifferenceBuilder => Xing::Builders::OrderedListDifferenceBuilder
|
12
13
|
}
|
13
14
|
end
|
14
15
|
|
data/lib/xing-backend.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'xing/services/locator'
|
2
|
+
|
3
|
+
module Xing
|
4
|
+
module Builders
|
5
|
+
class ListDifferenceBuilder
|
6
|
+
|
7
|
+
# list_data is is an array of JSON objects passed in by the mapper (the new list of records)
|
8
|
+
# collection is the ActiveRecord collection of existing records (i.e. person.pets, rainbow.colors, book.chapters)
|
9
|
+
def initialize(list_data, collection, mapper_class)
|
10
|
+
@list_data = list_data
|
11
|
+
@collection = collection
|
12
|
+
@mapper_class = mapper_class
|
13
|
+
|
14
|
+
@errors = Hash.new { |hash, key| hash[key] = {} }
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :errors
|
18
|
+
|
19
|
+
def build
|
20
|
+
sort_json_items
|
21
|
+
map_items
|
22
|
+
|
23
|
+
{ save: @new_list, delete: @delete_ids }
|
24
|
+
end
|
25
|
+
|
26
|
+
def sort_json_items
|
27
|
+
@existing_ids = @collection.map{|item| item.send(@mapper_class.locator_attribute_name)}
|
28
|
+
|
29
|
+
@list_data = @list_data.map do |data|
|
30
|
+
{ :locator => set_locator(data), :incoming => data}
|
31
|
+
end
|
32
|
+
|
33
|
+
@delete_ids = @existing_ids - @list_data.map { |item| item[:locator] }
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_locator(data)
|
37
|
+
locator_for(data) unless (data[:links] || {})[:self].blank?
|
38
|
+
end
|
39
|
+
|
40
|
+
def locator_for(data)
|
41
|
+
Xing::Services::Locator.route_to(data[:links][:self])[:id].to_i
|
42
|
+
end
|
43
|
+
|
44
|
+
def map_items
|
45
|
+
@new_list = []
|
46
|
+
@list_data.each_with_index do |item, index|
|
47
|
+
|
48
|
+
mapper = @mapper_class.new(item[:incoming], item[:locator])
|
49
|
+
|
50
|
+
# Sets association, attributes
|
51
|
+
@collection << mapper.record
|
52
|
+
mapper.perform_mapping
|
53
|
+
|
54
|
+
@new_list << mapper
|
55
|
+
@errors[index] = mapper.errors[:data] unless mapper.errors[:data].blank?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Xing
|
2
|
+
module Builders
|
3
|
+
class OrderedListDifferenceBuilder < ListDifferenceBuilder
|
4
|
+
def map_items
|
5
|
+
@new_list = []
|
6
|
+
@list_data.each_with_index do |item, index|
|
7
|
+
|
8
|
+
mapper = @mapper_class.new(item[:incoming], item[:locator])
|
9
|
+
|
10
|
+
# Sets association, attributes and position
|
11
|
+
@collection << mapper.record
|
12
|
+
mapper.perform_mapping
|
13
|
+
set_position(mapper.record, index)
|
14
|
+
|
15
|
+
@new_list << mapper
|
16
|
+
@errors[index] = mapper.errors[:data] unless mapper.errors[:data].blank?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def set_position(record, index)
|
21
|
+
record.position = index if record.has_attribute?(:position)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/xing/mappers/base.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'active_support'
|
4
4
|
require 'active_support/core_ext'
|
5
5
|
require 'xing/services/error_converter'
|
6
|
+
require 'xing/services/locator'
|
6
7
|
|
7
8
|
module Xing
|
8
9
|
module Mappers
|
@@ -17,6 +18,7 @@ module Xing
|
|
17
18
|
# assign_values -- move values from JSON into the mapped AR record
|
18
19
|
#
|
19
20
|
# Subclasses may also want to define:
|
21
|
+
# locator_attribute_name -- if the locator something other than :id, like :url_slug
|
20
22
|
# find_existing_record -- for locating the underlying AR record
|
21
23
|
# build_new_record -- for for instantiating a new underlying AR record
|
22
24
|
# map_nested_models
|
@@ -34,8 +36,13 @@ module Xing
|
|
34
36
|
end
|
35
37
|
@locator = locator
|
36
38
|
end
|
37
|
-
attr_accessor :locator, :error_data
|
39
|
+
attr_accessor :locator, :locator_attribute_name, :error_data
|
38
40
|
attr_writer :record
|
41
|
+
attr_reader :links
|
42
|
+
|
43
|
+
def locator_attribute_name
|
44
|
+
:id
|
45
|
+
end
|
39
46
|
|
40
47
|
def router
|
41
48
|
Rails.application.routes
|
@@ -65,6 +72,7 @@ module Xing
|
|
65
72
|
def save
|
66
73
|
perform_mapping
|
67
74
|
unless self.errors[:data].present?
|
75
|
+
save_nested_models
|
68
76
|
self.record.save
|
69
77
|
end
|
70
78
|
end
|
@@ -83,6 +91,7 @@ module Xing
|
|
83
91
|
|
84
92
|
def perform_mapping
|
85
93
|
data = unwrap_data(@source_hash)
|
94
|
+
@links = unwrap_links(@source_hash)
|
86
95
|
self.error_data = Hash.new { |hash, key| hash[key] = {} }
|
87
96
|
|
88
97
|
assign_values(data)
|
@@ -90,7 +99,12 @@ module Xing
|
|
90
99
|
build_errors
|
91
100
|
end
|
92
101
|
|
102
|
+
def unwrap_links(hash)
|
103
|
+
hash['links'].with_indifferent_access
|
104
|
+
end
|
105
|
+
|
93
106
|
def unwrap_data(hash)
|
107
|
+
return hash['data'] if hash['data'].is_a?(Array)
|
94
108
|
hash['data'].with_indifferent_access
|
95
109
|
end
|
96
110
|
|
@@ -119,15 +133,18 @@ module Xing
|
|
119
133
|
def map_nested_models
|
120
134
|
end
|
121
135
|
|
136
|
+
def save_nested_models
|
137
|
+
end
|
138
|
+
|
122
139
|
def build_errors
|
123
|
-
self.
|
140
|
+
self.add_ar_errors(self.record)
|
124
141
|
end
|
125
142
|
|
126
143
|
def errors
|
127
144
|
wrap_data(error_data)
|
128
145
|
end
|
129
146
|
|
130
|
-
def
|
147
|
+
def add_ar_errors(object)
|
131
148
|
object_errors = Xing::Services::ErrorConverter.new(object).convert
|
132
149
|
error_data.deep_merge!(object_errors)
|
133
150
|
end
|
data/lib/xing/services.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
module Xing::Services
|
2
|
+
module Locator
|
3
|
+
|
4
|
+
def route_to(path)
|
5
|
+
path = "http://#{BACKEND_SUBDOMAIN}.example.com#{normalize_path(path)}";
|
6
|
+
router.recognize_path(path)
|
7
|
+
end
|
8
|
+
|
9
|
+
def normalize_path(path)
|
10
|
+
path = "/#{path}"
|
11
|
+
path.squeeze!('/')
|
12
|
+
path.sub!(%r{/+\Z}, '')
|
13
|
+
path.gsub!(/(%[a-f0-9]{2})/) { $1.upcase }
|
14
|
+
path = '/' if path == ''
|
15
|
+
path
|
16
|
+
end
|
17
|
+
|
18
|
+
def router
|
19
|
+
Rails.application.routes
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'deprecated_classes'
|
2
|
+
|
3
|
+
describe ListDifferenceBuilder, :type => :deprecation do
|
4
|
+
let :list_data do
|
5
|
+
double('list_data')
|
6
|
+
end
|
7
|
+
|
8
|
+
let :collection do
|
9
|
+
double('many.things')
|
10
|
+
end
|
11
|
+
|
12
|
+
let :mapper do
|
13
|
+
double('ThingMapper')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be the correct class" do
|
17
|
+
expect(ListDifferenceBuilder.new(list_data, collection, mapper)).to be_a(Xing::Builders::OrderedListDifferenceBuilder)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,193 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xing::Builders::ListDifferenceBuilder do
|
4
|
+
|
5
|
+
let :builder do
|
6
|
+
Xing::Builders::ListDifferenceBuilder.new(list_data, collection, mapper_class)
|
7
|
+
end
|
8
|
+
|
9
|
+
let :mapper_class do
|
10
|
+
double("ItemMapper")
|
11
|
+
end
|
12
|
+
|
13
|
+
let :mapper_instance do
|
14
|
+
double("mapper")
|
15
|
+
end
|
16
|
+
|
17
|
+
let :collection do
|
18
|
+
[double("Relation AR Object id: 1"), double("Relation AR Object id: 2"), double("Relation AR Object id: 3")]
|
19
|
+
end
|
20
|
+
|
21
|
+
let :new_ar_object do
|
22
|
+
double("New Relation AR Object")
|
23
|
+
end
|
24
|
+
|
25
|
+
let :updated_ar_object do
|
26
|
+
double("Updated AR Object")
|
27
|
+
end
|
28
|
+
|
29
|
+
let :existing_ids do
|
30
|
+
[1,2,3]
|
31
|
+
end
|
32
|
+
|
33
|
+
let :list_data do
|
34
|
+
[
|
35
|
+
{
|
36
|
+
links: {
|
37
|
+
self: "/somethings/1"
|
38
|
+
},
|
39
|
+
data: {
|
40
|
+
stuff: "some updated stuff"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
{
|
44
|
+
links: {
|
45
|
+
self: ""
|
46
|
+
},
|
47
|
+
data: {
|
48
|
+
stuff: "some new stuff"
|
49
|
+
}
|
50
|
+
}
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
let :new_list_data do
|
55
|
+
[
|
56
|
+
{
|
57
|
+
locator: 1,
|
58
|
+
incoming: {
|
59
|
+
links: {
|
60
|
+
self: "/somethings/1"
|
61
|
+
},
|
62
|
+
data: {
|
63
|
+
stuff: "some updated stuff"
|
64
|
+
}
|
65
|
+
}
|
66
|
+
},
|
67
|
+
{
|
68
|
+
locator: nil,
|
69
|
+
incoming: {
|
70
|
+
links: {
|
71
|
+
self: ""
|
72
|
+
},
|
73
|
+
data: {
|
74
|
+
stuff: "some new stuff"
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
]
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should initialize and assign list_data, collection, mapper class and errors" do
|
82
|
+
expect(builder.instance_variable_get('@list_data')).to eq(list_data)
|
83
|
+
expect(builder.instance_variable_get('@collection')).to eq(collection)
|
84
|
+
expect(builder.instance_variable_get('@mapper_class')).to eq(mapper_class)
|
85
|
+
expect(builder.instance_variable_get('@errors')).to eq({})
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#sort_json_items" do
|
89
|
+
before :each do
|
90
|
+
allow(collection).to receive(:map).and_return(existing_ids)
|
91
|
+
allow(builder).to receive(:locator_for).and_return(1)
|
92
|
+
builder.sort_json_items
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should create a list of existing ids" do
|
96
|
+
expect(builder.instance_variable_get('@existing_ids')).to eq(existing_ids)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should insert index and locator into the item data" do
|
100
|
+
expect(builder.instance_variable_get('@list_data')).to eq(new_list_data)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should find the ids to delete" do
|
104
|
+
expect(builder.instance_variable_get('@delete_ids')).to eq([2,3])
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#set_locator" do
|
109
|
+
|
110
|
+
it "should be nil if links is empty" do
|
111
|
+
data = { links: {}, data: { text:"bs" } }
|
112
|
+
expect(builder.set_locator(data)).to be_nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should be nil if links/self is empty" do
|
116
|
+
data = { links: {self: ""}}
|
117
|
+
expect(builder.set_locator(data)).to be_nil
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should set locator if links/self is present" do
|
121
|
+
data = { links: {self: "some_link/1/something"}}
|
122
|
+
allow(builder).to receive(:locator_for).and_return(1)
|
123
|
+
|
124
|
+
expect(builder.set_locator(data)).to eq(1)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "#map_items" do
|
129
|
+
before :each do
|
130
|
+
builder.instance_variable_set('@list_data', new_list_data)
|
131
|
+
allow(mapper_class).to receive(:new).and_return(mapper_instance)
|
132
|
+
allow(mapper_instance).to receive(:record).and_return(new_ar_object, new_ar_object, updated_ar_object, updated_ar_object)
|
133
|
+
allow(mapper_instance).to receive(:perform_mapping)
|
134
|
+
allow(new_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
135
|
+
allow(updated_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
136
|
+
end
|
137
|
+
|
138
|
+
context "successful" do
|
139
|
+
it "should create a new ar list" do
|
140
|
+
allow(mapper_instance).to receive(:errors).and_return({})
|
141
|
+
builder.map_items
|
142
|
+
|
143
|
+
expect(builder.instance_variable_get('@new_list')).to match_array([mapper_instance, mapper_instance])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "with errors" do
|
148
|
+
it "should add to the error hash with the correct index" do
|
149
|
+
allow(mapper_instance).to receive(:errors).and_return({}, {data: {type: "I would do anything for love", message: "but I won't do that"}}, {data: {type: "I would do anything for love", message: "but I won't do that"}})
|
150
|
+
builder.map_items
|
151
|
+
|
152
|
+
expect(builder.instance_variable_get('@errors')).to eq({1=>{:type=>"I would do anything for love", :message=>"but I won't do that"}})
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#build" do
|
158
|
+
before :each do
|
159
|
+
allow(collection).to receive(:map).and_return(existing_ids)
|
160
|
+
allow(builder).to receive(:locator_for).and_return(1)
|
161
|
+
allow(mapper_class).to receive(:new).and_return(mapper_instance)
|
162
|
+
allow(mapper_instance).to receive(:record).and_return(new_ar_object, new_ar_object, updated_ar_object, updated_ar_object)
|
163
|
+
allow(mapper_instance).to receive(:perform_mapping)
|
164
|
+
allow(new_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
165
|
+
allow(updated_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
166
|
+
end
|
167
|
+
|
168
|
+
context "successful" do
|
169
|
+
before :each do
|
170
|
+
allow(mapper_instance).to receive(:errors).and_return({})
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should return a hash with save keys" do
|
174
|
+
expect(builder.build[:save]).to match_array([mapper_instance, mapper_instance])
|
175
|
+
end
|
176
|
+
|
177
|
+
it "should return a hash with delete keys" do
|
178
|
+
expect(builder.build[:delete]).to match_array([2,3])
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "with errors" do
|
183
|
+
before :each do
|
184
|
+
allow(mapper_instance).to receive(:errors).and_return({data: {type: "I would do anything for love", message: "but I won't do that"}}, {data: {type: "I would do anything for love", message: "but I won't do that"}}, {})
|
185
|
+
builder.build
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should return errors" do
|
189
|
+
expect(builder.errors).to eq({0=>{:type=>"I would do anything for love", :message=>"but I won't do that"}})
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
@@ -0,0 +1,210 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Xing::Builders::OrderedListDifferenceBuilder do
|
4
|
+
|
5
|
+
let :builder do
|
6
|
+
Xing::Builders::OrderedListDifferenceBuilder.new(list_data, collection, mapper_class)
|
7
|
+
end
|
8
|
+
|
9
|
+
let :mapper_class do
|
10
|
+
double("ItemMapper")
|
11
|
+
end
|
12
|
+
|
13
|
+
let :mapper_instance do
|
14
|
+
double("mapper")
|
15
|
+
end
|
16
|
+
|
17
|
+
let :collection do
|
18
|
+
[double("Relation AR Object id: 1"), double("Relation AR Object id: 2"), double("Relation AR Object id: 3")]
|
19
|
+
end
|
20
|
+
|
21
|
+
let :new_ar_object do
|
22
|
+
double("New Relation AR Object")
|
23
|
+
end
|
24
|
+
|
25
|
+
let :updated_ar_object do
|
26
|
+
double("Updated AR Object")
|
27
|
+
end
|
28
|
+
|
29
|
+
let :existing_ids do
|
30
|
+
[1,2,3]
|
31
|
+
end
|
32
|
+
|
33
|
+
let :list_data do
|
34
|
+
[
|
35
|
+
{
|
36
|
+
links: {
|
37
|
+
self: "/somethings/1"
|
38
|
+
},
|
39
|
+
data: {
|
40
|
+
stuff: "some updated stuff"
|
41
|
+
}
|
42
|
+
},
|
43
|
+
{
|
44
|
+
links: {
|
45
|
+
self: ""
|
46
|
+
},
|
47
|
+
data: {
|
48
|
+
stuff: "some new stuff"
|
49
|
+
}
|
50
|
+
}
|
51
|
+
]
|
52
|
+
end
|
53
|
+
|
54
|
+
let :new_list_data do
|
55
|
+
[
|
56
|
+
{
|
57
|
+
locator: 1,
|
58
|
+
incoming: {
|
59
|
+
links: {
|
60
|
+
self: "/somethings/1"
|
61
|
+
},
|
62
|
+
data: {
|
63
|
+
stuff: "some updated stuff"
|
64
|
+
}
|
65
|
+
}
|
66
|
+
},
|
67
|
+
{
|
68
|
+
locator: nil,
|
69
|
+
incoming: {
|
70
|
+
links: {
|
71
|
+
self: ""
|
72
|
+
},
|
73
|
+
data: {
|
74
|
+
stuff: "some new stuff"
|
75
|
+
}
|
76
|
+
}
|
77
|
+
}
|
78
|
+
]
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should initialize and assign list_data, collection, mapper class and errors" do
|
82
|
+
expect(builder.instance_variable_get('@list_data')).to eq(list_data)
|
83
|
+
expect(builder.instance_variable_get('@collection')).to eq(collection)
|
84
|
+
expect(builder.instance_variable_get('@mapper_class')).to eq(mapper_class)
|
85
|
+
expect(builder.instance_variable_get('@errors')).to eq({})
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "#sort_json_items" do
|
89
|
+
before :each do
|
90
|
+
allow(collection).to receive(:map).and_return(existing_ids)
|
91
|
+
allow(builder).to receive(:locator_for).and_return(1)
|
92
|
+
builder.sort_json_items
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should create a list of existing ids" do
|
96
|
+
expect(builder.instance_variable_get('@existing_ids')).to eq(existing_ids)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should insert index and locator into the item data" do
|
100
|
+
expect(builder.instance_variable_get('@list_data')).to eq(new_list_data)
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should find the ids to delete" do
|
104
|
+
expect(builder.instance_variable_get('@delete_ids')).to eq([2,3])
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#set_locator" do
|
109
|
+
|
110
|
+
it "should be nil if links is empty" do
|
111
|
+
data = { links: {}, data: { text:"bs" } }
|
112
|
+
expect(builder.set_locator(data)).to be_nil
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should be nil if links/self is empty" do
|
116
|
+
data = { links: {self: ""}}
|
117
|
+
expect(builder.set_locator(data)).to be_nil
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should set locator if links/self is present" do
|
121
|
+
data = { links: {self: "some_link/1/something"}}
|
122
|
+
allow(builder).to receive(:locator_for).and_return(1)
|
123
|
+
|
124
|
+
expect(builder.set_locator(data)).to eq(1)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "#map_items" do
|
129
|
+
before :each do
|
130
|
+
builder.instance_variable_set('@list_data', new_list_data)
|
131
|
+
allow(mapper_class).to receive(:new).and_return(mapper_instance)
|
132
|
+
allow(mapper_instance).to receive(:record).and_return(new_ar_object, new_ar_object, updated_ar_object, updated_ar_object)
|
133
|
+
allow(mapper_instance).to receive(:perform_mapping)
|
134
|
+
allow(new_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
135
|
+
allow(updated_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
136
|
+
end
|
137
|
+
|
138
|
+
context "successful" do
|
139
|
+
it "should create a new ar list" do
|
140
|
+
allow(mapper_instance).to receive(:errors).and_return({})
|
141
|
+
builder.map_items
|
142
|
+
|
143
|
+
expect(builder.instance_variable_get('@new_list')).to match_array([mapper_instance, mapper_instance])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "with errors" do
|
148
|
+
it "should add to the error hash with the correct index" do
|
149
|
+
allow(mapper_instance).to receive(:errors).and_return({}, {data: {type: "I would do anything for love", message: "but I won't do that"}}, {data: {type: "I would do anything for love", message: "but I won't do that"}})
|
150
|
+
builder.map_items
|
151
|
+
|
152
|
+
expect(builder.instance_variable_get('@errors')).to eq({1=>{:type=>"I would do anything for love", :message=>"but I won't do that"}})
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
describe "#set_position" do
|
158
|
+
|
159
|
+
it "should update the position if the record has a position attribute" do
|
160
|
+
allow(new_ar_object).to receive(:has_attribute?).with(:position).and_return(true)
|
161
|
+
expect(new_ar_object).to receive(:position=).with(1)
|
162
|
+
|
163
|
+
builder.set_position(new_ar_object, 1)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should not blow up if the record does not have a position attribute" do
|
167
|
+
allow(new_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
168
|
+
expect(new_ar_object).to_not receive(:position=)
|
169
|
+
|
170
|
+
builder.set_position(new_ar_object, 1)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
describe "#build" do
|
175
|
+
before :each do
|
176
|
+
allow(collection).to receive(:map).and_return(existing_ids)
|
177
|
+
allow(builder).to receive(:locator_for).and_return(1)
|
178
|
+
allow(mapper_class).to receive(:new).and_return(mapper_instance)
|
179
|
+
allow(mapper_instance).to receive(:record).and_return(new_ar_object, new_ar_object, updated_ar_object, updated_ar_object)
|
180
|
+
allow(mapper_instance).to receive(:perform_mapping)
|
181
|
+
allow(new_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
182
|
+
allow(updated_ar_object).to receive(:has_attribute?).with(:position).and_return(false)
|
183
|
+
end
|
184
|
+
|
185
|
+
context "successful" do
|
186
|
+
before :each do
|
187
|
+
allow(mapper_instance).to receive(:errors).and_return({})
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should return a hash with save keys" do
|
191
|
+
expect(builder.build[:save]).to match_array([mapper_instance, mapper_instance])
|
192
|
+
end
|
193
|
+
|
194
|
+
it "should return a hash with delete keys" do
|
195
|
+
expect(builder.build[:delete]).to match_array([2,3])
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context "with errors" do
|
200
|
+
before :each do
|
201
|
+
allow(mapper_instance).to receive(:errors).and_return({data: {type: "I would do anything for love", message: "but I won't do that"}}, {data: {type: "I would do anything for love", message: "but I won't do that"}}, {})
|
202
|
+
builder.build
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should return errors" do
|
206
|
+
expect(builder.errors).to eq({0=>{:type=>"I would do anything for love", :message=>"but I won't do that"}})
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: xing-backend
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.14
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Dorn
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2015-06-
|
14
|
+
date: 2015-06-26 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: rails
|
@@ -124,28 +124,35 @@ extensions: []
|
|
124
124
|
extra_rdoc_files: []
|
125
125
|
files:
|
126
126
|
- lib/deprecated_classes.rb
|
127
|
+
- lib/xing-backend.rb
|
128
|
+
- lib/xing/builders.rb
|
129
|
+
- lib/xing/builders/list_difference_builder.rb
|
130
|
+
- lib/xing/builders/ordered_list_difference_builder.rb
|
127
131
|
- lib/xing/controllers/base.rb
|
128
132
|
- lib/xing/controllers/root_resources_controller.rb
|
129
133
|
- lib/xing/engine.rb
|
130
|
-
- lib/xing/mappers/base.rb
|
131
134
|
- lib/xing/mappers.rb
|
135
|
+
- lib/xing/mappers/base.rb
|
136
|
+
- lib/xing/serializers.rb
|
132
137
|
- lib/xing/serializers/base.rb
|
133
138
|
- lib/xing/serializers/list.rb
|
134
139
|
- lib/xing/serializers/paged_list.rb
|
135
140
|
- lib/xing/serializers/root_resources.rb
|
136
|
-
- lib/xing/
|
141
|
+
- lib/xing/services.rb
|
137
142
|
- lib/xing/services/error_converter.rb
|
138
143
|
- lib/xing/services/json_tree_lister.rb
|
144
|
+
- lib/xing/services/locator.rb
|
139
145
|
- lib/xing/services/snapshot_fetcher.rb
|
140
146
|
- lib/xing/services/snapshot_writer.rb
|
141
|
-
- lib/xing/services.rb
|
142
|
-
- lib/xing-backend.rb
|
143
147
|
- spec/deprecated_classes/active_model_error_converter_spec.rb
|
144
148
|
- spec/deprecated_classes/base_serializer_spec.rb
|
145
149
|
- spec/deprecated_classes/hypermedia_json_mapper_spec.rb
|
146
150
|
- spec/deprecated_classes/json_tree_lister_spec.rb
|
151
|
+
- spec/deprecated_classes/list_difference_builder_spec.rb
|
147
152
|
- spec/deprecated_classes/remote_snapshot_fetcher_spec.rb
|
148
153
|
- spec/deprecated_classes/resources_serializer_spec.rb
|
154
|
+
- spec/xing/builders/list_difference_builder_spec.rb
|
155
|
+
- spec/xing/builders/ordered_list_difference_builder_spec.rb
|
149
156
|
- spec/xing/controllers/base_spec.rb
|
150
157
|
- spec/xing/controllers/root_resources_controller_spec.rb
|
151
158
|
- spec/xing/mappers/base_spec.rb
|
@@ -156,6 +163,8 @@ files:
|
|
156
163
|
- spec/xing/services/json_tree_lister_spec.rb
|
157
164
|
- spec/xing/services/snapshot_fetcher_spec.rb
|
158
165
|
- spec/xing_spec.rb
|
166
|
+
- spec_help/dummy/README.rdoc
|
167
|
+
- spec_help/dummy/Rakefile
|
159
168
|
- spec_help/dummy/app/assets/javascripts/application.js
|
160
169
|
- spec_help/dummy/app/assets/stylesheets/application.css
|
161
170
|
- spec_help/dummy/app/controllers/application_controller.rb
|
@@ -165,6 +174,7 @@ files:
|
|
165
174
|
- spec_help/dummy/bin/rails
|
166
175
|
- spec_help/dummy/bin/rake
|
167
176
|
- spec_help/dummy/bin/setup
|
177
|
+
- spec_help/dummy/config.ru
|
168
178
|
- spec_help/dummy/config/application.rb
|
169
179
|
- spec_help/dummy/config/boot.rb
|
170
180
|
- spec_help/dummy/config/database.yml
|
@@ -183,15 +193,10 @@ files:
|
|
183
193
|
- spec_help/dummy/config/locales/en.yml
|
184
194
|
- spec_help/dummy/config/routes.rb
|
185
195
|
- spec_help/dummy/config/secrets.yml
|
186
|
-
- spec_help/dummy/config.ru
|
187
|
-
- spec_help/dummy/db/test.sqlite3
|
188
|
-
- spec_help/dummy/log/test.log
|
189
196
|
- spec_help/dummy/public/404.html
|
190
197
|
- spec_help/dummy/public/422.html
|
191
198
|
- spec_help/dummy/public/500.html
|
192
199
|
- spec_help/dummy/public/favicon.ico
|
193
|
-
- spec_help/dummy/Rakefile
|
194
|
-
- spec_help/dummy/README.rdoc
|
195
200
|
- spec_help/spec_helper.rb
|
196
201
|
homepage: http://github.com/xing-backend
|
197
202
|
licenses:
|
@@ -203,7 +208,7 @@ rdoc_options:
|
|
203
208
|
- "--main"
|
204
209
|
- doc/README
|
205
210
|
- "--title"
|
206
|
-
- xing-backend-0.0.
|
211
|
+
- xing-backend-0.0.14 Documentation
|
207
212
|
require_paths:
|
208
213
|
- lib/
|
209
214
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -218,7 +223,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
218
223
|
version: '0'
|
219
224
|
requirements: []
|
220
225
|
rubyforge_project:
|
221
|
-
rubygems_version: 2.
|
226
|
+
rubygems_version: 2.4.5
|
222
227
|
signing_key:
|
223
228
|
specification_version: 4
|
224
229
|
summary: Rails backend classes for the Xing web development framework.
|
File without changes
|
@@ -1,26 +0,0 @@
|
|
1
|
-
Processing by Xing::RootResourcesController#index as HTML
|
2
|
-
Completed 200 OK in 3ms (Views: 2.1ms | ActiveRecord: 0.0ms)
|
3
|
-
Processing by Xing::RootResourcesController#index as HTML
|
4
|
-
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
|
5
|
-
Processing by Xing::RootResourcesController#index as HTML
|
6
|
-
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)
|
7
|
-
Processing by Xing::RootResourcesController#index as HTML
|
8
|
-
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
|
9
|
-
Processing by Xing::RootResourcesController#index as HTML
|
10
|
-
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
|
11
|
-
Processing by Xing::RootResourcesController#index as HTML
|
12
|
-
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
|
13
|
-
Processing by Xing::RootResourcesController#index as HTML
|
14
|
-
Completed 500 Internal Server Error in 1ms (ActiveRecord: 0.0ms)
|
15
|
-
Processing by Xing::RootResourcesController#index as HTML
|
16
|
-
Completed 200 OK in 2ms (Views: 1.4ms | ActiveRecord: 0.0ms)
|
17
|
-
Processing by Xing::RootResourcesController#index as HTML
|
18
|
-
Completed 200 OK in 2ms (Views: 1.5ms | ActiveRecord: 0.0ms)
|
19
|
-
Processing by Xing::RootResourcesController#index as HTML
|
20
|
-
Completed 200 OK in 2ms (Views: 1.5ms | ActiveRecord: 0.0ms)
|
21
|
-
Processing by Xing::RootResourcesController#index as HTML
|
22
|
-
Completed 200 OK in 2ms (Views: 1.5ms | ActiveRecord: 0.0ms)
|
23
|
-
Processing by Xing::RootResourcesController#index as HTML
|
24
|
-
Completed 200 OK in 3ms (Views: 1.9ms | ActiveRecord: 0.0ms)
|
25
|
-
Processing by Xing::RootResourcesController#index as HTML
|
26
|
-
Completed 200 OK in 2ms (Views: 1.4ms | ActiveRecord: 0.0ms)
|