maestrano-connector-rails 1.2.3 → 1.3.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/.rubocop_todo.yml +7 -20
- data/VERSION +1 -1
- data/app/controllers/maestrano/synchronizations_controller.rb +3 -3
- data/app/models/maestrano/connector/rails/concerns/complex_entity.rb +50 -22
- data/app/models/maestrano/connector/rails/concerns/connec_helper.rb +157 -19
- data/app/models/maestrano/connector/rails/concerns/entity.rb +63 -42
- data/app/models/maestrano/connector/rails/concerns/external.rb +4 -0
- data/app/models/maestrano/connector/rails/concerns/sub_entity_base.rb +18 -5
- data/app/models/maestrano/connector/rails/organization.rb +1 -1
- data/lib/generators/connector/templates/complex_entity_example/contact_and_lead.rb +5 -5
- data/lib/generators/connector/templates/entity.rb +4 -5
- data/lib/generators/connector/templates/external.rb +6 -0
- data/lib/generators/connector/templates/home_index.haml +7 -4
- data/maestrano-connector-rails.gemspec +7 -4
- data/release_notes.md +5 -0
- data/spec/factories.rb +2 -2
- data/spec/integration/complex_id_references_spec.rb +248 -0
- data/spec/integration/complex_naming_spec.rb +191 -0
- data/spec/integration/{integration_complex_spec.rb → complex_spec.rb} +9 -9
- data/spec/integration/connec_to_external_spec.rb +7 -3
- data/spec/integration/id_references_spec.rb +581 -0
- data/spec/integration/singleton_spec.rb +3 -3
- data/spec/models/complex_entity_spec.rb +42 -27
- data/spec/models/connec_helper_spec.rb +399 -31
- data/spec/models/entity_spec.rb +76 -21
- data/spec/models/external_spec.rb +4 -0
- data/spec/models/sub_entity_base_spec.rb +11 -4
- metadata +6 -3
@@ -148,7 +148,7 @@ describe 'singleton workflow' do
|
|
148
148
|
it 'does the mapping correctly' do
|
149
149
|
idmap = Entities::SingletonIntegration.create_idmap(organization_id: organization.id, external_id: ext_comp_id, connec_id: 'some connec id')
|
150
150
|
allow(Entities::SingletonIntegration).to receive(:create_idmap).and_return(idmap)
|
151
|
-
expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: {name: 'My awesome company'}, idmap: idmap}])
|
151
|
+
expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: {name: 'My awesome company'}, idmap: idmap, id_refs_only_connec_entity: {}}])
|
152
152
|
subject
|
153
153
|
end
|
154
154
|
|
@@ -207,7 +207,7 @@ describe 'singleton workflow' do
|
|
207
207
|
end
|
208
208
|
|
209
209
|
it 'does the mapping correctly' do
|
210
|
-
expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: mapped_connec_entity, idmap: idmap}])
|
210
|
+
expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: mapped_connec_entity, idmap: idmap, id_refs_only_connec_entity: {}}])
|
211
211
|
subject
|
212
212
|
end
|
213
213
|
|
@@ -263,7 +263,7 @@ describe 'singleton workflow' do
|
|
263
263
|
end
|
264
264
|
|
265
265
|
it 'does the mapping correctly' do
|
266
|
-
expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: mapped_connec_entity, idmap: idmap}])
|
266
|
+
expect_any_instance_of(Entities::SingletonIntegration).to receive(:push_entities_to_external).with([{entity: mapped_connec_entity, idmap: idmap, id_refs_only_connec_entity: {}}])
|
267
267
|
subject
|
268
268
|
end
|
269
269
|
end
|
@@ -81,8 +81,8 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
81
81
|
}
|
82
82
|
|
83
83
|
it 'calls get_external_entities on each connec sub complex entities' do
|
84
|
-
expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities_wrapper).with(nil)
|
85
|
-
expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities_wrapper).with(nil)
|
84
|
+
expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities_wrapper).with(nil, 'sc_e1')
|
85
|
+
expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities_wrapper).with(nil, 'ScE2')
|
86
86
|
subject.get_external_entities_wrapper(nil)
|
87
87
|
end
|
88
88
|
|
@@ -129,8 +129,10 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
129
129
|
let(:id) { 'id' }
|
130
130
|
let(:external_name) { 'sc_e1' }
|
131
131
|
let(:connec_name) { 'connec1' }
|
132
|
-
let(:
|
132
|
+
let(:modelled_external_entities) { {external_name => {connec_name => [entity]}} }
|
133
133
|
before {
|
134
|
+
allow(subject.class).to receive(:connec_entities_names).and_return(['connec1'])
|
135
|
+
allow(subject.class).to receive(:external_entities_names).and_return(['sc_e1'])
|
134
136
|
allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(true)
|
135
137
|
allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return(external_name)
|
136
138
|
allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).and_return(id)
|
@@ -144,19 +146,19 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
144
146
|
|
145
147
|
it 'does not create one' do
|
146
148
|
expect{
|
147
|
-
subject.consolidate_and_map_external_entities(
|
149
|
+
subject.consolidate_and_map_external_entities(modelled_external_entities)
|
148
150
|
}.to_not change{ Maestrano::Connector::Rails::IdMap.count }
|
149
151
|
end
|
150
152
|
|
151
153
|
it 'returns the mapped entity with the idmap' do
|
152
|
-
expect(subject.consolidate_and_map_external_entities(
|
154
|
+
expect(subject.consolidate_and_map_external_entities(modelled_external_entities)).to eql({external_name => {connec_name => [{entity: mapped_entity, idmap: idmap}]}})
|
153
155
|
end
|
154
156
|
|
155
157
|
context 'when to_connec is false' do
|
156
158
|
before { idmap.update(to_connec: false) }
|
157
159
|
|
158
160
|
it 'discards the entity' do
|
159
|
-
expect(subject.consolidate_and_map_external_entities(
|
161
|
+
expect(subject.consolidate_and_map_external_entities(modelled_external_entities)).to eql({external_name => {connec_name => []}})
|
160
162
|
end
|
161
163
|
end
|
162
164
|
|
@@ -166,11 +168,11 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
166
168
|
}
|
167
169
|
|
168
170
|
it 'discards the entity' do
|
169
|
-
expect(subject.consolidate_and_map_external_entities(
|
171
|
+
expect(subject.consolidate_and_map_external_entities(modelled_external_entities)).to eql({external_name => {connec_name => []}})
|
170
172
|
end
|
171
173
|
|
172
174
|
it 'updates the idmaps' do
|
173
|
-
subject.consolidate_and_map_external_entities(
|
175
|
+
subject.consolidate_and_map_external_entities(modelled_external_entities)
|
174
176
|
expect(idmap.reload.external_inactive).to be true
|
175
177
|
end
|
176
178
|
end
|
@@ -179,7 +181,7 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
179
181
|
before { idmap.update(last_push_to_connec: 2.second.ago) }
|
180
182
|
|
181
183
|
it 'discards the entity' do
|
182
|
-
expect(subject.consolidate_and_map_external_entities(
|
184
|
+
expect(subject.consolidate_and_map_external_entities(modelled_external_entities)).to eql({external_name => {connec_name => []}})
|
183
185
|
end
|
184
186
|
end
|
185
187
|
|
@@ -190,22 +192,25 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
190
192
|
let(:id) { 'external-unfolded-id' }
|
191
193
|
let(:connec_id) { 'connec-id' }
|
192
194
|
let(:entity) { {'id' => id, 'name' => 'John', 'updated_at' => date} }
|
193
|
-
let(:
|
194
|
-
let(:
|
195
|
+
let(:modelled_connec_entities) { {connec_name => {external_name => [entity]}} }
|
196
|
+
let(:modelled_external_entities) { {} }
|
195
197
|
let(:connec_name) { 'sc_e1' }
|
196
198
|
let(:external_name) { 'ext1' }
|
199
|
+
let(:id_refs_only_connec_entity) { {a: 1} }
|
197
200
|
before{
|
201
|
+
allow(subject.class).to receive(:connec_entities_names).and_return(['sc_e1'])
|
202
|
+
allow(subject.class).to receive(:external_entities_names).and_return(['ext1'])
|
198
203
|
allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(false)
|
199
204
|
allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return(connec_name)
|
200
205
|
allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).with(external_name, entity).and_return(mapped_entity)
|
201
206
|
allow(Entities::SubEntities::ScE1).to receive(:object_name_from_connec_entity_hash).and_return(human_name)
|
202
|
-
allow(Maestrano::Connector::Rails::ConnecHelper).to receive(:unfold_references).and_return(entity
|
207
|
+
allow(Maestrano::Connector::Rails::ConnecHelper).to receive(:unfold_references).and_return({entity: entity, connec_id: connec_id, id_refs_only_connec_entity: id_refs_only_connec_entity})
|
203
208
|
}
|
204
209
|
|
205
210
|
context 'when idmaps do not exist' do
|
206
211
|
it 'creates the idmaps with a name and returns the mapped entities with their idmaps' do
|
207
212
|
expect{
|
208
|
-
expect(subject.consolidate_and_map_connec_entities(
|
213
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, {})).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first, id_refs_only_connec_entity: id_refs_only_connec_entity}]}})
|
209
214
|
}.to change{ Maestrano::Connector::Rails::IdMap.count }.by(1)
|
210
215
|
expect(Maestrano::Connector::Rails::IdMap.last.name).to eql(human_name)
|
211
216
|
end
|
@@ -216,38 +221,38 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
216
221
|
|
217
222
|
it 'does not create an idmap' do
|
218
223
|
expect{
|
219
|
-
subject.consolidate_and_map_connec_entities(
|
224
|
+
subject.consolidate_and_map_connec_entities(modelled_connec_entities, {})
|
220
225
|
}.to_not change{ Maestrano::Connector::Rails::IdMap.count }
|
221
226
|
end
|
222
227
|
|
223
228
|
it 'returns the entity with its idmap' do
|
224
|
-
expect(subject.consolidate_and_map_connec_entities(
|
229
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, {})).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: idmap1, id_refs_only_connec_entity: id_refs_only_connec_entity}]}})
|
225
230
|
end
|
226
231
|
|
227
232
|
context 'when external inactive' do
|
228
233
|
before { idmap1.update(external_inactive: true) }
|
229
234
|
it 'discards the entity' do
|
230
|
-
expect(subject.consolidate_and_map_connec_entities(
|
235
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, {})).to eql({connec_name => {external_name => []}})
|
231
236
|
end
|
232
237
|
end
|
233
238
|
|
234
239
|
context 'when to external flag is false' do
|
235
240
|
before { idmap1.update(to_external: false) }
|
236
241
|
it 'discards the entity' do
|
237
|
-
expect(subject.consolidate_and_map_connec_entities(
|
242
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, {})).to eql({connec_name => {external_name => []}})
|
238
243
|
end
|
239
244
|
end
|
240
245
|
|
241
246
|
context 'when last_push_to_external is recent' do
|
242
247
|
before { idmap1.update(last_push_to_external: 2.second.ago) }
|
243
248
|
it 'discards the entity' do
|
244
|
-
expect(subject.consolidate_and_map_connec_entities(
|
249
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, {})).to eql({connec_name => {external_name => []}})
|
245
250
|
end
|
246
251
|
end
|
247
252
|
|
248
253
|
context 'when conflict' do
|
249
254
|
let(:external_entity_1) { {'id' => id} }
|
250
|
-
let(:
|
255
|
+
let(:modelled_external_entities) { {external_name => {connec_name => [external_entity_1]}} }
|
251
256
|
before {
|
252
257
|
allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).and_return(id)
|
253
258
|
}
|
@@ -256,16 +261,16 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
256
261
|
context 'with connec preemption false' do
|
257
262
|
it 'discards the entity and keep the external one' do
|
258
263
|
subject.instance_variable_set(:@opts, {connec_preemption: false})
|
259
|
-
expect(subject.consolidate_and_map_connec_entities(
|
260
|
-
expect(
|
264
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, modelled_external_entities)).to eql({connec_name => {external_name => []}})
|
265
|
+
expect(modelled_external_entities[external_name][connec_name]).to_not be_empty
|
261
266
|
end
|
262
267
|
end
|
263
268
|
|
264
269
|
context 'with connec preemption true' do
|
265
270
|
it 'keeps the entity and discards the external one' do
|
266
271
|
subject.instance_variable_set(:@opts, {connec_preemption: true})
|
267
|
-
expect(subject.consolidate_and_map_connec_entities(
|
268
|
-
expect(
|
272
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, modelled_external_entities)).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first, id_refs_only_connec_entity: id_refs_only_connec_entity}]}})
|
273
|
+
expect(modelled_external_entities[external_name][connec_name]).to be_empty
|
269
274
|
end
|
270
275
|
end
|
271
276
|
end
|
@@ -280,8 +285,8 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
280
285
|
let(:date) { 1.day.ago }
|
281
286
|
|
282
287
|
it 'keeps the entity and discards the external one' do
|
283
|
-
expect(subject.consolidate_and_map_connec_entities(
|
284
|
-
expect(
|
288
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, modelled_external_entities)).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first, id_refs_only_connec_entity: id_refs_only_connec_entity}]}})
|
289
|
+
expect(modelled_external_entities[external_name][connec_name]).to be_empty
|
285
290
|
end
|
286
291
|
end
|
287
292
|
|
@@ -290,8 +295,8 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
290
295
|
let(:date) { 1.year.ago }
|
291
296
|
|
292
297
|
it 'discards the entity and keep the external one' do
|
293
|
-
expect(subject.consolidate_and_map_connec_entities(
|
294
|
-
expect(
|
298
|
+
expect(subject.consolidate_and_map_connec_entities(modelled_connec_entities, modelled_external_entities)).to eql({connec_name => {external_name => []}})
|
299
|
+
expect(modelled_external_entities[external_name][connec_name]).to_not be_empty
|
295
300
|
end
|
296
301
|
end
|
297
302
|
end
|
@@ -311,6 +316,11 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
311
316
|
}
|
312
317
|
}
|
313
318
|
|
319
|
+
before {
|
320
|
+
allow(subject.class).to receive(:external_entities_names).and_return(['sc_e1', 'ScE2'])
|
321
|
+
allow(subject.class).to receive(:connec_entities_names).and_return(['Connec1', 'connec2'])
|
322
|
+
}
|
323
|
+
|
314
324
|
it 'calls push_entities_to_connec on each sub complex entity' do
|
315
325
|
expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_connec_to).once.with([mapped_entity_with_idmap], 'Connec1')
|
316
326
|
expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_connec_to).twice
|
@@ -343,6 +353,11 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
343
353
|
}
|
344
354
|
}
|
345
355
|
|
356
|
+
before {
|
357
|
+
allow(subject.class).to receive(:external_entities_names).and_return(['ext1', 'ext2'])
|
358
|
+
allow(subject.class).to receive(:connec_entities_names).and_return(['sc_e1', 'ScE2'])
|
359
|
+
}
|
360
|
+
|
346
361
|
it 'calls push_entities_to_connec on each sub complex entity' do
|
347
362
|
expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_external_to).once.with([mapped_entity_with_idmap], 'ext1')
|
348
363
|
expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_external_to).twice
|
@@ -54,68 +54,71 @@ describe Maestrano::Connector::Rails::ConnecHelper do
|
|
54
54
|
|
55
55
|
let(:output_hash) {
|
56
56
|
{
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
connec_id: connec_id,
|
58
|
+
entity: {
|
59
|
+
id: id_id,
|
60
|
+
organization_id: org_id_id,
|
61
|
+
lines: [
|
62
|
+
{
|
63
|
+
linked_transaction: {
|
64
|
+
id: lt1_id_id
|
65
|
+
}
|
66
|
+
},
|
67
|
+
{
|
68
|
+
linked_transaction: {
|
69
|
+
id: lt2_id_id
|
70
|
+
}
|
64
71
|
}
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
id: lt2_id_id
|
69
|
-
}
|
70
|
-
}
|
71
|
-
]
|
72
|
+
]
|
73
|
+
}.with_indifferent_access,
|
74
|
+
id_refs_only_connec_entity: {}
|
72
75
|
}
|
73
76
|
}
|
74
77
|
let(:lt1_id_id) { 'lt1_id' }
|
75
78
|
let(:lt2_id_id) { 'lt2_id' }
|
76
79
|
let(:lt1_id) { [subject.id_hash(lt1_id_id, organization)] }
|
77
80
|
let(:lt2_id) { [subject.id_hash(lt2_id_id, organization)] }
|
81
|
+
let(:connec_id) { 'cid1' }
|
82
|
+
let(:connec_org_id) { 'cid2' }
|
83
|
+
let(:org_id_id) { 'org_id' }
|
78
84
|
|
79
85
|
context 'when all ids are here' do
|
80
86
|
let(:id_id) { 'id' }
|
81
|
-
let(:
|
82
|
-
let(:
|
83
|
-
let(:org_id) { [subject.id_hash(org_id_id, organization), {'provider' => 'connec', 'id' => 'abcd'}] }
|
87
|
+
let(:id) { [subject.id_hash(id_id, organization), {'provider' => 'connec', 'id' => connec_id}] }
|
88
|
+
let(:org_id) { [subject.id_hash(org_id_id, organization), {'provider' => 'connec', 'id' => connec_org_id}] }
|
84
89
|
|
85
90
|
it 'unfolds everything' do
|
86
|
-
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to eql(output_hash
|
91
|
+
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to eql(output_hash)
|
87
92
|
end
|
88
93
|
end
|
89
94
|
|
90
95
|
context 'when only id is missing' do
|
91
96
|
let(:id_id) { nil }
|
92
|
-
let(:
|
93
|
-
let(:id) { [{'provider' => 'connec', 'realm' => 'some realm', 'id' => 'id'}] }
|
97
|
+
let(:id) { [{'provider' => 'connec', 'realm' => 'some realm', 'id' => connec_id}] }
|
94
98
|
let(:org_id) { [subject.id_hash(org_id_id, organization)] }
|
95
99
|
|
96
100
|
it 'unfolds the other refs and keep the connec_id' do
|
97
|
-
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to eql(output_hash.merge(
|
101
|
+
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to eql(output_hash.merge(connec_id: connec_id))
|
98
102
|
end
|
99
103
|
end
|
100
104
|
|
101
105
|
context 'when at least one ref is missing and there is a connec id' do
|
102
106
|
let(:id_id) { nil }
|
103
|
-
let(:
|
104
|
-
let(:
|
105
|
-
let(:org_id) { [{'provider' => 'connec', 'realm' => 'some realm', 'id' => org_id_id}] }
|
107
|
+
let(:id) { [{'provider' => 'connec', 'realm' => 'some realm', 'id' => connec_id}] }
|
108
|
+
let(:org_id) { [{'provider' => 'connec', 'realm' => 'some realm', 'id' => connec_org_id}] }
|
106
109
|
|
107
110
|
it 'returns nil' do
|
108
|
-
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to
|
111
|
+
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to eql(output_hash.merge(entity: nil))
|
109
112
|
end
|
110
113
|
end
|
111
114
|
context 'when at least one ref is missing but there is no connec id' do
|
112
115
|
let(:id_id) { 'id' }
|
113
|
-
let(:id) { [subject.id_hash(id_id, organization), {'provider' => 'connec', 'id' =>
|
116
|
+
let(:id) { [subject.id_hash(id_id, organization), {'provider' => 'connec', 'id' => connec_id}] }
|
114
117
|
let(:org_id_id) { nil }
|
115
118
|
let(:org_id) { nil }
|
116
119
|
|
117
120
|
it 'unfold the others refs' do
|
118
|
-
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to eql(output_hash
|
121
|
+
expect(subject.unfold_references(connec_hash, ['organization_id', 'lines/linked_transaction/id'], organization)).to eql(output_hash)
|
119
122
|
end
|
120
123
|
end
|
121
124
|
|
@@ -129,13 +132,16 @@ describe Maestrano::Connector::Rails::ConnecHelper do
|
|
129
132
|
|
130
133
|
let(:output_hash) {
|
131
134
|
{
|
132
|
-
|
133
|
-
|
135
|
+
connec_id: 'abcd',
|
136
|
+
entity: {
|
137
|
+
id: '123'
|
138
|
+
}.with_indifferent_access,
|
139
|
+
id_refs_only_connec_entity: {}
|
134
140
|
}
|
135
141
|
}
|
136
142
|
|
137
|
-
it '
|
138
|
-
expect(subject.unfold_references(connec_hash, ['organization_id'], organization)).to eql(output_hash
|
143
|
+
it 'ignores the string' do
|
144
|
+
expect(subject.unfold_references(connec_hash, ['organization_id'], organization)).to eql(output_hash)
|
139
145
|
end
|
140
146
|
end
|
141
147
|
end
|
@@ -188,6 +194,10 @@ describe Maestrano::Connector::Rails::ConnecHelper do
|
|
188
194
|
expect(subject.fold_references(mapped_hash, ['organization_id', 'contact/id', 'lines/id', 'not_here_ref'], organization)).to eql(output_hash.with_indifferent_access)
|
189
195
|
end
|
190
196
|
|
197
|
+
it 'folds the existing refs (both id and record refs)' do
|
198
|
+
expect(subject.fold_references(mapped_hash, {record_references: %w(organization_id contact/id), id_references: %w(lines/id not_here_ref)}, organization)).to eql(output_hash.with_indifferent_access)
|
199
|
+
end
|
200
|
+
|
191
201
|
context 'when id is an integer' do
|
192
202
|
let(:id) { 1234 }
|
193
203
|
|
@@ -196,4 +206,362 @@ describe Maestrano::Connector::Rails::ConnecHelper do
|
|
196
206
|
end
|
197
207
|
end
|
198
208
|
end
|
209
|
+
|
210
|
+
describe 'build_id_references_tree' do
|
211
|
+
let(:id_references) { %w(lines/id lines/linked/id lines/linked/id2 linked/id) }
|
212
|
+
let(:tree) {
|
213
|
+
{
|
214
|
+
"lines"=>{
|
215
|
+
"id"=>{},
|
216
|
+
"linked"=>{
|
217
|
+
"id"=>{},
|
218
|
+
"id2"=>{}
|
219
|
+
}
|
220
|
+
},
|
221
|
+
"linked"=>{
|
222
|
+
"id"=>{}
|
223
|
+
}
|
224
|
+
}
|
225
|
+
}
|
226
|
+
|
227
|
+
it 'returns the tree' do
|
228
|
+
expect(subject.build_id_references_tree(id_references)).to eql(tree)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe 'format_references' do
|
233
|
+
context 'when array' do
|
234
|
+
it 'transforms it to an hash' do
|
235
|
+
expect(subject.format_references([1])).to eql({record_references: [1], id_references: []})
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context 'when hash with both keys' do
|
240
|
+
let(:hash) { {id_references: [1], record_references: [2]} }
|
241
|
+
it 'returns it' do
|
242
|
+
expect(subject.format_references(hash)).to eql(hash)
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
context 'when hash with only one key' do
|
247
|
+
context 'when missing id_references' do
|
248
|
+
it 'returns the completed hash' do
|
249
|
+
expect(subject.format_references(record_references: [1])).to eql({record_references: [1], id_references: []})
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
context 'when missing record_references' do
|
254
|
+
it 'returns the completed hash' do
|
255
|
+
expect(subject.format_references(id_references: [1])).to eql({id_references: [1], record_references: []})
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe 'filter_connec_entity_for_id_refs' do
|
262
|
+
let(:connec_entity) {
|
263
|
+
{
|
264
|
+
id: [{"id"=>"001", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
265
|
+
name: "Brewer Supplies Ltd",
|
266
|
+
description: "We supply all things brewed\n",
|
267
|
+
lines: [
|
268
|
+
{
|
269
|
+
id: [{"id"=>"002", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
270
|
+
amount: 12,
|
271
|
+
linked: {
|
272
|
+
linked_transactions: [
|
273
|
+
{
|
274
|
+
class: 'Invoice',
|
275
|
+
id: [{"id"=>"003", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
276
|
+
id2: [{"id"=>"013", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
277
|
+
},
|
278
|
+
{
|
279
|
+
class: 'Sales order',
|
280
|
+
id: [{"id"=>"004", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
281
|
+
id2: [{"id"=>"014", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
282
|
+
}
|
283
|
+
]
|
284
|
+
}
|
285
|
+
}
|
286
|
+
],
|
287
|
+
linked_transactions: [
|
288
|
+
{
|
289
|
+
class: 'Test',
|
290
|
+
id: [{"id"=>"005", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
291
|
+
}
|
292
|
+
]
|
293
|
+
}
|
294
|
+
}
|
295
|
+
|
296
|
+
context 'with id_references' do
|
297
|
+
let(:id_references) { %w(lines/id lines/linked/linked_transactions/id lines/linked/linked_transactions/id2 linked_transactions/id) }
|
298
|
+
let(:filtered_connec_entity) {
|
299
|
+
{
|
300
|
+
lines: [
|
301
|
+
{
|
302
|
+
id: [{"id"=>"002", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
303
|
+
linked: {
|
304
|
+
linked_transactions: [
|
305
|
+
{
|
306
|
+
id: [{"id"=>"003", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
307
|
+
id2: [{"id"=>"013", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
308
|
+
},
|
309
|
+
{
|
310
|
+
id: [{"id"=>"004", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
311
|
+
id2: [{"id"=>"014", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
312
|
+
}
|
313
|
+
]
|
314
|
+
}
|
315
|
+
}
|
316
|
+
],
|
317
|
+
linked_transactions: [
|
318
|
+
{
|
319
|
+
id: [{"id"=>"005", "provider"=>"this_app", "realm"=>"sfuiy765"}],
|
320
|
+
}
|
321
|
+
]
|
322
|
+
}.with_indifferent_access
|
323
|
+
}
|
324
|
+
|
325
|
+
it 'returns the connec_entity with only the relevant keys' do
|
326
|
+
expect(subject.filter_connec_entity_for_id_refs(connec_entity, id_references)).to eql(filtered_connec_entity)
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context 'without id_references' do
|
331
|
+
it 'returns an empty hash' do
|
332
|
+
expect(subject.filter_connec_entity_for_id_refs(connec_entity, [])).to eql({})
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
describe 'value from hash' do
|
338
|
+
let(:hash) {
|
339
|
+
{
|
340
|
+
lines: [
|
341
|
+
{
|
342
|
+
linked: [
|
343
|
+
{
|
344
|
+
a: {
|
345
|
+
b: [1]
|
346
|
+
}
|
347
|
+
}
|
348
|
+
]
|
349
|
+
},
|
350
|
+
{
|
351
|
+
linked: [
|
352
|
+
{
|
353
|
+
a: {
|
354
|
+
b: [2]
|
355
|
+
}
|
356
|
+
},
|
357
|
+
{
|
358
|
+
a: {
|
359
|
+
b: [3]
|
360
|
+
}
|
361
|
+
}
|
362
|
+
]
|
363
|
+
},
|
364
|
+
]
|
365
|
+
}
|
366
|
+
}
|
367
|
+
|
368
|
+
let(:path) { [:lines, 1,:linked, 0, :a, :b] }
|
369
|
+
|
370
|
+
it 'returns the value from the path' do
|
371
|
+
expect(subject.value_from_hash(hash, path)).to eql([2])
|
372
|
+
end
|
373
|
+
|
374
|
+
context 'when the path leads to nowhere' do
|
375
|
+
context 'with a wrong array' do
|
376
|
+
let(:hash) {
|
377
|
+
{
|
378
|
+
lines: [
|
379
|
+
{
|
380
|
+
linked: [
|
381
|
+
{
|
382
|
+
a: {
|
383
|
+
b: [1]
|
384
|
+
}
|
385
|
+
}
|
386
|
+
]
|
387
|
+
},
|
388
|
+
]
|
389
|
+
}
|
390
|
+
}
|
391
|
+
|
392
|
+
it 'returns nil' do
|
393
|
+
expect(subject.value_from_hash(hash, path)).to eql(nil)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
context 'with a wrong hash' do
|
398
|
+
let(:hash) {
|
399
|
+
{
|
400
|
+
lines: [
|
401
|
+
{
|
402
|
+
},
|
403
|
+
{
|
404
|
+
linked: [
|
405
|
+
{
|
406
|
+
},
|
407
|
+
{
|
408
|
+
}
|
409
|
+
]
|
410
|
+
},
|
411
|
+
]
|
412
|
+
}
|
413
|
+
}
|
414
|
+
|
415
|
+
it 'returns nil' do
|
416
|
+
expect(subject.value_from_hash(hash, path)).to eql(nil)
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
describe 'merge_id_hashes' do
|
423
|
+
let(:dist) {
|
424
|
+
{
|
425
|
+
lines: [
|
426
|
+
{
|
427
|
+
id: [{"id"=>"002", "provider"=>"connec", "realm"=>"org-123"}],
|
428
|
+
linked: {
|
429
|
+
linked_transactions: [
|
430
|
+
{
|
431
|
+
id: [{"id"=>"003", "provider"=>"connec", "realm"=>"org-123"}],
|
432
|
+
id2: [{"id"=>"013", "provider"=>"connec", "realm"=>"org-123"}],
|
433
|
+
},
|
434
|
+
{
|
435
|
+
id: [{"id"=>"004", "provider"=>"connec", "realm"=>"org-123"}],
|
436
|
+
id2: [{"id"=>"014", "provider"=>"connec", "realm"=>"org-123"}],
|
437
|
+
}
|
438
|
+
]
|
439
|
+
}
|
440
|
+
}
|
441
|
+
],
|
442
|
+
linked_transactions: [
|
443
|
+
{
|
444
|
+
id: [{"id"=>"005", "provider"=>"connec", "realm"=>"org-123"}],
|
445
|
+
}
|
446
|
+
]
|
447
|
+
}
|
448
|
+
}
|
449
|
+
|
450
|
+
let(:src) {
|
451
|
+
{
|
452
|
+
title: 'Title',
|
453
|
+
lines: [
|
454
|
+
{
|
455
|
+
amount: 123,
|
456
|
+
id: [{"id"=>"002", "provider"=>"this-app", "realm"=>"6543"}],
|
457
|
+
linked: {
|
458
|
+
linked_transactions: [
|
459
|
+
{
|
460
|
+
class: 'Invoice',
|
461
|
+
id: [{"id"=>"003", "provider"=>"this-app", "realm"=>"6543"}],
|
462
|
+
id2: [{"id"=>"013", "provider"=>"this-app", "realm"=>"6543"}],
|
463
|
+
},
|
464
|
+
{
|
465
|
+
class: 'Sales Order',
|
466
|
+
id: [{"id"=>"004", "provider"=>"this-app", "realm"=>"6543"}],
|
467
|
+
id2: [{"id"=>"014", "provider"=>"this-app", "realm"=>"6543"}],
|
468
|
+
}
|
469
|
+
]
|
470
|
+
}
|
471
|
+
}
|
472
|
+
],
|
473
|
+
linked_transactions: [
|
474
|
+
{
|
475
|
+
class: 'Payment',
|
476
|
+
id: [{"id"=>"005", "provider"=>"this-app", "realm"=>"6543"}],
|
477
|
+
}
|
478
|
+
]
|
479
|
+
}
|
480
|
+
}
|
481
|
+
|
482
|
+
let(:id_references) {
|
483
|
+
%w(lines/id lines/linked/linked_transactions/id lines/linked/linked_transactions/id2 linked_transactions/id)
|
484
|
+
}
|
485
|
+
|
486
|
+
let(:output_hash) {
|
487
|
+
{
|
488
|
+
lines: [
|
489
|
+
{
|
490
|
+
id: [{"id"=>"002", "provider"=>"connec", "realm"=>"org-123"}, {"id"=>"002", "provider"=>"this-app", "realm"=>"6543"}],
|
491
|
+
linked: {
|
492
|
+
linked_transactions: [
|
493
|
+
{
|
494
|
+
id: [{"id"=>"003", "provider"=>"connec", "realm"=>"org-123"}, {"id"=>"003", "provider"=>"this-app", "realm"=>"6543"}],
|
495
|
+
id2: [{"id"=>"013", "provider"=>"connec", "realm"=>"org-123"}, {"id"=>"013", "provider"=>"this-app", "realm"=>"6543"}],
|
496
|
+
},
|
497
|
+
{
|
498
|
+
id: [{"id"=>"004", "provider"=>"connec", "realm"=>"org-123"}, {"id"=>"004", "provider"=>"this-app", "realm"=>"6543"}],
|
499
|
+
id2: [{"id"=>"014", "provider"=>"connec", "realm"=>"org-123"}, {"id"=>"014", "provider"=>"this-app", "realm"=>"6543"}],
|
500
|
+
}
|
501
|
+
]
|
502
|
+
}
|
503
|
+
}
|
504
|
+
],
|
505
|
+
linked_transactions: [
|
506
|
+
{
|
507
|
+
id: [{"id"=>"005", "provider"=>"connec", "realm"=>"org-123"}, {"id"=>"005", "provider"=>"this-app", "realm"=>"6543"}],
|
508
|
+
}
|
509
|
+
]
|
510
|
+
}.with_indifferent_access
|
511
|
+
}
|
512
|
+
|
513
|
+
it 'merge the id from the src to the dist' do
|
514
|
+
expect(subject.merge_id_hashes(dist, src, id_references)).to eql(output_hash)
|
515
|
+
end
|
516
|
+
|
517
|
+
describe 'edge cases' do
|
518
|
+
context 'uncomplete src' do
|
519
|
+
describe 'when an id is missing in an array' do
|
520
|
+
before {
|
521
|
+
src[:linked_transactions] = []
|
522
|
+
output_hash[:linked_transactions].first.delete(:id)
|
523
|
+
}
|
524
|
+
|
525
|
+
it 'does not merge this id' do
|
526
|
+
expect(subject.merge_id_hashes(dist, src, id_references)).to eql(output_hash)
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
describe 'when an id is missing in a hash' do
|
531
|
+
before {
|
532
|
+
src[:lines].first.delete(:id)
|
533
|
+
output_hash[:lines].first.delete(:id)
|
534
|
+
}
|
535
|
+
|
536
|
+
it 'does not merge this id' do
|
537
|
+
expect(subject.merge_id_hashes(dist, src, id_references)).to eql(output_hash)
|
538
|
+
end
|
539
|
+
end
|
540
|
+
end
|
541
|
+
|
542
|
+
context 'uncomplete dist' do
|
543
|
+
describe 'when an id is missing in an array' do
|
544
|
+
before {
|
545
|
+
dist[:linked_transactions] = []
|
546
|
+
output_hash[:linked_transactions] = []
|
547
|
+
}
|
548
|
+
|
549
|
+
it 'does not merge this id' do
|
550
|
+
expect(subject.merge_id_hashes(dist, src, id_references)).to eql(output_hash)
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
describe 'when an id is missing in a hash' do
|
555
|
+
before {
|
556
|
+
dist[:lines].first.delete(:id)
|
557
|
+
output_hash[:lines].first.delete(:id)
|
558
|
+
}
|
559
|
+
|
560
|
+
it 'does not merge this id' do
|
561
|
+
expect(subject.merge_id_hashes(dist, src, id_references)).to eql(output_hash)
|
562
|
+
end
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|
199
567
|
end
|