maestrano-connector-rails 0.4.4 → 1.0.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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/README.md +1 -1
  4. data/VERSION +1 -1
  5. data/app/controllers/maestrano/connec_controller.rb +17 -19
  6. data/app/jobs/maestrano/connector/rails/all_synchronizations_job.rb +1 -1
  7. data/app/jobs/maestrano/connector/rails/push_to_connec_job.rb +11 -11
  8. data/app/jobs/maestrano/connector/rails/synchronization_job.rb +20 -11
  9. data/app/models/maestrano/connector/rails/concerns/complex_entity.rb +66 -74
  10. data/app/models/maestrano/connector/rails/concerns/connec_helper.rb +102 -0
  11. data/app/models/maestrano/connector/rails/concerns/entity.rb +233 -231
  12. data/app/models/maestrano/connector/rails/concerns/external.rb +7 -0
  13. data/app/models/maestrano/connector/rails/concerns/sub_entity_base.rb +14 -43
  14. data/app/models/maestrano/connector/rails/connec_helper.rb +5 -0
  15. data/app/models/maestrano/connector/rails/organization.rb +8 -2
  16. data/db/20160524112054_add_encryption_on_oauth_keys.rb +8 -0
  17. data/lib/generators/connector/install_generator.rb +1 -0
  18. data/lib/generators/connector/templates/complex_entity_example/contact.rb +1 -1
  19. data/lib/generators/connector/templates/complex_entity_example/contact_and_lead.rb +2 -2
  20. data/lib/generators/connector/templates/entity.rb +13 -19
  21. data/lib/generators/connector/templates/example_entity.rb +2 -2
  22. data/lib/generators/connector/templates/example_entity_spec.rb +73 -0
  23. data/lib/generators/connector/templates/external.rb +11 -0
  24. data/maestrano-connector-rails.gemspec +13 -8
  25. data/release_notes.md +81 -0
  26. data/spec/controllers/connec_controller_spec.rb +19 -6
  27. data/spec/dummy/app/models/maestrano/connector/rails/entity.rb +0 -7
  28. data/spec/dummy/app/models/maestrano/connector/rails/external.rb +7 -0
  29. data/spec/dummy/app/views/home/index.html.erb +1 -36
  30. data/spec/factories.rb +3 -0
  31. data/spec/integration/connec_to_external_spec.rb +188 -0
  32. data/spec/integration/external_to_connec_spec.rb +155 -0
  33. data/spec/integration/integration_complex_spec.rb +281 -0
  34. data/spec/integration/singleton_spec.rb +288 -0
  35. data/spec/jobs/all_synchronizations_job_spec.rb +5 -0
  36. data/spec/jobs/push_to_connec_job_spec.rb +3 -6
  37. data/spec/jobs/synchronization_job_spec.rb +29 -17
  38. data/spec/models/complex_entity_spec.rb +257 -412
  39. data/spec/models/connec_helper_spec.rb +143 -0
  40. data/spec/models/entity_spec.rb +420 -348
  41. data/spec/models/external_spec.rb +4 -0
  42. data/spec/models/organization_spec.rb +2 -1
  43. data/spec/models/sub_entity_base_spec.rb +28 -69
  44. data/template/factories.rb +3 -1
  45. data/template/maestrano-connector-template.rb +11 -13
  46. data/template/maestrano.rb +2 -1
  47. data/template/settings/development.yml +4 -2
  48. data/template/settings/production.yml +1 -11
  49. data/template/settings/settings.yml +8 -0
  50. data/template/settings/test.yml +2 -0
  51. data/template/settings/uat.yml +1 -9
  52. metadata +12 -7
  53. data/Gemfile.lock +0 -256
  54. data/realse_notes.md +0 -16
  55. data/spec/dummy/app/views/admin/index.html.erb +0 -51
  56. data/spec/dummy/db/development.sqlite3 +0 -0
  57. data/spec/dummy/db/test.sqlite3 +0 -0
@@ -7,6 +7,11 @@ describe Maestrano::Connector::Rails::AllSynchronizationsJob do
7
7
 
8
8
  subject { Maestrano::Connector::Rails::AllSynchronizationsJob.perform_now() }
9
9
 
10
+ # before{
11
+ # organization_not_active.update(encrypted_oauth_token: Maestrano::Connector::Rails::Organization.encrypt_oauth_token('123', key: 'This is a key that is 256 bits!!', iv: 'This iv is 12 bytes or longer'))
12
+ # organization_to_process.update(encrypted_oauth_token: Maestrano::Connector::Rails::Organization.encrypt_oauth_token('123', key: 'This is a key that is 256 bits!!', iv: 'This iv is 12 bytes or longer'))
13
+ # }
14
+
10
15
  describe 'perform' do
11
16
  it 'does not calls sync entity' do
12
17
  expect(Maestrano::Connector::Rails::SynchronizationJob).to_not receive(:perform_later).with(organization_not_linked, anything)
@@ -6,9 +6,6 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
6
6
  let(:entity_name2) { 'entity2' }
7
7
  before {
8
8
  class Entities::Entity1 < Maestrano::Connector::Rails::Entity
9
- def map_to_connec(entity, organization)
10
- entity
11
- end
12
9
  end
13
10
  allow_any_instance_of(Entities::Entity1).to receive(:push_entities_to_connec)
14
11
  allow(Entities::Entity1).to receive(:external_entity_name).and_return('ext_entity1')
@@ -16,7 +13,7 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
16
13
  end
17
14
  allow_any_instance_of(Entities::Entity2).to receive(:consolidate_and_map_data).and_return({})
18
15
  allow_any_instance_of(Entities::Entity2).to receive(:push_entities_to_connec)
19
- allow(Entities::Entity2).to receive(:connec_entities_names).and_return(%w())
16
+ allow(Entities::Entity2).to receive(:connec_entities_names).and_return(['Connec name'])
20
17
  allow(Entities::Entity2).to receive(:external_entities_names).and_return(%w(Subs ll))
21
18
  module Entities::SubEntities end;
22
19
  class Entities::SubEntities::Sub < Maestrano::Connector::Rails::SubEntityBase
@@ -66,7 +63,7 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
66
63
  before { organization.update(synchronized_entities: {:"#{entity_name1}" => false, :"#{entity_name2}" => true})}
67
64
 
68
65
  it 'calls consolidate and map data on the complex entity with the right arguments' do
69
- expect_any_instance_of(Entities::Entity2).to receive(:consolidate_and_map_data).with({}, {"Subs"=>[entity21], "ll"=>[]}, organization, {})
66
+ expect_any_instance_of(Entities::Entity2).to receive(:consolidate_and_map_data).with({"Connec name" => []}, {"Subs"=>[entity21], "ll"=>[]})
70
67
  expect_any_instance_of(Entities::Entity2).to receive(:push_entities_to_connec)
71
68
  subject
72
69
  end
@@ -87,7 +84,7 @@ describe Maestrano::Connector::Rails::PushToConnecJob do
87
84
  before { organization.update(synchronized_entities: {:"#{entity_name1}" => true, :"#{entity_name2}" => false})}
88
85
 
89
86
  it 'calls consolidate_and_map_data on the non complex entity with the right arguments' do
90
- expect_any_instance_of(Entities::Entity1).to receive(:consolidate_and_map_data).with([], [entity11, entity12], organization, {}).and_return({})
87
+ expect_any_instance_of(Entities::Entity1).to receive(:consolidate_and_map_data).with([], [entity11, entity12]).and_return({})
91
88
  expect_any_instance_of(Entities::Entity1).to receive(:push_entities_to_connec)
92
89
  subject
93
90
  end
@@ -69,29 +69,41 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
69
69
 
70
70
  it { performes }
71
71
 
72
- it 'calls sync entity on all the organization synchronized entities set to true' do
73
- organization.synchronized_entities[organization.synchronized_entities.keys.first] = false
74
- expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(organization.synchronized_entities.count - 1).times
75
-
76
- subject
72
+ context 'first sync' do
73
+ it 'does two half syncs' do
74
+ expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(2 * organization.synchronized_entities.count).times
75
+ subject
76
+ end
77
77
  end
78
78
 
79
- context 'with options' do
80
- context 'with only_entities' do
81
- let(:opts) { {only_entities: %w(people price)} }
79
+ context 'subsequent sync' do
80
+ let!(:old_sync) { create(:synchronization, partial: false, status: 'SUCCESS', organization: organization) }
82
81
 
83
- it 'calls sync entity on the specified entities' do
84
- expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).twice
82
+ it 'calls sync entity on all the organization synchronized entities set to true' do
83
+ organization.synchronized_entities[organization.synchronized_entities.keys.first] = false
84
+ expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).exactly(organization.synchronized_entities.count - 1).times
85
85
 
86
- subject
87
- end
86
+ subject
87
+ end
88
+
89
+ context 'with options' do
90
+ context 'with only_entities' do
91
+ let(:opts) { {only_entities: %w(people price)} }
88
92
 
89
- it 'set the current syncrhonization as partial' do
90
- subject
91
- expect(Maestrano::Connector::Rails::Synchronization.last.partial).to be(true)
93
+ it 'calls sync entity on the specified entities' do
94
+ expect_any_instance_of(Maestrano::Connector::Rails::SynchronizationJob).to receive(:sync_entity).twice
95
+
96
+ subject
97
+ end
98
+
99
+ it 'set the current syncrhonization as partial' do
100
+ subject
101
+ expect(Maestrano::Connector::Rails::Synchronization.last.partial).to be(true)
102
+ end
92
103
  end
93
104
  end
94
105
  end
106
+
95
107
  end
96
108
  end
97
109
 
@@ -107,7 +119,7 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
107
119
  it 'calls the seven methods' do
108
120
  expect_any_instance_of(Entities::Person).to receive(:before_sync)
109
121
  expect_any_instance_of(Entities::Person).to receive(:get_connec_entities)
110
- expect_any_instance_of(Entities::Person).to receive(:get_external_entities)
122
+ expect_any_instance_of(Entities::Person).to receive(:get_external_entities_wrapper)
111
123
  expect_any_instance_of(Entities::Person).to receive(:consolidate_and_map_data).and_return({})
112
124
  expect_any_instance_of(Entities::Person).to receive(:push_entities_to_external)
113
125
  expect_any_instance_of(Entities::Person).to receive(:push_entities_to_connec)
@@ -125,7 +137,7 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
125
137
  it 'calls the seven methods' do
126
138
  expect_any_instance_of(Entities::SomeStuff).to receive(:before_sync)
127
139
  expect_any_instance_of(Entities::SomeStuff).to receive(:get_connec_entities)
128
- expect_any_instance_of(Entities::SomeStuff).to receive(:get_external_entities)
140
+ expect_any_instance_of(Entities::SomeStuff).to receive(:get_external_entities_wrapper)
129
141
  expect_any_instance_of(Entities::SomeStuff).to receive(:consolidate_and_map_data).and_return({})
130
142
  expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_external)
131
143
  expect_any_instance_of(Entities::SomeStuff).to receive(:push_entities_to_connec)
@@ -2,496 +2,341 @@ require 'spec_helper'
2
2
 
3
3
  describe Maestrano::Connector::Rails::ComplexEntity do
4
4
 
5
- subject { Maestrano::Connector::Rails::ComplexEntity.new }
6
-
7
- #Complex specific methods
8
- describe 'complex specific methods' do
9
- describe 'connec_entities_names' do
10
- it { expect{ subject.class.connec_entities_names }.to raise_error('Not implemented') }
11
- end
12
- describe 'external_entities_names' do
13
- it { expect{ subject.class.external_entities_names }.to raise_error('Not implemented') }
14
- end
15
- describe 'connec_model_to_external_model' do
16
- it { expect{ subject.connec_model_to_external_model({}, nil) }.to raise_error('Not implemented') }
17
- end
18
- describe 'external_model_to_connec_model' do
19
- it { expect{ subject.external_model_to_connec_model({}, nil) }.to raise_error('Not implemented') }
20
- end
21
- end
22
-
23
- describe 'general methods' do
24
- let(:organization) { create(:organization) }
25
-
26
- describe 'map_to_external_with_idmap' do
27
- let(:id) { '322j-bbfg4' }
28
- let(:entity) { {'id' => id, 'name' => 'John', 'updated_at' => 2.day.ago} }
29
- let(:mapped_entity) { {'first_name' => 'John'} }
30
- let(:connec_name) { 'Connec_name' }
31
- let(:external_name) { 'External_name' }
32
- let(:sub_instance) { Maestrano::Connector::Rails::SubEntityBase.new }
33
- let(:human_name) { 'ET' }
34
- before {
35
- allow(sub_instance.class).to receive(:external?).and_return(false)
36
- allow(sub_instance.class).to receive(:entity_name).and_return(connec_name)
37
- allow(sub_instance).to receive(:map_to).and_return(mapped_entity)
38
- allow(sub_instance.class).to receive(:object_name_from_connec_entity_hash).and_return(human_name)
39
- }
40
-
41
- context 'when entity has no idmap' do
42
- it 'creates one' do
43
- expect {
44
- subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)
45
- }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(1)
46
- end
5
+ describe 'class methods' do
6
+ subject { Maestrano::Connector::Rails::ComplexEntity }
7
+
8
+ describe 'connec_entities_names' do
9
+ it { expect{ subject.connec_entities_names }.to raise_error('Not implemented') }
47
10
  end
48
- it 'returns the mapped entity with its idmap' do
49
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to eql({entity: mapped_entity, idmap: Maestrano::Connector::Rails::IdMap.last})
11
+ describe 'external_entities_names' do
12
+ it { expect{ subject.external_entities_names }.to raise_error('Not implemented') }
50
13
  end
14
+ end
51
15
 
52
- context 'when entity has an idmap without last_push_to_external' do
53
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, last_push_to_external: nil, external_entity: external_name.downcase) }
54
-
55
- it 'returns the mapped entity with its idmap' do
56
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to eql({entity: mapped_entity, idmap: idmap})
57
- end
58
- end
59
-
60
- context 'when entity has an idmap with an older last_push_to_external' do
61
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, last_push_to_external: 1.year.ago, external_entity: external_name.downcase) }
62
-
63
- it 'returns the mapped entity with its idmap' do
64
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to eql({entity: mapped_entity, idmap: idmap})
65
- end
66
- end
67
-
68
- context 'when entity has an idmap with a more recent last_push_to_external' do
69
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, last_push_to_external: 1.second.ago, external_entity: external_name.downcase) }
70
-
71
- it 'discards the entity' do
72
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to be_nil
73
- end
16
+ describe 'instance methods' do
17
+ let!(:organization) { create(:organization, uid: 'cld-123') }
18
+ let!(:connec_client) { Maestrano::Connec::Client[organization.tenant].new(organization.uid) }
19
+ let!(:external_client) { Object.new }
20
+ let(:opts) { {} }
21
+ subject { Maestrano::Connector::Rails::ComplexEntity.new(organization, connec_client, external_client, opts) }
22
+
23
+ #Complex specific methods
24
+ describe 'complex specific methods' do
25
+ describe 'connec_model_to_external_model' do
26
+ it { expect{ subject.connec_model_to_external_model({}) }.to raise_error('Not implemented') }
74
27
  end
75
-
76
- context 'when entity has an idmap with to_external set to false' do
77
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, to_external: false, external_entity: external_name.downcase) }
78
-
79
- it 'discards the entity' do
80
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to be_nil
81
- end
82
- end
83
-
84
- context 'when entity has an idmap with external_inactive set to true' do
85
- let!(:idmap) { create(:idmap, organization: organization, connec_id: id, connec_entity: connec_name.downcase, external_inactive: true, external_entity: external_name.downcase) }
86
-
87
- it 'discards the entity' do
88
- expect(subject.map_to_external_with_idmap(entity, organization, external_name, sub_instance)).to be_nil
89
- end
28
+ describe 'external_model_to_connec_model' do
29
+ it { expect{ subject.external_model_to_connec_model({}) }.to raise_error('Not implemented') }
90
30
  end
91
31
  end
92
32
 
93
33
  describe 'filter_connec_entities' do
94
- it { expect(subject.filter_connec_entities({'lead' => [{a: 2}]}, organization)).to eql({'lead' => [{a: 2}]}) }
95
- end
96
- end
97
-
98
- describe 'methods with sub complex entities' do
99
- before {
100
- module Entities::SubEntities
101
- end
102
- class Entities::SubEntities::ScE1 < Maestrano::Connector::Rails::SubEntityBase
103
- end
104
- class Entities::SubEntities::ScE2 < Maestrano::Connector::Rails::SubEntityBase
105
- end
106
- }
107
-
108
- describe 'get_connec_entities' do
109
- before {
110
- allow(subject.class).to receive(:connec_entities_names).and_return(%w(sc_e1 ScE2))
111
- }
112
-
113
- it 'calls get_connec_entities on each connec sub complex entities' do
114
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).with(nil, nil, nil, {opts: true})
115
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).with(nil, nil, nil, {opts: true})
116
- subject.get_connec_entities(nil, nil, nil, {opts: true})
117
- end
118
-
119
- let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
120
- let(:arr2) { [{'price' => 92}, {'price' => 300}] }
121
- it 'returns an hash of the connec_entities keyed by connec_entity_name' do
122
- allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).and_return(arr1)
123
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).and_return(arr2)
124
- expect(subject.get_connec_entities(nil, nil, nil, {opts: true})).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
125
- end
34
+ it { expect(subject.filter_connec_entities({'lead' => [{a: 2}]})).to eql({'lead' => [{a: 2}]}) }
126
35
  end
127
36
 
128
- describe 'get_external_entities' do
37
+ describe 'methods with sub complex entities' do
129
38
  before {
130
- allow(subject.class).to receive(:external_entities_names).and_return(%w(sc_e1 ScE2))
39
+ module Entities::SubEntities
40
+ end
41
+ class Entities::SubEntities::ScE1 < Maestrano::Connector::Rails::SubEntityBase
42
+ end
43
+ class Entities::SubEntities::ScE2 < Maestrano::Connector::Rails::SubEntityBase
44
+ end
131
45
  }
132
46
 
133
- it 'calls get_external_entities on each connec sub complex entities' do
134
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities).with(nil, nil, nil, {opts: true})
135
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities).with(nil, nil, nil, {opts: true})
136
- subject.get_external_entities(nil, nil, nil, {opts: true})
137
- end
138
-
139
- let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
140
- let(:arr2) { [{'price' => 92}, {'price' => 300}] }
141
- it 'returns an hash of the external_entities keyed by external_entity_name' do
142
- allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities).and_return(arr1)
143
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities).and_return(arr2)
144
- expect(subject.get_external_entities(nil, nil, nil, {opts: true})).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
145
- end
146
- end
147
-
148
-
149
- describe 'consolidate_and_map_data' do
150
- let(:opt) { {opt: true} }
151
- let(:organization) { create(:organization) }
47
+ describe 'get_connec_entities' do
48
+ before {
49
+ allow(subject.class).to receive(:connec_entities_names).and_return(%w(sc_e1 ScE2))
50
+ }
152
51
 
153
- it 'calls external_model_to_connec_model' do
154
- allow(subject).to receive(:connec_model_to_external_model).and_return({})
155
- expect(subject).to receive(:external_model_to_connec_model).with({a: {}}, organization).and_return({})
156
- subject.consolidate_and_map_data({}, {a: {}}, organization, opt)
157
- end
52
+ it 'calls get_connec_entities on each connec sub complex entities' do
53
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).with(nil)
54
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).with(nil)
55
+ subject.get_connec_entities(nil)
56
+ end
158
57
 
159
- it 'calls connec_model_to_external_model' do
160
- allow(subject).to receive(:external_model_to_connec_model).and_return({})
161
- expect(subject).to receive(:connec_model_to_external_model).with({a: {}}, organization).and_return({})
162
- subject.consolidate_and_map_data({a: {}}, {}, organization, opt)
58
+ let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
59
+ let(:arr2) { [{'price' => 92}, {'price' => 300}] }
60
+ it 'returns an hash of the connec_entities keyed by connec_entity_name' do
61
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_connec_entities).and_return(arr1)
62
+ allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_connec_entities).and_return(arr2)
63
+ expect(subject.get_connec_entities(nil)).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
64
+ end
163
65
  end
164
66
 
165
- describe 'connec_entities treatment' do
166
- #hash as it should be after connec_model_to_external_model
167
- let(:connec_hash) {
168
- {
169
- 'sc_e1' => {'ext1' => [{'name' => 'John'}, {'name' => 'Jane'}]},
170
- 'ScE2' => {'ext1' => [{'name' => 'Robert'}], 'ext2' => [{'price' => 45}]}
171
- }
172
- }
173
- before{
174
- allow(subject).to receive(:external_model_to_connec_model).and_return({})
175
- allow(subject).to receive(:connec_model_to_external_model).and_return(connec_hash)
67
+ describe 'get_external_entities' do
68
+ before {
69
+ allow(subject.class).to receive(:external_entities_names).and_return(%w(sc_e1 ScE2))
176
70
  }
177
71
 
178
- it 'calls map_to_external_with_idmap on each entity' do
179
- expect(subject).to receive(:map_to_external_with_idmap).exactly(4).times
180
- subject.consolidate_and_map_data({}, {}, organization, opt)
72
+ it 'calls get_external_entities on each connec sub complex entities' do
73
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities_wrapper).with(nil)
74
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities_wrapper).with(nil)
75
+ subject.get_external_entities_wrapper(nil)
181
76
  end
182
- end
183
77
 
184
- describe 'external_entities treatment' do
185
- #hash as it should be after external_model_to_connec_model
186
- let(:id1) { '5678ttd3' }
187
- let(:id2) { '5678taa3' }
188
- let(:entity1) { {'id' => id1, 'name' => 'Robert'} }
189
- let(:entity2) { {'id' => id2, 'price' => 45} }
190
- let(:mapped_entity1) { {'first_name' => 'Robert'} }
191
- let(:mapped_entity2) { {'net_price' => 45} }
192
- let(:external_hash) {
193
- {
194
- 'sc_e1' => {'Connec1' => [entity1]},
195
- 'ScE2' => {'Connec1' => [entity1], 'connec2' => [entity2]}
196
- }
197
- }
198
- let(:connec_hash) { {} }
199
- let(:human_name) { 'Jabba' }
200
- before{
201
- allow(subject).to receive(:external_model_to_connec_model).and_return(external_hash)
202
- allow(subject).to receive(:connec_model_to_external_model).and_return(connec_hash)
203
- allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(true)
204
- allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return('sc_e1')
205
- allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).with(entity1).and_return(id1)
206
- allow(Entities::SubEntities::ScE1).to receive(:last_update_date_from_external_entity_hash).and_return(1.minute.ago)
207
- allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).with('Connec1', entity1, organization).and_return(mapped_entity1)
208
- allow(Entities::SubEntities::ScE2).to receive(:external?).and_return(true)
209
- allow(Entities::SubEntities::ScE2).to receive(:entity_name).and_return('Sce2')
210
- allow(Entities::SubEntities::ScE2).to receive(:id_from_external_entity_hash).with(entity1).and_return(id1)
211
- allow(Entities::SubEntities::ScE2).to receive(:id_from_external_entity_hash).with(entity2).and_return(id2)
212
- allow(Entities::SubEntities::ScE2).to receive(:last_update_date_from_external_entity_hash).and_return(1.minute.ago)
213
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:map_to).with('Connec1', entity1, organization).and_return(mapped_entity1)
214
- allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:map_to).with('connec2', entity2, organization).and_return(mapped_entity2)
215
- allow(Entities::SubEntities::ScE1).to receive(:object_name_from_external_entity_hash).and_return(human_name)
216
- allow(Entities::SubEntities::ScE2).to receive(:object_name_from_external_entity_hash).and_return(human_name)
217
- }
78
+ let(:arr1) { [{'name' => 'Water'}, {'name' => 'Sugar'}] }
79
+ let(:arr2) { [{'price' => 92}, {'price' => 300}] }
80
+ it 'returns an hash of the external_entities keyed by external_entity_name' do
81
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:get_external_entities_wrapper).and_return(arr1)
82
+ allow_any_instance_of(Entities::SubEntities::ScE2).to receive(:get_external_entities_wrapper).and_return(arr2)
83
+ expect(subject.get_external_entities_wrapper(nil)).to eql({'sc_e1' => arr1, 'ScE2' => arr2})
84
+ end
85
+ end
218
86
 
219
- context 'when entities have no idmaps' do
220
87
 
221
- it 'creates an idmap for each entity' do
222
- expect{
223
- subject.consolidate_and_map_data({}, {}, organization, opt)
224
- }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(3)
88
+ describe 'consolidate and map methods' do
89
+ let(:human_name) { 'Jabba' }
90
+ let(:mapped_entity) { {mapped: 'entity'} }
91
+ let(:date) { 2.hour.ago }
92
+
93
+ describe 'consolidate_and_map_data' do
94
+ before{
95
+ allow(subject).to receive(:external_model_to_connec_model).and_return({})
96
+ allow(subject).to receive(:connec_model_to_external_model).and_return({})
97
+ }
98
+
99
+ it 'calls external_model_to_connec_model' do
100
+ expect(subject).to receive(:external_model_to_connec_model).with({a: {}}).and_return({})
101
+ subject.consolidate_and_map_data({}, {a: {}})
225
102
  end
226
103
 
227
- it 'returns the entity with their new idmaps' do
228
- mapped_entities = subject.consolidate_and_map_data({}, external_hash, organization, opt)
229
- expect(mapped_entities).to eql(external_entities: {
230
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: Maestrano::Connector::Rails::IdMap.first}]},
231
- 'ScE2' => {
232
- 'Connec1' => [{entity: mapped_entity1, idmap: Maestrano::Connector::Rails::IdMap.second}],
233
- 'connec2' => [{entity: mapped_entity2, idmap: Maestrano::Connector::Rails::IdMap.last}],
234
- }
235
- },
236
- connec_entities: {})
104
+ it 'calls connec_model_to_external_model' do
105
+ expect(subject).to receive(:connec_model_to_external_model).with({a: {}}).and_return({})
106
+ subject.consolidate_and_map_data({a: {}}, {})
237
107
  end
238
- end
239
108
 
240
- context 'when entities have idmaps with to_connec set to false' do
241
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', to_connec: false) }
242
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', to_connec: false) }
243
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', to_connec: false) }
244
-
245
- it 'discards the entities' do
246
- mapped_entities = subject.consolidate_and_map_data({}, external_hash, organization, opt)
247
- expect(mapped_entities).to eql(external_entities: {
248
- 'sc_e1' => {'Connec1' => []},
249
- 'ScE2' => {
250
- 'Connec1' => [],
251
- 'connec2' => [],
252
- }
253
- },
254
- connec_entities: {})
109
+ it 'calls the consolidation on both connec and external and returns an hash with the results' do
110
+ expect(subject).to receive(:consolidate_and_map_connec_entities).with({}, {}).and_return({connec_result: 1})
111
+ expect(subject).to receive(:consolidate_and_map_external_entities).with({}).and_return({ext_result: 1})
112
+ expect(subject.consolidate_and_map_data({}, {})).to eql({connec_entities: {connec_result: 1}, external_entities: {ext_result: 1}})
255
113
  end
256
114
  end
257
115
 
258
- describe 'external_inactive flagging' do
116
+ describe 'consolidate_and_map_external_entities' do
117
+ let(:entity) { {'id' => id, 'name' => 'Jane'} }
118
+ let(:id) { 'id' }
119
+ let(:external_name) { 'sc_e1' }
120
+ let(:connec_name) { 'connec1' }
121
+ let(:modeled_external_entities) { {external_name => {connec_name => [entity]}} }
122
+ before {
123
+ allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(true)
124
+ allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return(external_name)
125
+ allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).and_return(id)
126
+ allow(Entities::SubEntities::ScE1).to receive(:object_name_from_external_entity_hash).and_return(human_name)
127
+ allow(Entities::SubEntities::ScE1).to receive(:last_update_date_from_external_entity_hash).and_return(date)
128
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).and_return(mapped_entity)
129
+ }
259
130
 
260
- context 'idmaps external_inactive set to true' do
261
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', external_inactive: true) }
262
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', external_inactive: true) }
263
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', external_inactive: true) }
131
+ context 'when idmap exists' do
132
+ let!(:idmap) { create(:idmap, organization: organization, connec_entity: connec_name.downcase, external_entity: external_name.downcase, external_id: id) }
264
133
 
265
- context 'entities inactive' do
266
- before {
267
- allow(Entities::SubEntities::ScE2).to receive(:inactive_from_external_entity_hash?).and_return(true)
268
- allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)
269
- }
134
+ it 'does not create one' do
135
+ expect{
136
+ subject.consolidate_and_map_external_entities(modeled_external_entities)
137
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
138
+ end
270
139
 
271
- it 'discards the entities' do
272
- expect(subject.consolidate_and_map_data({}, external_hash, organization, opt)).to eql(external_entities: {
273
- 'sc_e1' => {'Connec1' => []},
274
- 'ScE2' => {
275
- 'Connec1' => [],
276
- 'connec2' => [],
277
- }
278
- },
279
- connec_entities: {})
140
+ it 'returns the mapped entity with the idmap' do
141
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => [{entity: mapped_entity, idmap: idmap}]}})
142
+ end
143
+
144
+ context 'when to_connec is false' do
145
+ before { idmap.update(to_connec: false) }
146
+
147
+ it 'discards the entity' do
148
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => []}})
280
149
  end
281
150
  end
282
151
 
283
- context 'entities active' do
152
+ context 'when entity is inactive' do
284
153
  before {
285
- allow(Entities::SubEntities::ScE2).to receive(:inactive_from_external_entity_hash?).and_return(false)
286
- allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(false)
287
- [idmap1, idmap21, idmap22].each{|i| i.update(last_push_to_connec: 1.second.ago)} #Used only to simplify specing
154
+ allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)
288
155
  }
289
156
 
157
+ it 'discards the entity' do
158
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => []}})
159
+ end
160
+
290
161
  it 'updates the idmaps' do
291
- subject.consolidate_and_map_data({}, external_hash, organization, opt)
292
- expect(idmap1.reload.external_inactive).to be false
293
- expect(idmap21.reload.external_inactive).to be false
294
- expect(idmap22.reload.external_inactive).to be false
295
- end
162
+ subject.consolidate_and_map_external_entities(modeled_external_entities)
163
+ expect(idmap.reload.external_inactive).to be true
164
+ end
296
165
  end
297
- end
298
166
 
299
- context 'idmaps external_inactive set to false' do
300
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', external_inactive: false) }
301
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', external_inactive: false) }
302
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', external_inactive: false) }
167
+ context 'when last_push_to_connec is recent' do
168
+ before { idmap.update(last_push_to_connec: 2.second.ago) }
303
169
 
304
- context 'entities inactive' do
305
- before {
306
- allow(Entities::SubEntities::ScE2).to receive(:inactive_from_external_entity_hash?).and_return(true)
307
- allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)
308
- }
309
-
310
- it 'discards the entities and updates the idmaps' do
311
- expect(subject.consolidate_and_map_data({}, external_hash, organization, opt)).to eql(external_entities: {
312
- 'sc_e1' => {'Connec1' => []},
313
- 'ScE2' => {
314
- 'Connec1' => [],
315
- 'connec2' => [],
316
- }
317
- },
318
- connec_entities: {})
319
- expect(idmap1.reload.external_inactive).to be true
320
- expect(idmap21.reload.external_inactive).to be true
321
- expect(idmap22.reload.external_inactive).to be true
170
+ it 'discards the entity' do
171
+ expect(subject.consolidate_and_map_external_entities(modeled_external_entities)).to eql({external_name => {connec_name => []}})
322
172
  end
323
173
  end
324
- end
325
- end
326
174
 
327
- context 'when entities have idmaps with more recent last_push_to_connec' do
328
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', last_push_to_connec: 1.second.ago) }
329
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', last_push_to_connec: 1.second.ago) }
330
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', last_push_to_connec: 1.second.ago) }
331
-
332
- it 'discards the entities' do
333
- mapped_entities = subject.consolidate_and_map_data({}, external_hash, organization, opt)
334
- expect(mapped_entities).to eql(external_entities: {
335
- 'sc_e1' => {'Connec1' => []},
336
- 'ScE2' => {
337
- 'Connec1' => [],
338
- 'connec2' => [],
339
- }
340
- },
341
- connec_entities: {})
342
175
  end
343
176
  end
344
177
 
345
- context 'when entities have idmaps with older last_push_to_connec' do
178
+ describe 'consolidate_and_map_connec_entities' do
179
+ let(:id) { 'external-unfolded-id' }
180
+ let(:connec_id) { 'connec-id' }
181
+ let(:entity) { {'id' => id, 'name' => 'John', 'updated_at' => date} }
182
+ let(:modeled_connec_entities) { {connec_name => {external_name => [entity]}} }
183
+ let(:modeled_external_entities) { {} }
184
+ let(:connec_name) { 'sc_e1' }
185
+ let(:external_name) { 'ext1' }
346
186
  before{
347
- class Entities::SubEntities::Connec1 < Maestrano::Connector::Rails::SubEntityBase
348
- end
349
- class Entities::SubEntities::Connec2 < Maestrano::Connector::Rails::SubEntityBase
350
- end
351
- allow_any_instance_of(Entities::SubEntities::Connec1).to receive(:map_to).and_return({'name' => 'Jacob'})
352
- allow(Entities::SubEntities::Connec1).to receive(:external?).and_return(false)
353
- allow(Entities::SubEntities::Connec1).to receive(:entity_name).and_return('Connec1')
354
- allow(Entities::SubEntities::Connec1).to receive(:object_name_from_connec_entity_hash).and_return('human name')
187
+ allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(false)
188
+ allow(Entities::SubEntities::ScE1).to receive(:entity_name).and_return(connec_name)
189
+ allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).with(external_name, entity).and_return(mapped_entity)
190
+ allow(Entities::SubEntities::ScE1).to receive(:object_name_from_connec_entity_hash).and_return(human_name)
191
+ allow(Maestrano::Connector::Rails::ConnecHelper).to receive(:unfold_references).and_return(entity.merge(__connec_id: connec_id))
355
192
  }
356
- let(:connec_id1) { '67ttf-5rr4d' }
357
- let!(:idmap1) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sc_e1', connec_entity: 'connec1', last_push_to_connec: 1.year.ago, connec_id: connec_id1) }
358
- let!(:idmap21) { create(:idmap, organization: organization, external_id: id1, external_entity: 'sce2', connec_entity: 'connec1', last_push_to_connec: 1.year.ago) }
359
- let!(:idmap22) { create(:idmap, organization: organization, external_id: id2, external_entity: 'sce2', connec_entity: 'connec2', last_push_to_connec: 1.year.ago) }
360
- let(:connec_hash) { {'Connec1' => {'sc_e1' => [{'id' => connec_id1, 'first_name' => 'Jacob', 'updated_at' => 1.hour.ago}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}} }
361
-
362
- context 'without conflict' do
363
- it 'returns the entity with their idmaps' do
364
- subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
365
- expect(external_hash).to eql({
366
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: idmap1}]},
367
- 'ScE2' => {
368
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
369
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
370
- }
371
- })
193
+
194
+ context 'when idmaps do not exist' do
195
+ it 'creates the idmaps with a name and returns the mapped entities with their idmaps' do
196
+ expect{
197
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first}]}})
198
+ }.to change{ Maestrano::Connector::Rails::IdMap.count }.by(1)
199
+ expect(Maestrano::Connector::Rails::IdMap.last.name).to eql(human_name)
372
200
  end
373
201
  end
374
202
 
375
- context 'with conflict' do
376
- context 'with option connec_preemption' do
377
- context 'set to true' do
378
- let(:opt) { {connec_preemption: true} }
379
-
380
- it 'keeps the connec entities' do
381
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
382
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => [{entity: {'name' => 'Jacob'}, idmap: idmap1}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
383
- expect(mapped_entities[:external_entities]).to eql({
384
- 'sc_e1' => {'Connec1' => []},
385
- 'ScE2' => {
386
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
387
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
388
- }
389
- })
390
- end
203
+ context 'when idmap exists' do
204
+ let!(:idmap1) { create(:idmap, organization: organization, connec_entity: connec_name.downcase, external_entity: external_name.downcase, external_id: id, connec_id: connec_id) }
205
+
206
+ it 'does not create an idmap' do
207
+ expect{
208
+ subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})
209
+ }.to_not change{ Maestrano::Connector::Rails::IdMap.count }
210
+ end
211
+
212
+ it 'returns the entity with its idmap' do
213
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: idmap1}]}})
214
+ end
215
+
216
+ context 'when external inactive' do
217
+ before { idmap1.update(external_inactive: true) }
218
+ it 'discards the entity' do
219
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => []}})
391
220
  end
221
+ end
392
222
 
393
- context 'set to false' do
394
- let(:opt) { {connec_preemption: false} }
395
-
396
- it 'keeps the external entities' do
397
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
398
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => []}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
399
- expect(mapped_entities[:external_entities]).to eql({
400
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: idmap1}]},
401
- 'ScE2' => {
402
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
403
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
404
- }
405
- })
406
- end
223
+ context 'when to external flag is false' do
224
+ before { idmap1.update(to_external: false) }
225
+ it 'discards the entity' do
226
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => []}})
407
227
  end
408
228
  end
409
229
 
410
- context 'without option' do
411
- context 'with a more recently updated external entity' do
412
- it 'keeps the external entity' do
413
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
414
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => []}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
415
- expect(mapped_entities[:external_entities]).to eql({
416
- 'sc_e1' => {'Connec1' => [{entity: mapped_entity1, idmap: idmap1}]},
417
- 'ScE2' => {
418
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
419
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
420
- }
421
- })
230
+ context 'when last_push_to_external is recent' do
231
+ before { idmap1.update(last_push_to_external: 2.second.ago) }
232
+ it 'discards the entity' do
233
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, {})).to eql({connec_name => {external_name => []}})
234
+ end
235
+ end
236
+
237
+ context 'when conflict' do
238
+ let(:external_entity_1) { {'id' => id} }
239
+ let(:modeled_external_entities) { {external_name => {connec_name => [external_entity_1]}} }
240
+ before {
241
+ allow(Entities::SubEntities::ScE1).to receive(:id_from_external_entity_hash).and_return(id)
242
+ }
243
+
244
+ context 'with opts' do
245
+ context 'with connec preemption false' do
246
+ it 'discards the entity and keep the external one' do
247
+ subject.instance_variable_set(:@opts, {connec_preemption: false})
248
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => []}})
249
+ expect(modeled_external_entities[external_name][connec_name]).to_not be_empty
250
+ end
251
+ end
252
+
253
+ context 'with connec preemption true' do
254
+ it 'keeps the entity and discards the external one' do
255
+ subject.instance_variable_set(:@opts, {connec_preemption: true})
256
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first}]}})
257
+ expect(modeled_external_entities[external_name][connec_name]).to be_empty
258
+ end
422
259
  end
423
260
  end
424
261
 
425
- context 'with a more recently updated connec entity' do
426
- let(:connec_hash) { {'Connec1' => {'sc_e1' => [{'id' => connec_id1, 'first_name' => 'Jacob', 'updated_at' => 1.second.ago}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}} }
427
-
428
- it 'keeps the connec entities' do
429
- mapped_entities = subject.consolidate_and_map_data({'Connec1' => []}, {'sc_e1' => []}, organization, opt)
430
- expect(mapped_entities[:connec_entities]).to eq({'Connec1' => {'sc_e1' => [{entity: {'name' => 'Jacob'}, idmap: idmap1}]}, 'connec2' => {'sc_e1' => [], 'ScE2' => []}})
431
- expect(mapped_entities[:external_entities]).to eql({
432
- 'sc_e1' => {'Connec1' => []},
433
- 'ScE2' => {
434
- 'Connec1' => [{entity: mapped_entity1, idmap: idmap21}],
435
- 'connec2' => [{entity: mapped_entity2, idmap: idmap22}],
436
- }
437
- })
262
+ context 'without opts' do
263
+ before {
264
+ allow(Entities::SubEntities::ScE1).to receive(:last_update_date_from_external_entity_hash).and_return(external_date)
265
+ }
266
+
267
+ context 'with connec one more recent' do
268
+ let(:external_date) { 1.year.ago }
269
+ let(:date) { 1.day.ago }
270
+
271
+ it 'keeps the entity and discards the external one' do
272
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => [{entity: {mapped: 'entity'}, idmap: Maestrano::Connector::Rails::IdMap.first}]}})
273
+ expect(modeled_external_entities[external_name][connec_name]).to be_empty
274
+ end
275
+ end
276
+
277
+ context 'with external one more recent' do
278
+ let(:external_date) { 1.month.ago }
279
+ let(:date) { 1.year.ago }
280
+
281
+ it 'discards the entity and keep the external one' do
282
+ expect(subject.consolidate_and_map_connec_entities(modeled_connec_entities, modeled_external_entities)).to eql({connec_name => {external_name => []}})
283
+ expect(modeled_external_entities[external_name][connec_name]).to_not be_empty
284
+ end
438
285
  end
439
286
  end
440
287
  end
441
288
  end
442
289
  end
443
290
  end
444
- end
445
291
 
446
- describe 'push_entities_to_connec' do
447
- let(:idmap) { nil }
448
- let(:mapped_entity_with_idmap) { {entity: {}, idmap: idmap} }
449
- let(:external_hash) {
450
- {
451
- 'sc_e1' => {'Connec1' => [mapped_entity_with_idmap]},
452
- 'ScE2' => {'Connec1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'connec2' => [mapped_entity_with_idmap]}
292
+
293
+ describe 'push_entities_to_connec' do
294
+ let(:idmap) { nil }
295
+ let(:mapped_entity_with_idmap) { {entity: {}, idmap: idmap} }
296
+ let(:external_hash) {
297
+ {
298
+ 'sc_e1' => {'Connec1' => [mapped_entity_with_idmap]},
299
+ 'ScE2' => {'Connec1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'connec2' => [mapped_entity_with_idmap]}
300
+ }
453
301
  }
454
- }
455
302
 
456
- it 'calls push_entities_to_connec on each sub complex entity' do
457
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_connec_to).once.with(nil, [mapped_entity_with_idmap], 'Connec1', nil)
458
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_connec_to).twice
459
- subject.push_entities_to_connec(nil, external_hash, nil)
460
- end
303
+ it 'calls push_entities_to_connec on each sub complex entity' do
304
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_connec_to).once.with([mapped_entity_with_idmap], 'Connec1')
305
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_connec_to).twice
306
+ subject.push_entities_to_connec(external_hash)
307
+ end
461
308
 
462
- describe 'full call' do
463
- let(:organization) { create(:organization) }
464
- let!(:client) { Maestrano::Connec::Client.new(organization.uid) }
465
- let(:idmap) { create(:idmap, organization: organization) }
466
- before {
467
- [Entities::SubEntities::ScE1, Entities::SubEntities::ScE2].each do |klass|
468
- allow(klass).to receive(:external?).and_return(true)
469
- allow(klass).to receive(:entity_name).and_return('n')
309
+ describe 'full call' do
310
+ let(:idmap) { create(:idmap, organization: organization) }
311
+ before {
312
+ [Entities::SubEntities::ScE1, Entities::SubEntities::ScE2].each do |klass|
313
+ allow(klass).to receive(:external?).and_return(true)
314
+ allow(klass).to receive(:entity_name).and_return('n')
315
+ end
316
+ allow(connec_client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec1s: {id: [{provider: 'connec', id: 'connec-id'}]}}}]}.to_json, {}), ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec1s: {id: [{provider: 'connec', id: 'connec-id'}]}}}]}.to_json, {}), ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec2s: {id: [{provider: 'connec', id: 'connec-id'}]}}}]}.to_json, {}))
317
+ }
318
+ it 'is successful' do
319
+ subject.push_entities_to_connec(external_hash)
320
+ idmap.reload
321
+ expect(idmap.message).to be nil
470
322
  end
471
- allow(client).to receive(:batch).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec1s: {}}}]}.to_json, {}))
472
- }
473
- it 'is successful' do
474
- subject.push_entities_to_connec(client, external_hash, organization)
475
- idmap.reload
476
- expect(idmap.message).to be nil
477
323
  end
478
324
  end
479
- end
480
325
 
481
-
482
- describe 'push_entities_to_external' do
483
- let(:mapped_entity_with_idmap) { {entity: {}, idmap: nil} }
484
- let(:connec_hash) {
485
- {
486
- 'sc_e1' => {'ext1' => [mapped_entity_with_idmap]},
487
- 'ScE2' => {'ext1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'ext2' => [mapped_entity_with_idmap]}
326
+ describe 'push_entities_to_external' do
327
+ let(:mapped_entity_with_idmap) { {entity: {}, idmap: nil} }
328
+ let(:connec_hash) {
329
+ {
330
+ 'sc_e1' => {'ext1' => [mapped_entity_with_idmap]},
331
+ 'ScE2' => {'ext1' => [mapped_entity_with_idmap, mapped_entity_with_idmap], 'ext2' => [mapped_entity_with_idmap]}
332
+ }
488
333
  }
489
- }
490
334
 
491
- it 'calls push_entities_to_connec on each sub complex entity' do
492
- expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_external_to).once.with(nil, [mapped_entity_with_idmap], 'ext1', nil)
493
- expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_external_to).twice
494
- subject.push_entities_to_external(nil, connec_hash, nil)
335
+ it 'calls push_entities_to_connec on each sub complex entity' do
336
+ expect_any_instance_of(Entities::SubEntities::ScE1).to receive(:push_entities_to_external_to).once.with([mapped_entity_with_idmap], 'ext1')
337
+ expect_any_instance_of(Entities::SubEntities::ScE2).to receive(:push_entities_to_external_to).twice
338
+ subject.push_entities_to_external(connec_hash)
339
+ end
495
340
  end
496
341
  end
497
342
  end